From 69982a8358dbea4b476fa55d278e9fff31b48bd5 Mon Sep 17 00:00:00 2001 From: Eddy Filip Date: Thu, 2 May 2024 18:56:39 +0200 Subject: [PATCH 01/36] Update all Go packages to the latest version Run the following commands: - `go get -u ./...` - `go mod tidy` - `go mod vendor` With this, we also update Go version to 1.21. --- go.mod | 68 +- go.sum | 199 +- .../connect-sdk-go/connect/client.go | 10 +- .../connect-sdk-go/connect/version.go | 2 +- .../connect-sdk-go/onepassword/vaults.go | 2 +- .../Masterminds/semver/v3/.golangci.yml | 23 +- .../Masterminds/semver/v3/CHANGELOG.md | 20 + .../github.com/Masterminds/semver/v3/Makefile | 17 +- .../Masterminds/semver/v3/README.md | 22 +- .../Masterminds/semver/v3/SECURITY.md | 19 + .../Masterminds/semver/v3/constraints.go | 32 +- .../github.com/Masterminds/semver/v3/doc.go | 178 +- .../github.com/Masterminds/semver/v3/fuzz.go | 22 - .../Masterminds/semver/v3/version.go | 47 +- .../Masterminds/sprig/v3/CHANGELOG.md | 15 +- .../github.com/Masterminds/sprig/v3/README.md | 9 +- .../go-crypto/bitcurves/bitcurve.go | 4 +- .../ProtonMail/go-crypto/brainpool/rcurve.go | 2 +- .../ProtonMail/go-crypto/eax/eax.go | 4 +- .../go-crypto/internal/byteutil/byteutil.go | 8 +- .../ProtonMail/go-crypto/ocb/ocb.go | 15 +- .../ocb/rfc7253_test_vectors_suite_b.go | 31 +- .../go-crypto/openpgp/armor/armor.go | 87 +- .../go-crypto/openpgp/armor/encode.go | 80 +- .../go-crypto/openpgp/canonical_text.go | 12 +- .../ProtonMail/go-crypto/openpgp/ecdh/ecdh.go | 14 +- .../go-crypto/openpgp/ecdsa/ecdsa.go | 2 +- .../go-crypto/openpgp/ed25519/ed25519.go | 115 + .../go-crypto/openpgp/ed448/ed448.go | 119 + .../go-crypto/openpgp/eddsa/eddsa.go | 2 +- .../go-crypto/openpgp/elgamal/elgamal.go | 4 +- .../go-crypto/openpgp/errors/errors.go | 29 +- .../ProtonMail/go-crypto/openpgp/hash.go | 24 + .../openpgp/internal/algorithm/cipher.go | 12 +- .../openpgp/internal/algorithm/hash.go | 38 +- .../openpgp/internal/ecc/curve25519.go | 6 +- .../openpgp/internal/ecc/curve_info.go | 51 +- .../go-crypto/openpgp/internal/ecc/curves.go | 2 +- .../go-crypto/openpgp/internal/ecc/ed25519.go | 7 +- .../go-crypto/openpgp/internal/ecc/ed448.go | 8 +- .../go-crypto/openpgp/internal/ecc/x448.go | 10 +- .../go-crypto/openpgp/key_generation.go | 106 +- .../ProtonMail/go-crypto/openpgp/keys.go | 185 +- .../go-crypto/openpgp/packet/aead_crypter.go | 34 +- .../go-crypto/openpgp/packet/compressed.go | 45 +- .../go-crypto/openpgp/packet/config.go | 160 +- .../go-crypto/openpgp/packet/encrypted_key.go | 413 +- .../go-crypto/openpgp/packet/literal.go | 6 +- .../go-crypto/openpgp/packet/marker.go | 33 + .../openpgp/packet/one_pass_signature.go | 134 +- .../go-crypto/openpgp/packet/opaque.go | 3 +- .../go-crypto/openpgp/packet/packet.go | 170 +- .../openpgp/packet/packet_sequence.go | 222 + .../openpgp/packet/packet_unsupported.go | 24 + .../go-crypto/openpgp/packet/padding.go | 27 + .../go-crypto/openpgp/packet/private_key.go | 644 +- .../go-crypto/openpgp/packet/public_key.go | 401 +- .../go-crypto/openpgp/packet/reader.go | 159 +- .../go-crypto/openpgp/packet/recipient.go | 15 + .../go-crypto/openpgp/packet/signature.go | 451 +- .../openpgp/packet/symmetric_key_encrypted.go | 64 +- .../openpgp/packet/symmetrically_encrypted.go | 13 +- .../packet/symmetrically_encrypted_aead.go | 39 +- .../packet/symmetrically_encrypted_mdc.go | 7 +- .../go-crypto/openpgp/packet/userattribute.go | 3 +- .../go-crypto/openpgp/packet/userid.go | 3 +- .../ProtonMail/go-crypto/openpgp/read.go | 136 +- .../go-crypto/openpgp/read_write_test_data.go | 201 +- .../ProtonMail/go-crypto/openpgp/s2k/s2k.go | 269 +- .../go-crypto/openpgp/s2k/s2k_cache.go | 26 + .../go-crypto/openpgp/s2k/s2k_config.go | 129 + .../ProtonMail/go-crypto/openpgp/write.go | 65 +- .../go-crypto/openpgp/x25519/x25519.go | 221 + .../ProtonMail/go-crypto/openpgp/x448/x448.go | 229 + .../v13/textseg/grapheme_clusters.go | 4138 ---- .../go-textseg/{v13 => v15}/LICENSE | 0 .../{v13 => v15}/textseg/all_tokens.go | 0 .../{v13 => v15}/textseg/emoji_table.rl | 54 +- .../{v13 => v15}/textseg/generate.go | 4 +- .../v15/textseg/grapheme_clusters.go | 4349 ++++ .../{v13 => v15}/textseg/grapheme_clusters.rl | 0 .../textseg/grapheme_clusters_table.rl | 48 +- .../go-textseg/{v13 => v15}/textseg/tables.go | 425 +- .../{v13 => v15}/textseg/unicode2ragel.rb | 0 .../{v13 => v15}/textseg/utf8_seqs.go | 0 vendor/github.com/fatih/color/color.go | 56 +- .../golang/protobuf/jsonpb/decode.go | 530 - .../golang/protobuf/jsonpb/encode.go | 559 - .../github.com/golang/protobuf/jsonpb/json.go | 69 - .../github.com/golang/protobuf/ptypes/any.go | 179 - .../golang/protobuf/ptypes/any/any.pb.go | 62 - .../github.com/golang/protobuf/ptypes/doc.go | 10 - .../golang/protobuf/ptypes/duration.go | 76 - .../protobuf/ptypes/duration/duration.pb.go | 63 - .../golang/protobuf/ptypes/timestamp.go | 112 - .../protobuf/ptypes/timestamp/timestamp.pb.go | 64 - .../github.com/google/go-cmp/cmp/compare.go | 38 +- .../cmp/{export_unsafe.go => export.go} | 5 - .../google/go-cmp/cmp/export_panic.go | 16 - .../value/{pointer_unsafe.go => pointer.go} | 3 - .../cmp/internal/value/pointer_purego.go | 34 - .../github.com/google/go-cmp/cmp/options.go | 84 +- vendor/github.com/google/go-cmp/cmp/path.go | 46 +- .../google/go-cmp/cmp/report_reflect.go | 2 +- vendor/github.com/google/uuid/.travis.yml | 9 - vendor/github.com/google/uuid/CHANGELOG.md | 41 + vendor/github.com/google/uuid/CONTRIBUTING.md | 16 + vendor/github.com/google/uuid/README.md | 10 +- vendor/github.com/google/uuid/hash.go | 6 + vendor/github.com/google/uuid/node_js.go | 2 +- vendor/github.com/google/uuid/time.go | 21 +- vendor/github.com/google/uuid/uuid.go | 89 +- vendor/github.com/google/uuid/version6.go | 56 + vendor/github.com/google/uuid/version7.go | 104 + .../github.com/hashicorp/go-hclog/README.md | 5 +- .../hashicorp/go-hclog/intlogger.go | 135 +- .../github.com/hashicorp/go-hclog/logger.go | 22 + .../hashicorp/go-plugin/CHANGELOG.md | 55 +- .../hashicorp/go-plugin/buf.gen.yaml | 14 + .../github.com/hashicorp/go-plugin/buf.yaml | 7 + .../github.com/hashicorp/go-plugin/client.go | 396 +- .../hashicorp/go-plugin/constants.go | 16 + .../hashicorp/go-plugin/grpc_broker.go | 242 +- .../hashicorp/go-plugin/grpc_client.go | 7 +- .../hashicorp/go-plugin/grpc_server.go | 5 +- .../internal/cmdrunner/addr_translator.go | 16 + .../internal/cmdrunner/cmd_reattach.go | 63 + .../internal/cmdrunner/cmd_runner.go | 129 + .../{ => internal/cmdrunner}/notes_unix.go | 2 +- .../{ => internal/cmdrunner}/notes_windows.go | 2 +- .../go-plugin/internal/cmdrunner/process.go | 25 + .../{ => internal/cmdrunner}/process_posix.go | 2 +- .../cmdrunner}/process_windows.go | 2 +- .../grpcmux/blocked_client_listener.go | 51 + .../grpcmux/blocked_server_listener.go | 49 + .../internal/grpcmux/grpc_client_muxer.go | 105 + .../go-plugin/internal/grpcmux/grpc_muxer.go | 41 + .../internal/grpcmux/grpc_server_muxer.go | 190 + .../go-plugin/internal/plugin/gen.go | 6 - .../internal/plugin/grpc_broker.pb.go | 347 +- .../internal/plugin/grpc_broker.proto | 8 +- .../internal/plugin/grpc_broker_grpc.pb.go | 142 + .../internal/plugin/grpc_controller.pb.go | 224 +- .../internal/plugin/grpc_controller.proto | 2 +- .../plugin/grpc_controller_grpc.pb.go | 110 + .../internal/plugin/grpc_stdio.pb.go | 356 +- .../internal/plugin/grpc_stdio.proto | 2 +- .../internal/plugin/grpc_stdio_grpc.pb.go | 148 + .../github.com/hashicorp/go-plugin/process.go | 23 - .../hashicorp/go-plugin/runner/runner.go | 72 + .../github.com/hashicorp/go-plugin/server.go | 101 +- .../github.com/hashicorp/go-plugin/testing.go | 56 +- .../hashicorp/hc-install/.go-version | 2 +- .../github.com/hashicorp/hc-install/README.md | 7 +- .../hc-install/checkpoint/latest_version.go | 2 +- .../internal/build/install_go_version.go | 17 +- .../internal/releasesjson/downloader.go | 24 +- .../internal/releasesjson/releases.go | 20 - .../hashicorp/hc-install/product/nomad.go | 54 + .../hc-install/releases/enterprise.go | 38 + .../hc-install/releases/exact_version.go | 37 +- .../hc-install/releases/latest_version.go | 22 +- .../hashicorp/hc-install/releases/versions.go | 19 + .../hashicorp/hc-install/version/VERSION | 2 +- .../github.com/hashicorp/hcl/v2/CHANGELOG.md | 60 +- vendor/github.com/hashicorp/hcl/v2/Makefile | 18 + .../hashicorp/hcl/v2/hclsyntax/expression.go | 239 +- .../hcl/v2/hclsyntax/expression_template.go | 11 +- .../hcl/v2/hclsyntax/expression_vars.go | 6 +- .../hashicorp/hcl/v2/hclsyntax/generate.go | 2 +- .../hashicorp/hcl/v2/hclsyntax/parser.go | 78 +- .../hcl/v2/hclsyntax/parser_template.go | 2 +- .../hcl/v2/hclsyntax/scan_string_lit.go | 25 +- .../hcl/v2/hclsyntax/scan_string_lit.rl | 2 + .../hashicorp/hcl/v2/hclsyntax/scan_tokens.go | 1101 +- .../hashicorp/hcl/v2/hclsyntax/scan_tokens.rl | 4 + .../hashicorp/hcl/v2/hclsyntax/spec.md | 2 +- .../hashicorp/hcl/v2/hclsyntax/token.go | 7 +- .../hcl/v2/hclsyntax/token_type_string.go | 12 +- .../hashicorp/hcl/v2/pos_scanner.go | 2 +- vendor/github.com/hashicorp/hcl/v2/tools.go | 11 + .../internal/version/version.go | 5 +- .../hashicorp/terraform-exec/tfexec/apply.go | 33 + .../hashicorp/terraform-exec/tfexec/cmd.go | 5 +- .../terraform-exec/tfexec/cmd_default.go | 3 + .../terraform-exec/tfexec/cmd_linux.go | 3 + .../terraform-exec/tfexec/destroy.go | 3 + .../hashicorp/terraform-exec/tfexec/doc.go | 3 + .../hashicorp/terraform-exec/tfexec/errors.go | 3 + .../hashicorp/terraform-exec/tfexec/fmt.go | 3 + .../terraform-exec/tfexec/force_unlock.go | 3 + .../hashicorp/terraform-exec/tfexec/get.go | 3 + .../hashicorp/terraform-exec/tfexec/graph.go | 5 +- .../hashicorp/terraform-exec/tfexec/import.go | 3 + .../hashicorp/terraform-exec/tfexec/init.go | 3 + .../tfexec/metadata_functions.go | 3 + .../terraform-exec/tfexec/options.go | 29 + .../hashicorp/terraform-exec/tfexec/output.go | 3 + .../hashicorp/terraform-exec/tfexec/plan.go | 19 + .../terraform-exec/tfexec/providers_lock.go | 3 + .../terraform-exec/tfexec/providers_schema.go | 3 + .../terraform-exec/tfexec/refresh.go | 3 + .../hashicorp/terraform-exec/tfexec/show.go | 23 + .../terraform-exec/tfexec/state_mv.go | 3 + .../terraform-exec/tfexec/state_pull.go | 3 + .../terraform-exec/tfexec/state_push.go | 3 + .../terraform-exec/tfexec/state_rm.go | 3 + .../hashicorp/terraform-exec/tfexec/taint.go | 3 + .../terraform-exec/tfexec/terraform.go | 3 + .../hashicorp/terraform-exec/tfexec/test.go | 66 + .../terraform-exec/tfexec/untaint.go | 3 + .../terraform-exec/tfexec/upgrade012.go | 3 + .../terraform-exec/tfexec/upgrade013.go | 3 + .../terraform-exec/tfexec/validate.go | 3 + .../terraform-exec/tfexec/version.go | 5 + .../terraform-exec/tfexec/workspace_delete.go | 3 + .../terraform-exec/tfexec/workspace_list.go | 3 + .../terraform-exec/tfexec/workspace_new.go | 3 + .../terraform-exec/tfexec/workspace_select.go | 3 + .../terraform-exec/tfexec/workspace_show.go | 3 + .../hashicorp/terraform-json/README.md | 34 +- .../hashicorp/terraform-json/metadata.go | 8 + .../hashicorp/terraform-json/plan.go | 34 +- .../hashicorp/terraform-json/schemas.go | 3 + .../hashicorp/terraform-json/state.go | 2 +- .../internal/logging/keys.go | 15 + .../tfprotov5/data_source.go | 7 + .../terraform-plugin-go/tfprotov5/function.go | 141 + .../tfprotov5/function_error.go | 14 + .../internal/fromproto/attribute_path.go | 66 - .../internal/fromproto/data_source.go | 50 +- .../internal/fromproto/diagnostic.go | 45 - .../tfprotov5/internal/fromproto/doc.go | 6 + .../fromproto/{types.go => dynamic_value.go} | 8 +- .../tfprotov5/internal/fromproto/function.go | 36 + .../tfprotov5/internal/fromproto/provider.go | 118 +- .../fromproto/{state.go => raw_state.go} | 8 +- .../tfprotov5/internal/fromproto/resource.go | 220 +- .../tfprotov5/internal/fromproto/schema.go | 117 - .../internal/fromproto/string_kind.go | 13 - .../tfprotov5/internal/funcerr/doc.go | 6 + .../internal/funcerr/function_error.go | 50 + .../tf5serverlogging/downstream_request.go | 22 + .../tf5serverlogging/server_capabilities.go | 26 + .../internal/tfplugin5/tfplugin5.pb.go | 3555 +++- .../internal/tfplugin5/tfplugin5.proto | 216 +- .../internal/tfplugin5/tfplugin5_grpc.pb.go | 176 +- .../internal/toproto/attribute_path.go | 128 +- .../tfprotov5/internal/toproto/data_source.go | 67 +- .../tfprotov5/internal/toproto/diagnostic.go | 56 +- .../tfprotov5/internal/toproto/doc.go | 6 + .../internal/toproto/dynamic_value.go | 38 +- .../tfprotov5/internal/toproto/function.go | 102 + .../internal/toproto/function_error.go | 22 + .../tfprotov5/internal/toproto/provider.go | 173 +- .../tfprotov5/internal/toproto/resource.go | 246 +- .../tfprotov5/internal/toproto/schema.go | 138 +- .../internal/toproto/server_capabilities.go | 10 +- .../tfprotov5/internal/toproto/state.go | 21 - .../tfprotov5/internal/toproto/string_kind.go | 11 +- .../terraform-plugin-go/tfprotov5/provider.go | 49 + .../terraform-plugin-go/tfprotov5/resource.go | 72 + .../tfprotov5/server_capabilities.go | 9 + .../tfprotov5/tf5server/server.go | 538 +- .../tfprotov6/data_source.go | 7 + .../terraform-plugin-go/tfprotov6/function.go | 141 + .../tfprotov6/function_error.go | 14 + .../internal/fromproto/attribute_path.go | 66 - .../internal/fromproto/data_source.go | 50 +- .../internal/fromproto/diagnostic.go | 45 - .../tfprotov6/internal/fromproto/doc.go | 6 + .../fromproto/{types.go => dynamic_value.go} | 8 +- .../tfprotov6/internal/fromproto/function.go | 36 + .../tfprotov6/internal/fromproto/provider.go | 115 +- .../fromproto/{state.go => raw_state.go} | 8 +- .../tfprotov6/internal/fromproto/resource.go | 220 +- .../tfprotov6/internal/fromproto/schema.go | 147 - .../internal/fromproto/string_kind.go | 13 - .../tfprotov6/internal/funcerr/doc.go | 6 + .../internal/funcerr/function_error.go | 50 + .../tf6serverlogging/downstream_request.go | 22 + .../tf6serverlogging/server_capabilities.go | 26 + .../internal/tfplugin6/tfplugin6.pb.go | 4701 +++-- .../internal/tfplugin6/tfplugin6.proto | 214 +- .../internal/tfplugin6/tfplugin6_grpc.pb.go | 176 +- .../internal/toproto/attribute_path.go | 128 +- .../tfprotov6/internal/toproto/data_source.go | 65 +- .../tfprotov6/internal/toproto/diagnostic.go | 56 +- .../tfprotov6/internal/toproto/doc.go | 6 + .../internal/toproto/dynamic_value.go | 38 +- .../tfprotov6/internal/toproto/function.go | 100 + .../internal/toproto/function_error.go | 22 + .../tfprotov6/internal/toproto/provider.go | 171 +- .../tfprotov6/internal/toproto/resource.go | 246 +- .../tfprotov6/internal/toproto/schema.go | 164 +- .../internal/toproto/server_capabilities.go | 10 +- .../tfprotov6/internal/toproto/state.go | 21 - .../tfprotov6/internal/toproto/string_kind.go | 11 +- .../terraform-plugin-go/tfprotov6/provider.go | 49 + .../terraform-plugin-go/tfprotov6/resource.go | 72 + .../tfprotov6/server_capabilities.go | 9 + .../tfprotov6/tf6server/server.go | 540 +- .../terraform-plugin-go/tftypes/list.go | 17 +- .../terraform-plugin-go/tftypes/map.go | 17 +- .../terraform-plugin-go/tftypes/object.go | 93 +- .../terraform-plugin-go/tftypes/primitive.go | 5 +- .../terraform-plugin-go/tftypes/set.go | 17 +- .../terraform-plugin-go/tftypes/tuple.go | 23 +- .../terraform-plugin-go/tftypes/type.go | 2 +- .../terraform-plugin-go/tftypes/value.go | 2 +- .../tftypes/value_msgpack.go | 2 +- .../v2/helper/schema/grpc_provider.go | 139 +- .../v2/helper/schema/provider.go | 21 +- .../v2/helper/schema/resource.go | 45 + .../v2/helper/schema/resource_data.go | 6 + .../v2/helper/validation/meta.go | 28 + .../v2/helper/validation/strings.go | 2 +- .../v2/helper/validation/testing.go | 56 +- .../terraform-plugin-sdk/v2/meta/meta.go | 11 +- .../v2/terraform/resource.go | 19 + .../v2/terraform/state.go | 8 +- vendor/github.com/huandu/xstrings/.travis.yml | 7 - vendor/github.com/huandu/xstrings/README.md | 182 +- vendor/github.com/huandu/xstrings/convert.go | 2 +- .../github.com/imdario/mergo/CONTRIBUTING.md | 112 + vendor/github.com/imdario/mergo/README.md | 5 +- vendor/github.com/imdario/mergo/SECURITY.md | 14 + vendor/github.com/imdario/mergo/map.go | 6 +- vendor/github.com/imdario/mergo/merge.go | 59 +- vendor/github.com/imdario/mergo/mergo.go | 11 +- .../github.com/mattn/go-isatty/isatty_bsd.go | 3 +- .../mattn/go-isatty/isatty_others.go | 5 +- .../mattn/go-isatty/isatty_tcgets.go | 3 +- .../vmihailenco/msgpack/v5/CHANGELOG.md | 26 +- .../vmihailenco/msgpack/v5/README.md | 30 +- .../vmihailenco/msgpack/v5/decode.go | 81 +- .../vmihailenco/msgpack/v5/decode_map.go | 39 +- .../vmihailenco/msgpack/v5/decode_query.go | 3 +- .../vmihailenco/msgpack/v5/decode_slice.go | 23 +- .../vmihailenco/msgpack/v5/decode_typgen.go | 46 + .../vmihailenco/msgpack/v5/decode_value.go | 7 +- .../vmihailenco/msgpack/v5/encode.go | 21 +- .../vmihailenco/msgpack/v5/encode_map.go | 48 +- .../vmihailenco/msgpack/v5/encode_value.go | 9 + .../github.com/vmihailenco/msgpack/v5/ext.go | 8 +- .../vmihailenco/msgpack/v5/intern.go | 18 +- .../vmihailenco/msgpack/v5/msgpack.go | 2 +- .../vmihailenco/msgpack/v5/package.json | 2 +- .../github.com/vmihailenco/msgpack/v5/time.go | 8 +- .../vmihailenco/msgpack/v5/types.go | 24 +- .../vmihailenco/msgpack/v5/version.go | 2 +- .../go-cty/cty/convert/conversion_dynamic.go | 29 +- .../zclconf/go-cty/cty/ctystrings/prefix.go | 6 +- .../go-cty/cty/function/stdlib/collection.go | 4 +- .../go-cty/cty/function/stdlib/conversion.go | 5 +- .../go-cty/cty/function/stdlib/format.go | 2 +- .../go-cty/cty/function/stdlib/string.go | 2 +- .../zclconf/go-cty/cty/json/marshal.go | 12 +- .../zclconf/go-cty/cty/primitive_type.go | 16 +- .../zclconf/go-cty/cty/unknown_refinement.go | 61 +- .../zclconf/go-cty/cty/value_range.go | 4 + vendor/golang.org/x/crypto/argon2/argon2.go | 283 + vendor/golang.org/x/crypto/argon2/blake2b.go | 53 + .../x/crypto/argon2/blamka_amd64.go | 60 + .../golang.org/x/crypto/argon2/blamka_amd64.s | 243 + .../x/crypto/argon2/blamka_generic.go | 163 + .../golang.org/x/crypto/argon2/blamka_ref.go | 15 + vendor/golang.org/x/crypto/blake2b/blake2b.go | 291 + .../x/crypto/blake2b/blake2bAVX2_amd64.go | 37 + .../x/crypto/blake2b/blake2bAVX2_amd64.s | 744 + .../x/crypto/blake2b/blake2b_amd64.s | 278 + .../x/crypto/blake2b/blake2b_generic.go | 182 + .../x/crypto/blake2b/blake2b_ref.go | 11 + vendor/golang.org/x/crypto/blake2b/blake2x.go | 177 + .../golang.org/x/crypto/blake2b/register.go | 30 + .../x/mod/internal/lazyregexp/lazyre.go | 2 +- vendor/golang.org/x/mod/modfile/read.go | 4 +- vendor/golang.org/x/mod/modfile/rule.go | 43 +- vendor/golang.org/x/mod/modfile/work.go | 4 +- vendor/golang.org/x/mod/module/module.go | 30 +- vendor/golang.org/x/mod/module/pseudo.go | 2 +- vendor/golang.org/x/mod/semver/semver.go | 6 +- vendor/golang.org/x/net/context/context.go | 56 - vendor/golang.org/x/net/context/go17.go | 73 - vendor/golang.org/x/net/context/go19.go | 21 - vendor/golang.org/x/net/context/pre_go17.go | 301 - vendor/golang.org/x/net/context/pre_go19.go | 110 - vendor/golang.org/x/net/http2/databuffer.go | 59 +- vendor/golang.org/x/net/http2/frame.go | 42 +- vendor/golang.org/x/net/http2/go111.go | 30 - vendor/golang.org/x/net/http2/go115.go | 27 - vendor/golang.org/x/net/http2/go118.go | 17 - vendor/golang.org/x/net/http2/not_go111.go | 21 - vendor/golang.org/x/net/http2/not_go115.go | 31 - vendor/golang.org/x/net/http2/not_go118.go | 17 - vendor/golang.org/x/net/http2/pipe.go | 11 +- vendor/golang.org/x/net/http2/server.go | 37 +- vendor/golang.org/x/net/http2/testsync.go | 331 + vendor/golang.org/x/net/http2/transport.go | 340 +- vendor/golang.org/x/net/idna/go118.go | 1 - vendor/golang.org/x/net/idna/idna10.0.0.go | 1 - vendor/golang.org/x/net/idna/idna9.0.0.go | 1 - vendor/golang.org/x/net/idna/pre_go118.go | 1 - vendor/golang.org/x/net/idna/tables10.0.0.go | 1 - vendor/golang.org/x/net/idna/tables11.0.0.go | 1 - vendor/golang.org/x/net/idna/tables12.0.0.go | 1 - vendor/golang.org/x/net/idna/tables13.0.0.go | 1 - vendor/golang.org/x/net/idna/tables15.0.0.go | 1 - vendor/golang.org/x/net/idna/tables9.0.0.go | 1 - vendor/golang.org/x/net/idna/trie12.0.0.go | 1 - vendor/golang.org/x/net/idna/trie13.0.0.go | 1 - vendor/golang.org/x/sync/LICENSE | 27 + vendor/golang.org/x/sync/PATENTS | 22 + vendor/golang.org/x/sync/errgroup/errgroup.go | 135 + vendor/golang.org/x/sync/errgroup/go120.go | 13 + .../golang.org/x/sync/errgroup/pre_go120.go | 14 + vendor/golang.org/x/sys/unix/aliases.go | 2 +- vendor/golang.org/x/sys/unix/mkerrors.sh | 39 +- vendor/golang.org/x/sys/unix/mmap_nomremap.go | 2 +- .../x/sys/unix/syscall_darwin_libSystem.go | 2 +- .../golang.org/x/sys/unix/syscall_freebsd.go | 12 +- vendor/golang.org/x/sys/unix/syscall_linux.go | 99 + .../x/sys/unix/syscall_zos_s390x.go | 8 + vendor/golang.org/x/sys/unix/zerrors_linux.go | 90 +- .../x/sys/unix/zerrors_linux_386.go | 3 + .../x/sys/unix/zerrors_linux_amd64.go | 3 + .../x/sys/unix/zerrors_linux_arm.go | 3 + .../x/sys/unix/zerrors_linux_arm64.go | 3 + .../x/sys/unix/zerrors_linux_loong64.go | 3 + .../x/sys/unix/zerrors_linux_mips.go | 3 + .../x/sys/unix/zerrors_linux_mips64.go | 3 + .../x/sys/unix/zerrors_linux_mips64le.go | 3 + .../x/sys/unix/zerrors_linux_mipsle.go | 3 + .../x/sys/unix/zerrors_linux_ppc.go | 3 + .../x/sys/unix/zerrors_linux_ppc64.go | 3 + .../x/sys/unix/zerrors_linux_ppc64le.go | 3 + .../x/sys/unix/zerrors_linux_riscv64.go | 3 + .../x/sys/unix/zerrors_linux_s390x.go | 3 + .../x/sys/unix/zerrors_linux_sparc64.go | 3 + .../golang.org/x/sys/unix/zsyscall_linux.go | 10 + .../x/sys/unix/zsyscall_openbsd_386.go | 2 - .../x/sys/unix/zsyscall_openbsd_amd64.go | 2 - .../x/sys/unix/zsyscall_openbsd_arm.go | 2 - .../x/sys/unix/zsyscall_openbsd_arm64.go | 2 - .../x/sys/unix/zsyscall_openbsd_mips64.go | 2 - .../x/sys/unix/zsyscall_openbsd_ppc64.go | 2 - .../x/sys/unix/zsyscall_openbsd_riscv64.go | 2 - .../x/sys/unix/zsysnum_linux_386.go | 4 + .../x/sys/unix/zsysnum_linux_amd64.go | 3 + .../x/sys/unix/zsysnum_linux_arm.go | 4 + .../x/sys/unix/zsysnum_linux_arm64.go | 4 + .../x/sys/unix/zsysnum_linux_loong64.go | 4 + .../x/sys/unix/zsysnum_linux_mips.go | 4 + .../x/sys/unix/zsysnum_linux_mips64.go | 4 + .../x/sys/unix/zsysnum_linux_mips64le.go | 4 + .../x/sys/unix/zsysnum_linux_mipsle.go | 4 + .../x/sys/unix/zsysnum_linux_ppc.go | 4 + .../x/sys/unix/zsysnum_linux_ppc64.go | 4 + .../x/sys/unix/zsysnum_linux_ppc64le.go | 4 + .../x/sys/unix/zsysnum_linux_riscv64.go | 4 + .../x/sys/unix/zsysnum_linux_s390x.go | 4 + .../x/sys/unix/zsysnum_linux_sparc64.go | 4 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 185 +- .../golang.org/x/sys/windows/env_windows.go | 17 +- .../x/sys/windows/syscall_windows.go | 86 +- .../golang.org/x/sys/windows/types_windows.go | 24 + .../x/sys/windows/zsyscall_windows.go | 117 + vendor/golang.org/x/tools/LICENSE | 27 + vendor/golang.org/x/tools/PATENTS | 22 + .../x/tools/cmd/stringer/stringer.go | 660 + .../x/tools/go/gcexportdata/gcexportdata.go | 186 + .../x/tools/go/gcexportdata/importer.go | 75 + .../tools/go/internal/packagesdriver/sizes.go | 53 + vendor/golang.org/x/tools/go/packages/doc.go | 250 + .../x/tools/go/packages/external.go | 140 + .../golang.org/x/tools/go/packages/golist.go | 1106 + .../x/tools/go/packages/golist_overlay.go | 83 + .../x/tools/go/packages/loadmode_string.go | 57 + .../x/tools/go/packages/packages.go | 1426 ++ .../golang.org/x/tools/go/packages/visit.go | 59 + .../x/tools/go/types/objectpath/objectpath.go | 753 + .../x/tools/internal/aliases/aliases.go | 28 + .../x/tools/internal/aliases/aliases_go121.go | 30 + .../x/tools/internal/aliases/aliases_go122.go | 72 + .../x/tools/internal/event/core/event.go | 85 + .../x/tools/internal/event/core/export.go | 70 + .../x/tools/internal/event/core/fast.go | 77 + .../golang.org/x/tools/internal/event/doc.go | 7 + .../x/tools/internal/event/event.go | 127 + .../x/tools/internal/event/keys/keys.go | 564 + .../x/tools/internal/event/keys/standard.go | 22 + .../x/tools/internal/event/keys/util.go | 21 + .../x/tools/internal/event/label/label.go | 215 + .../x/tools/internal/event/tag/tag.go | 59 + .../x/tools/internal/gcimporter/bimport.go | 150 + .../x/tools/internal/gcimporter/exportdata.go | 99 + .../x/tools/internal/gcimporter/gcimporter.go | 266 + .../x/tools/internal/gcimporter/iexport.go | 1349 ++ .../x/tools/internal/gcimporter/iimport.go | 1098 + .../internal/gcimporter/newInterface10.go | 22 + .../internal/gcimporter/newInterface11.go | 14 + .../internal/gcimporter/support_go118.go | 34 + .../x/tools/internal/gcimporter/unified_no.go | 10 + .../tools/internal/gcimporter/unified_yes.go | 10 + .../tools/internal/gcimporter/ureader_yes.go | 726 + .../x/tools/internal/gocommand/invoke.go | 468 + .../x/tools/internal/gocommand/vendor.go | 109 + .../x/tools/internal/gocommand/version.go | 71 + .../internal/packagesinternal/packages.go | 22 + .../x/tools/internal/pkgbits/codes.go | 77 + .../x/tools/internal/pkgbits/decoder.go | 517 + .../x/tools/internal/pkgbits/doc.go | 32 + .../x/tools/internal/pkgbits/encoder.go | 383 + .../x/tools/internal/pkgbits/flags.go | 9 + .../x/tools/internal/pkgbits/frames_go1.go | 21 + .../x/tools/internal/pkgbits/frames_go17.go | 28 + .../x/tools/internal/pkgbits/reloc.go | 42 + .../x/tools/internal/pkgbits/support.go | 17 + .../x/tools/internal/pkgbits/sync.go | 113 + .../internal/pkgbits/syncmarker_string.go | 89 + .../x/tools/internal/stdlib/manifest.go | 17320 ++++++++++++++++ .../x/tools/internal/stdlib/stdlib.go | 97 + .../internal/tokeninternal/tokeninternal.go | 137 + .../tools/internal/typesinternal/errorcode.go | 1560 ++ .../typesinternal/errorcode_string.go | 179 + .../x/tools/internal/typesinternal/recv.go | 43 + .../x/tools/internal/typesinternal/toonew.go | 89 + .../x/tools/internal/typesinternal/types.go | 50 + .../x/tools/internal/versions/features.go | 43 + .../x/tools/internal/versions/gover.go | 172 + .../x/tools/internal/versions/toolchain.go | 14 + .../internal/versions/toolchain_go119.go | 14 + .../internal/versions/toolchain_go120.go | 14 + .../internal/versions/toolchain_go121.go | 14 + .../x/tools/internal/versions/types.go | 19 + .../x/tools/internal/versions/types_go121.go | 30 + .../x/tools/internal/versions/types_go122.go | 41 + .../x/tools/internal/versions/versions.go | 57 + .../google.golang.org/appengine/.travis.yml | 18 - .../appengine/CONTRIBUTING.md | 6 +- vendor/google.golang.org/appengine/README.md | 6 +- .../google.golang.org/appengine/appengine.go | 23 +- .../appengine/appengine_vm.go | 12 +- .../appengine/datastore/datastore.go | 2 +- .../appengine/datastore/doc.go | 21 +- .../appengine/datastore/key.go | 2 +- .../appengine/datastore/keycompat.go | 3 +- .../appengine/datastore/metadata.go | 17 +- .../appengine/datastore/query.go | 6 +- .../appengine/datastore/transaction.go | 3 +- .../google.golang.org/appengine/identity.go | 3 +- .../appengine/internal/api.go | 347 +- .../appengine/internal/api_classic.go | 29 +- .../appengine/internal/api_common.go | 50 +- .../appengine/internal/identity.go | 7 +- .../appengine/internal/identity_classic.go | 23 +- .../appengine/internal/identity_flex.go | 1 + .../appengine/internal/identity_vm.go | 20 +- .../appengine/internal/main.go | 1 + .../appengine/internal/main_vm.go | 3 +- .../appengine/internal/transaction.go | 10 +- .../google.golang.org/appengine/namespace.go | 3 +- vendor/google.golang.org/appengine/timeout.go | 2 +- .../appengine/travis_install.sh | 18 - .../appengine/travis_test.sh | 12 - vendor/google.golang.org/grpc/README.md | 60 +- .../grpc/attributes/attributes.go | 59 +- .../grpc/balancer/balancer.go | 69 +- .../grpc/balancer/base/balancer.go | 22 +- .../grpc/balancer_conn_wrappers.go | 459 - .../grpc/balancer_wrapper.go | 337 + .../grpc_binarylog_v1/binarylog.pb.go | 6 +- vendor/google.golang.org/grpc/call.go | 11 +- vendor/google.golang.org/grpc/clientconn.go | 903 +- vendor/google.golang.org/grpc/codec.go | 8 +- vendor/google.golang.org/grpc/codes/codes.go | 8 +- .../grpc/credentials/credentials.go | 4 +- .../google.golang.org/grpc/credentials/tls.go | 75 +- vendor/google.golang.org/grpc/dialoptions.go | 98 +- .../grpc/encoding/encoding.go | 17 +- .../grpc/encoding/proto/proto.go | 28 +- .../grpc/grpclog/component.go | 40 +- .../google.golang.org/grpc/grpclog/grpclog.go | 30 +- .../google.golang.org/grpc/grpclog/logger.go | 30 +- .../grpc/grpclog/loggerv2.go | 56 +- .../google.golang.org/grpc/health/client.go | 2 +- .../grpc/health/grpc_health_v1/health.pb.go | 4 +- .../health/grpc_health_v1/health_grpc.pb.go | 24 +- vendor/google.golang.org/grpc/idle.go | 287 - vendor/google.golang.org/grpc/interceptor.go | 12 +- .../grpc/internal/backoff/backoff.go | 36 + .../balancer/gracefulswitch/config.go | 83 + .../balancer/gracefulswitch/gracefulswitch.go | 104 +- .../grpc/internal/balancerload/load.go | 4 +- .../grpc/internal/binarylog/method_logger.go | 13 +- .../grpc/internal/binarylog/sink.go | 2 +- .../grpc/internal/buffer/unbounded.go | 57 +- .../grpc/internal/channelz/channel.go | 255 + .../grpc/internal/channelz/channelmap.go | 402 + .../grpc/internal/channelz/funcs.go | 761 +- .../grpc/internal/channelz/id.go | 75 - .../grpc/internal/channelz/logging.go | 28 +- .../grpc/internal/channelz/server.go | 119 + .../grpc/internal/channelz/socket.go | 130 + .../grpc/internal/channelz/subchannel.go | 151 + .../{types_linux.go => syscall_linux.go} | 14 + ...{types_nonlinux.go => syscall_nonlinux.go} | 6 +- .../grpc/internal/channelz/trace.go | 204 + .../grpc/internal/channelz/types.go | 722 - .../grpc/internal/credentials/credentials.go | 8 +- .../grpc/internal/envconfig/envconfig.go | 11 +- .../grpc/internal/envconfig/xds.go | 39 - .../grpc/internal/experimental.go | 28 + .../grpc/internal/grpclog/grpclog.go | 40 +- .../grpc/internal/grpclog/prefixLogger.go | 8 +- .../grpc/internal/grpcrand/grpcrand.go | 12 + .../grpc/internal/grpcrand/grpcrand_go1.21.go | 73 + .../internal/grpcsync/callback_serializer.go | 75 +- .../grpc/internal/grpcsync/pubsub.go | 121 + .../grpc/internal/idle/idle.go | 278 + .../grpc/internal/internal.go | 78 +- .../grpc/internal/metadata/metadata.go | 2 +- .../grpc/internal/pretty/pretty.go | 37 +- .../grpc/internal/resolver/config_selector.go | 4 +- .../internal/resolver/dns/dns_resolver.go | 166 +- .../resolver/dns/internal/internal.go | 70 + .../grpc/internal/resolver/unix/unix.go | 4 + .../grpc/internal/status/status.go | 51 +- ...il_nonlinux.go => tcp_keepalive_others.go} | 18 +- .../grpc/internal/tcp_keepalive_unix.go | 54 + .../grpc/internal/tcp_keepalive_windows.go | 54 + .../grpc/internal/transport/controlbuf.go | 21 +- .../grpc/internal/transport/handler_server.go | 93 +- .../grpc/internal/transport/http2_client.go | 158 +- .../grpc/internal/transport/http2_server.go | 232 +- .../grpc/internal/transport/http_util.go | 76 +- .../grpc/internal/transport/proxy.go | 14 +- .../grpc/internal/transport/transport.go | 78 +- .../grpc/internal/xds_handshake_cluster.go | 40 - .../grpc/metadata/metadata.go | 31 +- vendor/google.golang.org/grpc/peer/peer.go | 2 + .../google.golang.org/grpc/picker_wrapper.go | 53 +- vendor/google.golang.org/grpc/pickfirst.go | 90 +- vendor/google.golang.org/grpc/preloader.go | 2 +- .../grpc/reflection/README.md | 2 +- .../grpc/reflection/adapt.go | 187 + .../grpc_reflection_v1/reflection.pb.go | 953 + .../grpc_reflection_v1/reflection_grpc.pb.go | 164 + .../grpc_reflection_v1alpha/reflection.pb.go | 4 +- .../reflection_grpc.pb.go | 2 +- .../grpc/reflection/serverreflection.go | 102 +- .../grpc/resolver/dns/dns_resolver.go | 54 + vendor/google.golang.org/grpc/resolver/map.go | 123 +- .../grpc/resolver/resolver.go | 110 +- .../grpc/resolver_conn_wrapper.go | 239 - .../grpc/resolver_wrapper.go | 198 + vendor/google.golang.org/grpc/rpc_util.go | 114 +- vendor/google.golang.org/grpc/server.go | 592 +- .../google.golang.org/grpc/service_config.go | 41 +- .../grpc/shared_buffer_pool.go | 154 + vendor/google.golang.org/grpc/stats/stats.go | 14 +- .../google.golang.org/grpc/status/status.go | 14 +- vendor/google.golang.org/grpc/stream.go | 143 +- vendor/google.golang.org/grpc/tap/tap.go | 6 + vendor/google.golang.org/grpc/trace.go | 32 +- .../google.golang.org/grpc/trace_notrace.go | 52 + .../util_linux.go => trace_withtrace.go} | 32 +- vendor/google.golang.org/grpc/version.go | 2 +- vendor/google.golang.org/grpc/vet.sh | 179 +- .../protobuf/encoding/protojson/encode.go | 20 +- .../protobuf/encoding/prototext/encode.go | 20 +- .../protobuf/internal/descfmt/stringer.go | 1 + .../editiondefaults/editions_defaults.binpb | Bin 63 -> 78 bytes .../internal/editionssupport/editions.go | 13 + .../protobuf/internal/encoding/tag/tag.go | 4 +- .../protobuf/internal/errors/errors.go | 15 + .../protobuf/internal/filedesc/desc.go | 84 +- .../protobuf/internal/filedesc/desc_init.go | 41 +- .../protobuf/internal/filedesc/desc_lazy.go | 44 +- .../protobuf/internal/filedesc/editions.go | 18 +- .../protobuf/internal/filedesc/placeholder.go | 1 + .../internal/genid/go_features_gen.go | 2 +- .../protobuf/internal/impl/codec_field.go | 64 +- .../protobuf/internal/impl/codec_map.go | 15 +- .../protobuf/internal/impl/legacy_enum.go | 1 + .../internal/impl/legacy_extension.go | 2 +- .../protobuf/internal/impl/legacy_file.go | 4 +- .../protobuf/internal/impl/legacy_message.go | 10 +- .../protobuf/internal/impl/message_reflect.go | 31 +- .../internal/impl/message_reflect_gen.go | 142 +- .../protobuf/internal/version/version.go | 2 +- .../protobuf/proto/decode.go | 2 + .../protobuf/proto/encode.go | 44 +- .../protobuf/proto/extension.go | 11 +- .../protobuf/proto/messageset.go | 7 +- .../google.golang.org/protobuf/proto/size.go | 2 + .../protobuf/protoadapt/convert.go | 31 + .../protobuf/reflect/protodesc/desc.go | 13 +- .../protobuf/reflect/protodesc/desc_init.go | 49 +- .../reflect/protodesc/desc_validate.go | 61 +- .../protobuf/reflect/protodesc/editions.go | 5 - .../protobuf/reflect/protodesc/proto.go | 22 + .../protobuf/reflect/protoreflect/proto.go | 2 +- .../protobuf/reflect/protoreflect/type.go | 6 + .../types/gofeaturespb/go_features.pb.go | 116 +- .../types/gofeaturespb/go_features.proto | 28 - vendor/modules.txt | 129 +- 707 files changed, 68473 insertions(+), 20438 deletions(-) create mode 100644 vendor/github.com/Masterminds/semver/v3/SECURITY.md delete mode 100644 vendor/github.com/Masterminds/semver/v3/fuzz.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/ed25519/ed25519.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/ed448/ed448.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/hash.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/packet/marker.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet_sequence.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet_unsupported.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/packet/padding.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/packet/recipient.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/x25519/x25519.go create mode 100644 vendor/github.com/ProtonMail/go-crypto/openpgp/x448/x448.go delete mode 100644 vendor/github.com/apparentlymart/go-textseg/v13/textseg/grapheme_clusters.go rename vendor/github.com/apparentlymart/go-textseg/{v13 => v15}/LICENSE (100%) rename vendor/github.com/apparentlymart/go-textseg/{v13 => v15}/textseg/all_tokens.go (100%) rename vendor/github.com/apparentlymart/go-textseg/{v13 => v15}/textseg/emoji_table.rl (93%) rename vendor/github.com/apparentlymart/go-textseg/{v13 => v15}/textseg/generate.go (79%) create mode 100644 vendor/github.com/apparentlymart/go-textseg/v15/textseg/grapheme_clusters.go rename vendor/github.com/apparentlymart/go-textseg/{v13 => v15}/textseg/grapheme_clusters.rl (100%) rename vendor/github.com/apparentlymart/go-textseg/{v13 => v15}/textseg/grapheme_clusters_table.rl (97%) rename vendor/github.com/apparentlymart/go-textseg/{v13 => v15}/textseg/tables.go (93%) rename vendor/github.com/apparentlymart/go-textseg/{v13 => v15}/textseg/unicode2ragel.rb (100%) rename vendor/github.com/apparentlymart/go-textseg/{v13 => v15}/textseg/utf8_seqs.go (100%) delete mode 100644 vendor/github.com/golang/protobuf/jsonpb/decode.go delete mode 100644 vendor/github.com/golang/protobuf/jsonpb/encode.go delete mode 100644 vendor/github.com/golang/protobuf/jsonpb/json.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/any.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/any/any.pb.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/doc.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/duration.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/timestamp.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go rename vendor/github.com/google/go-cmp/cmp/{export_unsafe.go => export.go} (94%) delete mode 100644 vendor/github.com/google/go-cmp/cmp/export_panic.go rename vendor/github.com/google/go-cmp/cmp/internal/value/{pointer_unsafe.go => pointer.go} (95%) delete mode 100644 vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go delete mode 100644 vendor/github.com/google/uuid/.travis.yml create mode 100644 vendor/github.com/google/uuid/CHANGELOG.md create mode 100644 vendor/github.com/google/uuid/version6.go create mode 100644 vendor/github.com/google/uuid/version7.go create mode 100644 vendor/github.com/hashicorp/go-plugin/buf.gen.yaml create mode 100644 vendor/github.com/hashicorp/go-plugin/buf.yaml create mode 100644 vendor/github.com/hashicorp/go-plugin/constants.go create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/addr_translator.go create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/cmd_reattach.go create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/cmd_runner.go rename vendor/github.com/hashicorp/go-plugin/{ => internal/cmdrunner}/notes_unix.go (99%) rename vendor/github.com/hashicorp/go-plugin/{ => internal/cmdrunner}/notes_windows.go (98%) create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/process.go rename vendor/github.com/hashicorp/go-plugin/{ => internal/cmdrunner}/process_posix.go (95%) rename vendor/github.com/hashicorp/go-plugin/{ => internal/cmdrunner}/process_windows.go (97%) create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/grpcmux/blocked_client_listener.go create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/grpcmux/blocked_server_listener.go create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_client_muxer.go create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_muxer.go create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_server_muxer.go delete mode 100644 vendor/github.com/hashicorp/go-plugin/internal/plugin/gen.go create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker_grpc.pb.go create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller_grpc.pb.go create mode 100644 vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio_grpc.pb.go create mode 100644 vendor/github.com/hashicorp/go-plugin/runner/runner.go create mode 100644 vendor/github.com/hashicorp/hc-install/product/nomad.go create mode 100644 vendor/github.com/hashicorp/hc-install/releases/enterprise.go create mode 100644 vendor/github.com/hashicorp/hcl/v2/Makefile create mode 100644 vendor/github.com/hashicorp/hcl/v2/tools.go create mode 100644 vendor/github.com/hashicorp/terraform-exec/tfexec/test.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/function.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/function_error.go delete mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/attribute_path.go delete mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/diagnostic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/doc.go rename vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/{types.go => dynamic_value.go} (81%) create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/function.go rename vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/{state.go => raw_state.go} (81%) delete mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/schema.go delete mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/string_kind.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/funcerr/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/funcerr/function_error.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tf5serverlogging/server_capabilities.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/function.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/function_error.go delete mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/function.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/function_error.go delete mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/attribute_path.go delete mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/diagnostic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/doc.go rename vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/{types.go => dynamic_value.go} (81%) create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/function.go rename vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/{state.go => raw_state.go} (81%) delete mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/schema.go delete mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/string_kind.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/funcerr/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/funcerr/function_error.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tf6serverlogging/server_capabilities.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/function.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/function_error.go delete mode 100644 vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/state.go delete mode 100644 vendor/github.com/huandu/xstrings/.travis.yml create mode 100644 vendor/github.com/imdario/mergo/CONTRIBUTING.md create mode 100644 vendor/github.com/imdario/mergo/SECURITY.md create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/decode_typgen.go create mode 100644 vendor/golang.org/x/crypto/argon2/argon2.go create mode 100644 vendor/golang.org/x/crypto/argon2/blake2b.go create mode 100644 vendor/golang.org/x/crypto/argon2/blamka_amd64.go create mode 100644 vendor/golang.org/x/crypto/argon2/blamka_amd64.s create mode 100644 vendor/golang.org/x/crypto/argon2/blamka_generic.go create mode 100644 vendor/golang.org/x/crypto/argon2/blamka_ref.go create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b.go create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_generic.go create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_ref.go create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2x.go create mode 100644 vendor/golang.org/x/crypto/blake2b/register.go delete mode 100644 vendor/golang.org/x/net/context/context.go delete mode 100644 vendor/golang.org/x/net/context/go17.go delete mode 100644 vendor/golang.org/x/net/context/go19.go delete mode 100644 vendor/golang.org/x/net/context/pre_go17.go delete mode 100644 vendor/golang.org/x/net/context/pre_go19.go delete mode 100644 vendor/golang.org/x/net/http2/go111.go delete mode 100644 vendor/golang.org/x/net/http2/go115.go delete mode 100644 vendor/golang.org/x/net/http2/go118.go delete mode 100644 vendor/golang.org/x/net/http2/not_go111.go delete mode 100644 vendor/golang.org/x/net/http2/not_go115.go delete mode 100644 vendor/golang.org/x/net/http2/not_go118.go create mode 100644 vendor/golang.org/x/net/http2/testsync.go create mode 100644 vendor/golang.org/x/sync/LICENSE create mode 100644 vendor/golang.org/x/sync/PATENTS create mode 100644 vendor/golang.org/x/sync/errgroup/errgroup.go create mode 100644 vendor/golang.org/x/sync/errgroup/go120.go create mode 100644 vendor/golang.org/x/sync/errgroup/pre_go120.go create mode 100644 vendor/golang.org/x/tools/LICENSE create mode 100644 vendor/golang.org/x/tools/PATENTS create mode 100644 vendor/golang.org/x/tools/cmd/stringer/stringer.go create mode 100644 vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go create mode 100644 vendor/golang.org/x/tools/go/gcexportdata/importer.go create mode 100644 vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go create mode 100644 vendor/golang.org/x/tools/go/packages/doc.go create mode 100644 vendor/golang.org/x/tools/go/packages/external.go create mode 100644 vendor/golang.org/x/tools/go/packages/golist.go create mode 100644 vendor/golang.org/x/tools/go/packages/golist_overlay.go create mode 100644 vendor/golang.org/x/tools/go/packages/loadmode_string.go create mode 100644 vendor/golang.org/x/tools/go/packages/packages.go create mode 100644 vendor/golang.org/x/tools/go/packages/visit.go create mode 100644 vendor/golang.org/x/tools/go/types/objectpath/objectpath.go create mode 100644 vendor/golang.org/x/tools/internal/aliases/aliases.go create mode 100644 vendor/golang.org/x/tools/internal/aliases/aliases_go121.go create mode 100644 vendor/golang.org/x/tools/internal/aliases/aliases_go122.go create mode 100644 vendor/golang.org/x/tools/internal/event/core/event.go create mode 100644 vendor/golang.org/x/tools/internal/event/core/export.go create mode 100644 vendor/golang.org/x/tools/internal/event/core/fast.go create mode 100644 vendor/golang.org/x/tools/internal/event/doc.go create mode 100644 vendor/golang.org/x/tools/internal/event/event.go create mode 100644 vendor/golang.org/x/tools/internal/event/keys/keys.go create mode 100644 vendor/golang.org/x/tools/internal/event/keys/standard.go create mode 100644 vendor/golang.org/x/tools/internal/event/keys/util.go create mode 100644 vendor/golang.org/x/tools/internal/event/label/label.go create mode 100644 vendor/golang.org/x/tools/internal/event/tag/tag.go create mode 100644 vendor/golang.org/x/tools/internal/gcimporter/bimport.go create mode 100644 vendor/golang.org/x/tools/internal/gcimporter/exportdata.go create mode 100644 vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go create mode 100644 vendor/golang.org/x/tools/internal/gcimporter/iexport.go create mode 100644 vendor/golang.org/x/tools/internal/gcimporter/iimport.go create mode 100644 vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go create mode 100644 vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go create mode 100644 vendor/golang.org/x/tools/internal/gcimporter/support_go118.go create mode 100644 vendor/golang.org/x/tools/internal/gcimporter/unified_no.go create mode 100644 vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go create mode 100644 vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go create mode 100644 vendor/golang.org/x/tools/internal/gocommand/invoke.go create mode 100644 vendor/golang.org/x/tools/internal/gocommand/vendor.go create mode 100644 vendor/golang.org/x/tools/internal/gocommand/version.go create mode 100644 vendor/golang.org/x/tools/internal/packagesinternal/packages.go create mode 100644 vendor/golang.org/x/tools/internal/pkgbits/codes.go create mode 100644 vendor/golang.org/x/tools/internal/pkgbits/decoder.go create mode 100644 vendor/golang.org/x/tools/internal/pkgbits/doc.go create mode 100644 vendor/golang.org/x/tools/internal/pkgbits/encoder.go create mode 100644 vendor/golang.org/x/tools/internal/pkgbits/flags.go create mode 100644 vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go create mode 100644 vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go create mode 100644 vendor/golang.org/x/tools/internal/pkgbits/reloc.go create mode 100644 vendor/golang.org/x/tools/internal/pkgbits/support.go create mode 100644 vendor/golang.org/x/tools/internal/pkgbits/sync.go create mode 100644 vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go create mode 100644 vendor/golang.org/x/tools/internal/stdlib/manifest.go create mode 100644 vendor/golang.org/x/tools/internal/stdlib/stdlib.go create mode 100644 vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/errorcode.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/recv.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/toonew.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/types.go create mode 100644 vendor/golang.org/x/tools/internal/versions/features.go create mode 100644 vendor/golang.org/x/tools/internal/versions/gover.go create mode 100644 vendor/golang.org/x/tools/internal/versions/toolchain.go create mode 100644 vendor/golang.org/x/tools/internal/versions/toolchain_go119.go create mode 100644 vendor/golang.org/x/tools/internal/versions/toolchain_go120.go create mode 100644 vendor/golang.org/x/tools/internal/versions/toolchain_go121.go create mode 100644 vendor/golang.org/x/tools/internal/versions/types.go create mode 100644 vendor/golang.org/x/tools/internal/versions/types_go121.go create mode 100644 vendor/golang.org/x/tools/internal/versions/types_go122.go create mode 100644 vendor/golang.org/x/tools/internal/versions/versions.go delete mode 100644 vendor/google.golang.org/appengine/.travis.yml delete mode 100644 vendor/google.golang.org/appengine/travis_install.sh delete mode 100644 vendor/google.golang.org/appengine/travis_test.sh delete mode 100644 vendor/google.golang.org/grpc/balancer_conn_wrappers.go create mode 100644 vendor/google.golang.org/grpc/balancer_wrapper.go delete mode 100644 vendor/google.golang.org/grpc/idle.go create mode 100644 vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/channel.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/channelmap.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/id.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/server.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/socket.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/subchannel.go rename vendor/google.golang.org/grpc/internal/channelz/{types_linux.go => syscall_linux.go} (83%) rename vendor/google.golang.org/grpc/internal/channelz/{types_nonlinux.go => syscall_nonlinux.go} (90%) create mode 100644 vendor/google.golang.org/grpc/internal/channelz/trace.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/types.go create mode 100644 vendor/google.golang.org/grpc/internal/experimental.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go create mode 100644 vendor/google.golang.org/grpc/internal/idle/idle.go create mode 100644 vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go rename vendor/google.golang.org/grpc/internal/{channelz/util_nonlinux.go => tcp_keepalive_others.go} (69%) create mode 100644 vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go create mode 100644 vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go delete mode 100644 vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go create mode 100644 vendor/google.golang.org/grpc/reflection/adapt.go create mode 100644 vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go create mode 100644 vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go create mode 100644 vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go delete mode 100644 vendor/google.golang.org/grpc/resolver_conn_wrapper.go create mode 100644 vendor/google.golang.org/grpc/resolver_wrapper.go create mode 100644 vendor/google.golang.org/grpc/shared_buffer_pool.go create mode 100644 vendor/google.golang.org/grpc/trace_notrace.go rename vendor/google.golang.org/grpc/{internal/channelz/util_linux.go => trace_withtrace.go} (59%) create mode 100644 vendor/google.golang.org/protobuf/internal/editionssupport/editions.go create mode 100644 vendor/google.golang.org/protobuf/protoadapt/convert.go delete mode 100644 vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.proto diff --git a/go.mod b/go.mod index ff9ddc56..dcac12bd 100644 --- a/go.mod +++ b/go.mod @@ -1,50 +1,52 @@ module github.com/1Password/terraform-provider-onepassword -go 1.20 +go 1.21 + +toolchain go1.22.2 require ( - github.com/1Password/connect-sdk-go v1.5.2 - github.com/Masterminds/semver/v3 v3.1.1 + github.com/1Password/connect-sdk-go v1.5.3 + github.com/Masterminds/semver/v3 v3.2.1 github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/terraform-plugin-docs v0.16.0 github.com/hashicorp/terraform-plugin-log v0.9.0 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 ) require ( github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/sprig/v3 v3.2.2 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/ProtonMail/go-crypto v1.1.0-alpha.0 // indirect github.com/agext/levenshtein v1.2.3 // indirect - github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect - github.com/fatih/color v1.15.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.4.10 // indirect + github.com/hashicorp/go-plugin v1.6.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hc-install v0.5.2 // indirect - github.com/hashicorp/hcl/v2 v2.17.0 // indirect + github.com/hashicorp/hc-install v0.6.3 // indirect + github.com/hashicorp/hcl/v2 v2.20.1 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.18.1 // indirect - github.com/hashicorp/terraform-json v0.17.1 // indirect - github.com/hashicorp/terraform-plugin-go v0.18.0 // indirect - github.com/hashicorp/terraform-registry-address v0.2.1 // indirect + github.com/hashicorp/terraform-exec v0.20.0 // indirect + github.com/hashicorp/terraform-json v0.21.0 // indirect + github.com/hashicorp/terraform-plugin-go v0.22.2 // indirect + github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect - github.com/huandu/xstrings v1.3.2 // indirect - github.com/imdario/mergo v0.3.13 // indirect + github.com/huandu/xstrings v1.3.3 // indirect + github.com/imdario/mergo v0.3.15 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/cli v1.1.5 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect @@ -61,18 +63,20 @@ require ( github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/zclconf/go-cty v1.13.2 // indirect + github.com/zclconf/go-cty v1.14.4 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/crypto v0.17.0 // indirect + golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect - golang.org/x/mod v0.11.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect - google.golang.org/grpc v1.56.3 // indirect - google.golang.org/protobuf v1.33.0 // indirect + golang.org/x/tools v0.20.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect + google.golang.org/grpc v1.63.2 // indirect + google.golang.org/protobuf v1.34.0 // indirect ) diff --git a/go.sum b/go.sum index 3bbb303b..0be63d3b 100644 --- a/go.sum +++ b/go.sum @@ -1,57 +1,72 @@ -github.com/1Password/connect-sdk-go v1.5.2 h1:JTE0pVRrbtt38VI7R9VFTTY7qy/elXN15fnFk/Eyo/w= -github.com/1Password/connect-sdk-go v1.5.2/go.mod h1:5rSymY4oIYtS4G3t0oMkGAXBeoYiukV3vkqlnEjIDJs= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/1Password/connect-sdk-go v1.5.3 h1:KyjJ+kCKj6BwB2Y8tPM1Ixg5uIS6HsB0uWA8U38p/Uk= +github.com/1Password/connect-sdk-go v1.5.3/go.mod h1:5rSymY4oIYtS4G3t0oMkGAXBeoYiukV3vkqlnEjIDJs= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= +github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= -github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= -github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= -github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= -github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= -github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= -github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v1.1.0-alpha.0 h1:nHGfwXmFvJrSR9xu8qL7BkO4DqTHXE9N5vPhgY2I+j0= +github.com/ProtonMail/go-crypto v1.1.0-alpha.0/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= -github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= -github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= -github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= -github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= -github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= +github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -62,57 +77,62 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.4.10 h1:xUbmA4jC6Dq163/fWcp8P3JuHilrHHMLNRxzGQJ9hNk= -github.com/hashicorp/go-plugin v1.4.10/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= +github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= +github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.5.2 h1:SfwMFnEXVVirpwkDuSF5kymUOhrUxrTq3udEseZdOD0= -github.com/hashicorp/hc-install v0.5.2/go.mod h1:9QISwe6newMWIfEiXpzuu1k9HAGtQYgnSH8H9T8wmoI= -github.com/hashicorp/hcl/v2 v2.17.0 h1:z1XvSUyXd1HP10U4lrLg5e0JMVz6CPaJvAgxM0KNZVY= -github.com/hashicorp/hcl/v2 v2.17.0/go.mod h1:gJyW2PTShkJqQBKpAmPO3yxMxIuoXkOF2TpqXzrQyx4= +github.com/hashicorp/hc-install v0.6.3 h1:yE/r1yJvWbtrJ0STwScgEnCanb0U9v7zp0Gbkmcoxqs= +github.com/hashicorp/hc-install v0.6.3/go.mod h1:KamGdbodYzlufbWh4r9NRo8y6GLHWZP2GBtdnms1Ln0= +github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= +github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/terraform-exec v0.18.1 h1:LAbfDvNQU1l0NOQlTuudjczVhHj061fNX5H8XZxHlH4= -github.com/hashicorp/terraform-exec v0.18.1/go.mod h1:58wg4IeuAJ6LVsLUeD2DWZZoc/bYi6dzhLHzxM41980= -github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA= -github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= +github.com/hashicorp/terraform-exec v0.20.0 h1:DIZnPsqzPGuUnq6cH8jWcPunBfY+C+M8JyYF3vpnuEo= +github.com/hashicorp/terraform-exec v0.20.0/go.mod h1:ckKGkJWbsNqFKV1itgMnE0hY9IYf1HoiekpuN0eWoDw= +github.com/hashicorp/terraform-json v0.21.0 h1:9NQxbLNqPbEMze+S6+YluEdXgJmhQykRyRNd+zTI05U= +github.com/hashicorp/terraform-json v0.21.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk= github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI= github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA= -github.com/hashicorp/terraform-plugin-go v0.18.0 h1:IwTkOS9cOW1ehLd/rG0y+u/TGLK9y6fGoBjXVUquzpE= -github.com/hashicorp/terraform-plugin-go v0.18.0/go.mod h1:l7VK+2u5Kf2y+A+742GX0ouLut3gttudmvMgN0PA74Y= +github.com/hashicorp/terraform-plugin-go v0.22.2 h1:5o8uveu6eZUf5J7xGPV0eY0TPXg3qpmwX9sce03Bxnc= +github.com/hashicorp/terraform-plugin-go v0.22.2/go.mod h1:drq8Snexp9HsbFZddvyLHN6LuWHHndSQg+gV+FPkcIM= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0 h1:I8efBnjuDrgPjNF1MEypHy48VgcTIUY4X6rOFunrR3Y= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0/go.mod h1:cUEP4ly/nxlHy5HzD6YRrHydtlheGvGRJDhiWqqVik4= -github.com/hashicorp/terraform-registry-address v0.2.1 h1:QuTf6oJ1+WSflJw6WYOHhLgwUiQ0FrROpHPYFtwTYWM= -github.com/hashicorp/terraform-registry-address v0.2.1/go.mod h1:BSE9fIFzp0qWsJUUyGquo4ldV9k2n+psif6NYkBRS3Y= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 h1:qHprzXy/As0rxedphECBEQAh3R4yp6pKksKHcqZx5G8= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0/go.mod h1:H+8tjs9TjV2w57QFVSMBQacf8k/E1XwLXGCARgViC6A= +github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= +github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= +github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= @@ -122,8 +142,8 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= @@ -139,11 +159,13 @@ github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -152,13 +174,16 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0= +github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= @@ -171,6 +196,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= @@ -178,31 +204,43 @@ github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6 github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= -github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0= -github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= +github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= -golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= -golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -211,38 +249,51 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= -google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= -google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 h1:DujSIu+2tC9Ht0aPNA7jgj23Iq8Ewi5sgkQ++wdvonE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= +google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/1Password/connect-sdk-go/connect/client.go b/vendor/github.com/1Password/connect-sdk-go/connect/client.go index 6324b7d0..66019c52 100644 --- a/vendor/github.com/1Password/connect-sdk-go/connect/client.go +++ b/vendor/github.com/1Password/connect-sdk-go/connect/client.go @@ -246,10 +246,14 @@ func (rs *restClient) GetItem(itemQuery string, vaultQuery string) (*onepassword if itemQuery == "" { return nil, fmt.Errorf("Please provide either the item name or its ID.") } - if !isValidUUID(itemQuery) { - return rs.GetItemByTitle(itemQuery, vaultQuery) + + if isValidUUID(itemQuery) { + item, err := rs.GetItemByUUID(itemQuery, vaultQuery) + if item != nil { + return item, err + } } - return rs.GetItemByUUID(itemQuery, vaultQuery) + return rs.GetItemByTitle(itemQuery, vaultQuery) } // GetItemByUUID Get a specific Item from the 1Password Connect API by its UUID diff --git a/vendor/github.com/1Password/connect-sdk-go/connect/version.go b/vendor/github.com/1Password/connect-sdk-go/connect/version.go index 01aaeeb5..39e406fe 100644 --- a/vendor/github.com/1Password/connect-sdk-go/connect/version.go +++ b/vendor/github.com/1Password/connect-sdk-go/connect/version.go @@ -10,7 +10,7 @@ import ( // SDKVersion is the latest Semantic Version of the library // Do not rename this variable without changing the regex in the Makefile -const SDKVersion = "1.5.2" +const SDKVersion = "1.5.3" const VersionHeaderKey = "1Password-Connect-Version" diff --git a/vendor/github.com/1Password/connect-sdk-go/onepassword/vaults.go b/vendor/github.com/1Password/connect-sdk-go/onepassword/vaults.go index 03844adf..b19e8797 100644 --- a/vendor/github.com/1Password/connect-sdk-go/onepassword/vaults.go +++ b/vendor/github.com/1Password/connect-sdk-go/onepassword/vaults.go @@ -12,7 +12,7 @@ type Vault struct { Description string `json:"description,omitempty"` AttrVersion int `json:"attributeVersion,omitempty"` - ContentVersoin int `json:"contentVersion,omitempty"` + ContentVersion int `json:"contentVersion,omitempty"` Items int `json:"items,omitempty"` Type VaultType `json:"type,omitempty"` diff --git a/vendor/github.com/Masterminds/semver/v3/.golangci.yml b/vendor/github.com/Masterminds/semver/v3/.golangci.yml index fdbdf144..fbc63325 100644 --- a/vendor/github.com/Masterminds/semver/v3/.golangci.yml +++ b/vendor/github.com/Masterminds/semver/v3/.golangci.yml @@ -4,23 +4,24 @@ run: linters: disable-all: true enable: - - deadcode - - dupl - - errcheck - - gofmt - - goimports - - golint - - gosimple + - misspell - govet + - staticcheck + - errcheck + - unparam - ineffassign - - misspell - nakedret - - structcheck + - gocyclo + - dupl + - goimports + - revive + - gosec + - gosimple + - typecheck - unused - - varcheck linters-settings: gofmt: simplify: true dupl: - threshold: 400 + threshold: 600 diff --git a/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md b/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md index 1f90c38d..f1262642 100644 --- a/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md +++ b/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## 3.2.0 (2022-11-28) + +### Added + +- #190: Added text marshaling and unmarshaling +- #167: Added JSON marshalling for constraints (thanks @SimonTheLeg) +- #173: Implement encoding.TextMarshaler and encoding.TextUnmarshaler on Version (thanks @MarkRosemaker) +- #179: Added New() version constructor (thanks @kazhuravlev) + +### Changed + +- #182/#183: Updated CI testing setup + +### Fixed + +- #186: Fixing issue where validation of constraint section gave false positives +- #176: Fix constraints check with *-0 (thanks @mtt0) +- #181: Fixed Caret operator (^) gives unexpected results when the minor version in constraint is 0 (thanks @arshchimni) +- #161: Fixed godoc (thanks @afirth) + ## 3.1.1 (2020-11-23) ### Fixed diff --git a/vendor/github.com/Masterminds/semver/v3/Makefile b/vendor/github.com/Masterminds/semver/v3/Makefile index eac19178..0e7b5c71 100644 --- a/vendor/github.com/Masterminds/semver/v3/Makefile +++ b/vendor/github.com/Masterminds/semver/v3/Makefile @@ -1,7 +1,5 @@ GOPATH=$(shell go env GOPATH) GOLANGCI_LINT=$(GOPATH)/bin/golangci-lint -GOFUZZBUILD = $(GOPATH)/bin/go-fuzz-build -GOFUZZ = $(GOPATH)/bin/go-fuzz .PHONY: lint lint: $(GOLANGCI_LINT) @@ -19,19 +17,14 @@ test-cover: GO111MODULE=on go test -cover . .PHONY: fuzz -fuzz: $(GOFUZZBUILD) $(GOFUZZ) - @echo "==> Fuzz testing" - $(GOFUZZBUILD) - $(GOFUZZ) -workdir=_fuzz +fuzz: + @echo "==> Running Fuzz Tests" + go test -fuzz=FuzzNewVersion -fuzztime=15s . + go test -fuzz=FuzzStrictNewVersion -fuzztime=15s . + go test -fuzz=FuzzNewConstraint -fuzztime=15s . $(GOLANGCI_LINT): # Install golangci-lint. The configuration for it is in the .golangci.yml # file in the root of the repository echo ${GOPATH} curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.17.1 - -$(GOFUZZBUILD): - cd / && go get -u github.com/dvyukov/go-fuzz/go-fuzz-build - -$(GOFUZZ): - cd / && go get -u github.com/dvyukov/go-fuzz/go-fuzz github.com/dvyukov/go-fuzz/go-fuzz-dep \ No newline at end of file diff --git a/vendor/github.com/Masterminds/semver/v3/README.md b/vendor/github.com/Masterminds/semver/v3/README.md index d8f54dcb..eab8cac3 100644 --- a/vendor/github.com/Masterminds/semver/v3/README.md +++ b/vendor/github.com/Masterminds/semver/v3/README.md @@ -18,18 +18,20 @@ If you are looking for a command line tool for version comparisons please see ## Package Versions +Note, import `github.com/github.com/Masterminds/semver/v3` to use the latest version. + There are three major versions fo the `semver` package. -* 3.x.x is the new stable and active version. This version is focused on constraint +* 3.x.x is the stable and active version. This version is focused on constraint compatibility for range handling in other tools from other languages. It has a similar API to the v1 releases. The development of this version is on the master branch. The documentation for this version is below. * 2.x was developed primarily for [dep](https://github.com/golang/dep). There are no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer). There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x). -* 1.x.x is the most widely used version with numerous tagged releases. This is the - previous stable and is still maintained for bug fixes. The development, to fix - bugs, occurs on the release-1 branch. You can read the documentation [here](https://github.com/Masterminds/semver/blob/release-1/README.md). +* 1.x.x is the original release. It is no longer maintained. You should use the + v3 release instead. You can read the documentation for the 1.x.x release + [here](https://github.com/Masterminds/semver/blob/release-1/README.md). ## Parsing Semantic Versions @@ -242,3 +244,15 @@ for _, m := range msgs { If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues) or [create a pull request](https://github.com/Masterminds/semver/pulls). + +## Security + +Security is an important consideration for this project. The project currently +uses the following tools to help discover security issues: + +* [CodeQL](https://github.com/Masterminds/semver) +* [gosec](https://github.com/securego/gosec) +* Daily Fuzz testing + +If you believe you have found a security vulnerability you can privately disclose +it through the [GitHub security page](https://github.com/Masterminds/semver/security). diff --git a/vendor/github.com/Masterminds/semver/v3/SECURITY.md b/vendor/github.com/Masterminds/semver/v3/SECURITY.md new file mode 100644 index 00000000..a30a66b1 --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/SECURITY.md @@ -0,0 +1,19 @@ +# Security Policy + +## Supported Versions + +The following versions of semver are currently supported: + +| Version | Supported | +| ------- | ------------------ | +| 3.x | :white_check_mark: | +| 2.x | :x: | +| 1.x | :x: | + +Fixes are only released for the latest minor version in the form of a patch release. + +## Reporting a Vulnerability + +You can privately disclose a vulnerability through GitHubs +[private vulnerability reporting](https://github.com/Masterminds/semver/security/advisories) +mechanism. diff --git a/vendor/github.com/Masterminds/semver/v3/constraints.go b/vendor/github.com/Masterminds/semver/v3/constraints.go index 547613f0..8461c7ed 100644 --- a/vendor/github.com/Masterminds/semver/v3/constraints.go +++ b/vendor/github.com/Masterminds/semver/v3/constraints.go @@ -134,6 +134,23 @@ func (cs Constraints) String() string { return strings.Join(buf, " || ") } +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (cs *Constraints) UnmarshalText(text []byte) error { + temp, err := NewConstraint(string(text)) + if err != nil { + return err + } + + *cs = *temp + + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (cs Constraints) MarshalText() ([]byte, error) { + return []byte(cs.String()), nil +} + var constraintOps map[string]cfunc var constraintRegex *regexp.Regexp var constraintRangeRegex *regexp.Regexp @@ -180,8 +197,13 @@ func init() { ops, cvRegex)) + // The first time a constraint shows up will look slightly different from + // future times it shows up due to a leading space or comma in a given + // string. validConstraintRegex = regexp.MustCompile(fmt.Sprintf( - `^(\s*(%s)\s*(%s)\s*\,?)+$`, + `^(\s*(%s)\s*(%s)\s*)((?:\s+|,\s*)(%s)\s*(%s)\s*)*$`, + ops, + cvRegex, ops, cvRegex)) } @@ -233,7 +255,7 @@ func parseConstraint(c string) (*constraint, error) { patchDirty := false dirty := false if isX(m[3]) || m[3] == "" { - ver = "0.0.0" + ver = fmt.Sprintf("0.0.0%s", m[6]) dirty = true } else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" { minorDirty = true @@ -534,6 +556,10 @@ func constraintCaret(v *Version, c *constraint) (bool, error) { } return false, fmt.Errorf("%s does not have same minor version as %s. Expected minor versions to match when constraint major version is 0", v, c.orig) } + // ^ when the minor is 0 and minor > 0 is =0.0.z + if c.con.Minor() == 0 && v.Minor() > 0 { + return false, fmt.Errorf("%s does not have same minor version as %s", v, c.orig) + } // At this point the major is 0 and the minor is 0 and not dirty. The patch // is not dirty so we need to check if they are equal. If they are not equal @@ -560,7 +586,7 @@ func rewriteRange(i string) string { } o := i for _, v := range m { - t := fmt.Sprintf(">= %s, <= %s", v[1], v[11]) + t := fmt.Sprintf(">= %s, <= %s ", v[1], v[11]) o = strings.Replace(o, v[0], t, 1) } diff --git a/vendor/github.com/Masterminds/semver/v3/doc.go b/vendor/github.com/Masterminds/semver/v3/doc.go index 391aa46b..74f97caa 100644 --- a/vendor/github.com/Masterminds/semver/v3/doc.go +++ b/vendor/github.com/Masterminds/semver/v3/doc.go @@ -3,12 +3,12 @@ Package semver provides the ability to work with Semantic Versions (http://semve Specifically it provides the ability to: - * Parse semantic versions - * Sort semantic versions - * Check if a semantic version fits within a set of constraints - * Optionally work with a `v` prefix + - Parse semantic versions + - Sort semantic versions + - Check if a semantic version fits within a set of constraints + - Optionally work with a `v` prefix -Parsing Semantic Versions +# Parsing Semantic Versions There are two functions that can parse semantic versions. The `StrictNewVersion` function only parses valid version 2 semantic versions as outlined in the @@ -21,48 +21,48 @@ that can be sorted, compared, and used in constraints. When parsing a version an optional error can be returned if there is an issue parsing the version. For example, - v, err := semver.NewVersion("1.2.3-beta.1+b345") + v, err := semver.NewVersion("1.2.3-beta.1+b345") The version object has methods to get the parts of the version, compare it to other versions, convert the version back into a string, and get the original string. For more details please see the documentation at https://godoc.org/github.com/Masterminds/semver. -Sorting Semantic Versions +# Sorting Semantic Versions A set of versions can be sorted using the `sort` package from the standard library. For example, - raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} - vs := make([]*semver.Version, len(raw)) - for i, r := range raw { - v, err := semver.NewVersion(r) - if err != nil { - t.Errorf("Error parsing version: %s", err) - } + raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} + vs := make([]*semver.Version, len(raw)) + for i, r := range raw { + v, err := semver.NewVersion(r) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } - vs[i] = v - } + vs[i] = v + } - sort.Sort(semver.Collection(vs)) + sort.Sort(semver.Collection(vs)) -Checking Version Constraints and Comparing Versions +# Checking Version Constraints and Comparing Versions There are two methods for comparing versions. One uses comparison methods on `Version` instances and the other is using Constraints. There are some important differences to notes between these two methods of comparison. -1. When two versions are compared using functions such as `Compare`, `LessThan`, - and others it will follow the specification and always include prereleases - within the comparison. It will provide an answer valid with the comparison - spec section at https://semver.org/#spec-item-11 -2. When constraint checking is used for checks or validation it will follow a - different set of rules that are common for ranges with tools like npm/js - and Rust/Cargo. This includes considering prereleases to be invalid if the - ranges does not include on. If you want to have it include pre-releases a - simple solution is to include `-0` in your range. -3. Constraint ranges can have some complex rules including the shorthard use of - ~ and ^. For more details on those see the options below. + 1. When two versions are compared using functions such as `Compare`, `LessThan`, + and others it will follow the specification and always include prereleases + within the comparison. It will provide an answer valid with the comparison + spec section at https://semver.org/#spec-item-11 + 2. When constraint checking is used for checks or validation it will follow a + different set of rules that are common for ranges with tools like npm/js + and Rust/Cargo. This includes considering prereleases to be invalid if the + ranges does not include on. If you want to have it include pre-releases a + simple solution is to include `-0` in your range. + 3. Constraint ranges can have some complex rules including the shorthard use of + ~ and ^. For more details on those see the options below. There are differences between the two methods or checking versions because the comparison methods on `Version` follow the specification while comparison ranges @@ -76,19 +76,19 @@ patters with their versions. Checking a version against version constraints is one of the most featureful parts of the package. - c, err := semver.NewConstraint(">= 1.2.3") - if err != nil { - // Handle constraint not being parsable. - } + c, err := semver.NewConstraint(">= 1.2.3") + if err != nil { + // Handle constraint not being parsable. + } - v, err := semver.NewVersion("1.3") - if err != nil { - // Handle version not being parsable. - } - // Check if the version meets the constraints. The a variable will be true. - a := c.Check(v) + v, err := semver.NewVersion("1.3") + if err != nil { + // Handle version not being parsable. + } + // Check if the version meets the constraints. The a variable will be true. + a := c.Check(v) -Basic Comparisons +# Basic Comparisons There are two elements to the comparisons. First, a comparison string is a list of comma or space separated AND comparisons. These are then separated by || (OR) @@ -99,31 +99,31 @@ greater than or equal to 4.2.3. This can also be written as The basic comparisons are: - * `=`: equal (aliased to no operator) - * `!=`: not equal - * `>`: greater than - * `<`: less than - * `>=`: greater than or equal to - * `<=`: less than or equal to + - `=`: equal (aliased to no operator) + - `!=`: not equal + - `>`: greater than + - `<`: less than + - `>=`: greater than or equal to + - `<=`: less than or equal to -Hyphen Range Comparisons +# Hyphen Range Comparisons There are multiple methods to handle ranges and the first is hyphens ranges. These look like: - * `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` - * `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` + - `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` + - `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` -Wildcards In Comparisons +# Wildcards In Comparisons The `x`, `X`, and `*` characters can be used as a wildcard character. This works for all comparison operators. When used on the `=` operator it falls back to the tilde operation. For example, - * `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` - * `>= 1.2.x` is equivalent to `>= 1.2.0` - * `<= 2.x` is equivalent to `<= 3` - * `*` is equivalent to `>= 0.0.0` + - `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` + - `>= 1.2.x` is equivalent to `>= 1.2.0` + - `<= 2.x` is equivalent to `<= 3` + - `*` is equivalent to `>= 0.0.0` Tilde Range Comparisons (Patch) @@ -131,11 +131,11 @@ The tilde (`~`) comparison operator is for patch level ranges when a minor version is specified and major level changes when the minor number is missing. For example, - * `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0` - * `~1` is equivalent to `>= 1, < 2` - * `~2.3` is equivalent to `>= 2.3 < 2.4` - * `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` - * `~1.x` is equivalent to `>= 1 < 2` + - `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0` + - `~1` is equivalent to `>= 1, < 2` + - `~2.3` is equivalent to `>= 2.3 < 2.4` + - `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` + - `~1.x` is equivalent to `>= 1 < 2` Caret Range Comparisons (Major) @@ -144,41 +144,41 @@ The caret (`^`) comparison operator is for major level changes once a stable as the API stability level. This is useful when comparisons of API versions as a major change is API breaking. For example, - * `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` - * `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` - * `^2.3` is equivalent to `>= 2.3, < 3` - * `^2.x` is equivalent to `>= 2.0.0, < 3` - * `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` - * `^0.2` is equivalent to `>=0.2.0 <0.3.0` - * `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` - * `^0.0` is equivalent to `>=0.0.0 <0.1.0` - * `^0` is equivalent to `>=0.0.0 <1.0.0` + - `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` + - `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` + - `^2.3` is equivalent to `>= 2.3, < 3` + - `^2.x` is equivalent to `>= 2.0.0, < 3` + - `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` + - `^0.2` is equivalent to `>=0.2.0 <0.3.0` + - `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` + - `^0.0` is equivalent to `>=0.0.0 <0.1.0` + - `^0` is equivalent to `>=0.0.0 <1.0.0` -Validation +# Validation In addition to testing a version against a constraint, a version can be validated against a constraint. When validation fails a slice of errors containing why a version didn't meet the constraint is returned. For example, - c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") - if err != nil { - // Handle constraint not being parseable. - } - - v, _ := semver.NewVersion("1.3") - if err != nil { - // Handle version not being parseable. - } - - // Validate a version against a constraint. - a, msgs := c.Validate(v) - // a is false - for _, m := range msgs { - fmt.Println(m) - - // Loops over the errors which would read - // "1.3 is greater than 1.2.3" - // "1.3 is less than 1.4" - } + c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") + if err != nil { + // Handle constraint not being parseable. + } + + v, _ := semver.NewVersion("1.3") + if err != nil { + // Handle version not being parseable. + } + + // Validate a version against a constraint. + a, msgs := c.Validate(v) + // a is false + for _, m := range msgs { + fmt.Println(m) + + // Loops over the errors which would read + // "1.3 is greater than 1.2.3" + // "1.3 is less than 1.4" + } */ package semver diff --git a/vendor/github.com/Masterminds/semver/v3/fuzz.go b/vendor/github.com/Masterminds/semver/v3/fuzz.go deleted file mode 100644 index a242ad70..00000000 --- a/vendor/github.com/Masterminds/semver/v3/fuzz.go +++ /dev/null @@ -1,22 +0,0 @@ -// +build gofuzz - -package semver - -func Fuzz(data []byte) int { - d := string(data) - - // Test NewVersion - _, _ = NewVersion(d) - - // Test StrictNewVersion - _, _ = StrictNewVersion(d) - - // Test NewConstraint - _, _ = NewConstraint(d) - - // The return value should be 0 normally, 1 if the priority in future tests - // should be increased, and -1 if future tests should skip passing in that - // data. We do not have a reason to change priority so 0 is always returned. - // There are example tests that do this. - return 0 -} diff --git a/vendor/github.com/Masterminds/semver/v3/version.go b/vendor/github.com/Masterminds/semver/v3/version.go index d6b9cda3..7c4bed33 100644 --- a/vendor/github.com/Masterminds/semver/v3/version.go +++ b/vendor/github.com/Masterminds/semver/v3/version.go @@ -55,14 +55,16 @@ func init() { versionRegex = regexp.MustCompile("^" + semVerRegex + "$") } -const num string = "0123456789" -const allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num +const ( + num string = "0123456789" + allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num +) // StrictNewVersion parses a given version and returns an instance of Version or // an error if unable to parse the version. Only parses valid semantic versions. // Performs checking that can find errors within the version. -// If you want to coerce a version, such as 1 or 1.2, and perse that as the 1.x -// releases of semver provided use the NewSemver() function. +// If you want to coerce a version such as 1 or 1.2 and parse it as the 1.x +// releases of semver did, use the NewVersion() function. func StrictNewVersion(v string) (*Version, error) { // Parsing here does not use RegEx in order to increase performance and reduce // allocations. @@ -207,6 +209,23 @@ func NewVersion(v string) (*Version, error) { return sv, nil } +// New creates a new instance of Version with each of the parts passed in as +// arguments instead of parsing a version string. +func New(major, minor, patch uint64, pre, metadata string) *Version { + v := Version{ + major: major, + minor: minor, + patch: patch, + pre: pre, + metadata: metadata, + original: "", + } + + v.original = v.String() + + return &v +} + // MustParse parses a given version and panics on error. func MustParse(v string) *Version { sv, err := NewVersion(v) @@ -267,7 +286,6 @@ func (v Version) Metadata() string { // originalVPrefix returns the original 'v' prefix if any. func (v Version) originalVPrefix() string { - // Note, only lowercase v is supported as a prefix by the parser. if v.original != "" && v.original[:1] == "v" { return v.original[:1] @@ -436,6 +454,23 @@ func (v Version) MarshalJSON() ([]byte, error) { return json.Marshal(v.String()) } +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (v *Version) UnmarshalText(text []byte) error { + temp, err := NewVersion(string(text)) + if err != nil { + return err + } + + *v = *temp + + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (v Version) MarshalText() ([]byte, error) { + return []byte(v.String()), nil +} + // Scan implements the SQL.Scanner interface. func (v *Version) Scan(value interface{}) error { var s string @@ -470,7 +505,6 @@ func compareSegment(v, o uint64) int { } func comparePrerelease(v, o string) int { - // split the prelease versions by their part. The separator, per the spec, // is a . sparts := strings.Split(v, ".") @@ -562,7 +596,6 @@ func comparePrePart(s, o string) int { return 1 } return -1 - } // Like strings.ContainsAny but does an only instead of any. diff --git a/vendor/github.com/Masterminds/sprig/v3/CHANGELOG.md b/vendor/github.com/Masterminds/sprig/v3/CHANGELOG.md index fcdd4e88..2ce45dd4 100644 --- a/vendor/github.com/Masterminds/sprig/v3/CHANGELOG.md +++ b/vendor/github.com/Masterminds/sprig/v3/CHANGELOG.md @@ -1,8 +1,21 @@ # Changelog +## Release 3.2.3 (2022-11-29) + +### Changed + +- Updated docs (thanks @book987 @aJetHorn @neelayu @pellizzetti @apricote @SaigyoujiYuyuko233 @AlekSi) +- #348: Updated huandu/xstrings which fixed a snake case bug (thanks @yxxhero) +- #353: Updated masterminds/semver which included bug fixes +- #354: Updated golang.org/x/crypto which included bug fixes + +## Release 3.2.2 (2021-02-04) + +This is a re-release of 3.2.1 to satisfy something with the Go module system. + ## Release 3.2.1 (2021-02-04) -### Changed +### Changed - Upgraded `Masterminds/goutils` to `v1.1.1`. see the [Security Advisory](https://github.com/Masterminds/goutils/security/advisories/GHSA-xg2h-wx96-xgxr) diff --git a/vendor/github.com/Masterminds/sprig/v3/README.md b/vendor/github.com/Masterminds/sprig/v3/README.md index c37ba01c..3e22c60e 100644 --- a/vendor/github.com/Masterminds/sprig/v3/README.md +++ b/vendor/github.com/Masterminds/sprig/v3/README.md @@ -17,10 +17,9 @@ JavaScript libraries, such as [underscore.js](http://underscorejs.org/). ## IMPORTANT NOTES Sprig leverages [mergo](https://github.com/imdario/mergo) to handle merges. In -its v0.3.9 release there was a behavior change that impacts merging template -functions in sprig. It is currently recommended to use v0.3.8 of that package. -Using v0.3.9 will cause sprig tests to fail. The issue in mergo is tracked at -https://github.com/imdario/mergo/issues/139. +its v0.3.9 release, there was a behavior change that impacts merging template +functions in sprig. It is currently recommended to use v0.3.10 or later of that package. +Using v0.3.9 will cause sprig tests to fail. ## Package Versions @@ -51,7 +50,7 @@ To load the Sprig `FuncMap`: ```go import ( - "github.com/Masterminds/sprig" + "github.com/Masterminds/sprig/v3" "html/template" ) diff --git a/vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go b/vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go index 3ed3f435..c85e6bef 100644 --- a/vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go +++ b/vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go @@ -191,7 +191,7 @@ func (bitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, return x3, y3, z3 } -//TODO: double check if it is okay +// TODO: double check if it is okay // ScalarMult returns k*(Bx,By) where k is a number in big-endian form. func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { // We have a slight problem in that the identity of the group (the @@ -239,7 +239,7 @@ func (bitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f} -//TODO: double check if it is okay +// TODO: double check if it is okay // GenerateKey returns a public/private key pair. The private key is generated // using the given reader, which must return random data. func (bitCurve *BitCurve) GenerateKey(rand io.Reader) (priv []byte, x, y *big.Int, err error) { diff --git a/vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go b/vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go index 2d535508..7e291d6a 100644 --- a/vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go +++ b/vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go @@ -80,4 +80,4 @@ func (curve *rcurve) ScalarMult(x1, y1 *big.Int, scalar []byte) (x, y *big.Int) func (curve *rcurve) ScalarBaseMult(scalar []byte) (x, y *big.Int) { return curve.fromTwisted(curve.twisted.ScalarBaseMult(scalar)) -} \ No newline at end of file +} diff --git a/vendor/github.com/ProtonMail/go-crypto/eax/eax.go b/vendor/github.com/ProtonMail/go-crypto/eax/eax.go index 6b6bc7ae..3ae91d59 100644 --- a/vendor/github.com/ProtonMail/go-crypto/eax/eax.go +++ b/vendor/github.com/ProtonMail/go-crypto/eax/eax.go @@ -67,7 +67,7 @@ func (e *eax) Seal(dst, nonce, plaintext, adata []byte) []byte { if len(nonce) > e.nonceSize { panic("crypto/eax: Nonce too long for this instance") } - ret, out := byteutil.SliceForAppend(dst, len(plaintext) + e.tagSize) + ret, out := byteutil.SliceForAppend(dst, len(plaintext)+e.tagSize) omacNonce := e.omacT(0, nonce) omacAdata := e.omacT(1, adata) @@ -85,7 +85,7 @@ func (e *eax) Seal(dst, nonce, plaintext, adata []byte) []byte { return ret } -func (e* eax) Open(dst, nonce, ciphertext, adata []byte) ([]byte, error) { +func (e *eax) Open(dst, nonce, ciphertext, adata []byte) ([]byte, error) { if len(nonce) > e.nonceSize { panic("crypto/eax: Nonce too long for this instance") } diff --git a/vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go b/vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go index a6bdf512..affb74a7 100644 --- a/vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go +++ b/vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go @@ -41,7 +41,7 @@ func ShiftNBytesLeft(dst, x []byte, n int) { bits := uint(n % 8) l := len(dst) for i := 0; i < l-1; i++ { - dst[i] = (dst[i] << bits) | (dst[i+1] >> uint(8 - bits)) + dst[i] = (dst[i] << bits) | (dst[i+1] >> uint(8-bits)) } dst[l-1] = dst[l-1] << bits @@ -56,7 +56,6 @@ func XorBytesMut(X, Y []byte) { } } - // XorBytes assumes equal input length, puts X XOR Y into Z func XorBytes(Z, X, Y []byte) { for i := 0; i < len(X); i++ { @@ -67,10 +66,10 @@ func XorBytes(Z, X, Y []byte) { // RightXor XORs smaller input (assumed Y) at the right of the larger input (assumed X) func RightXor(X, Y []byte) []byte { offset := len(X) - len(Y) - xored := make([]byte, len(X)); + xored := make([]byte, len(X)) copy(xored, X) for i := 0; i < len(Y); i++ { - xored[offset + i] ^= Y[i] + xored[offset+i] ^= Y[i] } return xored } @@ -89,4 +88,3 @@ func SliceForAppend(in []byte, n int) (head, tail []byte) { tail = head[len(in):] return } - diff --git a/vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go b/vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go index 7f78cfa7..5022285b 100644 --- a/vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go +++ b/vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go @@ -18,8 +18,9 @@ import ( "crypto/cipher" "crypto/subtle" "errors" - "github.com/ProtonMail/go-crypto/internal/byteutil" "math/bits" + + "github.com/ProtonMail/go-crypto/internal/byteutil" ) type ocb struct { @@ -93,13 +94,13 @@ func NewOCBWithNonceAndTagSize( return nil, ocbError("Custom tag length exceeds blocksize") } return &ocb{ - block: block, - tagSize: tagSize, - nonceSize: nonceSize, - mask: initializeMaskTable(block), + block: block, + tagSize: tagSize, + nonceSize: nonceSize, + mask: initializeMaskTable(block), reusableKtop: reusableKtop{ noncePrefix: nil, - Ktop: nil, + Ktop: nil, }, }, nil } @@ -153,7 +154,7 @@ func (o *ocb) crypt(instruction int, Y, nonce, adata, X []byte) []byte { truncatedNonce := make([]byte, len(nonce)) copy(truncatedNonce, nonce) truncatedNonce[len(truncatedNonce)-1] &= 192 - Ktop := make([]byte, blockSize) + var Ktop []byte if bytes.Equal(truncatedNonce, o.reusableKtop.noncePrefix) { Ktop = o.reusableKtop.Ktop } else { diff --git a/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go b/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go index 5dc158f0..14a3c336 100644 --- a/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go +++ b/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go @@ -4,21 +4,22 @@ package ocb var rfc7253TestVectorTaglen96 = struct { key, nonce, header, plaintext, ciphertext string }{"0F0E0D0C0B0A09080706050403020100", - "BBAA9988776655443322110D", - "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627", - "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627", - "1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FDAC4F02AA"} + "BBAA9988776655443322110D", + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627", + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627", + "1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FDAC4F02AA"} var rfc7253AlgorithmTest = []struct { KEYLEN, TAGLEN int - OUTPUT string }{ - {128, 128, "67E944D23256C5E0B6C61FA22FDF1EA2"}, - {192, 128, "F673F2C3E7174AAE7BAE986CA9F29E17"}, - {256, 128, "D90EB8E9C977C88B79DD793D7FFA161C"}, - {128, 96, "77A3D8E73589158D25D01209"}, - {192, 96, "05D56EAD2752C86BE6932C5E"}, - {256, 96, "5458359AC23B0CBA9E6330DD"}, - {128, 64, "192C9B7BD90BA06A"}, - {192, 64, "0066BC6E0EF34E24"}, - {256, 64, "7D4EA5D445501CBE"}, - } + OUTPUT string +}{ + {128, 128, "67E944D23256C5E0B6C61FA22FDF1EA2"}, + {192, 128, "F673F2C3E7174AAE7BAE986CA9F29E17"}, + {256, 128, "D90EB8E9C977C88B79DD793D7FFA161C"}, + {128, 96, "77A3D8E73589158D25D01209"}, + {192, 96, "05D56EAD2752C86BE6932C5E"}, + {256, 96, "5458359AC23B0CBA9E6330DD"}, + {128, 64, "192C9B7BD90BA06A"}, + {192, 64, "0066BC6E0EF34E24"}, + {256, 64, "7D4EA5D445501CBE"}, +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go index 3b357e58..e0a677f2 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go @@ -10,19 +10,22 @@ import ( "bufio" "bytes" "encoding/base64" - "github.com/ProtonMail/go-crypto/openpgp/errors" "io" + + "github.com/ProtonMail/go-crypto/openpgp/errors" ) // A Block represents an OpenPGP armored structure. // // The encoded form is: -// -----BEGIN Type----- -// Headers // -// base64-encoded Bytes -// '=' base64 encoded checksum -// -----END Type----- +// -----BEGIN Type----- +// Headers +// +// base64-encoded Bytes +// '=' base64 encoded checksum (optional) not checked anymore +// -----END Type----- +// // where Headers is a possibly empty sequence of Key: Value lines. // // Since the armored data can be very large, this package presents a streaming @@ -37,36 +40,15 @@ type Block struct { var ArmorCorrupt error = errors.StructuralError("armor invalid") -const crc24Init = 0xb704ce -const crc24Poly = 0x1864cfb -const crc24Mask = 0xffffff - -// crc24 calculates the OpenPGP checksum as specified in RFC 4880, section 6.1 -func crc24(crc uint32, d []byte) uint32 { - for _, b := range d { - crc ^= uint32(b) << 16 - for i := 0; i < 8; i++ { - crc <<= 1 - if crc&0x1000000 != 0 { - crc ^= crc24Poly - } - } - } - return crc -} - var armorStart = []byte("-----BEGIN ") var armorEnd = []byte("-----END ") var armorEndOfLine = []byte("-----") -// lineReader wraps a line based reader. It watches for the end of an armor -// block and records the expected CRC value. +// lineReader wraps a line based reader. It watches for the end of an armor block type lineReader struct { - in *bufio.Reader - buf []byte - eof bool - crc uint32 - crcSet bool + in *bufio.Reader + buf []byte + eof bool } func (l *lineReader) Read(p []byte) (n int, err error) { @@ -95,26 +77,9 @@ func (l *lineReader) Read(p []byte) (n int, err error) { if len(line) == 5 && line[0] == '=' { // This is the checksum line - var expectedBytes [3]byte - var m int - m, err = base64.StdEncoding.Decode(expectedBytes[0:], line[1:]) - if m != 3 || err != nil { - return - } - l.crc = uint32(expectedBytes[0])<<16 | - uint32(expectedBytes[1])<<8 | - uint32(expectedBytes[2]) - - line, _, err = l.in.ReadLine() - if err != nil && err != io.EOF { - return - } - if !bytes.HasPrefix(line, armorEnd) { - return 0, ArmorCorrupt - } + // Don't check the checksum l.eof = true - l.crcSet = true return 0, io.EOF } @@ -135,23 +100,14 @@ func (l *lineReader) Read(p []byte) (n int, err error) { return } -// openpgpReader passes Read calls to the underlying base64 decoder, but keeps -// a running CRC of the resulting data and checks the CRC against the value -// found by the lineReader at EOF. +// openpgpReader passes Read calls to the underlying base64 decoder. type openpgpReader struct { - lReader *lineReader - b64Reader io.Reader - currentCRC uint32 + lReader *lineReader + b64Reader io.Reader } func (r *openpgpReader) Read(p []byte) (n int, err error) { n, err = r.b64Reader.Read(p) - r.currentCRC = crc24(r.currentCRC, p[:n]) - - if err == io.EOF && r.lReader.crcSet && r.lReader.crc != uint32(r.currentCRC&crc24Mask) { - return 0, ArmorCorrupt - } - return } @@ -206,16 +162,19 @@ TryNextBlock: break } - i := bytes.Index(line, []byte(": ")) + i := bytes.Index(line, []byte(":")) if i == -1 { goto TryNextBlock } lastKey = string(line[:i]) - p.Header[lastKey] = string(line[i+2:]) + var value string + if len(line) > i+2 { + value = string(line[i+2:]) + } + p.Header[lastKey] = value } p.lReader.in = r - p.oReader.currentCRC = crc24Init p.oReader.lReader = &p.lReader p.oReader.b64Reader = base64.NewDecoder(base64.StdEncoding, &p.lReader) p.Body = &p.oReader diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/encode.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/encode.go index 6f07582c..112f98b8 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/encode.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/encode.go @@ -14,6 +14,23 @@ var blockEnd = []byte("\n=") var newline = []byte("\n") var armorEndOfLineOut = []byte("-----\n") +const crc24Init = 0xb704ce +const crc24Poly = 0x1864cfb + +// crc24 calculates the OpenPGP checksum as specified in RFC 4880, section 6.1 +func crc24(crc uint32, d []byte) uint32 { + for _, b := range d { + crc ^= uint32(b) << 16 + for i := 0; i < 8; i++ { + crc <<= 1 + if crc&0x1000000 != 0 { + crc ^= crc24Poly + } + } + } + return crc +} + // writeSlices writes its arguments to the given Writer. func writeSlices(out io.Writer, slices ...[]byte) (err error) { for _, s := range slices { @@ -96,17 +113,21 @@ func (l *lineBreaker) Close() (err error) { // trailer. // // It's built into a stack of io.Writers: -// encoding -> base64 encoder -> lineBreaker -> out +// +// encoding -> base64 encoder -> lineBreaker -> out type encoding struct { - out io.Writer - breaker *lineBreaker - b64 io.WriteCloser - crc uint32 - blockType []byte + out io.Writer + breaker *lineBreaker + b64 io.WriteCloser + crc uint32 + crcEnabled bool + blockType []byte } func (e *encoding) Write(data []byte) (n int, err error) { - e.crc = crc24(e.crc, data) + if e.crcEnabled { + e.crc = crc24(e.crc, data) + } return e.b64.Write(data) } @@ -117,20 +138,21 @@ func (e *encoding) Close() (err error) { } e.breaker.Close() - var checksumBytes [3]byte - checksumBytes[0] = byte(e.crc >> 16) - checksumBytes[1] = byte(e.crc >> 8) - checksumBytes[2] = byte(e.crc) + if e.crcEnabled { + var checksumBytes [3]byte + checksumBytes[0] = byte(e.crc >> 16) + checksumBytes[1] = byte(e.crc >> 8) + checksumBytes[2] = byte(e.crc) - var b64ChecksumBytes [4]byte - base64.StdEncoding.Encode(b64ChecksumBytes[:], checksumBytes[:]) + var b64ChecksumBytes [4]byte + base64.StdEncoding.Encode(b64ChecksumBytes[:], checksumBytes[:]) - return writeSlices(e.out, blockEnd, b64ChecksumBytes[:], newline, armorEnd, e.blockType, armorEndOfLine) + return writeSlices(e.out, blockEnd, b64ChecksumBytes[:], newline, armorEnd, e.blockType, armorEndOfLine) + } + return writeSlices(e.out, newline, armorEnd, e.blockType, armorEndOfLine) } -// Encode returns a WriteCloser which will encode the data written to it in -// OpenPGP armor. -func Encode(out io.Writer, blockType string, headers map[string]string) (w io.WriteCloser, err error) { +func encode(out io.Writer, blockType string, headers map[string]string, checksum bool) (w io.WriteCloser, err error) { bType := []byte(blockType) err = writeSlices(out, armorStart, bType, armorEndOfLineOut) if err != nil { @@ -150,11 +172,27 @@ func Encode(out io.Writer, blockType string, headers map[string]string) (w io.Wr } e := &encoding{ - out: out, - breaker: newLineBreaker(out, 64), - crc: crc24Init, - blockType: bType, + out: out, + breaker: newLineBreaker(out, 64), + blockType: bType, + crc: crc24Init, + crcEnabled: checksum, } e.b64 = base64.NewEncoder(base64.StdEncoding, e.breaker) return e, nil } + +// Encode returns a WriteCloser which will encode the data written to it in +// OpenPGP armor. +func Encode(out io.Writer, blockType string, headers map[string]string) (w io.WriteCloser, err error) { + return encode(out, blockType, headers, true) +} + +// EncodeWithChecksumOption returns a WriteCloser which will encode the data written to it in +// OpenPGP armor and provides the option to include a checksum. +// When forming ASCII Armor, the CRC24 footer SHOULD NOT be generated, +// unless interoperability with implementations that require the CRC24 footer +// to be present is a concern. +func EncodeWithChecksumOption(out io.Writer, blockType string, headers map[string]string, doChecksum bool) (w io.WriteCloser, err error) { + return encode(out, blockType, headers, doChecksum) +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/canonical_text.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/canonical_text.go index a94f6150..5b40e137 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/canonical_text.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/canonical_text.go @@ -30,8 +30,12 @@ func writeCanonical(cw io.Writer, buf []byte, s *int) (int, error) { if c == '\r' { *s = 1 } else if c == '\n' { - cw.Write(buf[start:i]) - cw.Write(newline) + if _, err := cw.Write(buf[start:i]); err != nil { + return 0, err + } + if _, err := cw.Write(newline); err != nil { + return 0, err + } start = i + 1 } case 1: @@ -39,7 +43,9 @@ func writeCanonical(cw io.Writer, buf []byte, s *int) (int, error) { } } - cw.Write(buf[start:]) + if _, err := cw.Write(buf[start:]); err != nil { + return 0, err + } return len(buf), nil } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdh/ecdh.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdh/ecdh.go index b09e2a73..c895bad6 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdh/ecdh.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdh/ecdh.go @@ -34,7 +34,7 @@ type PrivateKey struct { func NewPublicKey(curve ecc.ECDHCurve, kdfHash algorithm.Hash, kdfCipher algorithm.Cipher) *PublicKey { return &PublicKey{ - curve: curve, + curve: curve, KDF: KDF{ Hash: kdfHash, Cipher: kdfCipher, @@ -167,7 +167,7 @@ func buildKey(pub *PublicKey, zb []byte, curveOID, fingerprint []byte, stripLead if _, err := param.Write(fingerprint[:20]); err != nil { return nil, err } - if param.Len() - len(curveOID) != 45 { + if param.Len()-len(curveOID) != 45 { return nil, errors.New("ecdh: malformed KDF Param") } @@ -181,15 +181,19 @@ func buildKey(pub *PublicKey, zb []byte, curveOID, fingerprint []byte, stripLead j := zbLen - 1 if stripLeading { // Work around old go crypto bug where the leading zeros are missing. - for ; i < zbLen && zb[i] == 0; i++ {} + for i < zbLen && zb[i] == 0 { + i++ + } } if stripTrailing { // Work around old OpenPGP.js bug where insignificant trailing zeros in // this little-endian number are missing. // (See https://github.com/openpgpjs/openpgpjs/pull/853.) - for ; j >= 0 && zb[j] == 0; j-- {} + for j >= 0 && zb[j] == 0 { + j-- + } } - if _, err := h.Write(zb[i:j+1]); err != nil { + if _, err := h.Write(zb[i : j+1]); err != nil { return nil, err } if _, err := h.Write(param.Bytes()); err != nil { diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdsa/ecdsa.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdsa/ecdsa.go index 6682a21a..f94ae1b2 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdsa/ecdsa.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdsa/ecdsa.go @@ -10,7 +10,7 @@ import ( ) type PublicKey struct { - X, Y *big.Int + X, Y *big.Int curve ecc.ECDSACurve } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/ed25519/ed25519.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/ed25519/ed25519.go new file mode 100644 index 00000000..6abdf7c4 --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/ed25519/ed25519.go @@ -0,0 +1,115 @@ +// Package ed25519 implements the ed25519 signature algorithm for OpenPGP +// as defined in the Open PGP crypto refresh. +package ed25519 + +import ( + "crypto/subtle" + "io" + + "github.com/ProtonMail/go-crypto/openpgp/errors" + ed25519lib "github.com/cloudflare/circl/sign/ed25519" +) + +const ( + // PublicKeySize is the size, in bytes, of public keys in this package. + PublicKeySize = ed25519lib.PublicKeySize + // SeedSize is the size, in bytes, of private key seeds. + // The private key representation used by RFC 8032. + SeedSize = ed25519lib.SeedSize + // SignatureSize is the size, in bytes, of signatures generated and verified by this package. + SignatureSize = ed25519lib.SignatureSize +) + +type PublicKey struct { + // Point represents the elliptic curve point of the public key. + Point []byte +} + +type PrivateKey struct { + PublicKey + // Key the private key representation by RFC 8032, + // encoded as seed | pub key point. + Key []byte +} + +// NewPublicKey creates a new empty ed25519 public key. +func NewPublicKey() *PublicKey { + return &PublicKey{} +} + +// NewPrivateKey creates a new empty private key referencing the public key. +func NewPrivateKey(key PublicKey) *PrivateKey { + return &PrivateKey{ + PublicKey: key, + } +} + +// Seed returns the ed25519 private key secret seed. +// The private key representation by RFC 8032. +func (pk *PrivateKey) Seed() []byte { + return pk.Key[:SeedSize] +} + +// MarshalByteSecret returns the underlying 32 byte seed of the private key. +func (pk *PrivateKey) MarshalByteSecret() []byte { + return pk.Seed() +} + +// UnmarshalByteSecret computes the private key from the secret seed +// and stores it in the private key object. +func (sk *PrivateKey) UnmarshalByteSecret(seed []byte) error { + sk.Key = ed25519lib.NewKeyFromSeed(seed) + return nil +} + +// GenerateKey generates a fresh private key with the provided randomness source. +func GenerateKey(rand io.Reader) (*PrivateKey, error) { + publicKey, privateKey, err := ed25519lib.GenerateKey(rand) + if err != nil { + return nil, err + } + privateKeyOut := new(PrivateKey) + privateKeyOut.PublicKey.Point = publicKey[:] + privateKeyOut.Key = privateKey[:] + return privateKeyOut, nil +} + +// Sign signs a message with the ed25519 algorithm. +// priv MUST be a valid key! Check this with Validate() before use. +func Sign(priv *PrivateKey, message []byte) ([]byte, error) { + return ed25519lib.Sign(priv.Key, message), nil +} + +// Verify verifies an ed25519 signature. +func Verify(pub *PublicKey, message []byte, signature []byte) bool { + return ed25519lib.Verify(pub.Point, message, signature) +} + +// Validate checks if the ed25519 private key is valid. +func Validate(priv *PrivateKey) error { + expectedPrivateKey := ed25519lib.NewKeyFromSeed(priv.Seed()) + if subtle.ConstantTimeCompare(priv.Key, expectedPrivateKey) == 0 { + return errors.KeyInvalidError("ed25519: invalid ed25519 secret") + } + if subtle.ConstantTimeCompare(priv.PublicKey.Point, expectedPrivateKey[SeedSize:]) == 0 { + return errors.KeyInvalidError("ed25519: invalid ed25519 public key") + } + return nil +} + +// ENCODING/DECODING signature: + +// WriteSignature encodes and writes an ed25519 signature to writer. +func WriteSignature(writer io.Writer, signature []byte) error { + _, err := writer.Write(signature) + return err +} + +// ReadSignature decodes an ed25519 signature from a reader. +func ReadSignature(reader io.Reader) ([]byte, error) { + signature := make([]byte, SignatureSize) + if _, err := io.ReadFull(reader, signature); err != nil { + return nil, err + } + return signature, nil +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/ed448/ed448.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/ed448/ed448.go new file mode 100644 index 00000000..b11fb4fb --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/ed448/ed448.go @@ -0,0 +1,119 @@ +// Package ed448 implements the ed448 signature algorithm for OpenPGP +// as defined in the Open PGP crypto refresh. +package ed448 + +import ( + "crypto/subtle" + "io" + + "github.com/ProtonMail/go-crypto/openpgp/errors" + ed448lib "github.com/cloudflare/circl/sign/ed448" +) + +const ( + // PublicKeySize is the size, in bytes, of public keys in this package. + PublicKeySize = ed448lib.PublicKeySize + // SeedSize is the size, in bytes, of private key seeds. + // The private key representation used by RFC 8032. + SeedSize = ed448lib.SeedSize + // SignatureSize is the size, in bytes, of signatures generated and verified by this package. + SignatureSize = ed448lib.SignatureSize +) + +type PublicKey struct { + // Point represents the elliptic curve point of the public key. + Point []byte +} + +type PrivateKey struct { + PublicKey + // Key the private key representation by RFC 8032, + // encoded as seed | public key point. + Key []byte +} + +// NewPublicKey creates a new empty ed448 public key. +func NewPublicKey() *PublicKey { + return &PublicKey{} +} + +// NewPrivateKey creates a new empty private key referencing the public key. +func NewPrivateKey(key PublicKey) *PrivateKey { + return &PrivateKey{ + PublicKey: key, + } +} + +// Seed returns the ed448 private key secret seed. +// The private key representation by RFC 8032. +func (pk *PrivateKey) Seed() []byte { + return pk.Key[:SeedSize] +} + +// MarshalByteSecret returns the underlying seed of the private key. +func (pk *PrivateKey) MarshalByteSecret() []byte { + return pk.Seed() +} + +// UnmarshalByteSecret computes the private key from the secret seed +// and stores it in the private key object. +func (sk *PrivateKey) UnmarshalByteSecret(seed []byte) error { + sk.Key = ed448lib.NewKeyFromSeed(seed) + return nil +} + +// GenerateKey generates a fresh private key with the provided randomness source. +func GenerateKey(rand io.Reader) (*PrivateKey, error) { + publicKey, privateKey, err := ed448lib.GenerateKey(rand) + if err != nil { + return nil, err + } + privateKeyOut := new(PrivateKey) + privateKeyOut.PublicKey.Point = publicKey[:] + privateKeyOut.Key = privateKey[:] + return privateKeyOut, nil +} + +// Sign signs a message with the ed448 algorithm. +// priv MUST be a valid key! Check this with Validate() before use. +func Sign(priv *PrivateKey, message []byte) ([]byte, error) { + // Ed448 is used with the empty string as a context string. + // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-08#section-13.7 + return ed448lib.Sign(priv.Key, message, ""), nil +} + +// Verify verifies a ed448 signature +func Verify(pub *PublicKey, message []byte, signature []byte) bool { + // Ed448 is used with the empty string as a context string. + // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-08#section-13.7 + return ed448lib.Verify(pub.Point, message, signature, "") +} + +// Validate checks if the ed448 private key is valid +func Validate(priv *PrivateKey) error { + expectedPrivateKey := ed448lib.NewKeyFromSeed(priv.Seed()) + if subtle.ConstantTimeCompare(priv.Key, expectedPrivateKey) == 0 { + return errors.KeyInvalidError("ed448: invalid ed448 secret") + } + if subtle.ConstantTimeCompare(priv.PublicKey.Point, expectedPrivateKey[SeedSize:]) == 0 { + return errors.KeyInvalidError("ed448: invalid ed448 public key") + } + return nil +} + +// ENCODING/DECODING signature: + +// WriteSignature encodes and writes an ed448 signature to writer. +func WriteSignature(writer io.Writer, signature []byte) error { + _, err := writer.Write(signature) + return err +} + +// ReadSignature decodes an ed448 signature from a reader. +func ReadSignature(reader io.Reader) ([]byte, error) { + signature := make([]byte, SignatureSize) + if _, err := io.ReadFull(reader, signature); err != nil { + return nil, err + } + return signature, nil +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/eddsa/eddsa.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/eddsa/eddsa.go index 12866c12..99ecfc7f 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/eddsa/eddsa.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/eddsa/eddsa.go @@ -9,7 +9,7 @@ import ( ) type PublicKey struct { - X []byte + X []byte curve ecc.EdDSACurve } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/elgamal/elgamal.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/elgamal/elgamal.go index 6a07d8ff..bad27743 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/elgamal/elgamal.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/elgamal/elgamal.go @@ -71,8 +71,8 @@ func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err // returns the plaintext of the message. An error can result only if the // ciphertext is invalid. Users should keep in mind that this is a padding // oracle and thus, if exposed to an adaptive chosen ciphertext attack, can -// be used to break the cryptosystem. See ``Chosen Ciphertext Attacks -// Against Protocols Based on the RSA Encryption Standard PKCS #1'', Daniel +// be used to break the cryptosystem. See “Chosen Ciphertext Attacks +// Against Protocols Based on the RSA Encryption Standard PKCS #1”, Daniel // Bleichenbacher, Advances in Cryptology (Crypto '98), func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) { s := new(big.Int).Exp(c1, priv.X, priv.P) diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go index 17e2bcfe..8d6969c0 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Package errors contains common error types for the OpenPGP packages. -package errors // import "github.com/ProtonMail/go-crypto/openpgp/errors" +package errors // import "github.com/ProtonMail/go-crypto/v2/openpgp/errors" import ( "strconv" @@ -58,6 +58,14 @@ func (ke keyExpiredError) Error() string { return "openpgp: key expired" } +var ErrSignatureOlderThanKey error = signatureOlderThanKeyError(0) + +type signatureOlderThanKeyError int + +func (ske signatureOlderThanKeyError) Error() string { + return "openpgp: signature is older than the key" +} + var ErrKeyExpired error = keyExpiredError(0) type keyIncorrectError int @@ -92,12 +100,24 @@ func (keyRevokedError) Error() string { var ErrKeyRevoked error = keyRevokedError(0) +type WeakAlgorithmError string + +func (e WeakAlgorithmError) Error() string { + return "openpgp: weak algorithms are rejected: " + string(e) +} + type UnknownPacketTypeError uint8 func (upte UnknownPacketTypeError) Error() string { return "openpgp: unknown packet type: " + strconv.Itoa(int(upte)) } +type CriticalUnknownPacketTypeError uint8 + +func (upte CriticalUnknownPacketTypeError) Error() string { + return "openpgp: unknown critical packet type: " + strconv.Itoa(int(upte)) +} + // AEADError indicates that there is a problem when initializing or using a // AEAD instance, configuration struct, nonces or index values. type AEADError string @@ -114,3 +134,10 @@ type ErrDummyPrivateKey string func (dke ErrDummyPrivateKey) Error() string { return "openpgp: s2k GNU dummy key: " + string(dke) } + +// ErrMalformedMessage results when the packet sequence is incorrect +type ErrMalformedMessage string + +func (dke ErrMalformedMessage) Error() string { + return "openpgp: malformed message " + string(dke) +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/hash.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/hash.go new file mode 100644 index 00000000..526bd777 --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/hash.go @@ -0,0 +1,24 @@ +package openpgp + +import ( + "crypto" + + "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm" +) + +// HashIdToHash returns a crypto.Hash which corresponds to the given OpenPGP +// hash id. +func HashIdToHash(id byte) (h crypto.Hash, ok bool) { + return algorithm.HashIdToHash(id) +} + +// HashIdToString returns the name of the hash function corresponding to the +// given OpenPGP hash id. +func HashIdToString(id byte) (name string, ok bool) { + return algorithm.HashIdToString(id) +} + +// HashToHashId returns an OpenPGP hash id which corresponds the given Hash. +func HashToHashId(h crypto.Hash) (id byte, ok bool) { + return algorithm.HashToHashId(h) +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/cipher.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/cipher.go index 5760cff8..c76a75bc 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/cipher.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/cipher.go @@ -51,24 +51,14 @@ func (sk CipherFunction) Id() uint8 { return uint8(sk) } -var keySizeByID = map[uint8]int{ - TripleDES.Id(): 24, - CAST5.Id(): cast5.KeySize, - AES128.Id(): 16, - AES192.Id(): 24, - AES256.Id(): 32, -} - // KeySize returns the key size, in bytes, of cipher. func (cipher CipherFunction) KeySize() int { switch cipher { - case TripleDES: - return 24 case CAST5: return cast5.KeySize case AES128: return 16 - case AES192: + case AES192, TripleDES: return 24 case AES256: return 32 diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/hash.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/hash.go index 82e43d67..d1a00fc7 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/hash.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/hash.go @@ -32,25 +32,25 @@ type Hash interface { // The following vars mirror the crypto/Hash supported hash functions. var ( - SHA1 Hash = cryptoHash{2, crypto.SHA1} - SHA256 Hash = cryptoHash{8, crypto.SHA256} - SHA384 Hash = cryptoHash{9, crypto.SHA384} - SHA512 Hash = cryptoHash{10, crypto.SHA512} - SHA224 Hash = cryptoHash{11, crypto.SHA224} - SHA3_256 Hash = cryptoHash{12, crypto.SHA3_256} - SHA3_512 Hash = cryptoHash{14, crypto.SHA3_512} + SHA1 Hash = cryptoHash{2, crypto.SHA1} + SHA256 Hash = cryptoHash{8, crypto.SHA256} + SHA384 Hash = cryptoHash{9, crypto.SHA384} + SHA512 Hash = cryptoHash{10, crypto.SHA512} + SHA224 Hash = cryptoHash{11, crypto.SHA224} + SHA3_256 Hash = cryptoHash{12, crypto.SHA3_256} + SHA3_512 Hash = cryptoHash{14, crypto.SHA3_512} ) // HashById represents the different hash functions specified for OpenPGP. See // http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-14 var ( HashById = map[uint8]Hash{ - SHA256.Id(): SHA256, - SHA384.Id(): SHA384, - SHA512.Id(): SHA512, - SHA224.Id(): SHA224, - SHA3_256.Id(): SHA3_256, - SHA3_512.Id(): SHA3_512, + SHA256.Id(): SHA256, + SHA384.Id(): SHA384, + SHA512.Id(): SHA512, + SHA224.Id(): SHA224, + SHA3_256.Id(): SHA3_256, + SHA3_512.Id(): SHA3_512, } ) @@ -67,12 +67,12 @@ func (h cryptoHash) Id() uint8 { } var hashNames = map[uint8]string{ - SHA256.Id(): "SHA256", - SHA384.Id(): "SHA384", - SHA512.Id(): "SHA512", - SHA224.Id(): "SHA224", - SHA3_256.Id(): "SHA3-256", - SHA3_512.Id(): "SHA3-512", + SHA256.Id(): "SHA256", + SHA384.Id(): "SHA384", + SHA512.Id(): "SHA512", + SHA224.Id(): "SHA224", + SHA3_256.Id(): "SHA3-256", + SHA3_512.Id(): "SHA3-512", } func (h cryptoHash) String() string { diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve25519.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve25519.go index 266635ec..888767c4 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve25519.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve25519.go @@ -9,7 +9,7 @@ import ( x25519lib "github.com/cloudflare/circl/dh/x25519" ) -type curve25519 struct {} +type curve25519 struct{} func NewCurve25519() *curve25519 { return &curve25519{} @@ -21,14 +21,14 @@ func (c *curve25519) GetCurveName() string { // MarshalBytePoint encodes the public point from native format, adding the prefix. // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6 -func (c *curve25519) MarshalBytePoint(point [] byte) []byte { +func (c *curve25519) MarshalBytePoint(point []byte) []byte { return append([]byte{0x40}, point...) } // UnmarshalBytePoint decodes the public point to native format, removing the prefix. // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6 func (c *curve25519) UnmarshalBytePoint(point []byte) []byte { - if len(point) != x25519lib.Size + 1 { + if len(point) != x25519lib.Size+1 { return nil } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve_info.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve_info.go index df2878c9..97f891ff 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve_info.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve_info.go @@ -4,6 +4,7 @@ package ecc import ( "bytes" "crypto/elliptic" + "github.com/ProtonMail/go-crypto/bitcurves" "github.com/ProtonMail/go-crypto/brainpool" "github.com/ProtonMail/go-crypto/openpgp/internal/encoding" @@ -11,76 +12,76 @@ import ( type CurveInfo struct { GenName string - Oid *encoding.OID - Curve Curve + Oid *encoding.OID + Curve Curve } var Curves = []CurveInfo{ { // NIST P-256 GenName: "P256", - Oid: encoding.NewOID([]byte{0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}), - Curve: NewGenericCurve(elliptic.P256()), + Oid: encoding.NewOID([]byte{0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}), + Curve: NewGenericCurve(elliptic.P256()), }, { // NIST P-384 GenName: "P384", - Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x22}), - Curve: NewGenericCurve(elliptic.P384()), + Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x22}), + Curve: NewGenericCurve(elliptic.P384()), }, { // NIST P-521 GenName: "P521", - Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x23}), - Curve: NewGenericCurve(elliptic.P521()), + Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x23}), + Curve: NewGenericCurve(elliptic.P521()), }, { // SecP256k1 GenName: "SecP256k1", - Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x0A}), - Curve: NewGenericCurve(bitcurves.S256()), + Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x0A}), + Curve: NewGenericCurve(bitcurves.S256()), }, { // Curve25519 GenName: "Curve25519", - Oid: encoding.NewOID([]byte{0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01}), - Curve: NewCurve25519(), + Oid: encoding.NewOID([]byte{0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01}), + Curve: NewCurve25519(), }, { - // X448 + // x448 GenName: "Curve448", - Oid: encoding.NewOID([]byte{0x2B, 0x65, 0x6F}), - Curve: NewX448(), + Oid: encoding.NewOID([]byte{0x2B, 0x65, 0x6F}), + Curve: NewX448(), }, { // Ed25519 GenName: "Curve25519", - Oid: encoding.NewOID([]byte{0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01}), - Curve: NewEd25519(), + Oid: encoding.NewOID([]byte{0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01}), + Curve: NewEd25519(), }, { // Ed448 GenName: "Curve448", - Oid: encoding.NewOID([]byte{0x2B, 0x65, 0x71}), - Curve: NewEd448(), + Oid: encoding.NewOID([]byte{0x2B, 0x65, 0x71}), + Curve: NewEd448(), }, { // BrainpoolP256r1 GenName: "BrainpoolP256", - Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07}), - Curve: NewGenericCurve(brainpool.P256r1()), + Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07}), + Curve: NewGenericCurve(brainpool.P256r1()), }, { // BrainpoolP384r1 GenName: "BrainpoolP384", - Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B}), - Curve: NewGenericCurve(brainpool.P384r1()), + Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B}), + Curve: NewGenericCurve(brainpool.P384r1()), }, { // BrainpoolP512r1 GenName: "BrainpoolP512", - Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D}), - Curve: NewGenericCurve(brainpool.P512r1()), + Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D}), + Curve: NewGenericCurve(brainpool.P512r1()), }, } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curves.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curves.go index c47072b4..5ed9c93b 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curves.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curves.go @@ -38,7 +38,7 @@ type EdDSACurve interface { type ECDHCurve interface { Curve MarshalBytePoint([]byte) (encoded []byte) - UnmarshalBytePoint(encoded []byte) ([]byte) + UnmarshalBytePoint(encoded []byte) []byte MarshalByteSecret(d []byte) []byte UnmarshalByteSecret(d []byte) []byte GenerateECDH(rand io.Reader) (point []byte, secret []byte, err error) diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed25519.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed25519.go index 29f6cba9..54a08a8a 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed25519.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed25519.go @@ -10,7 +10,8 @@ import ( ) const ed25519Size = 32 -type ed25519 struct {} + +type ed25519 struct{} func NewEd25519() *ed25519 { return &ed25519{} @@ -29,7 +30,7 @@ func (c *ed25519) MarshalBytePoint(x []byte) []byte { // UnmarshalBytePoint decodes a point from prefixed format to native. // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5 func (c *ed25519) UnmarshalBytePoint(point []byte) (x []byte) { - if len(point) != ed25519lib.PublicKeySize + 1 { + if len(point) != ed25519lib.PublicKeySize+1 { return nil } @@ -52,7 +53,7 @@ func (c *ed25519) UnmarshalByteSecret(s []byte) (d []byte) { // Handle stripped leading zeroes d = make([]byte, ed25519lib.SeedSize) - copy(d[ed25519lib.SeedSize - len(s):], s) + copy(d[ed25519lib.SeedSize-len(s):], s) return } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed448.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed448.go index a2df3dab..18cd8043 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed448.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed448.go @@ -9,7 +9,7 @@ import ( ed448lib "github.com/cloudflare/circl/sign/ed448" ) -type ed448 struct {} +type ed448 struct{} func NewEd448() *ed448 { return &ed448{} @@ -29,7 +29,7 @@ func (c *ed448) MarshalBytePoint(x []byte) []byte { // UnmarshalBytePoint decodes a point from prefixed format to native. // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5 func (c *ed448) UnmarshalBytePoint(point []byte) (x []byte) { - if len(point) != ed448lib.PublicKeySize + 1 { + if len(point) != ed448lib.PublicKeySize+1 { return nil } @@ -48,7 +48,7 @@ func (c *ed448) MarshalByteSecret(d []byte) []byte { // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5 func (c *ed448) UnmarshalByteSecret(s []byte) (d []byte) { // Check prefixed size - if len(s) != ed448lib.SeedSize + 1 { + if len(s) != ed448lib.SeedSize+1 { return nil } @@ -66,7 +66,7 @@ func (c *ed448) MarshalSignature(sig []byte) (r, s []byte) { // UnmarshalSignature decodes R and S in the native format. Only R is used, in prefixed native format. // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.2.3.3.2 func (c *ed448) UnmarshalSignature(r, s []byte) (sig []byte) { - if len(r) != ed448lib.SignatureSize + 1 { + if len(r) != ed448lib.SignatureSize+1 { return nil } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go index 4a940b4f..df04262e 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go @@ -9,7 +9,7 @@ import ( x448lib "github.com/cloudflare/circl/dh/x448" ) -type x448 struct {} +type x448 struct{} func NewX448() *x448 { return &x448{} @@ -28,7 +28,7 @@ func (c *x448) MarshalBytePoint(point []byte) []byte { // UnmarshalBytePoint decodes a point from prefixed format to native. // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6 func (c *x448) UnmarshalBytePoint(point []byte) []byte { - if len(point) != x448lib.Size + 1 { + if len(point) != x448lib.Size+1 { return nil } @@ -44,7 +44,7 @@ func (c *x448) MarshalByteSecret(d []byte) []byte { // UnmarshalByteSecret decodes a scalar from prefixed format to native. // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6.1.2 func (c *x448) UnmarshalByteSecret(d []byte) []byte { - if len(d) != x448lib.Size + 1 { + if len(d) != x448lib.Size+1 { return nil } @@ -73,7 +73,9 @@ func (c *x448) GenerateECDH(rand io.Reader) (point []byte, secret []byte, err er func (c *x448) Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error) { var pk, ss x448lib.Key seed, e, err := c.generateKeyPairBytes(rand) - + if err != nil { + return nil, nil, err + } copy(pk[:], point) x448lib.Shared(&ss, &seed, &pk) diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/key_generation.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/key_generation.go index 0e71934c..a40e45be 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/key_generation.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/key_generation.go @@ -15,11 +15,15 @@ import ( "github.com/ProtonMail/go-crypto/openpgp/ecdh" "github.com/ProtonMail/go-crypto/openpgp/ecdsa" + "github.com/ProtonMail/go-crypto/openpgp/ed25519" + "github.com/ProtonMail/go-crypto/openpgp/ed448" "github.com/ProtonMail/go-crypto/openpgp/eddsa" "github.com/ProtonMail/go-crypto/openpgp/errors" "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm" "github.com/ProtonMail/go-crypto/openpgp/internal/ecc" "github.com/ProtonMail/go-crypto/openpgp/packet" + "github.com/ProtonMail/go-crypto/openpgp/x25519" + "github.com/ProtonMail/go-crypto/openpgp/x448" ) // NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a @@ -36,8 +40,8 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err return nil, err } primary := packet.NewSignerPrivateKey(creationTime, primaryPrivRaw) - if config != nil && config.V5Keys { - primary.UpgradeToV5() + if config.V6() { + primary.UpgradeToV6() } e := &Entity{ @@ -45,9 +49,25 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err PrivateKey: primary, Identities: make(map[string]*Identity), Subkeys: []Subkey{}, + Signatures: []*packet.Signature{}, } - err = e.addUserId(name, comment, email, config, creationTime, keyLifetimeSecs) + if config.V6() { + // In v6 keys algorithm preferences should be stored in direct key signatures + selfSignature := createSignaturePacket(&primary.PublicKey, packet.SigTypeDirectSignature, config) + err = writeKeyProperties(selfSignature, creationTime, keyLifetimeSecs, config) + if err != nil { + return nil, err + } + err = selfSignature.SignDirectKeyBinding(&primary.PublicKey, primary, config) + if err != nil { + return nil, err + } + e.Signatures = append(e.Signatures, selfSignature) + e.SelfSignature = selfSignature + } + + err = e.addUserId(name, comment, email, config, creationTime, keyLifetimeSecs, !config.V6()) if err != nil { return nil, err } @@ -65,27 +85,12 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err func (t *Entity) AddUserId(name, comment, email string, config *packet.Config) error { creationTime := config.Now() keyLifetimeSecs := config.KeyLifetime() - return t.addUserId(name, comment, email, config, creationTime, keyLifetimeSecs) + return t.addUserId(name, comment, email, config, creationTime, keyLifetimeSecs, !config.V6()) } -func (t *Entity) addUserId(name, comment, email string, config *packet.Config, creationTime time.Time, keyLifetimeSecs uint32) error { - uid := packet.NewUserId(name, comment, email) - if uid == nil { - return errors.InvalidArgumentError("user id field contained invalid characters") - } - - if _, ok := t.Identities[uid.Id]; ok { - return errors.InvalidArgumentError("user id exist") - } - - primary := t.PrivateKey - - isPrimaryId := len(t.Identities) == 0 - - selfSignature := createSignaturePacket(&primary.PublicKey, packet.SigTypePositiveCert, config) +func writeKeyProperties(selfSignature *packet.Signature, creationTime time.Time, keyLifetimeSecs uint32, config *packet.Config) error { selfSignature.CreationTime = creationTime selfSignature.KeyLifetimeSecs = &keyLifetimeSecs - selfSignature.IsPrimaryId = &isPrimaryId selfSignature.FlagsValid = true selfSignature.FlagSign = true selfSignature.FlagCertify = true @@ -131,6 +136,29 @@ func (t *Entity) addUserId(name, comment, email string, config *packet.Config, c selfSignature.PreferredCipherSuites = append(selfSignature.PreferredCipherSuites, [2]uint8{cipher, mode}) } } + return nil +} + +func (t *Entity) addUserId(name, comment, email string, config *packet.Config, creationTime time.Time, keyLifetimeSecs uint32, writeProperties bool) error { + uid := packet.NewUserId(name, comment, email) + if uid == nil { + return errors.InvalidArgumentError("user id field contained invalid characters") + } + + if _, ok := t.Identities[uid.Id]; ok { + return errors.InvalidArgumentError("user id exist") + } + + primary := t.PrivateKey + isPrimaryId := len(t.Identities) == 0 + selfSignature := createSignaturePacket(&primary.PublicKey, packet.SigTypePositiveCert, config) + if writeProperties { + err := writeKeyProperties(selfSignature, creationTime, keyLifetimeSecs, config) + if err != nil { + return err + } + } + selfSignature.IsPrimaryId = &isPrimaryId // User ID binding signature err := selfSignature.SignUserId(uid.Id, &primary.PublicKey, primary, config) @@ -158,8 +186,8 @@ func (e *Entity) AddSigningSubkey(config *packet.Config) error { } sub := packet.NewSignerPrivateKey(creationTime, subPrivRaw) sub.IsSubkey = true - if config != nil && config.V5Keys { - sub.UpgradeToV5() + if config.V6() { + sub.UpgradeToV6() } subkey := Subkey{ @@ -203,8 +231,8 @@ func (e *Entity) addEncryptionSubkey(config *packet.Config, creationTime time.Ti } sub := packet.NewDecrypterPrivateKey(creationTime, subPrivRaw) sub.IsSubkey = true - if config != nil && config.V5Keys { - sub.UpgradeToV5() + if config.V6() { + sub.UpgradeToV6() } subkey := Subkey{ @@ -242,6 +270,11 @@ func newSigner(config *packet.Config) (signer interface{}, err error) { } return rsa.GenerateKey(config.Random(), bits) case packet.PubKeyAlgoEdDSA: + if config.V6() { + // Implementations MUST NOT accept or generate v6 key material + // using the deprecated OIDs. + return nil, errors.InvalidArgumentError("EdDSALegacy cannot be used for v6 keys") + } curve := ecc.FindEdDSAByGenName(string(config.CurveName())) if curve == nil { return nil, errors.InvalidArgumentError("unsupported curve") @@ -263,6 +296,18 @@ func newSigner(config *packet.Config) (signer interface{}, err error) { return nil, err } return priv, nil + case packet.PubKeyAlgoEd25519: + priv, err := ed25519.GenerateKey(config.Random()) + if err != nil { + return nil, err + } + return priv, nil + case packet.PubKeyAlgoEd448: + priv, err := ed448.GenerateKey(config.Random()) + if err != nil { + return nil, err + } + return priv, nil default: return nil, errors.InvalidArgumentError("unsupported public key algorithm") } @@ -285,6 +330,13 @@ func newDecrypter(config *packet.Config) (decrypter interface{}, err error) { case packet.PubKeyAlgoEdDSA, packet.PubKeyAlgoECDSA: fallthrough // When passing EdDSA or ECDSA, we generate an ECDH subkey case packet.PubKeyAlgoECDH: + if config.V6() && + (config.CurveName() == packet.Curve25519 || + config.CurveName() == packet.Curve448) { + // Implementations MUST NOT accept or generate v6 key material + // using the deprecated OIDs. + return nil, errors.InvalidArgumentError("ECDH with Curve25519/448 legacy cannot be used for v6 keys") + } var kdf = ecdh.KDF{ Hash: algorithm.SHA512, Cipher: algorithm.AES256, @@ -294,6 +346,10 @@ func newDecrypter(config *packet.Config) (decrypter interface{}, err error) { return nil, errors.InvalidArgumentError("unsupported curve") } return ecdh.GenerateKey(config.Random(), curve, kdf) + case packet.PubKeyAlgoEd25519, packet.PubKeyAlgoX25519: // When passing Ed25519, we generate an x25519 subkey + return x25519.GenerateKey(config.Random()) + case packet.PubKeyAlgoEd448, packet.PubKeyAlgoX448: // When passing Ed448, we generate an x448 subkey + return x448.GenerateKey(config.Random()) default: return nil, errors.InvalidArgumentError("unsupported public key algorithm") } @@ -302,7 +358,7 @@ func newDecrypter(config *packet.Config) (decrypter interface{}, err error) { var bigOne = big.NewInt(1) // generateRSAKeyWithPrimes generates a multi-prime RSA keypair of the -// given bit size, using the given random source and prepopulated primes. +// given bit size, using the given random source and pre-populated primes. func generateRSAKeyWithPrimes(random io.Reader, nprimes int, bits int, prepopulatedPrimes []*big.Int) (*rsa.PrivateKey, error) { priv := new(rsa.PrivateKey) priv.E = 65537 diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go index 120f081a..a071353e 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go @@ -6,6 +6,7 @@ package openpgp import ( goerrors "errors" + "fmt" "io" "time" @@ -24,11 +25,13 @@ var PrivateKeyType = "PGP PRIVATE KEY BLOCK" // (which must be a signing key), one or more identities claimed by that key, // and zero or more subkeys, which may be encryption keys. type Entity struct { - PrimaryKey *packet.PublicKey - PrivateKey *packet.PrivateKey - Identities map[string]*Identity // indexed by Identity.Name - Revocations []*packet.Signature - Subkeys []Subkey + PrimaryKey *packet.PublicKey + PrivateKey *packet.PrivateKey + Identities map[string]*Identity // indexed by Identity.Name + Revocations []*packet.Signature + Subkeys []Subkey + SelfSignature *packet.Signature // Direct-key self signature of the PrimaryKey (contains primary key properties in v6) + Signatures []*packet.Signature // all (potentially unverified) self-signatures, revocations, and third-party signatures } // An Identity represents an identity claimed by an Entity and zero or more @@ -120,12 +123,12 @@ func shouldPreferIdentity(existingId, potentialNewId *Identity) bool { // given Entity. func (e *Entity) EncryptionKey(now time.Time) (Key, bool) { // Fail to find any encryption key if the... - i := e.PrimaryIdentity() - if e.PrimaryKey.KeyExpired(i.SelfSignature, now) || // primary key has expired - i.SelfSignature == nil || // user ID has no self-signature - i.SelfSignature.SigExpired(now) || // user ID self-signature has expired + primarySelfSignature, primaryIdentity := e.PrimarySelfSignature() + if primarySelfSignature == nil || // no self-signature found + e.PrimaryKey.KeyExpired(primarySelfSignature, now) || // primary key has expired e.Revoked(now) || // primary key has been revoked - i.Revoked(now) { // user ID has been revoked + primarySelfSignature.SigExpired(now) || // user ID or or direct self-signature has expired + (primaryIdentity != nil && primaryIdentity.Revoked(now)) { // user ID has been revoked (for v4 keys) return Key{}, false } @@ -150,19 +153,16 @@ func (e *Entity) EncryptionKey(now time.Time) (Key, bool) { return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig, subkey.Revocations}, true } - // If we don't have any candidate subkeys for encryption and - // the primary key doesn't have any usage metadata then we - // assume that the primary key is ok. Or, if the primary key is - // marked as ok to encrypt with, then we can obviously use it. - if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagEncryptCommunications && + // If we don't have any subkeys for encryption and the primary key + // is marked as OK to encrypt with, then we can use it. + if primarySelfSignature.FlagsValid && primarySelfSignature.FlagEncryptCommunications && e.PrimaryKey.PubKeyAlgo.CanEncrypt() { - return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature, e.Revocations}, true + return Key{e, e.PrimaryKey, e.PrivateKey, primarySelfSignature, e.Revocations}, true } return Key{}, false } - // CertificationKey return the best candidate Key for certifying a key with this // Entity. func (e *Entity) CertificationKey(now time.Time) (Key, bool) { @@ -189,12 +189,12 @@ func (e *Entity) SigningKeyById(now time.Time, id uint64) (Key, bool) { func (e *Entity) signingKeyByIdUsage(now time.Time, id uint64, flags int) (Key, bool) { // Fail to find any signing key if the... - i := e.PrimaryIdentity() - if e.PrimaryKey.KeyExpired(i.SelfSignature, now) || // primary key has expired - i.SelfSignature == nil || // user ID has no self-signature - i.SelfSignature.SigExpired(now) || // user ID self-signature has expired + primarySelfSignature, primaryIdentity := e.PrimarySelfSignature() + if primarySelfSignature == nil || // no self-signature found + e.PrimaryKey.KeyExpired(primarySelfSignature, now) || // primary key has expired e.Revoked(now) || // primary key has been revoked - i.Revoked(now) { // user ID has been revoked + primarySelfSignature.SigExpired(now) || // user ID or direct self-signature has expired + (primaryIdentity != nil && primaryIdentity.Revoked(now)) { // user ID has been revoked (for v4 keys) return Key{}, false } @@ -203,8 +203,8 @@ func (e *Entity) signingKeyByIdUsage(now time.Time, id uint64, flags int) (Key, var maxTime time.Time for idx, subkey := range e.Subkeys { if subkey.Sig.FlagsValid && - (flags & packet.KeyFlagCertify == 0 || subkey.Sig.FlagCertify) && - (flags & packet.KeyFlagSign == 0 || subkey.Sig.FlagSign) && + (flags&packet.KeyFlagCertify == 0 || subkey.Sig.FlagCertify) && + (flags&packet.KeyFlagSign == 0 || subkey.Sig.FlagSign) && subkey.PublicKey.PubKeyAlgo.CanSign() && !subkey.PublicKey.KeyExpired(subkey.Sig, now) && !subkey.Sig.SigExpired(now) && @@ -221,15 +221,14 @@ func (e *Entity) signingKeyByIdUsage(now time.Time, id uint64, flags int) (Key, return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig, subkey.Revocations}, true } - // If we have no candidate subkey then we assume that it's ok to sign - // with the primary key. Or, if the primary key is marked as ok to - // sign with, then we can use it. - if !i.SelfSignature.FlagsValid || ( - (flags & packet.KeyFlagCertify == 0 || i.SelfSignature.FlagCertify) && - (flags & packet.KeyFlagSign == 0 || i.SelfSignature.FlagSign)) && + // If we don't have any subkeys for signing and the primary key + // is marked as OK to sign with, then we can use it. + if primarySelfSignature.FlagsValid && + (flags&packet.KeyFlagCertify == 0 || primarySelfSignature.FlagCertify) && + (flags&packet.KeyFlagSign == 0 || primarySelfSignature.FlagSign) && e.PrimaryKey.PubKeyAlgo.CanSign() && (id == 0 || e.PrimaryKey.KeyId == id) { - return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature, e.Revocations}, true + return Key{e, e.PrimaryKey, e.PrivateKey, primarySelfSignature, e.Revocations}, true } // No keys with a valid Signing Flag or no keys matched the id passed in @@ -256,6 +255,44 @@ func (e *Entity) Revoked(now time.Time) bool { return revoked(e.Revocations, now) } +// EncryptPrivateKeys encrypts all non-encrypted keys in the entity with the same key +// derived from the provided passphrase. Public keys and dummy keys are ignored, +// and don't cause an error to be returned. +func (e *Entity) EncryptPrivateKeys(passphrase []byte, config *packet.Config) error { + var keysToEncrypt []*packet.PrivateKey + // Add entity private key to encrypt. + if e.PrivateKey != nil && !e.PrivateKey.Dummy() && !e.PrivateKey.Encrypted { + keysToEncrypt = append(keysToEncrypt, e.PrivateKey) + } + + // Add subkeys to encrypt. + for _, sub := range e.Subkeys { + if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && !sub.PrivateKey.Encrypted { + keysToEncrypt = append(keysToEncrypt, sub.PrivateKey) + } + } + return packet.EncryptPrivateKeys(keysToEncrypt, passphrase, config) +} + +// DecryptPrivateKeys decrypts all encrypted keys in the entity with the given passphrase. +// Avoids recomputation of similar s2k key derivations. Public keys and dummy keys are ignored, +// and don't cause an error to be returned. +func (e *Entity) DecryptPrivateKeys(passphrase []byte) error { + var keysToDecrypt []*packet.PrivateKey + // Add entity private key to decrypt. + if e.PrivateKey != nil && !e.PrivateKey.Dummy() && e.PrivateKey.Encrypted { + keysToDecrypt = append(keysToDecrypt, e.PrivateKey) + } + + // Add subkeys to decrypt. + for _, sub := range e.Subkeys { + if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && sub.PrivateKey.Encrypted { + keysToDecrypt = append(keysToDecrypt, sub.PrivateKey) + } + } + return packet.DecryptPrivateKeys(keysToDecrypt, passphrase) +} + // Revoked returns whether the identity has been revoked by a self-signature. // Note that third-party revocation signatures are not supported. func (i *Identity) Revoked(now time.Time) bool { @@ -284,8 +321,7 @@ type EntityList []*Entity func (el EntityList) KeysById(id uint64) (keys []Key) { for _, e := range el { if e.PrimaryKey.KeyId == id { - ident := e.PrimaryIdentity() - selfSig := ident.SelfSignature + selfSig, _ := e.PrimarySelfSignature() keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig, e.Revocations}) } @@ -303,7 +339,11 @@ func (el EntityList) KeysById(id uint64) (keys []Key) { // the bitwise-OR of packet.KeyFlag* values. func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) { for _, key := range el.KeysById(id) { - if key.SelfSignature != nil && key.SelfSignature.FlagsValid && requiredUsage != 0 { + if requiredUsage != 0 { + if key.SelfSignature == nil || !key.SelfSignature.FlagsValid { + continue + } + var usage byte if key.SelfSignature.FlagCertify { usage |= packet.KeyFlagCertify @@ -331,7 +371,7 @@ func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) { func (el EntityList) DecryptionKeys() (keys []Key) { for _, e := range el { for _, subKey := range e.Subkeys { - if subKey.PrivateKey != nil && (!subKey.Sig.FlagsValid || subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) { + if subKey.PrivateKey != nil && subKey.Sig.FlagsValid && (subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) { keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig, subKey.Revocations}) } } @@ -403,7 +443,6 @@ func readToNextPublicKey(packets *packet.Reader) (err error) { return } else if err != nil { if _, ok := err.(errors.UnsupportedError); ok { - err = nil continue } return @@ -441,6 +480,7 @@ func ReadEntity(packets *packet.Reader) (*Entity, error) { } var revocations []*packet.Signature + var directSignatures []*packet.Signature EachPacket: for { p, err := packets.Next() @@ -459,14 +499,12 @@ EachPacket: if pkt.SigType == packet.SigTypeKeyRevocation { revocations = append(revocations, pkt) } else if pkt.SigType == packet.SigTypeDirectSignature { - // TODO: RFC4880 5.2.1 permits signatures - // directly on keys (eg. to bind additional - // revocation keys). + directSignatures = append(directSignatures, pkt) } // Else, ignoring the signature as it does not follow anything // we would know to attach it to. case *packet.PrivateKey: - if pkt.IsSubkey == false { + if !pkt.IsSubkey { packets.Unread(p) break EachPacket } @@ -475,7 +513,7 @@ EachPacket: return nil, err } case *packet.PublicKey: - if pkt.IsSubkey == false { + if !pkt.IsSubkey { packets.Unread(p) break EachPacket } @@ -484,12 +522,39 @@ EachPacket: return nil, err } default: - // we ignore unknown packets + // we ignore unknown packets. } } - if len(e.Identities) == 0 { - return nil, errors.StructuralError("entity without any identities") + if len(e.Identities) == 0 && e.PrimaryKey.Version < 6 { + return nil, errors.StructuralError(fmt.Sprintf("v%d entity without any identities", e.PrimaryKey.Version)) + } + + // An implementation MUST ensure that a valid direct-key signature is present before using a v6 key. + if e.PrimaryKey.Version == 6 { + if len(directSignatures) == 0 { + return nil, errors.StructuralError("v6 entity without a valid direct-key signature") + } + // Select main direct key signature. + var mainDirectKeySelfSignature *packet.Signature + for _, directSignature := range directSignatures { + if directSignature.SigType == packet.SigTypeDirectSignature && + directSignature.CheckKeyIdOrFingerprint(e.PrimaryKey) && + (mainDirectKeySelfSignature == nil || + directSignature.CreationTime.After(mainDirectKeySelfSignature.CreationTime)) { + mainDirectKeySelfSignature = directSignature + } + } + if mainDirectKeySelfSignature == nil { + return nil, errors.StructuralError("no valid direct-key self-signature for v6 primary key found") + } + // Check that the main self-signature is valid. + err = e.PrimaryKey.VerifyDirectKeySignature(mainDirectKeySelfSignature) + if err != nil { + return nil, errors.StructuralError("invalid direct-key self-signature for v6 primary key") + } + e.SelfSignature = mainDirectKeySelfSignature + e.Signatures = directSignatures } for _, revocation := range revocations { @@ -634,6 +699,12 @@ func (e *Entity) serializePrivate(w io.Writer, config *packet.Config, reSign boo return err } } + for _, directSignature := range e.Signatures { + err := directSignature.Serialize(w) + if err != nil { + return err + } + } for _, ident := range e.Identities { err = ident.UserId.Serialize(w) if err != nil { @@ -700,6 +771,12 @@ func (e *Entity) Serialize(w io.Writer) error { return err } } + for _, directSignature := range e.Signatures { + err := directSignature.Serialize(w) + if err != nil { + return err + } + } for _, ident := range e.Identities { err = ident.UserId.Serialize(w) if err != nil { @@ -802,3 +879,23 @@ func (e *Entity) RevokeSubkey(sk *Subkey, reason packet.ReasonForRevocation, rea sk.Revocations = append(sk.Revocations, revSig) return nil } + +func (e *Entity) primaryDirectSignature() *packet.Signature { + return e.SelfSignature +} + +// PrimarySelfSignature searches the entity for the self-signature that stores key preferences. +// For V4 keys, returns the self-signature of the primary identity, and the identity. +// For V6 keys, returns the latest valid direct-key self-signature, and no identity (nil). +// This self-signature is to be used to check the key expiration, +// algorithm preferences, and so on. +func (e *Entity) PrimarySelfSignature() (*packet.Signature, *Identity) { + if e.PrimaryKey.Version == 6 { + return e.primaryDirectSignature(), nil + } + primaryIdentity := e.PrimaryIdentity() + if primaryIdentity == nil { + return nil, nil + } + return primaryIdentity.SelfSignature, primaryIdentity +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_crypter.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_crypter.go index a82b040b..2d1aeed6 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_crypter.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_crypter.go @@ -18,7 +18,7 @@ type aeadCrypter struct { initialNonce []byte associatedData []byte // Chunk-independent associated data chunkIndex []byte // Chunk counter - packetTag packetType + packetTag packetType // SEIP packet (v2) or AEAD Encrypted Data packet bytesProcessed int // Amount of plaintext bytes encrypted/decrypted buffer bytes.Buffer // Buffered bytes across chunks } @@ -83,22 +83,25 @@ func (ar *aeadDecrypter) Read(dst []byte) (n int, err error) { // Read a chunk tagLen := ar.aead.Overhead() cipherChunkBuf := new(bytes.Buffer) - _, errRead := io.CopyN(cipherChunkBuf, ar.reader, int64(ar.chunkSize + tagLen)) + _, errRead := io.CopyN(cipherChunkBuf, ar.reader, int64(ar.chunkSize+tagLen)) cipherChunk := cipherChunkBuf.Bytes() if errRead != nil && errRead != io.EOF { return 0, errRead } - decrypted, errChunk := ar.openChunk(cipherChunk) - if errChunk != nil { - return 0, errChunk - } - // Return decrypted bytes, buffering if necessary - if len(dst) < len(decrypted) { - n = copy(dst, decrypted[:len(dst)]) - ar.buffer.Write(decrypted[len(dst):]) - } else { - n = copy(dst, decrypted) + if len(cipherChunk) > 0 { + decrypted, errChunk := ar.openChunk(cipherChunk) + if errChunk != nil { + return 0, errChunk + } + + // Return decrypted bytes, buffering if necessary + if len(dst) < len(decrypted) { + n = copy(dst, decrypted[:len(dst)]) + ar.buffer.Write(decrypted[len(dst):]) + } else { + n = copy(dst, decrypted) + } } // Check final authentication tag @@ -116,6 +119,12 @@ func (ar *aeadDecrypter) Read(dst []byte) (n int, err error) { // checked in the last Read call. In the future, this function could be used to // wipe the reader and peeked, decrypted bytes, if necessary. func (ar *aeadDecrypter) Close() (err error) { + if !ar.eof { + errChunk := ar.validateFinalTag(ar.peekedBytes) + if errChunk != nil { + return errChunk + } + } return nil } @@ -177,7 +186,6 @@ type aeadEncrypter struct { writer io.WriteCloser // 'writer' is a partialLengthWriter } - // Write encrypts and writes bytes. It encrypts when necessary and buffers extra // plaintext bytes for next call. When the stream is finished, Close() MUST be // called to append the final tag. diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go index 2f5cad71..334de286 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go @@ -8,9 +8,11 @@ import ( "compress/bzip2" "compress/flate" "compress/zlib" - "github.com/ProtonMail/go-crypto/openpgp/errors" "io" + "io/ioutil" "strconv" + + "github.com/ProtonMail/go-crypto/openpgp/errors" ) // Compressed represents a compressed OpenPGP packet. The decompressed contents @@ -39,6 +41,37 @@ type CompressionConfig struct { Level int } +// decompressionReader ensures that the whole compression packet is read. +type decompressionReader struct { + compressed io.Reader + decompressed io.ReadCloser + readAll bool +} + +func newDecompressionReader(r io.Reader, decompressor io.ReadCloser) *decompressionReader { + return &decompressionReader{ + compressed: r, + decompressed: decompressor, + } +} + +func (dr *decompressionReader) Read(data []byte) (n int, err error) { + if dr.readAll { + return 0, io.EOF + } + n, err = dr.decompressed.Read(data) + if err == io.EOF { + dr.readAll = true + // Close the decompressor. + if errDec := dr.decompressed.Close(); errDec != nil { + return n, errDec + } + // Consume all remaining data from the compressed packet. + consumeAll(dr.compressed) + } + return n, err +} + func (c *Compressed) parse(r io.Reader) error { var buf [1]byte _, err := readFull(r, buf[:]) @@ -50,11 +83,15 @@ func (c *Compressed) parse(r io.Reader) error { case 0: c.Body = r case 1: - c.Body = flate.NewReader(r) + c.Body = newDecompressionReader(r, flate.NewReader(r)) case 2: - c.Body, err = zlib.NewReader(r) + decompressor, err := zlib.NewReader(r) + if err != nil { + return err + } + c.Body = newDecompressionReader(r, decompressor) case 3: - c.Body = bzip2.NewReader(r) + c.Body = newDecompressionReader(r, ioutil.NopCloser(bzip2.NewReader(r))) default: err = errors.UnsupportedError("unknown compression algorithm: " + strconv.Itoa(int(buf[0]))) } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go index 82ae5399..181d5d34 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go @@ -10,6 +10,23 @@ import ( "io" "math/big" "time" + + "github.com/ProtonMail/go-crypto/openpgp/s2k" +) + +var ( + defaultRejectPublicKeyAlgorithms = map[PublicKeyAlgorithm]bool{ + PubKeyAlgoElGamal: true, + PubKeyAlgoDSA: true, + } + defaultRejectMessageHashAlgorithms = map[crypto.Hash]bool{ + crypto.SHA1: true, + crypto.MD5: true, + crypto.RIPEMD160: true, + } + defaultRejectCurves = map[Curve]bool{ + CurveSecP256k1: true, + } ) // Config collects a number of parameters along with sensible defaults. @@ -33,16 +50,24 @@ type Config struct { DefaultCompressionAlgo CompressionAlgo // CompressionConfig configures the compression settings. CompressionConfig *CompressionConfig - // S2KCount is only used for symmetric encryption. It - // determines the strength of the passphrase stretching when + // S2K (String to Key) config, used for key derivation in the context of secret key encryption + // and password-encrypted data. + // If nil, the default configuration is used + S2KConfig *s2k.Config + // Iteration count for Iterated S2K (String to Key). + // Only used if sk2.Mode is nil. + // This value is duplicated here from s2k.Config for backwards compatibility. + // It determines the strength of the passphrase stretching when // the said passphrase is hashed to produce a key. S2KCount - // should be between 1024 and 65011712, inclusive. If Config - // is nil or S2KCount is 0, the value 65536 used. Not all + // should be between 65536 and 65011712, inclusive. If Config + // is nil or S2KCount is 0, the value 16777216 used. Not all // values in the above range can be represented. S2KCount will // be rounded up to the next representable value if it cannot // be encoded exactly. When set, it is strongly encrouraged to // use a value that is at least 65536. See RFC 4880 Section // 3.7.1.3. + // + // Deprecated: SK2Count should be configured in S2KConfig instead. S2KCount int // RSABits is the number of bits in new RSA keys made with NewEntity. // If zero, then 2048 bit keys are created. @@ -63,9 +88,15 @@ type Config struct { // **Note: using this option may break compatibility with other OpenPGP // implementations, as well as future versions of this library.** AEADConfig *AEADConfig - // V5Keys configures version 5 key generation. If false, this package still - // supports version 5 keys, but produces version 4 keys. - V5Keys bool + // V6Keys configures version 6 key generation. If false, this package still + // supports version 6 keys, but produces version 4 keys. + V6Keys bool + // Minimum RSA key size allowed for key generation and message signing, verification and encryption. + MinRSABits uint16 + // Reject insecure algorithms, only works with v2 api + RejectPublicKeyAlgorithms map[PublicKeyAlgorithm]bool + RejectMessageHashAlgorithms map[crypto.Hash]bool + RejectCurves map[Curve]bool // "The validity period of the key. This is the number of seconds after // the key creation time that the key expires. If this is not present // or has a value of zero, the key never expires. This is found only on @@ -100,6 +131,21 @@ type Config struct { KnownNotations map[string]bool // SignatureNotations is a list of Notations to be added to any signatures. SignatureNotations []*Notation + // CheckIntendedRecipients controls, whether the OpenPGP Intended Recipient Fingerprint feature + // should be enabled for encryption and decryption. + // (See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-intended-recipient-fingerpr). + // When the flag is set, encryption produces Intended Recipient Fingerprint signature sub-packets and decryption + // checks whether the key it was encrypted to is one of the included fingerprints in the signature. + // If the flag is disabled, no Intended Recipient Fingerprint sub-packets are created or checked. + // The default behavior, when the config or flag is nil, is to enable the feature. + CheckIntendedRecipients *bool + // CacheSessionKey controls if decryption should return the session key used for decryption. + // If the flag is set, the session key is cached in the message details struct. + CacheSessionKey bool + // CheckPacketSequence is a flag that controls if the pgp message reader should strictly check + // that the packet sequence conforms with the grammar mandated by rfc4880. + // The default behavior, when the config or flag is nil, is to check the packet sequence. + CheckPacketSequence *bool } func (c *Config) Random() io.Reader { @@ -125,9 +171,9 @@ func (c *Config) Cipher() CipherFunction { func (c *Config) Now() time.Time { if c == nil || c.Time == nil { - return time.Now() + return time.Now().Truncate(time.Second) } - return c.Time() + return c.Time().Truncate(time.Second) } // KeyLifetime returns the validity period of the key. @@ -153,13 +199,6 @@ func (c *Config) Compression() CompressionAlgo { return c.DefaultCompressionAlgo } -func (c *Config) PasswordHashIterations() int { - if c == nil || c.S2KCount == 0 { - return 0 - } - return c.S2KCount -} - func (c *Config) RSAModulusBits() int { if c == nil || c.RSABits == 0 { return 2048 @@ -181,6 +220,27 @@ func (c *Config) CurveName() Curve { return c.Curve } +// Deprecated: The hash iterations should now be queried via the S2K() method. +func (c *Config) PasswordHashIterations() int { + if c == nil || c.S2KCount == 0 { + return 0 + } + return c.S2KCount +} + +func (c *Config) S2K() *s2k.Config { + if c == nil { + return nil + } + // for backwards compatibility + if c != nil && c.S2KCount > 0 && c.S2KConfig == nil { + return &s2k.Config{ + S2KCount: c.S2KCount, + } + } + return c.S2KConfig +} + func (c *Config) AEAD() *AEADConfig { if c == nil { return nil @@ -222,3 +282,71 @@ func (c *Config) Notations() []*Notation { } return c.SignatureNotations } + +func (c *Config) V6() bool { + if c == nil { + return false + } + return c.V6Keys +} + +func (c *Config) IntendedRecipients() bool { + if c == nil || c.CheckIntendedRecipients == nil { + return true + } + return *c.CheckIntendedRecipients +} + +func (c *Config) RetrieveSessionKey() bool { + if c == nil { + return false + } + return c.CacheSessionKey +} + +func (c *Config) MinimumRSABits() uint16 { + if c == nil || c.MinRSABits == 0 { + return 2047 + } + return c.MinRSABits +} + +func (c *Config) RejectPublicKeyAlgorithm(alg PublicKeyAlgorithm) bool { + var rejectedAlgorithms map[PublicKeyAlgorithm]bool + if c == nil || c.RejectPublicKeyAlgorithms == nil { + // Default + rejectedAlgorithms = defaultRejectPublicKeyAlgorithms + } else { + rejectedAlgorithms = c.RejectPublicKeyAlgorithms + } + return rejectedAlgorithms[alg] +} + +func (c *Config) RejectMessageHashAlgorithm(hash crypto.Hash) bool { + var rejectedAlgorithms map[crypto.Hash]bool + if c == nil || c.RejectMessageHashAlgorithms == nil { + // Default + rejectedAlgorithms = defaultRejectMessageHashAlgorithms + } else { + rejectedAlgorithms = c.RejectMessageHashAlgorithms + } + return rejectedAlgorithms[hash] +} + +func (c *Config) RejectCurve(curve Curve) bool { + var rejectedCurve map[Curve]bool + if c == nil || c.RejectCurves == nil { + // Default + rejectedCurve = defaultRejectCurves + } else { + rejectedCurve = c.RejectCurves + } + return rejectedCurve[curve] +} + +func (c *Config) StrictPacketSequence() bool { + if c == nil || c.CheckPacketSequence == nil { + return true + } + return *c.CheckPacketSequence +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/encrypted_key.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/encrypted_key.go index eeff2902..e70f9d94 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/encrypted_key.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/encrypted_key.go @@ -5,9 +5,11 @@ package packet import ( + "bytes" "crypto" "crypto/rsa" "encoding/binary" + "encoding/hex" "io" "math/big" "strconv" @@ -16,32 +18,85 @@ import ( "github.com/ProtonMail/go-crypto/openpgp/elgamal" "github.com/ProtonMail/go-crypto/openpgp/errors" "github.com/ProtonMail/go-crypto/openpgp/internal/encoding" + "github.com/ProtonMail/go-crypto/openpgp/x25519" + "github.com/ProtonMail/go-crypto/openpgp/x448" ) -const encryptedKeyVersion = 3 - // EncryptedKey represents a public-key encrypted session key. See RFC 4880, // section 5.1. type EncryptedKey struct { - KeyId uint64 - Algo PublicKeyAlgorithm - CipherFunc CipherFunction // only valid after a successful Decrypt for a v3 packet - Key []byte // only valid after a successful Decrypt + Version int + KeyId uint64 + KeyVersion int // v6 + KeyFingerprint []byte // v6 + Algo PublicKeyAlgorithm + CipherFunc CipherFunction // only valid after a successful Decrypt for a v3 packet + Key []byte // only valid after a successful Decrypt encryptedMPI1, encryptedMPI2 encoding.Field + ephemeralPublicX25519 *x25519.PublicKey // used for x25519 + ephemeralPublicX448 *x448.PublicKey // used for x448 + encryptedSession []byte // used for x25519 and x448 } func (e *EncryptedKey) parse(r io.Reader) (err error) { - var buf [10]byte - _, err = readFull(r, buf[:]) + var buf [8]byte + _, err = readFull(r, buf[:versionSize]) if err != nil { return } - if buf[0] != encryptedKeyVersion { + e.Version = int(buf[0]) + if e.Version != 3 && e.Version != 6 { return errors.UnsupportedError("unknown EncryptedKey version " + strconv.Itoa(int(buf[0]))) } - e.KeyId = binary.BigEndian.Uint64(buf[1:9]) - e.Algo = PublicKeyAlgorithm(buf[9]) + if e.Version == 6 { + //Read a one-octet size of the following two fields. + if _, err = readFull(r, buf[:1]); err != nil { + return + } + // The size may also be zero, and the key version and + // fingerprint omitted for an "anonymous recipient" + if buf[0] != 0 { + // non-anonymous case + _, err = readFull(r, buf[:versionSize]) + if err != nil { + return + } + e.KeyVersion = int(buf[0]) + if e.KeyVersion != 4 && e.KeyVersion != 6 { + return errors.UnsupportedError("unknown public key version " + strconv.Itoa(e.KeyVersion)) + } + var fingerprint []byte + if e.KeyVersion == 6 { + fingerprint = make([]byte, fingerprintSizeV6) + } else if e.KeyVersion == 4 { + fingerprint = make([]byte, fingerprintSize) + } + _, err = readFull(r, fingerprint) + if err != nil { + return + } + e.KeyFingerprint = fingerprint + if e.KeyVersion == 6 { + e.KeyId = binary.BigEndian.Uint64(e.KeyFingerprint[:keyIdSize]) + } else if e.KeyVersion == 4 { + e.KeyId = binary.BigEndian.Uint64(e.KeyFingerprint[fingerprintSize-keyIdSize : fingerprintSize]) + } + } + } else { + _, err = readFull(r, buf[:8]) + if err != nil { + return + } + e.KeyId = binary.BigEndian.Uint64(buf[:keyIdSize]) + } + + _, err = readFull(r, buf[:1]) + if err != nil { + return + } + e.Algo = PublicKeyAlgorithm(buf[0]) + var cipherFunction byte switch e.Algo { case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: e.encryptedMPI1 = new(encoding.MPI) @@ -68,26 +123,39 @@ func (e *EncryptedKey) parse(r io.Reader) (err error) { if _, err = e.encryptedMPI2.ReadFrom(r); err != nil { return } + case PubKeyAlgoX25519: + e.ephemeralPublicX25519, e.encryptedSession, cipherFunction, err = x25519.DecodeFields(r, e.Version == 6) + if err != nil { + return + } + case PubKeyAlgoX448: + e.ephemeralPublicX448, e.encryptedSession, cipherFunction, err = x448.DecodeFields(r, e.Version == 6) + if err != nil { + return + } + } + if e.Version < 6 { + switch e.Algo { + case PubKeyAlgoX25519, PubKeyAlgoX448: + e.CipherFunc = CipherFunction(cipherFunction) + // Check for validiy is in the Decrypt method + } } + _, err = consumeAll(r) return } -func checksumKeyMaterial(key []byte) uint16 { - var checksum uint16 - for _, v := range key { - checksum += uint16(v) - } - return checksum -} - // Decrypt decrypts an encrypted session key with the given private key. The // private key must have been decrypted first. // If config is nil, sensible defaults will be used. func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error { - if e.KeyId != 0 && e.KeyId != priv.KeyId { + if e.Version < 6 && e.KeyId != 0 && e.KeyId != priv.KeyId { return errors.InvalidArgumentError("cannot decrypt encrypted session key for key id " + strconv.FormatUint(e.KeyId, 16) + " with private key id " + strconv.FormatUint(priv.KeyId, 16)) } + if e.Version == 6 && e.KeyVersion != 0 && !bytes.Equal(e.KeyFingerprint, priv.Fingerprint) { + return errors.InvalidArgumentError("cannot decrypt encrypted session key for key fingerprint " + hex.EncodeToString(e.KeyFingerprint) + " with private key fingerprint " + hex.EncodeToString(priv.Fingerprint)) + } if e.Algo != priv.PubKeyAlgo { return errors.InvalidArgumentError("cannot decrypt encrypted session key of type " + strconv.Itoa(int(e.Algo)) + " with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo))) } @@ -114,51 +182,110 @@ func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error { m := e.encryptedMPI2.Bytes() oid := priv.PublicKey.oid.EncodedBytes() b, err = ecdh.Decrypt(priv.PrivateKey.(*ecdh.PrivateKey), vsG, m, oid, priv.PublicKey.Fingerprint[:]) + case PubKeyAlgoX25519: + b, err = x25519.Decrypt(priv.PrivateKey.(*x25519.PrivateKey), e.ephemeralPublicX25519, e.encryptedSession) + case PubKeyAlgoX448: + b, err = x448.Decrypt(priv.PrivateKey.(*x448.PrivateKey), e.ephemeralPublicX448, e.encryptedSession) default: err = errors.InvalidArgumentError("cannot decrypt encrypted session key with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo))) } - if err != nil { return err } - e.CipherFunc = CipherFunction(b[0]) - if !e.CipherFunc.IsSupported() { - return errors.UnsupportedError("unsupported encryption function") - } - - e.Key = b[1 : len(b)-2] - expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1]) - checksum := checksumKeyMaterial(e.Key) - if checksum != expectedChecksum { - return errors.StructuralError("EncryptedKey checksum incorrect") + var key []byte + switch priv.PubKeyAlgo { + case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal, PubKeyAlgoECDH: + keyOffset := 0 + if e.Version < 6 { + e.CipherFunc = CipherFunction(b[0]) + keyOffset = 1 + if !e.CipherFunc.IsSupported() { + return errors.UnsupportedError("unsupported encryption function") + } + } + key, err = decodeChecksumKey(b[keyOffset:]) + if err != nil { + return err + } + case PubKeyAlgoX25519, PubKeyAlgoX448: + if e.Version < 6 { + switch e.CipherFunc { + case CipherAES128, CipherAES192, CipherAES256: + break + default: + return errors.StructuralError("v3 PKESK mandates AES as cipher function for x25519 and x448") + } + } + key = b[:] + default: + return errors.UnsupportedError("unsupported algorithm for decryption") } - + e.Key = key return nil } // Serialize writes the encrypted key packet, e, to w. func (e *EncryptedKey) Serialize(w io.Writer) error { - var mpiLen int + var encodedLength int switch e.Algo { case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: - mpiLen = int(e.encryptedMPI1.EncodedLength()) + encodedLength = int(e.encryptedMPI1.EncodedLength()) case PubKeyAlgoElGamal: - mpiLen = int(e.encryptedMPI1.EncodedLength()) + int(e.encryptedMPI2.EncodedLength()) + encodedLength = int(e.encryptedMPI1.EncodedLength()) + int(e.encryptedMPI2.EncodedLength()) case PubKeyAlgoECDH: - mpiLen = int(e.encryptedMPI1.EncodedLength()) + int(e.encryptedMPI2.EncodedLength()) + encodedLength = int(e.encryptedMPI1.EncodedLength()) + int(e.encryptedMPI2.EncodedLength()) + case PubKeyAlgoX25519: + encodedLength = x25519.EncodedFieldsLength(e.encryptedSession, e.Version == 6) + case PubKeyAlgoX448: + encodedLength = x448.EncodedFieldsLength(e.encryptedSession, e.Version == 6) default: return errors.InvalidArgumentError("don't know how to serialize encrypted key type " + strconv.Itoa(int(e.Algo))) } - err := serializeHeader(w, packetTypeEncryptedKey, 1 /* version */ +8 /* key id */ +1 /* algo */ +mpiLen) + packetLen := versionSize /* version */ + keyIdSize /* key id */ + algorithmSize /* algo */ + encodedLength + if e.Version == 6 { + packetLen = versionSize /* version */ + algorithmSize /* algo */ + encodedLength + keyVersionSize /* key version */ + if e.KeyVersion == 6 { + packetLen += fingerprintSizeV6 + } else if e.KeyVersion == 4 { + packetLen += fingerprintSize + } + } + + err := serializeHeader(w, packetTypeEncryptedKey, packetLen) if err != nil { return err } - w.Write([]byte{encryptedKeyVersion}) - binary.Write(w, binary.BigEndian, e.KeyId) - w.Write([]byte{byte(e.Algo)}) + _, err = w.Write([]byte{byte(e.Version)}) + if err != nil { + return err + } + if e.Version == 6 { + _, err = w.Write([]byte{byte(e.KeyVersion)}) + if err != nil { + return err + } + // The key version number may also be zero, + // and the fingerprint omitted + if e.KeyVersion != 0 { + _, err = w.Write(e.KeyFingerprint) + if err != nil { + return err + } + } + } else { + // Write KeyID + err = binary.Write(w, binary.BigEndian, e.KeyId) + if err != nil { + return err + } + } + _, err = w.Write([]byte{byte(e.Algo)}) + if err != nil { + return err + } switch e.Algo { case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: @@ -176,34 +303,113 @@ func (e *EncryptedKey) Serialize(w io.Writer) error { } _, err := w.Write(e.encryptedMPI2.EncodedBytes()) return err + case PubKeyAlgoX25519: + err := x25519.EncodeFields(w, e.ephemeralPublicX25519, e.encryptedSession, byte(e.CipherFunc), e.Version == 6) + return err + case PubKeyAlgoX448: + err := x448.EncodeFields(w, e.ephemeralPublicX448, e.encryptedSession, byte(e.CipherFunc), e.Version == 6) + return err default: panic("internal error") } } -// SerializeEncryptedKey serializes an encrypted key packet to w that contains +// SerializeEncryptedKeyAEAD serializes an encrypted key packet to w that contains // key, encrypted to pub. +// If aeadSupported is set, PKESK v6 is used else v4. // If config is nil, sensible defaults will be used. -func SerializeEncryptedKey(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, key []byte, config *Config) error { - var buf [10]byte - buf[0] = encryptedKeyVersion - binary.BigEndian.PutUint64(buf[1:9], pub.KeyId) - buf[9] = byte(pub.PubKeyAlgo) - - keyBlock := make([]byte, 1 /* cipher type */ +len(key)+2 /* checksum */) - keyBlock[0] = byte(cipherFunc) - copy(keyBlock[1:], key) - checksum := checksumKeyMaterial(key) - keyBlock[1+len(key)] = byte(checksum >> 8) - keyBlock[1+len(key)+1] = byte(checksum) +func SerializeEncryptedKeyAEAD(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, aeadSupported bool, key []byte, config *Config) error { + return SerializeEncryptedKeyAEADwithHiddenOption(w, pub, cipherFunc, aeadSupported, key, false, config) +} + +// SerializeEncryptedKeyAEADwithHiddenOption serializes an encrypted key packet to w that contains +// key, encrypted to pub. +// Offers the hidden flag option to indicated if the PKESK packet should include a wildcard KeyID. +// If aeadSupported is set, PKESK v6 is used else v4. +// If config is nil, sensible defaults will be used. +func SerializeEncryptedKeyAEADwithHiddenOption(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, aeadSupported bool, key []byte, hidden bool, config *Config) error { + var buf [36]byte // max possible header size is v6 + lenHeaderWritten := versionSize + version := 3 + + if aeadSupported { + version = 6 + } + // An implementation MUST NOT generate ElGamal v6 PKESKs. + if version == 6 && pub.PubKeyAlgo == PubKeyAlgoElGamal { + return errors.InvalidArgumentError("ElGamal v6 PKESK are not allowed") + } + // In v3 PKESKs, for x25519 and x448, mandate using AES + if version == 3 && (pub.PubKeyAlgo == PubKeyAlgoX25519 || pub.PubKeyAlgo == PubKeyAlgoX448) { + switch cipherFunc { + case CipherAES128, CipherAES192, CipherAES256: + break + default: + return errors.InvalidArgumentError("v3 PKESK mandates AES for x25519 and x448") + } + } + + buf[0] = byte(version) + + // If hidden is set, the key should be hidden + // An implementation MAY accept or use a Key ID of all zeros, + // or a key version of zero and no key fingerprint, to hide the intended decryption key. + // See Section 5.1.8. in the open pgp crypto refresh + if version == 6 { + if !hidden { + // A one-octet size of the following two fields. + buf[1] = byte(keyVersionSize + len(pub.Fingerprint)) + // A one octet key version number. + buf[2] = byte(pub.Version) + lenHeaderWritten += keyVersionSize + 1 + // The fingerprint of the public key + copy(buf[lenHeaderWritten:lenHeaderWritten+len(pub.Fingerprint)], pub.Fingerprint) + lenHeaderWritten += len(pub.Fingerprint) + } else { + // The size may also be zero, and the key version + // and fingerprint omitted for an "anonymous recipient" + buf[1] = 0 + lenHeaderWritten += 1 + } + } else { + if !hidden { + binary.BigEndian.PutUint64(buf[versionSize:(versionSize+keyIdSize)], pub.KeyId) + } + lenHeaderWritten += keyIdSize + } + buf[lenHeaderWritten] = byte(pub.PubKeyAlgo) + lenHeaderWritten += algorithmSize + + var keyBlock []byte + switch pub.PubKeyAlgo { + case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal, PubKeyAlgoECDH: + lenKeyBlock := len(key) + 2 + if version < 6 { + lenKeyBlock += 1 // cipher type included + } + keyBlock = make([]byte, lenKeyBlock) + keyOffset := 0 + if version < 6 { + keyBlock[0] = byte(cipherFunc) + keyOffset = 1 + } + encodeChecksumKey(keyBlock[keyOffset:], key) + case PubKeyAlgoX25519, PubKeyAlgoX448: + // algorithm is added in plaintext below + keyBlock = key + } switch pub.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: - return serializeEncryptedKeyRSA(w, config.Random(), buf, pub.PublicKey.(*rsa.PublicKey), keyBlock) + return serializeEncryptedKeyRSA(w, config.Random(), buf[:lenHeaderWritten], pub.PublicKey.(*rsa.PublicKey), keyBlock) case PubKeyAlgoElGamal: - return serializeEncryptedKeyElGamal(w, config.Random(), buf, pub.PublicKey.(*elgamal.PublicKey), keyBlock) + return serializeEncryptedKeyElGamal(w, config.Random(), buf[:lenHeaderWritten], pub.PublicKey.(*elgamal.PublicKey), keyBlock) case PubKeyAlgoECDH: - return serializeEncryptedKeyECDH(w, config.Random(), buf, pub.PublicKey.(*ecdh.PublicKey), keyBlock, pub.oid, pub.Fingerprint) + return serializeEncryptedKeyECDH(w, config.Random(), buf[:lenHeaderWritten], pub.PublicKey.(*ecdh.PublicKey), keyBlock, pub.oid, pub.Fingerprint) + case PubKeyAlgoX25519: + return serializeEncryptedKeyX25519(w, config.Random(), buf[:lenHeaderWritten], pub.PublicKey.(*x25519.PublicKey), keyBlock, byte(cipherFunc), version) + case PubKeyAlgoX448: + return serializeEncryptedKeyX448(w, config.Random(), buf[:lenHeaderWritten], pub.PublicKey.(*x448.PublicKey), keyBlock, byte(cipherFunc), version) case PubKeyAlgoDSA, PubKeyAlgoRSASignOnly: return errors.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo))) } @@ -211,14 +417,30 @@ func SerializeEncryptedKey(w io.Writer, pub *PublicKey, cipherFunc CipherFunctio return errors.UnsupportedError("encrypting a key to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo))) } -func serializeEncryptedKeyRSA(w io.Writer, rand io.Reader, header [10]byte, pub *rsa.PublicKey, keyBlock []byte) error { +// SerializeEncryptedKey serializes an encrypted key packet to w that contains +// key, encrypted to pub. +// PKESKv6 is used if config.AEAD() is not nil. +// If config is nil, sensible defaults will be used. +func SerializeEncryptedKey(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, key []byte, config *Config) error { + return SerializeEncryptedKeyAEAD(w, pub, cipherFunc, config.AEAD() != nil, key, config) +} + +// SerializeEncryptedKeyWithHiddenOption serializes an encrypted key packet to w that contains +// key, encrypted to pub. PKESKv6 is used if config.AEAD() is not nil. +// The hidden option controls if the packet should be anonymous, i.e., omit key metadata. +// If config is nil, sensible defaults will be used. +func SerializeEncryptedKeyWithHiddenOption(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, key []byte, hidden bool, config *Config) error { + return SerializeEncryptedKeyAEADwithHiddenOption(w, pub, cipherFunc, config.AEAD() != nil, key, hidden, config) +} + +func serializeEncryptedKeyRSA(w io.Writer, rand io.Reader, header []byte, pub *rsa.PublicKey, keyBlock []byte) error { cipherText, err := rsa.EncryptPKCS1v15(rand, pub, keyBlock) if err != nil { return errors.InvalidArgumentError("RSA encryption failed: " + err.Error()) } cipherMPI := encoding.NewMPI(cipherText) - packetLen := 10 /* header length */ + int(cipherMPI.EncodedLength()) + packetLen := len(header) /* header length */ + int(cipherMPI.EncodedLength()) err = serializeHeader(w, packetTypeEncryptedKey, packetLen) if err != nil { @@ -232,13 +454,13 @@ func serializeEncryptedKeyRSA(w io.Writer, rand io.Reader, header [10]byte, pub return err } -func serializeEncryptedKeyElGamal(w io.Writer, rand io.Reader, header [10]byte, pub *elgamal.PublicKey, keyBlock []byte) error { +func serializeEncryptedKeyElGamal(w io.Writer, rand io.Reader, header []byte, pub *elgamal.PublicKey, keyBlock []byte) error { c1, c2, err := elgamal.Encrypt(rand, pub, keyBlock) if err != nil { return errors.InvalidArgumentError("ElGamal encryption failed: " + err.Error()) } - packetLen := 10 /* header length */ + packetLen := len(header) /* header length */ packetLen += 2 /* mpi size */ + (c1.BitLen()+7)/8 packetLen += 2 /* mpi size */ + (c2.BitLen()+7)/8 @@ -257,7 +479,7 @@ func serializeEncryptedKeyElGamal(w io.Writer, rand io.Reader, header [10]byte, return err } -func serializeEncryptedKeyECDH(w io.Writer, rand io.Reader, header [10]byte, pub *ecdh.PublicKey, keyBlock []byte, oid encoding.Field, fingerprint []byte) error { +func serializeEncryptedKeyECDH(w io.Writer, rand io.Reader, header []byte, pub *ecdh.PublicKey, keyBlock []byte, oid encoding.Field, fingerprint []byte) error { vsG, c, err := ecdh.Encrypt(rand, pub, keyBlock, oid.EncodedBytes(), fingerprint) if err != nil { return errors.InvalidArgumentError("ECDH encryption failed: " + err.Error()) @@ -266,7 +488,7 @@ func serializeEncryptedKeyECDH(w io.Writer, rand io.Reader, header [10]byte, pub g := encoding.NewMPI(vsG) m := encoding.NewOID(c) - packetLen := 10 /* header length */ + packetLen := len(header) /* header length */ packetLen += int(g.EncodedLength()) + int(m.EncodedLength()) err = serializeHeader(w, packetTypeEncryptedKey, packetLen) @@ -284,3 +506,70 @@ func serializeEncryptedKeyECDH(w io.Writer, rand io.Reader, header [10]byte, pub _, err = w.Write(m.EncodedBytes()) return err } + +func serializeEncryptedKeyX25519(w io.Writer, rand io.Reader, header []byte, pub *x25519.PublicKey, keyBlock []byte, cipherFunc byte, version int) error { + ephemeralPublicX25519, ciphertext, err := x25519.Encrypt(rand, pub, keyBlock) + if err != nil { + return errors.InvalidArgumentError("x25519 encryption failed: " + err.Error()) + } + + packetLen := len(header) /* header length */ + packetLen += x25519.EncodedFieldsLength(ciphertext, version == 6) + + err = serializeHeader(w, packetTypeEncryptedKey, packetLen) + if err != nil { + return err + } + + _, err = w.Write(header[:]) + if err != nil { + return err + } + return x25519.EncodeFields(w, ephemeralPublicX25519, ciphertext, cipherFunc, version == 6) +} + +func serializeEncryptedKeyX448(w io.Writer, rand io.Reader, header []byte, pub *x448.PublicKey, keyBlock []byte, cipherFunc byte, version int) error { + ephemeralPublicX448, ciphertext, err := x448.Encrypt(rand, pub, keyBlock) + if err != nil { + return errors.InvalidArgumentError("x448 encryption failed: " + err.Error()) + } + + packetLen := len(header) /* header length */ + packetLen += x448.EncodedFieldsLength(ciphertext, version == 6) + + err = serializeHeader(w, packetTypeEncryptedKey, packetLen) + if err != nil { + return err + } + + _, err = w.Write(header[:]) + if err != nil { + return err + } + return x448.EncodeFields(w, ephemeralPublicX448, ciphertext, cipherFunc, version == 6) +} + +func checksumKeyMaterial(key []byte) uint16 { + var checksum uint16 + for _, v := range key { + checksum += uint16(v) + } + return checksum +} + +func decodeChecksumKey(msg []byte) (key []byte, err error) { + key = msg[:len(msg)-2] + expectedChecksum := uint16(msg[len(msg)-2])<<8 | uint16(msg[len(msg)-1]) + checksum := checksumKeyMaterial(key) + if checksum != expectedChecksum { + err = errors.StructuralError("session key checksum is incorrect") + } + return +} + +func encodeChecksumKey(buffer []byte, key []byte) { + copy(buffer, key) + checksum := checksumKeyMaterial(key) + buffer[len(key)] = byte(checksum >> 8) + buffer[len(key)+1] = byte(checksum) +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/literal.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/literal.go index 4be98760..8a028c8a 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/literal.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/literal.go @@ -58,9 +58,9 @@ func (l *LiteralData) parse(r io.Reader) (err error) { // on completion. The fileName is truncated to 255 bytes. func SerializeLiteral(w io.WriteCloser, isBinary bool, fileName string, time uint32) (plaintext io.WriteCloser, err error) { var buf [4]byte - buf[0] = 't' - if isBinary { - buf[0] = 'b' + buf[0] = 'b' + if !isBinary { + buf[0] = 'u' } if len(fileName) > 255 { fileName = fileName[:255] diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/marker.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/marker.go new file mode 100644 index 00000000..1ee378ba --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/marker.go @@ -0,0 +1,33 @@ +package packet + +import ( + "io" + + "github.com/ProtonMail/go-crypto/openpgp/errors" +) + +type Marker struct{} + +const markerString = "PGP" + +// parse just checks if the packet contains "PGP". +func (m *Marker) parse(reader io.Reader) error { + var buffer [3]byte + if _, err := io.ReadFull(reader, buffer[:]); err != nil { + return err + } + if string(buffer[:]) != markerString { + return errors.StructuralError("invalid marker packet") + } + return nil +} + +// SerializeMarker writes a marker packet to writer. +func SerializeMarker(writer io.Writer) error { + err := serializeHeader(writer, packetTypeMarker, len(markerString)) + if err != nil { + return err + } + _, err = writer.Write([]byte(markerString)) + return err +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/one_pass_signature.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/one_pass_signature.go index fff119e6..f393c406 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/one_pass_signature.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/one_pass_signature.go @@ -7,34 +7,37 @@ package packet import ( "crypto" "encoding/binary" - "github.com/ProtonMail/go-crypto/openpgp/errors" - "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm" "io" "strconv" + + "github.com/ProtonMail/go-crypto/openpgp/errors" + "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm" ) // OnePassSignature represents a one-pass signature packet. See RFC 4880, // section 5.4. type OnePassSignature struct { - SigType SignatureType - Hash crypto.Hash - PubKeyAlgo PublicKeyAlgorithm - KeyId uint64 - IsLast bool + Version int + SigType SignatureType + Hash crypto.Hash + PubKeyAlgo PublicKeyAlgorithm + KeyId uint64 + IsLast bool + Salt []byte // v6 only + KeyFingerprint []byte // v6 only } -const onePassSignatureVersion = 3 - func (ops *OnePassSignature) parse(r io.Reader) (err error) { - var buf [13]byte - - _, err = readFull(r, buf[:]) + var buf [8]byte + // Read: version | signature type | hash algorithm | public-key algorithm + _, err = readFull(r, buf[:4]) if err != nil { return } - if buf[0] != onePassSignatureVersion { - err = errors.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0]))) + if buf[0] != 3 && buf[0] != 6 { + return errors.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0]))) } + ops.Version = int(buf[0]) var ok bool ops.Hash, ok = algorithm.HashIdToHashWithSha1(buf[2]) @@ -44,30 +47,111 @@ func (ops *OnePassSignature) parse(r io.Reader) (err error) { ops.SigType = SignatureType(buf[1]) ops.PubKeyAlgo = PublicKeyAlgorithm(buf[3]) - ops.KeyId = binary.BigEndian.Uint64(buf[4:12]) - ops.IsLast = buf[12] != 0 + + if ops.Version == 6 { + // Only for v6, a variable-length field containing the salt + _, err = readFull(r, buf[:1]) + if err != nil { + return + } + saltLength := int(buf[0]) + var expectedSaltLength int + expectedSaltLength, err = SaltLengthForHash(ops.Hash) + if err != nil { + return + } + if saltLength != expectedSaltLength { + err = errors.StructuralError("unexpected salt size for the given hash algorithm") + return + } + salt := make([]byte, expectedSaltLength) + _, err = readFull(r, salt) + if err != nil { + return + } + ops.Salt = salt + + // Only for v6 packets, 32 octets of the fingerprint of the signing key. + fingerprint := make([]byte, 32) + _, err = readFull(r, fingerprint) + if err != nil { + return + } + ops.KeyFingerprint = fingerprint + ops.KeyId = binary.BigEndian.Uint64(ops.KeyFingerprint[:8]) + } else { + _, err = readFull(r, buf[:8]) + if err != nil { + return + } + ops.KeyId = binary.BigEndian.Uint64(buf[:8]) + } + + _, err = readFull(r, buf[:1]) + if err != nil { + return + } + ops.IsLast = buf[0] != 0 return } // Serialize marshals the given OnePassSignature to w. func (ops *OnePassSignature) Serialize(w io.Writer) error { - var buf [13]byte - buf[0] = onePassSignatureVersion + //v3 length 1+1+1+1+8+1 = + packetLength := 13 + if ops.Version == 6 { + // v6 length 1+1+1+1+1+len(salt)+32+1 = + packetLength = 38 + len(ops.Salt) + } + + if err := serializeHeader(w, packetTypeOnePassSignature, packetLength); err != nil { + return err + } + + var buf [8]byte + buf[0] = byte(ops.Version) buf[1] = uint8(ops.SigType) var ok bool - buf[2], ok = algorithm.HashToHashId(ops.Hash) + buf[2], ok = algorithm.HashToHashIdWithSha1(ops.Hash) if !ok { return errors.UnsupportedError("hash type: " + strconv.Itoa(int(ops.Hash))) } buf[3] = uint8(ops.PubKeyAlgo) - binary.BigEndian.PutUint64(buf[4:12], ops.KeyId) - if ops.IsLast { - buf[12] = 1 - } - if err := serializeHeader(w, packetTypeOnePassSignature, len(buf)); err != nil { + _, err := w.Write(buf[:4]) + if err != nil { return err } - _, err := w.Write(buf[:]) + + if ops.Version == 6 { + // write salt for v6 signatures + _, err := w.Write([]byte{uint8(len(ops.Salt))}) + if err != nil { + return err + } + _, err = w.Write(ops.Salt) + if err != nil { + return err + } + + // write fingerprint v6 signatures + _, err = w.Write(ops.KeyFingerprint) + if err != nil { + return err + } + } else { + binary.BigEndian.PutUint64(buf[:8], ops.KeyId) + _, err := w.Write(buf[:8]) + if err != nil { + return err + } + } + + isLast := []byte{byte(0)} + if ops.IsLast { + isLast[0] = 1 + } + + _, err = w.Write(isLast) return err } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/opaque.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/opaque.go index 4f820407..cef7c661 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/opaque.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/opaque.go @@ -7,7 +7,6 @@ package packet import ( "bytes" "io" - "io/ioutil" "github.com/ProtonMail/go-crypto/openpgp/errors" ) @@ -26,7 +25,7 @@ type OpaquePacket struct { } func (op *OpaquePacket) parse(r io.Reader) (err error) { - op.Contents, err = ioutil.ReadAll(r) + op.Contents, err = io.ReadAll(r) return } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet.go index f73f6f40..da12fbce 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet.go @@ -4,7 +4,7 @@ // Package packet implements parsing and serialization of OpenPGP packets, as // specified in RFC 4880. -package packet // import "github.com/ProtonMail/go-crypto/openpgp/packet" +package packet // import "github.com/ProtonMail/go-crypto/v2/openpgp/packet" import ( "bytes" @@ -311,12 +311,15 @@ const ( packetTypePrivateSubkey packetType = 7 packetTypeCompressed packetType = 8 packetTypeSymmetricallyEncrypted packetType = 9 + packetTypeMarker packetType = 10 packetTypeLiteralData packetType = 11 + packetTypeTrust packetType = 12 packetTypeUserId packetType = 13 packetTypePublicSubkey packetType = 14 packetTypeUserAttribute packetType = 17 packetTypeSymmetricallyEncryptedIntegrityProtected packetType = 18 packetTypeAEADEncrypted packetType = 20 + packetPadding packetType = 21 ) // EncryptedDataPacket holds encrypted data. It is currently implemented by @@ -328,7 +331,7 @@ type EncryptedDataPacket interface { // Read reads a single OpenPGP packet from the given io.Reader. If there is an // error parsing a packet, the whole packet is consumed from the input. func Read(r io.Reader) (p Packet, err error) { - tag, _, contents, err := readHeader(r) + tag, len, contents, err := readHeader(r) if err != nil { return } @@ -367,8 +370,93 @@ func Read(r io.Reader) (p Packet, err error) { p = se case packetTypeAEADEncrypted: p = new(AEADEncrypted) + case packetPadding: + p = Padding(len) + case packetTypeMarker: + p = new(Marker) + case packetTypeTrust: + // Not implemented, just consume + err = errors.UnknownPacketTypeError(tag) default: + // Packet Tags from 0 to 39 are critical. + // Packet Tags from 40 to 63 are non-critical. + if tag < 40 { + err = errors.CriticalUnknownPacketTypeError(tag) + } else { + err = errors.UnknownPacketTypeError(tag) + } + } + if p != nil { + err = p.parse(contents) + } + if err != nil { + consumeAll(contents) + } + return +} + +// ReadWithCheck reads a single OpenPGP message packet from the given io.Reader. If there is an +// error parsing a packet, the whole packet is consumed from the input. +// ReadWithCheck additionally checks if the OpenPGP message packet sequence adheres +// to the packet composition rules in rfc4880, if not throws an error. +func ReadWithCheck(r io.Reader, sequence *SequenceVerifier) (p Packet, msgErr error, err error) { + tag, len, contents, err := readHeader(r) + if err != nil { + return + } + switch tag { + case packetTypeEncryptedKey: + msgErr = sequence.Next(ESKSymbol) + p = new(EncryptedKey) + case packetTypeSignature: + msgErr = sequence.Next(SigSymbol) + p = new(Signature) + case packetTypeSymmetricKeyEncrypted: + msgErr = sequence.Next(ESKSymbol) + p = new(SymmetricKeyEncrypted) + case packetTypeOnePassSignature: + msgErr = sequence.Next(OPSSymbol) + p = new(OnePassSignature) + case packetTypeCompressed: + msgErr = sequence.Next(CompSymbol) + p = new(Compressed) + case packetTypeSymmetricallyEncrypted: + msgErr = sequence.Next(EncSymbol) + p = new(SymmetricallyEncrypted) + case packetTypeLiteralData: + msgErr = sequence.Next(LDSymbol) + p = new(LiteralData) + case packetTypeSymmetricallyEncryptedIntegrityProtected: + msgErr = sequence.Next(EncSymbol) + se := new(SymmetricallyEncrypted) + se.IntegrityProtected = true + p = se + case packetTypeAEADEncrypted: + msgErr = sequence.Next(EncSymbol) + p = new(AEADEncrypted) + case packetPadding: + p = Padding(len) + case packetTypeMarker: + p = new(Marker) + case packetTypeTrust: + // Not implemented, just consume err = errors.UnknownPacketTypeError(tag) + case packetTypePrivateKey, + packetTypePrivateSubkey, + packetTypePublicKey, + packetTypePublicSubkey, + packetTypeUserId, + packetTypeUserAttribute: + msgErr = sequence.Next(UnknownSymbol) + consumeAll(contents) + default: + // Packet Tags from 0 to 39 are critical. + // Packet Tags from 40 to 63 are non-critical. + if tag < 40 { + err = errors.CriticalUnknownPacketTypeError(tag) + } else { + err = errors.UnknownPacketTypeError(tag) + } } if p != nil { err = p.parse(contents) @@ -384,18 +472,18 @@ func Read(r io.Reader) (p Packet, err error) { type SignatureType uint8 const ( - SigTypeBinary SignatureType = 0x00 - SigTypeText = 0x01 - SigTypeGenericCert = 0x10 - SigTypePersonaCert = 0x11 - SigTypeCasualCert = 0x12 - SigTypePositiveCert = 0x13 - SigTypeSubkeyBinding = 0x18 - SigTypePrimaryKeyBinding = 0x19 - SigTypeDirectSignature = 0x1F - SigTypeKeyRevocation = 0x20 - SigTypeSubkeyRevocation = 0x28 - SigTypeCertificationRevocation = 0x30 + SigTypeBinary SignatureType = 0x00 + SigTypeText SignatureType = 0x01 + SigTypeGenericCert SignatureType = 0x10 + SigTypePersonaCert SignatureType = 0x11 + SigTypeCasualCert SignatureType = 0x12 + SigTypePositiveCert SignatureType = 0x13 + SigTypeSubkeyBinding SignatureType = 0x18 + SigTypePrimaryKeyBinding SignatureType = 0x19 + SigTypeDirectSignature SignatureType = 0x1F + SigTypeKeyRevocation SignatureType = 0x20 + SigTypeSubkeyRevocation SignatureType = 0x28 + SigTypeCertificationRevocation SignatureType = 0x30 ) // PublicKeyAlgorithm represents the different public key system specified for @@ -412,6 +500,11 @@ const ( PubKeyAlgoECDSA PublicKeyAlgorithm = 19 // https://www.ietf.org/archive/id/draft-koch-eddsa-for-openpgp-04.txt PubKeyAlgoEdDSA PublicKeyAlgorithm = 22 + // https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh + PubKeyAlgoX25519 PublicKeyAlgorithm = 25 + PubKeyAlgoX448 PublicKeyAlgorithm = 26 + PubKeyAlgoEd25519 PublicKeyAlgorithm = 27 + PubKeyAlgoEd448 PublicKeyAlgorithm = 28 // Deprecated in RFC 4880, Section 13.5. Use key flags instead. PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2 @@ -422,7 +515,7 @@ const ( // key of the given type. func (pka PublicKeyAlgorithm) CanEncrypt() bool { switch pka { - case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal, PubKeyAlgoECDH: + case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal, PubKeyAlgoECDH, PubKeyAlgoX25519, PubKeyAlgoX448: return true } return false @@ -432,7 +525,7 @@ func (pka PublicKeyAlgorithm) CanEncrypt() bool { // sign a message. func (pka PublicKeyAlgorithm) CanSign() bool { switch pka { - case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA: + case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA, PubKeyAlgoEd25519, PubKeyAlgoEd448: return true } return false @@ -512,6 +605,11 @@ func (mode AEADMode) TagLength() int { return algorithm.AEADMode(mode).TagLength() } +// IsSupported returns true if the aead mode is supported from the library +func (mode AEADMode) IsSupported() bool { + return algorithm.AEADMode(mode).TagLength() > 0 +} + // new returns a fresh instance of the given mode. func (mode AEADMode) new(block cipher.Block) cipher.AEAD { return algorithm.AEADMode(mode).New(block) @@ -526,26 +624,52 @@ const ( KeySuperseded ReasonForRevocation = 1 KeyCompromised ReasonForRevocation = 2 KeyRetired ReasonForRevocation = 3 + UserIDNotValid ReasonForRevocation = 32 + Unknown ReasonForRevocation = 200 ) +func NewReasonForRevocation(value byte) ReasonForRevocation { + if value < 4 || value == 32 { + return ReasonForRevocation(value) + } + return Unknown +} + // Curve is a mapping to supported ECC curves for key generation. // See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-06.html#name-curve-specific-wire-formats type Curve string const ( - Curve25519 Curve = "Curve25519" - Curve448 Curve = "Curve448" - CurveNistP256 Curve = "P256" - CurveNistP384 Curve = "P384" - CurveNistP521 Curve = "P521" - CurveSecP256k1 Curve = "SecP256k1" + Curve25519 Curve = "Curve25519" + Curve448 Curve = "Curve448" + CurveNistP256 Curve = "P256" + CurveNistP384 Curve = "P384" + CurveNistP521 Curve = "P521" + CurveSecP256k1 Curve = "SecP256k1" CurveBrainpoolP256 Curve = "BrainpoolP256" CurveBrainpoolP384 Curve = "BrainpoolP384" CurveBrainpoolP512 Curve = "BrainpoolP512" ) // TrustLevel represents a trust level per RFC4880 5.2.3.13 -type TrustLevel uint8 +type TrustLevel uint8 // TrustAmount represents a trust amount per RFC4880 5.2.3.13 type TrustAmount uint8 + +const ( + // versionSize is the length in bytes of the version value. + versionSize = 1 + // algorithmSize is the length in bytes of the key algorithm value. + algorithmSize = 1 + // keyVersionSize is the length in bytes of the key version value + keyVersionSize = 1 + // keyIdSize is the length in bytes of the key identifier value. + keyIdSize = 8 + // timestampSize is the length in bytes of encoded timestamps. + timestampSize = 4 + // fingerprintSizeV6 is the length in bytes of the key fingerprint in v6. + fingerprintSizeV6 = 32 + // fingerprintSize is the length in bytes of the key fingerprint. + fingerprintSize = 20 +) diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet_sequence.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet_sequence.go new file mode 100644 index 00000000..55a8a56c --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet_sequence.go @@ -0,0 +1,222 @@ +package packet + +// This file implements the pushdown automata (PDA) from PGPainless (Paul Schaub) +// to verify pgp packet sequences. See Paul's blogpost for more details: +// https://blog.jabberhead.tk/2022/10/26/implementing-packet-sequence-validation-using-pushdown-automata/ +import ( + "fmt" + + "github.com/ProtonMail/go-crypto/openpgp/errors" +) + +func NewErrMalformedMessage(from State, input InputSymbol, stackSymbol StackSymbol) errors.ErrMalformedMessage { + return errors.ErrMalformedMessage(fmt.Sprintf("state %d, input symbol %d, stack symbol %d ", from, input, stackSymbol)) +} + +// InputSymbol defines the input alphabet of the PDA +type InputSymbol uint8 + +const ( + LDSymbol InputSymbol = iota + SigSymbol + OPSSymbol + CompSymbol + ESKSymbol + EncSymbol + EOSSymbol + UnknownSymbol +) + +// StackSymbol defines the stack alphabet of the PDA +type StackSymbol int8 + +const ( + MsgStackSymbol StackSymbol = iota + OpsStackSymbol + KeyStackSymbol + EndStackSymbol + EmptyStackSymbol +) + +// State defines the states of the PDA +type State int8 + +const ( + OpenPGPMessage State = iota + ESKMessage + LiteralMessage + CompressedMessage + EncryptedMessage + ValidMessage +) + +// transition represents a state transition in the PDA +type transition func(input InputSymbol, stackSymbol StackSymbol) (State, []StackSymbol, bool, error) + +// SequenceVerifier is a pushdown automata to verify +// PGP messages packet sequences according to rfc4880. +type SequenceVerifier struct { + stack []StackSymbol + state State +} + +// Next performs a state transition with the given input symbol. +// If the transition fails a ErrMalformedMessage is returned. +func (sv *SequenceVerifier) Next(input InputSymbol) error { + for { + stackSymbol := sv.popStack() + transitionFunc := getTransition(sv.state) + nextState, newStackSymbols, redo, err := transitionFunc(input, stackSymbol) + if err != nil { + return err + } + if redo { + sv.pushStack(stackSymbol) + } + for _, newStackSymbol := range newStackSymbols { + sv.pushStack(newStackSymbol) + } + sv.state = nextState + if !redo { + break + } + } + return nil +} + +// Valid returns true if RDA is in a valid state. +func (sv *SequenceVerifier) Valid() bool { + return sv.state == ValidMessage && len(sv.stack) == 0 +} + +func (sv *SequenceVerifier) AssertValid() error { + if !sv.Valid() { + return errors.ErrMalformedMessage("invalid message") + } + return nil +} + +func NewSequenceVerifier() *SequenceVerifier { + return &SequenceVerifier{ + stack: []StackSymbol{EndStackSymbol, MsgStackSymbol}, + state: OpenPGPMessage, + } +} + +func (sv *SequenceVerifier) popStack() StackSymbol { + if len(sv.stack) == 0 { + return EmptyStackSymbol + } + elemIndex := len(sv.stack) - 1 + stackSymbol := sv.stack[elemIndex] + sv.stack = sv.stack[:elemIndex] + return stackSymbol +} + +func (sv *SequenceVerifier) pushStack(stackSymbol StackSymbol) { + sv.stack = append(sv.stack, stackSymbol) +} + +func getTransition(from State) transition { + switch from { + case OpenPGPMessage: + return fromOpenPGPMessage + case LiteralMessage: + return fromLiteralMessage + case CompressedMessage: + return fromCompressedMessage + case EncryptedMessage: + return fromEncryptedMessage + case ESKMessage: + return fromESKMessage + case ValidMessage: + return fromValidMessage + } + return nil +} + +// fromOpenPGPMessage is the transition for the state OpenPGPMessage. +func fromOpenPGPMessage(input InputSymbol, stackSymbol StackSymbol) (State, []StackSymbol, bool, error) { + if stackSymbol != MsgStackSymbol { + return 0, nil, false, NewErrMalformedMessage(OpenPGPMessage, input, stackSymbol) + } + switch input { + case LDSymbol: + return LiteralMessage, nil, false, nil + case SigSymbol: + return OpenPGPMessage, []StackSymbol{MsgStackSymbol}, false, nil + case OPSSymbol: + return OpenPGPMessage, []StackSymbol{OpsStackSymbol, MsgStackSymbol}, false, nil + case CompSymbol: + return CompressedMessage, nil, false, nil + case ESKSymbol: + return ESKMessage, []StackSymbol{KeyStackSymbol}, false, nil + case EncSymbol: + return EncryptedMessage, nil, false, nil + } + return 0, nil, false, NewErrMalformedMessage(OpenPGPMessage, input, stackSymbol) +} + +// fromESKMessage is the transition for the state ESKMessage. +func fromESKMessage(input InputSymbol, stackSymbol StackSymbol) (State, []StackSymbol, bool, error) { + if stackSymbol != KeyStackSymbol { + return 0, nil, false, NewErrMalformedMessage(ESKMessage, input, stackSymbol) + } + switch input { + case ESKSymbol: + return ESKMessage, []StackSymbol{KeyStackSymbol}, false, nil + case EncSymbol: + return EncryptedMessage, nil, false, nil + } + return 0, nil, false, NewErrMalformedMessage(ESKMessage, input, stackSymbol) +} + +// fromLiteralMessage is the transition for the state LiteralMessage. +func fromLiteralMessage(input InputSymbol, stackSymbol StackSymbol) (State, []StackSymbol, bool, error) { + switch input { + case SigSymbol: + if stackSymbol == OpsStackSymbol { + return LiteralMessage, nil, false, nil + } + case EOSSymbol: + if stackSymbol == EndStackSymbol { + return ValidMessage, nil, false, nil + } + } + return 0, nil, false, NewErrMalformedMessage(LiteralMessage, input, stackSymbol) +} + +// fromLiteralMessage is the transition for the state CompressedMessage. +func fromCompressedMessage(input InputSymbol, stackSymbol StackSymbol) (State, []StackSymbol, bool, error) { + switch input { + case SigSymbol: + if stackSymbol == OpsStackSymbol { + return CompressedMessage, nil, false, nil + } + case EOSSymbol: + if stackSymbol == EndStackSymbol { + return ValidMessage, nil, false, nil + } + } + return OpenPGPMessage, []StackSymbol{MsgStackSymbol}, true, nil +} + +// fromEncryptedMessage is the transition for the state EncryptedMessage. +func fromEncryptedMessage(input InputSymbol, stackSymbol StackSymbol) (State, []StackSymbol, bool, error) { + switch input { + case SigSymbol: + if stackSymbol == OpsStackSymbol { + return EncryptedMessage, nil, false, nil + } + case EOSSymbol: + if stackSymbol == EndStackSymbol { + return ValidMessage, nil, false, nil + } + } + return OpenPGPMessage, []StackSymbol{MsgStackSymbol}, true, nil +} + +// fromValidMessage is the transition for the state ValidMessage. +func fromValidMessage(input InputSymbol, stackSymbol StackSymbol) (State, []StackSymbol, bool, error) { + return 0, nil, false, NewErrMalformedMessage(ValidMessage, input, stackSymbol) +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet_unsupported.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet_unsupported.go new file mode 100644 index 00000000..2d714723 --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet_unsupported.go @@ -0,0 +1,24 @@ +package packet + +import ( + "io" + + "github.com/ProtonMail/go-crypto/openpgp/errors" +) + +// UnsupportedPackage represents a OpenPGP packet with a known packet type +// but with unsupported content. +type UnsupportedPacket struct { + IncompletePacket Packet + Error errors.UnsupportedError +} + +// Implements the Packet interface +func (up *UnsupportedPacket) parse(read io.Reader) error { + err := up.IncompletePacket.parse(read) + if castedErr, ok := err.(errors.UnsupportedError); ok { + up.Error = castedErr + return nil + } + return err +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/padding.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/padding.go new file mode 100644 index 00000000..06fa8374 --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/padding.go @@ -0,0 +1,27 @@ +package packet + +import ( + "io" + "io/ioutil" +) + +// Padding type represents a Padding Packet (Tag 21). +// The padding type is represented by the length of its padding. +// see https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#name-padding-packet-tag-21 +type Padding int + +// parse just ignores the padding content. +func (pad Padding) parse(reader io.Reader) error { + _, err := io.CopyN(ioutil.Discard, reader, int64(pad)) + return err +} + +// SerializePadding writes the padding to writer. +func (pad Padding) SerializePadding(writer io.Writer, rand io.Reader) error { + err := serializeHeader(writer, packetPadding, int(pad)) + if err != nil { + return err + } + _, err = io.CopyN(writer, rand, int64(pad)) + return err +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go index 2898fa74..099b4d9b 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go @@ -9,22 +9,28 @@ import ( "crypto" "crypto/cipher" "crypto/dsa" - "crypto/rand" "crypto/rsa" "crypto/sha1" + "crypto/sha256" + "crypto/subtle" + "fmt" "io" - "io/ioutil" "math/big" "strconv" "time" "github.com/ProtonMail/go-crypto/openpgp/ecdh" "github.com/ProtonMail/go-crypto/openpgp/ecdsa" + "github.com/ProtonMail/go-crypto/openpgp/ed25519" + "github.com/ProtonMail/go-crypto/openpgp/ed448" "github.com/ProtonMail/go-crypto/openpgp/eddsa" "github.com/ProtonMail/go-crypto/openpgp/elgamal" "github.com/ProtonMail/go-crypto/openpgp/errors" "github.com/ProtonMail/go-crypto/openpgp/internal/encoding" "github.com/ProtonMail/go-crypto/openpgp/s2k" + "github.com/ProtonMail/go-crypto/openpgp/x25519" + "github.com/ProtonMail/go-crypto/openpgp/x448" + "golang.org/x/crypto/hkdf" ) // PrivateKey represents a possibly encrypted private key. See RFC 4880, @@ -35,26 +41,28 @@ type PrivateKey struct { encryptedData []byte cipher CipherFunction s2k func(out, in []byte) - // An *{rsa|dsa|elgamal|ecdh|ecdsa|ed25519}.PrivateKey or + aead AEADMode // only relevant if S2KAEAD is enabled + // An *{rsa|dsa|elgamal|ecdh|ecdsa|ed25519|ed448}.PrivateKey or // crypto.Signer/crypto.Decrypter (Decryptor RSA only). - PrivateKey interface{} - sha1Checksum bool - iv []byte + PrivateKey interface{} + iv []byte // Type of encryption of the S2K packet - // Allowed values are 0 (Not encrypted), 254 (SHA1), or + // Allowed values are 0 (Not encrypted), 253 (AEAD), 254 (SHA1), or // 255 (2-byte checksum) s2kType S2KType // Full parameters of the S2K packet s2kParams *s2k.Params } -//S2KType s2k packet type +// S2KType s2k packet type type S2KType uint8 const ( // S2KNON unencrypt S2KNON S2KType = 0 + // S2KAEAD use authenticated encryption + S2KAEAD S2KType = 253 // S2KSHA1 sha1 sum check S2KSHA1 S2KType = 254 // S2KCHECKSUM sum check @@ -103,6 +111,34 @@ func NewECDHPrivateKey(creationTime time.Time, priv *ecdh.PrivateKey) *PrivateKe return pk } +func NewX25519PrivateKey(creationTime time.Time, priv *x25519.PrivateKey) *PrivateKey { + pk := new(PrivateKey) + pk.PublicKey = *NewX25519PublicKey(creationTime, &priv.PublicKey) + pk.PrivateKey = priv + return pk +} + +func NewX448PrivateKey(creationTime time.Time, priv *x448.PrivateKey) *PrivateKey { + pk := new(PrivateKey) + pk.PublicKey = *NewX448PublicKey(creationTime, &priv.PublicKey) + pk.PrivateKey = priv + return pk +} + +func NewEd25519PrivateKey(creationTime time.Time, priv *ed25519.PrivateKey) *PrivateKey { + pk := new(PrivateKey) + pk.PublicKey = *NewEd25519PublicKey(creationTime, &priv.PublicKey) + pk.PrivateKey = priv + return pk +} + +func NewEd448PrivateKey(creationTime time.Time, priv *ed448.PrivateKey) *PrivateKey { + pk := new(PrivateKey) + pk.PublicKey = *NewEd448PublicKey(creationTime, &priv.PublicKey) + pk.PrivateKey = priv + return pk +} + // NewSignerPrivateKey creates a PrivateKey from a crypto.Signer that // implements RSA, ECDSA or EdDSA. func NewSignerPrivateKey(creationTime time.Time, signer interface{}) *PrivateKey { @@ -122,6 +158,14 @@ func NewSignerPrivateKey(creationTime time.Time, signer interface{}) *PrivateKey pk.PublicKey = *NewEdDSAPublicKey(creationTime, &pubkey.PublicKey) case eddsa.PrivateKey: pk.PublicKey = *NewEdDSAPublicKey(creationTime, &pubkey.PublicKey) + case *ed25519.PrivateKey: + pk.PublicKey = *NewEd25519PublicKey(creationTime, &pubkey.PublicKey) + case ed25519.PrivateKey: + pk.PublicKey = *NewEd25519PublicKey(creationTime, &pubkey.PublicKey) + case *ed448.PrivateKey: + pk.PublicKey = *NewEd448PublicKey(creationTime, &pubkey.PublicKey) + case ed448.PrivateKey: + pk.PublicKey = *NewEd448PublicKey(creationTime, &pubkey.PublicKey) default: panic("openpgp: unknown signer type in NewSignerPrivateKey") } @@ -129,7 +173,7 @@ func NewSignerPrivateKey(creationTime time.Time, signer interface{}) *PrivateKey return pk } -// NewDecrypterPrivateKey creates a PrivateKey from a *{rsa|elgamal|ecdh}.PrivateKey. +// NewDecrypterPrivateKey creates a PrivateKey from a *{rsa|elgamal|ecdh|x25519|x448}.PrivateKey. func NewDecrypterPrivateKey(creationTime time.Time, decrypter interface{}) *PrivateKey { pk := new(PrivateKey) switch priv := decrypter.(type) { @@ -139,6 +183,10 @@ func NewDecrypterPrivateKey(creationTime time.Time, decrypter interface{}) *Priv pk.PublicKey = *NewElGamalPublicKey(creationTime, &priv.PublicKey) case *ecdh.PrivateKey: pk.PublicKey = *NewECDHPublicKey(creationTime, &priv.PublicKey) + case *x25519.PrivateKey: + pk.PublicKey = *NewX25519PublicKey(creationTime, &priv.PublicKey) + case *x448.PrivateKey: + pk.PublicKey = *NewX448PublicKey(creationTime, &priv.PublicKey) default: panic("openpgp: unknown decrypter type in NewDecrypterPrivateKey") } @@ -152,6 +200,7 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) { return } v5 := pk.PublicKey.Version == 5 + v6 := pk.PublicKey.Version == 6 var buf [1]byte _, err = readFull(r, buf[:]) @@ -160,7 +209,7 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) { } pk.s2kType = S2KType(buf[0]) var optCount [1]byte - if v5 { + if v5 || (v6 && pk.s2kType != S2KNON) { if _, err = readFull(r, optCount[:]); err != nil { return } @@ -170,9 +219,9 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) { case S2KNON: pk.s2k = nil pk.Encrypted = false - case S2KSHA1, S2KCHECKSUM: - if v5 && pk.s2kType == S2KCHECKSUM { - return errors.StructuralError("wrong s2k identifier for version 5") + case S2KSHA1, S2KCHECKSUM, S2KAEAD: + if (v5 || v6) && pk.s2kType == S2KCHECKSUM { + return errors.StructuralError(fmt.Sprintf("wrong s2k identifier for version %d", pk.Version)) } _, err = readFull(r, buf[:]) if err != nil { @@ -182,6 +231,29 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) { if pk.cipher != 0 && !pk.cipher.IsSupported() { return errors.UnsupportedError("unsupported cipher function in private key") } + // [Optional] If string-to-key usage octet was 253, + // a one-octet AEAD algorithm. + if pk.s2kType == S2KAEAD { + _, err = readFull(r, buf[:]) + if err != nil { + return + } + pk.aead = AEADMode(buf[0]) + if !pk.aead.IsSupported() { + return errors.UnsupportedError("unsupported aead mode in private key") + } + } + + // [Optional] Only for a version 6 packet, + // and if string-to-key usage octet was 255, 254, or 253, + // an one-octet count of the following field. + if v6 { + _, err = readFull(r, buf[:]) + if err != nil { + return + } + } + pk.s2kParams, err = s2k.ParseIntoParams(r) if err != nil { return @@ -194,23 +266,32 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) { return } pk.Encrypted = true - if pk.s2kType == S2KSHA1 { - pk.sha1Checksum = true - } default: return errors.UnsupportedError("deprecated s2k function in private key") } if pk.Encrypted { - blockSize := pk.cipher.blockSize() - if blockSize == 0 { + var ivSize int + // If the S2K usage octet was 253, the IV is of the size expected by the AEAD mode, + // unless it's a version 5 key, in which case it's the size of the symmetric cipher's block size. + // For all other S2K modes, it's always the block size. + if !v5 && pk.s2kType == S2KAEAD { + ivSize = pk.aead.IvLength() + } else { + ivSize = pk.cipher.blockSize() + } + + if ivSize == 0 { return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher))) } - pk.iv = make([]byte, blockSize) + pk.iv = make([]byte, ivSize) _, err = readFull(r, pk.iv) if err != nil { return } + if v5 && pk.s2kType == S2KAEAD { + pk.iv = pk.iv[:pk.aead.IvLength()] + } } var privateKeyData []byte @@ -230,7 +311,7 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) { return } } else { - privateKeyData, err = ioutil.ReadAll(r) + privateKeyData, err = io.ReadAll(r) if err != nil { return } @@ -239,16 +320,22 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) { if len(privateKeyData) < 2 { return errors.StructuralError("truncated private key data") } - var sum uint16 - for i := 0; i < len(privateKeyData)-2; i++ { - sum += uint16(privateKeyData[i]) - } - if privateKeyData[len(privateKeyData)-2] != uint8(sum>>8) || - privateKeyData[len(privateKeyData)-1] != uint8(sum) { - return errors.StructuralError("private key checksum failure") + if pk.Version != 6 { + // checksum + var sum uint16 + for i := 0; i < len(privateKeyData)-2; i++ { + sum += uint16(privateKeyData[i]) + } + if privateKeyData[len(privateKeyData)-2] != uint8(sum>>8) || + privateKeyData[len(privateKeyData)-1] != uint8(sum) { + return errors.StructuralError("private key checksum failure") + } + privateKeyData = privateKeyData[:len(privateKeyData)-2] + return pk.parsePrivateKey(privateKeyData) + } else { + // No checksum + return pk.parsePrivateKey(privateKeyData) } - privateKeyData = privateKeyData[:len(privateKeyData)-2] - return pk.parsePrivateKey(privateKeyData) } pk.encryptedData = privateKeyData @@ -280,18 +367,59 @@ func (pk *PrivateKey) Serialize(w io.Writer) (err error) { optional := bytes.NewBuffer(nil) if pk.Encrypted || pk.Dummy() { - optional.Write([]byte{uint8(pk.cipher)}) - if err := pk.s2kParams.Serialize(optional); err != nil { + // [Optional] If string-to-key usage octet was 255, 254, or 253, + // a one-octet symmetric encryption algorithm. + if _, err = optional.Write([]byte{uint8(pk.cipher)}); err != nil { + return + } + // [Optional] If string-to-key usage octet was 253, + // a one-octet AEAD algorithm. + if pk.s2kType == S2KAEAD { + if _, err = optional.Write([]byte{uint8(pk.aead)}); err != nil { + return + } + } + + s2kBuffer := bytes.NewBuffer(nil) + if err := pk.s2kParams.Serialize(s2kBuffer); err != nil { return err } + // [Optional] Only for a version 6 packet, and if string-to-key + // usage octet was 255, 254, or 253, an one-octet + // count of the following field. + if pk.Version == 6 { + if _, err = optional.Write([]byte{uint8(s2kBuffer.Len())}); err != nil { + return + } + } + // [Optional] If string-to-key usage octet was 255, 254, or 253, + // a string-to-key (S2K) specifier. The length of the string-to-key specifier + // depends on its type + if _, err = io.Copy(optional, s2kBuffer); err != nil { + return + } + + // IV if pk.Encrypted { - optional.Write(pk.iv) + if _, err = optional.Write(pk.iv); err != nil { + return + } + if pk.Version == 5 && pk.s2kType == S2KAEAD { + // Add padding for version 5 + padding := make([]byte, pk.cipher.blockSize()-len(pk.iv)) + if _, err = optional.Write(padding); err != nil { + return + } + } } } - if pk.Version == 5 { + if pk.Version == 5 || (pk.Version == 6 && pk.s2kType != S2KNON) { contents.Write([]byte{uint8(optional.Len())}) } - io.Copy(contents, optional) + + if _, err := io.Copy(contents, optional); err != nil { + return err + } if !pk.Dummy() { l := 0 @@ -303,8 +431,10 @@ func (pk *PrivateKey) Serialize(w io.Writer) (err error) { return err } l = buf.Len() - checksum := mod64kHash(buf.Bytes()) - buf.Write([]byte{byte(checksum >> 8), byte(checksum)}) + if pk.Version != 6 { + checksum := mod64kHash(buf.Bytes()) + buf.Write([]byte{byte(checksum >> 8), byte(checksum)}) + } priv = buf.Bytes() } else { priv, l = pk.encryptedData, len(pk.encryptedData) @@ -370,47 +500,79 @@ func serializeECDHPrivateKey(w io.Writer, priv *ecdh.PrivateKey) error { return err } -// Decrypt decrypts an encrypted private key using a passphrase. -func (pk *PrivateKey) Decrypt(passphrase []byte) error { +func serializeX25519PrivateKey(w io.Writer, priv *x25519.PrivateKey) error { + _, err := w.Write(priv.Secret) + return err +} + +func serializeX448PrivateKey(w io.Writer, priv *x448.PrivateKey) error { + _, err := w.Write(priv.Secret) + return err +} + +func serializeEd25519PrivateKey(w io.Writer, priv *ed25519.PrivateKey) error { + _, err := w.Write(priv.MarshalByteSecret()) + return err +} + +func serializeEd448PrivateKey(w io.Writer, priv *ed448.PrivateKey) error { + _, err := w.Write(priv.MarshalByteSecret()) + return err +} + +// decrypt decrypts an encrypted private key using a decryption key. +func (pk *PrivateKey) decrypt(decryptionKey []byte) error { if pk.Dummy() { return errors.ErrDummyPrivateKey("dummy key found") } if !pk.Encrypted { return nil } - - key := make([]byte, pk.cipher.KeySize()) - pk.s2k(key, passphrase) - block := pk.cipher.new(key) - cfb := cipher.NewCFBDecrypter(block, pk.iv) - - data := make([]byte, len(pk.encryptedData)) - cfb.XORKeyStream(data, pk.encryptedData) - - if pk.sha1Checksum { - if len(data) < sha1.Size { - return errors.StructuralError("truncated private key data") - } - h := sha1.New() - h.Write(data[:len(data)-sha1.Size]) - sum := h.Sum(nil) - if !bytes.Equal(sum, data[len(data)-sha1.Size:]) { - return errors.StructuralError("private key checksum failure") - } - data = data[:len(data)-sha1.Size] - } else { - if len(data) < 2 { - return errors.StructuralError("truncated private key data") + block := pk.cipher.new(decryptionKey) + var data []byte + switch pk.s2kType { + case S2KAEAD: + aead := pk.aead.new(block) + additionalData, err := pk.additionalData() + if err != nil { + return err } - var sum uint16 - for i := 0; i < len(data)-2; i++ { - sum += uint16(data[i]) + // Decrypt the encrypted key material with aead + data, err = aead.Open(nil, pk.iv, pk.encryptedData, additionalData) + if err != nil { + return err } - if data[len(data)-2] != uint8(sum>>8) || - data[len(data)-1] != uint8(sum) { - return errors.StructuralError("private key checksum failure") + case S2KSHA1, S2KCHECKSUM: + cfb := cipher.NewCFBDecrypter(block, pk.iv) + data = make([]byte, len(pk.encryptedData)) + cfb.XORKeyStream(data, pk.encryptedData) + if pk.s2kType == S2KSHA1 { + if len(data) < sha1.Size { + return errors.StructuralError("truncated private key data") + } + h := sha1.New() + h.Write(data[:len(data)-sha1.Size]) + sum := h.Sum(nil) + if !bytes.Equal(sum, data[len(data)-sha1.Size:]) { + return errors.StructuralError("private key checksum failure") + } + data = data[:len(data)-sha1.Size] + } else { + if len(data) < 2 { + return errors.StructuralError("truncated private key data") + } + var sum uint16 + for i := 0; i < len(data)-2; i++ { + sum += uint16(data[i]) + } + if data[len(data)-2] != uint8(sum>>8) || + data[len(data)-1] != uint8(sum) { + return errors.StructuralError("private key checksum failure") + } + data = data[:len(data)-2] } - data = data[:len(data)-2] + default: + return errors.InvalidArgumentError("invalid s2k type") } err := pk.parsePrivateKey(data) @@ -426,67 +588,206 @@ func (pk *PrivateKey) Decrypt(passphrase []byte) error { pk.s2k = nil pk.Encrypted = false pk.encryptedData = nil - return nil } -// Encrypt encrypts an unencrypted private key using a passphrase. -func (pk *PrivateKey) Encrypt(passphrase []byte) error { - priv := bytes.NewBuffer(nil) - err := pk.serializePrivateKey(priv) +func (pk *PrivateKey) decryptWithCache(passphrase []byte, keyCache *s2k.Cache) error { + if pk.Dummy() { + return errors.ErrDummyPrivateKey("dummy key found") + } + if !pk.Encrypted { + return nil + } + + key, err := keyCache.GetOrComputeDerivedKey(passphrase, pk.s2kParams, pk.cipher.KeySize()) if err != nil { return err } + if pk.s2kType == S2KAEAD { + key = pk.applyHKDF(key) + } + return pk.decrypt(key) +} - //Default config of private key encryption - pk.cipher = CipherAES256 - s2kConfig := &s2k.Config{ - S2KMode: 3, //Iterated - S2KCount: 65536, - Hash: crypto.SHA256, +// Decrypt decrypts an encrypted private key using a passphrase. +func (pk *PrivateKey) Decrypt(passphrase []byte) error { + if pk.Dummy() { + return errors.ErrDummyPrivateKey("dummy key found") + } + if !pk.Encrypted { + return nil } - pk.s2kParams, err = s2k.Generate(rand.Reader, s2kConfig) + key := make([]byte, pk.cipher.KeySize()) + pk.s2k(key, passphrase) + if pk.s2kType == S2KAEAD { + key = pk.applyHKDF(key) + } + return pk.decrypt(key) +} + +// DecryptPrivateKeys decrypts all encrypted keys with the given config and passphrase. +// Avoids recomputation of similar s2k key derivations. +func DecryptPrivateKeys(keys []*PrivateKey, passphrase []byte) error { + // Create a cache to avoid recomputation of key derviations for the same passphrase. + s2kCache := &s2k.Cache{} + for _, key := range keys { + if key != nil && !key.Dummy() && key.Encrypted { + err := key.decryptWithCache(passphrase, s2kCache) + if err != nil { + return err + } + } + } + return nil +} + +// encrypt encrypts an unencrypted private key. +func (pk *PrivateKey) encrypt(key []byte, params *s2k.Params, s2kType S2KType, cipherFunction CipherFunction, rand io.Reader) error { + if pk.Dummy() { + return errors.ErrDummyPrivateKey("dummy key found") + } + if pk.Encrypted { + return nil + } + // check if encryptionKey has the correct size + if len(key) != cipherFunction.KeySize() { + return errors.InvalidArgumentError("supplied encryption key has the wrong size") + } + + priv := bytes.NewBuffer(nil) + err := pk.serializePrivateKey(priv) if err != nil { return err } - privateKeyBytes := priv.Bytes() - key := make([]byte, pk.cipher.KeySize()) - pk.sha1Checksum = true + pk.cipher = cipherFunction + pk.s2kParams = params pk.s2k, err = pk.s2kParams.Function() if err != nil { return err } - pk.s2k(key, passphrase) + + privateKeyBytes := priv.Bytes() + pk.s2kType = s2kType block := pk.cipher.new(key) - pk.iv = make([]byte, pk.cipher.blockSize()) - _, err = rand.Read(pk.iv) + switch s2kType { + case S2KAEAD: + if pk.aead == 0 { + return errors.StructuralError("aead mode is not set on key") + } + aead := pk.aead.new(block) + additionalData, err := pk.additionalData() + if err != nil { + return err + } + pk.iv = make([]byte, aead.NonceSize()) + _, err = io.ReadFull(rand, pk.iv) + if err != nil { + return err + } + // Decrypt the encrypted key material with aead + pk.encryptedData = aead.Seal(nil, pk.iv, privateKeyBytes, additionalData) + case S2KSHA1, S2KCHECKSUM: + pk.iv = make([]byte, pk.cipher.blockSize()) + _, err = io.ReadFull(rand, pk.iv) + if err != nil { + return err + } + cfb := cipher.NewCFBEncrypter(block, pk.iv) + if s2kType == S2KSHA1 { + h := sha1.New() + h.Write(privateKeyBytes) + sum := h.Sum(nil) + privateKeyBytes = append(privateKeyBytes, sum...) + } else { + var sum uint16 + for _, b := range privateKeyBytes { + sum += uint16(b) + } + privateKeyBytes = append(privateKeyBytes, []byte{uint8(sum >> 8), uint8(sum)}...) + } + pk.encryptedData = make([]byte, len(privateKeyBytes)) + cfb.XORKeyStream(pk.encryptedData, privateKeyBytes) + default: + return errors.InvalidArgumentError("invalid s2k type for encryption") + } + + pk.Encrypted = true + pk.PrivateKey = nil + return err +} + +// EncryptWithConfig encrypts an unencrypted private key using the passphrase and the config. +func (pk *PrivateKey) EncryptWithConfig(passphrase []byte, config *Config) error { + params, err := s2k.Generate(config.Random(), config.S2K()) if err != nil { return err } - cfb := cipher.NewCFBEncrypter(block, pk.iv) + // Derive an encryption key with the configured s2k function. + key := make([]byte, config.Cipher().KeySize()) + s2k, err := params.Function() + if err != nil { + return err + } + s2k(key, passphrase) + s2kType := S2KSHA1 + if config.AEAD() != nil { + s2kType = S2KAEAD + pk.aead = config.AEAD().Mode() + pk.cipher = config.Cipher() + key = pk.applyHKDF(key) + } + // Encrypt the private key with the derived encryption key. + return pk.encrypt(key, params, s2kType, config.Cipher(), config.Random()) +} - if pk.sha1Checksum { - pk.s2kType = S2KSHA1 - h := sha1.New() - h.Write(privateKeyBytes) - sum := h.Sum(nil) - privateKeyBytes = append(privateKeyBytes, sum...) - } else { - pk.s2kType = S2KCHECKSUM - var sum uint16 - for _, b := range privateKeyBytes { - sum += uint16(b) +// EncryptPrivateKeys encrypts all unencrypted keys with the given config and passphrase. +// Only derives one key from the passphrase, which is then used to encrypt each key. +func EncryptPrivateKeys(keys []*PrivateKey, passphrase []byte, config *Config) error { + params, err := s2k.Generate(config.Random(), config.S2K()) + if err != nil { + return err + } + // Derive an encryption key with the configured s2k function. + encryptionKey := make([]byte, config.Cipher().KeySize()) + s2k, err := params.Function() + if err != nil { + return err + } + s2k(encryptionKey, passphrase) + for _, key := range keys { + if key != nil && !key.Dummy() && !key.Encrypted { + s2kType := S2KSHA1 + if config.AEAD() != nil { + s2kType = S2KAEAD + key.aead = config.AEAD().Mode() + key.cipher = config.Cipher() + derivedKey := key.applyHKDF(encryptionKey) + err = key.encrypt(derivedKey, params, s2kType, config.Cipher(), config.Random()) + } else { + err = key.encrypt(encryptionKey, params, s2kType, config.Cipher(), config.Random()) + } + if err != nil { + return err + } } - priv.Write([]byte{uint8(sum >> 8), uint8(sum)}) } + return nil +} - pk.encryptedData = make([]byte, len(privateKeyBytes)) - cfb.XORKeyStream(pk.encryptedData, privateKeyBytes) - pk.Encrypted = true - pk.PrivateKey = nil - return err +// Encrypt encrypts an unencrypted private key using a passphrase. +func (pk *PrivateKey) Encrypt(passphrase []byte) error { + // Default config of private key encryption + config := &Config{ + S2KConfig: &s2k.Config{ + S2KMode: s2k.IteratedSaltedS2K, + S2KCount: 65536, + Hash: crypto.SHA256, + }, + DefaultCipher: CipherAES256, + } + return pk.EncryptWithConfig(passphrase, config) } func (pk *PrivateKey) serializePrivateKey(w io.Writer) (err error) { @@ -503,6 +804,14 @@ func (pk *PrivateKey) serializePrivateKey(w io.Writer) (err error) { err = serializeEdDSAPrivateKey(w, priv) case *ecdh.PrivateKey: err = serializeECDHPrivateKey(w, priv) + case *x25519.PrivateKey: + err = serializeX25519PrivateKey(w, priv) + case *x448.PrivateKey: + err = serializeX448PrivateKey(w, priv) + case *ed25519.PrivateKey: + err = serializeEd25519PrivateKey(w, priv) + case *ed448.PrivateKey: + err = serializeEd448PrivateKey(w, priv) default: err = errors.InvalidArgumentError("unknown private key type") } @@ -523,8 +832,18 @@ func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) { return pk.parseECDHPrivateKey(data) case PubKeyAlgoEdDSA: return pk.parseEdDSAPrivateKey(data) + case PubKeyAlgoX25519: + return pk.parseX25519PrivateKey(data) + case PubKeyAlgoX448: + return pk.parseX448PrivateKey(data) + case PubKeyAlgoEd25519: + return pk.parseEd25519PrivateKey(data) + case PubKeyAlgoEd448: + return pk.parseEd448PrivateKey(data) + default: + err = errors.StructuralError("unknown private key type") + return } - panic("impossible") } func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) { @@ -645,6 +964,86 @@ func (pk *PrivateKey) parseECDHPrivateKey(data []byte) (err error) { return nil } +func (pk *PrivateKey) parseX25519PrivateKey(data []byte) (err error) { + publicKey := pk.PublicKey.PublicKey.(*x25519.PublicKey) + privateKey := x25519.NewPrivateKey(*publicKey) + privateKey.PublicKey = *publicKey + + privateKey.Secret = make([]byte, x25519.KeySize) + + if len(data) != x25519.KeySize { + err = errors.StructuralError("wrong x25519 key size") + return err + } + subtle.ConstantTimeCopy(1, privateKey.Secret, data) + if err = x25519.Validate(privateKey); err != nil { + return err + } + pk.PrivateKey = privateKey + return nil +} + +func (pk *PrivateKey) parseX448PrivateKey(data []byte) (err error) { + publicKey := pk.PublicKey.PublicKey.(*x448.PublicKey) + privateKey := x448.NewPrivateKey(*publicKey) + privateKey.PublicKey = *publicKey + + privateKey.Secret = make([]byte, x448.KeySize) + + if len(data) != x448.KeySize { + err = errors.StructuralError("wrong x448 key size") + return err + } + subtle.ConstantTimeCopy(1, privateKey.Secret, data) + if err = x448.Validate(privateKey); err != nil { + return err + } + pk.PrivateKey = privateKey + return nil +} + +func (pk *PrivateKey) parseEd25519PrivateKey(data []byte) (err error) { + publicKey := pk.PublicKey.PublicKey.(*ed25519.PublicKey) + privateKey := ed25519.NewPrivateKey(*publicKey) + privateKey.PublicKey = *publicKey + + if len(data) != ed25519.SeedSize { + err = errors.StructuralError("wrong ed25519 key size") + return err + } + err = privateKey.UnmarshalByteSecret(data) + if err != nil { + return err + } + err = ed25519.Validate(privateKey) + if err != nil { + return err + } + pk.PrivateKey = privateKey + return nil +} + +func (pk *PrivateKey) parseEd448PrivateKey(data []byte) (err error) { + publicKey := pk.PublicKey.PublicKey.(*ed448.PublicKey) + privateKey := ed448.NewPrivateKey(*publicKey) + privateKey.PublicKey = *publicKey + + if len(data) != ed448.SeedSize { + err = errors.StructuralError("wrong ed448 key size") + return err + } + err = privateKey.UnmarshalByteSecret(data) + if err != nil { + return err + } + err = ed448.Validate(privateKey) + if err != nil { + return err + } + pk.PrivateKey = privateKey + return nil +} + func (pk *PrivateKey) parseEdDSAPrivateKey(data []byte) (err error) { eddsaPub := pk.PublicKey.PublicKey.(*eddsa.PublicKey) eddsaPriv := eddsa.NewPrivateKey(*eddsaPub) @@ -669,6 +1068,41 @@ func (pk *PrivateKey) parseEdDSAPrivateKey(data []byte) (err error) { return nil } +func (pk *PrivateKey) additionalData() ([]byte, error) { + additionalData := bytes.NewBuffer(nil) + // Write additional data prefix based on packet type + var packetByte byte + if pk.PublicKey.IsSubkey { + packetByte = 0xc7 + } else { + packetByte = 0xc5 + } + // Write public key to additional data + _, err := additionalData.Write([]byte{packetByte}) + if err != nil { + return nil, err + } + err = pk.PublicKey.serializeWithoutHeaders(additionalData) + if err != nil { + return nil, err + } + return additionalData.Bytes(), nil +} + +func (pk *PrivateKey) applyHKDF(inputKey []byte) []byte { + var packetByte byte + if pk.PublicKey.IsSubkey { + packetByte = 0xc7 + } else { + packetByte = 0xc5 + } + associatedData := []byte{packetByte, byte(pk.Version), byte(pk.cipher), byte(pk.aead)} + hkdfReader := hkdf.New(sha256.New, inputKey, []byte{}, associatedData) + encryptionKey := make([]byte, pk.cipher.KeySize()) + _, _ = readFull(hkdfReader, encryptionKey) + return encryptionKey +} + func validateDSAParameters(priv *dsa.PrivateKey) error { p := priv.P // group prime q := priv.Q // subgroup order diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go index e0f5f74a..dd93c987 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go @@ -5,7 +5,6 @@ package packet import ( - "crypto" "crypto/dsa" "crypto/rsa" "crypto/sha1" @@ -21,23 +20,24 @@ import ( "github.com/ProtonMail/go-crypto/openpgp/ecdh" "github.com/ProtonMail/go-crypto/openpgp/ecdsa" + "github.com/ProtonMail/go-crypto/openpgp/ed25519" + "github.com/ProtonMail/go-crypto/openpgp/ed448" "github.com/ProtonMail/go-crypto/openpgp/eddsa" "github.com/ProtonMail/go-crypto/openpgp/elgamal" "github.com/ProtonMail/go-crypto/openpgp/errors" "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm" "github.com/ProtonMail/go-crypto/openpgp/internal/ecc" "github.com/ProtonMail/go-crypto/openpgp/internal/encoding" + "github.com/ProtonMail/go-crypto/openpgp/x25519" + "github.com/ProtonMail/go-crypto/openpgp/x448" ) -type kdfHashFunction byte -type kdfAlgorithm byte - // PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2. type PublicKey struct { Version int CreationTime time.Time PubKeyAlgo PublicKeyAlgorithm - PublicKey interface{} // *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey or *eddsa.PublicKey + PublicKey interface{} // *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey or *eddsa.PublicKey, *x25519.PublicKey, *x448.PublicKey, *ed25519.PublicKey, *ed448.PublicKey Fingerprint []byte KeyId uint64 IsSubkey bool @@ -61,11 +61,18 @@ func (pk *PublicKey) UpgradeToV5() { pk.setFingerprintAndKeyId() } +// UpgradeToV6 updates the version of the key to v6, and updates all necessary +// fields. +func (pk *PublicKey) UpgradeToV6() { + pk.Version = 6 + pk.setFingerprintAndKeyId() +} + // signingKey provides a convenient abstraction over signature verification // for v3 and v4 public keys. type signingKey interface { SerializeForHash(io.Writer) error - SerializeSignaturePrefix(io.Writer) + SerializeSignaturePrefix(io.Writer) error serializeWithoutHeaders(io.Writer) error } @@ -174,6 +181,54 @@ func NewEdDSAPublicKey(creationTime time.Time, pub *eddsa.PublicKey) *PublicKey return pk } +func NewX25519PublicKey(creationTime time.Time, pub *x25519.PublicKey) *PublicKey { + pk := &PublicKey{ + Version: 4, + CreationTime: creationTime, + PubKeyAlgo: PubKeyAlgoX25519, + PublicKey: pub, + } + + pk.setFingerprintAndKeyId() + return pk +} + +func NewX448PublicKey(creationTime time.Time, pub *x448.PublicKey) *PublicKey { + pk := &PublicKey{ + Version: 4, + CreationTime: creationTime, + PubKeyAlgo: PubKeyAlgoX448, + PublicKey: pub, + } + + pk.setFingerprintAndKeyId() + return pk +} + +func NewEd25519PublicKey(creationTime time.Time, pub *ed25519.PublicKey) *PublicKey { + pk := &PublicKey{ + Version: 4, + CreationTime: creationTime, + PubKeyAlgo: PubKeyAlgoEd25519, + PublicKey: pub, + } + + pk.setFingerprintAndKeyId() + return pk +} + +func NewEd448PublicKey(creationTime time.Time, pub *ed448.PublicKey) *PublicKey { + pk := &PublicKey{ + Version: 4, + CreationTime: creationTime, + PubKeyAlgo: PubKeyAlgoEd448, + PublicKey: pub, + } + + pk.setFingerprintAndKeyId() + return pk +} + func (pk *PublicKey) parse(r io.Reader) (err error) { // RFC 4880, section 5.5.2 var buf [6]byte @@ -181,12 +236,14 @@ func (pk *PublicKey) parse(r io.Reader) (err error) { if err != nil { return } - if buf[0] != 4 && buf[0] != 5 { + if buf[0] != 4 && buf[0] != 5 && buf[0] != 6 { return errors.UnsupportedError("public key version " + strconv.Itoa(int(buf[0]))) } pk.Version = int(buf[0]) - if pk.Version == 5 { + if pk.Version >= 5 { + // Read the four-octet scalar octet count + // The count is not used in this implementation var n [4]byte _, err = readFull(r, n[:]) if err != nil { @@ -195,6 +252,7 @@ func (pk *PublicKey) parse(r io.Reader) (err error) { } pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0) pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5]) + // Ignore four-ocet length switch pk.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: err = pk.parseRSA(r) @@ -208,6 +266,14 @@ func (pk *PublicKey) parse(r io.Reader) (err error) { err = pk.parseECDH(r) case PubKeyAlgoEdDSA: err = pk.parseEdDSA(r) + case PubKeyAlgoX25519: + err = pk.parseX25519(r) + case PubKeyAlgoX448: + err = pk.parseX448(r) + case PubKeyAlgoEd25519: + err = pk.parseEd25519(r) + case PubKeyAlgoEd448: + err = pk.parseEd448(r) default: err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo))) } @@ -221,15 +287,21 @@ func (pk *PublicKey) parse(r io.Reader) (err error) { func (pk *PublicKey) setFingerprintAndKeyId() { // RFC 4880, section 12.2 - if pk.Version == 5 { + if pk.Version >= 5 { fingerprint := sha256.New() - pk.SerializeForHash(fingerprint) + if err := pk.SerializeForHash(fingerprint); err != nil { + // Should not happen for a hash. + panic(err) + } pk.Fingerprint = make([]byte, 32) copy(pk.Fingerprint, fingerprint.Sum(nil)) pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[:8]) } else { fingerprint := sha1.New() - pk.SerializeForHash(fingerprint) + if err := pk.SerializeForHash(fingerprint); err != nil { + // Should not happen for a hash. + panic(err) + } pk.Fingerprint = make([]byte, 20) copy(pk.Fingerprint, fingerprint.Sum(nil)) pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20]) @@ -324,16 +396,17 @@ func (pk *PublicKey) parseECDSA(r io.Reader) (err error) { if _, err = pk.oid.ReadFrom(r); err != nil { return } - pk.p = new(encoding.MPI) - if _, err = pk.p.ReadFrom(r); err != nil { - return - } curveInfo := ecc.FindByOid(pk.oid) if curveInfo == nil { return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid)) } + pk.p = new(encoding.MPI) + if _, err = pk.p.ReadFrom(r); err != nil { + return + } + c, ok := curveInfo.Curve.(ecc.ECDSACurve) if !ok { return errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", pk.oid)) @@ -353,6 +426,12 @@ func (pk *PublicKey) parseECDH(r io.Reader) (err error) { if _, err = pk.oid.ReadFrom(r); err != nil { return } + + curveInfo := ecc.FindByOid(pk.oid) + if curveInfo == nil { + return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid)) + } + pk.p = new(encoding.MPI) if _, err = pk.p.ReadFrom(r); err != nil { return @@ -362,12 +441,6 @@ func (pk *PublicKey) parseECDH(r io.Reader) (err error) { return } - curveInfo := ecc.FindByOid(pk.oid) - - if curveInfo == nil { - return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid)) - } - c, ok := curveInfo.Curve.(ecc.ECDHCurve) if !ok { return errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", pk.oid)) @@ -400,6 +473,7 @@ func (pk *PublicKey) parseEdDSA(r io.Reader) (err error) { if _, err = pk.oid.ReadFrom(r); err != nil { return } + curveInfo := ecc.FindByOid(pk.oid) if curveInfo == nil { return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid)) @@ -415,6 +489,10 @@ func (pk *PublicKey) parseEdDSA(r io.Reader) (err error) { return } + if len(pk.p.Bytes()) == 0 { + return errors.StructuralError("empty EdDSA public key") + } + pub := eddsa.NewPublicKey(c) switch flag := pk.p.Bytes()[0]; flag { @@ -431,75 +509,148 @@ func (pk *PublicKey) parseEdDSA(r io.Reader) (err error) { return } +func (pk *PublicKey) parseX25519(r io.Reader) (err error) { + point := make([]byte, x25519.KeySize) + _, err = io.ReadFull(r, point) + if err != nil { + return + } + pub := &x25519.PublicKey{ + Point: point, + } + pk.PublicKey = pub + return +} + +func (pk *PublicKey) parseX448(r io.Reader) (err error) { + point := make([]byte, x448.KeySize) + _, err = io.ReadFull(r, point) + if err != nil { + return + } + pub := &x448.PublicKey{ + Point: point, + } + pk.PublicKey = pub + return +} + +func (pk *PublicKey) parseEd25519(r io.Reader) (err error) { + point := make([]byte, ed25519.PublicKeySize) + _, err = io.ReadFull(r, point) + if err != nil { + return + } + pub := &ed25519.PublicKey{ + Point: point, + } + pk.PublicKey = pub + return +} + +func (pk *PublicKey) parseEd448(r io.Reader) (err error) { + point := make([]byte, ed448.PublicKeySize) + _, err = io.ReadFull(r, point) + if err != nil { + return + } + pub := &ed448.PublicKey{ + Point: point, + } + pk.PublicKey = pub + return +} + // SerializeForHash serializes the PublicKey to w with the special packet // header format needed for hashing. func (pk *PublicKey) SerializeForHash(w io.Writer) error { - pk.SerializeSignaturePrefix(w) + if err := pk.SerializeSignaturePrefix(w); err != nil { + return err + } return pk.serializeWithoutHeaders(w) } // SerializeSignaturePrefix writes the prefix for this public key to the given Writer. // The prefix is used when calculating a signature over this public key. See // RFC 4880, section 5.2.4. -func (pk *PublicKey) SerializeSignaturePrefix(w io.Writer) { +func (pk *PublicKey) SerializeSignaturePrefix(w io.Writer) error { var pLength = pk.algorithmSpecificByteCount() - if pk.Version == 5 { - pLength += 10 // version, timestamp (4), algorithm, key octet count (4). - w.Write([]byte{ - 0x9A, + // version, timestamp, algorithm + pLength += versionSize + timestampSize + algorithmSize + if pk.Version >= 5 { + // key octet count (4). + pLength += 4 + _, err := w.Write([]byte{ + // When a v4 signature is made over a key, the hash data starts with the octet 0x99, followed by a two-octet length + // of the key, and then the body of the key packet. When a v6 signature is made over a key, the hash data starts + // with the salt, then octet 0x9B, followed by a four-octet length of the key, and then the body of the key packet. + 0x95 + byte(pk.Version), byte(pLength >> 24), byte(pLength >> 16), byte(pLength >> 8), byte(pLength), }) - return + if err != nil { + return err + } + return nil } - pLength += 6 - w.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)}) + if _, err := w.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)}); err != nil { + return err + } + return nil } func (pk *PublicKey) Serialize(w io.Writer) (err error) { - length := 6 // 6 byte header + length := uint32(versionSize + timestampSize + algorithmSize) // 6 byte header length += pk.algorithmSpecificByteCount() - if pk.Version == 5 { + if pk.Version >= 5 { length += 4 // octet key count } packetType := packetTypePublicKey if pk.IsSubkey { packetType = packetTypePublicSubkey } - err = serializeHeader(w, packetType, length) + err = serializeHeader(w, packetType, int(length)) if err != nil { return } return pk.serializeWithoutHeaders(w) } -func (pk *PublicKey) algorithmSpecificByteCount() int { - length := 0 +func (pk *PublicKey) algorithmSpecificByteCount() uint32 { + length := uint32(0) switch pk.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: - length += int(pk.n.EncodedLength()) - length += int(pk.e.EncodedLength()) + length += uint32(pk.n.EncodedLength()) + length += uint32(pk.e.EncodedLength()) case PubKeyAlgoDSA: - length += int(pk.p.EncodedLength()) - length += int(pk.q.EncodedLength()) - length += int(pk.g.EncodedLength()) - length += int(pk.y.EncodedLength()) + length += uint32(pk.p.EncodedLength()) + length += uint32(pk.q.EncodedLength()) + length += uint32(pk.g.EncodedLength()) + length += uint32(pk.y.EncodedLength()) case PubKeyAlgoElGamal: - length += int(pk.p.EncodedLength()) - length += int(pk.g.EncodedLength()) - length += int(pk.y.EncodedLength()) + length += uint32(pk.p.EncodedLength()) + length += uint32(pk.g.EncodedLength()) + length += uint32(pk.y.EncodedLength()) case PubKeyAlgoECDSA: - length += int(pk.oid.EncodedLength()) - length += int(pk.p.EncodedLength()) + length += uint32(pk.oid.EncodedLength()) + length += uint32(pk.p.EncodedLength()) case PubKeyAlgoECDH: - length += int(pk.oid.EncodedLength()) - length += int(pk.p.EncodedLength()) - length += int(pk.kdf.EncodedLength()) + length += uint32(pk.oid.EncodedLength()) + length += uint32(pk.p.EncodedLength()) + length += uint32(pk.kdf.EncodedLength()) case PubKeyAlgoEdDSA: - length += int(pk.oid.EncodedLength()) - length += int(pk.p.EncodedLength()) + length += uint32(pk.oid.EncodedLength()) + length += uint32(pk.p.EncodedLength()) + case PubKeyAlgoX25519: + length += x25519.KeySize + case PubKeyAlgoX448: + length += x448.KeySize + case PubKeyAlgoEd25519: + length += ed25519.PublicKeySize + case PubKeyAlgoEd448: + length += ed448.PublicKeySize default: panic("unknown public key algorithm") } @@ -518,7 +669,7 @@ func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) { return } - if pk.Version == 5 { + if pk.Version >= 5 { n := pk.algorithmSpecificByteCount() if _, err = w.Write([]byte{ byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n), @@ -576,6 +727,22 @@ func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) { } _, err = w.Write(pk.p.EncodedBytes()) return + case PubKeyAlgoX25519: + publicKey := pk.PublicKey.(*x25519.PublicKey) + _, err = w.Write(publicKey.Point) + return + case PubKeyAlgoX448: + publicKey := pk.PublicKey.(*x448.PublicKey) + _, err = w.Write(publicKey.Point) + return + case PubKeyAlgoEd25519: + publicKey := pk.PublicKey.(*ed25519.PublicKey) + _, err = w.Write(publicKey.Point) + return + case PubKeyAlgoEd448: + publicKey := pk.PublicKey.(*ed448.PublicKey) + _, err = w.Write(publicKey.Point) + return } return errors.InvalidArgumentError("bad public-key algorithm") } @@ -596,7 +763,8 @@ func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err erro } signed.Write(sig.HashSuffix) hashBytes := signed.Sum(nil) - if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] { + // see discussion https://github.com/ProtonMail/go-crypto/issues/107 + if sig.Version >= 5 && (hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1]) { return errors.SignatureError("hash tag doesn't match") } @@ -635,6 +803,18 @@ func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err erro return errors.SignatureError("EdDSA verification failure") } return nil + case PubKeyAlgoEd25519: + ed25519PublicKey := pk.PublicKey.(*ed25519.PublicKey) + if !ed25519.Verify(ed25519PublicKey, hashBytes, sig.EdSig) { + return errors.SignatureError("Ed25519 verification failure") + } + return nil + case PubKeyAlgoEd448: + ed448PublicKey := pk.PublicKey.(*ed448.PublicKey) + if !ed448.Verify(ed448PublicKey, hashBytes, sig.EdSig) { + return errors.SignatureError("ed448 verification failure") + } + return nil default: return errors.SignatureError("Unsupported public key algorithm used in signature") } @@ -642,11 +822,8 @@ func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err erro // keySignatureHash returns a Hash of the message that needs to be signed for // pk to assert a subkey relationship to signed. -func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) { - if !hashFunc.Available() { - return nil, errors.UnsupportedError("hash function") - } - h = hashFunc.New() +func keySignatureHash(pk, signed signingKey, hashFunc hash.Hash) (h hash.Hash, err error) { + h = hashFunc // RFC 4880, section 5.2.4 err = pk.SerializeForHash(h) @@ -661,7 +838,11 @@ func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, // VerifyKeySignature returns nil iff sig is a valid signature, made by this // public key, of signed. func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error { - h, err := keySignatureHash(pk, signed, sig.Hash) + preparedHash, err := sig.PrepareVerify() + if err != nil { + return err + } + h, err := keySignatureHash(pk, signed, preparedHash) if err != nil { return err } @@ -675,10 +856,14 @@ func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error if sig.EmbeddedSignature == nil { return errors.StructuralError("signing subkey is missing cross-signature") } + preparedHashEmbedded, err := sig.EmbeddedSignature.PrepareVerify() + if err != nil { + return err + } // Verify the cross-signature. This is calculated over the same // data as the main signature, so we cannot just recursively // call signed.VerifyKeySignature(...) - if h, err = keySignatureHash(pk, signed, sig.EmbeddedSignature.Hash); err != nil { + if h, err = keySignatureHash(pk, signed, preparedHashEmbedded); err != nil { return errors.StructuralError("error while hashing for cross-signature: " + err.Error()) } if err := signed.VerifySignature(h, sig.EmbeddedSignature); err != nil { @@ -689,32 +874,31 @@ func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error return nil } -func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) { - if !hashFunc.Available() { - return nil, errors.UnsupportedError("hash function") - } - h = hashFunc.New() - - // RFC 4880, section 5.2.4 - err = pk.SerializeForHash(h) - - return +func keyRevocationHash(pk signingKey, hashFunc hash.Hash) (err error) { + return pk.SerializeForHash(hashFunc) } // VerifyRevocationSignature returns nil iff sig is a valid signature, made by this // public key. func (pk *PublicKey) VerifyRevocationSignature(sig *Signature) (err error) { - h, err := keyRevocationHash(pk, sig.Hash) + preparedHash, err := sig.PrepareVerify() if err != nil { return err } - return pk.VerifySignature(h, sig) + if keyRevocationHash(pk, preparedHash); err != nil { + return err + } + return pk.VerifySignature(preparedHash, sig) } // VerifySubkeyRevocationSignature returns nil iff sig is a valid subkey revocation signature, // made by this public key, of signed. func (pk *PublicKey) VerifySubkeyRevocationSignature(sig *Signature, signed *PublicKey) (err error) { - h, err := keySignatureHash(pk, signed, sig.Hash) + preparedHash, err := sig.PrepareVerify() + if err != nil { + return err + } + h, err := keySignatureHash(pk, signed, preparedHash) if err != nil { return err } @@ -723,15 +907,15 @@ func (pk *PublicKey) VerifySubkeyRevocationSignature(sig *Signature, signed *Pub // userIdSignatureHash returns a Hash of the message that needs to be signed // to assert that pk is a valid key for id. -func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) { - if !hashFunc.Available() { - return nil, errors.UnsupportedError("hash function") - } - h = hashFunc.New() +func userIdSignatureHash(id string, pk *PublicKey, h hash.Hash) (err error) { // RFC 4880, section 5.2.4 - pk.SerializeSignaturePrefix(h) - pk.serializeWithoutHeaders(h) + if err := pk.SerializeSignaturePrefix(h); err != nil { + return err + } + if err := pk.serializeWithoutHeaders(h); err != nil { + return err + } var buf [5]byte buf[0] = 0xb4 @@ -742,16 +926,37 @@ func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash h.Write(buf[:]) h.Write([]byte(id)) - return + return nil +} + +// directKeySignatureHash returns a Hash of the message that needs to be signed. +func directKeySignatureHash(pk *PublicKey, h hash.Hash) (err error) { + return pk.SerializeForHash(h) } // VerifyUserIdSignature returns nil iff sig is a valid signature, made by this // public key, that id is the identity of pub. func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) { - h, err := userIdSignatureHash(id, pub, sig.Hash) + h, err := sig.PrepareVerify() + if err != nil { + return err + } + if err := userIdSignatureHash(id, pub, h); err != nil { + return err + } + return pk.VerifySignature(h, sig) +} + +// VerifyDirectKeySignature returns nil iff sig is a valid signature, made by this +// public key. +func (pk *PublicKey) VerifyDirectKeySignature(sig *Signature) (err error) { + h, err := sig.PrepareVerify() if err != nil { return err } + if err := directKeySignatureHash(pk, h); err != nil { + return err + } return pk.VerifySignature(h, sig) } @@ -782,21 +987,49 @@ func (pk *PublicKey) BitLength() (bitLength uint16, err error) { bitLength = pk.p.BitLength() case PubKeyAlgoEdDSA: bitLength = pk.p.BitLength() + case PubKeyAlgoX25519: + bitLength = x25519.KeySize * 8 + case PubKeyAlgoX448: + bitLength = x448.KeySize * 8 + case PubKeyAlgoEd25519: + bitLength = ed25519.PublicKeySize * 8 + case PubKeyAlgoEd448: + bitLength = ed448.PublicKeySize * 8 default: err = errors.InvalidArgumentError("bad public-key algorithm") } return } +// Curve returns the used elliptic curve of this public key. +// Returns an error if no elliptic curve is used. +func (pk *PublicKey) Curve() (curve Curve, err error) { + switch pk.PubKeyAlgo { + case PubKeyAlgoECDSA, PubKeyAlgoECDH, PubKeyAlgoEdDSA: + curveInfo := ecc.FindByOid(pk.oid) + if curveInfo == nil { + return "", errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid)) + } + curve = Curve(curveInfo.GenName) + case PubKeyAlgoEd25519, PubKeyAlgoX25519: + curve = Curve25519 + case PubKeyAlgoEd448, PubKeyAlgoX448: + curve = Curve448 + default: + err = errors.InvalidArgumentError("public key does not operate with an elliptic curve") + } + return +} + // KeyExpired returns whether sig is a self-signature of a key that has // expired or is created in the future. func (pk *PublicKey) KeyExpired(sig *Signature, currentTime time.Time) bool { - if pk.CreationTime.After(currentTime) { + if pk.CreationTime.Unix() > currentTime.Unix() { return true } if sig.KeyLifetimeSecs == nil || *sig.KeyLifetimeSecs == 0 { return false } expiry := pk.CreationTime.Add(time.Duration(*sig.KeyLifetimeSecs) * time.Second) - return currentTime.After(expiry) + return currentTime.Unix() > expiry.Unix() } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/reader.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/reader.go index 10215fe5..dd840923 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/reader.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/reader.go @@ -10,6 +10,12 @@ import ( "github.com/ProtonMail/go-crypto/openpgp/errors" ) +type PacketReader interface { + Next() (p Packet, err error) + Push(reader io.Reader) (err error) + Unread(p Packet) +} + // Reader reads packets from an io.Reader and allows packets to be 'unread' so // that they result from the next call to Next. type Reader struct { @@ -26,37 +32,81 @@ type Reader struct { const maxReaders = 32 // Next returns the most recently unread Packet, or reads another packet from -// the top-most io.Reader. Unknown packet types are skipped. +// the top-most io.Reader. Unknown/unsupported/Marker packet types are skipped. func (r *Reader) Next() (p Packet, err error) { + for { + p, err := r.read() + if err == io.EOF { + break + } else if err != nil { + if _, ok := err.(errors.UnknownPacketTypeError); ok { + continue + } + if _, ok := err.(errors.UnsupportedError); ok { + switch p.(type) { + case *SymmetricallyEncrypted, *AEADEncrypted, *Compressed, *LiteralData: + return nil, err + } + continue + } + return nil, err + } else { + //A marker packet MUST be ignored when received + switch p.(type) { + case *Marker: + continue + } + return p, nil + } + } + return nil, io.EOF +} + +// Next returns the most recently unread Packet, or reads another packet from +// the top-most io.Reader. Unknown/Marker packet types are skipped while unsupported +// packets are returned as UnsupportedPacket type. +func (r *Reader) NextWithUnsupported() (p Packet, err error) { + for { + p, err = r.read() + if err == io.EOF { + break + } else if err != nil { + if _, ok := err.(errors.UnknownPacketTypeError); ok { + continue + } + if casteErr, ok := err.(errors.UnsupportedError); ok { + return &UnsupportedPacket{ + IncompletePacket: p, + Error: casteErr, + }, nil + } + return + } else { + //A marker packet MUST be ignored when received + switch p.(type) { + case *Marker: + continue + } + return + } + } + return nil, io.EOF +} + +func (r *Reader) read() (p Packet, err error) { if len(r.q) > 0 { p = r.q[len(r.q)-1] r.q = r.q[:len(r.q)-1] return } - for len(r.readers) > 0 { p, err = Read(r.readers[len(r.readers)-1]) - if err == nil { - return - } if err == io.EOF { r.readers = r.readers[:len(r.readers)-1] continue } - // TODO: Add strict mode that rejects unknown packets, instead of ignoring them. - if _, ok := err.(errors.UnknownPacketTypeError); ok { - continue - } - if _, ok := err.(errors.UnsupportedError); ok { - switch p.(type) { - case *SymmetricallyEncrypted, *AEADEncrypted, *Compressed, *LiteralData: - return nil, err - } - continue - } - return nil, err + return p, err } - return nil, io.EOF } @@ -84,3 +134,76 @@ func NewReader(r io.Reader) *Reader { readers: []io.Reader{r}, } } + +// CheckReader is similar to Reader but additionally +// uses the pushdown automata to verify the read packet sequence. +type CheckReader struct { + Reader + verifier *SequenceVerifier + fullyRead bool +} + +// Next returns the most recently unread Packet, or reads another packet from +// the top-most io.Reader. Unknown packet types are skipped. +// If the read packet sequence does not conform to the packet composition +// rules in rfc4880, it returns an error. +func (r *CheckReader) Next() (p Packet, err error) { + if r.fullyRead { + return nil, io.EOF + } + if len(r.q) > 0 { + p = r.q[len(r.q)-1] + r.q = r.q[:len(r.q)-1] + return + } + var errMsg error + for len(r.readers) > 0 { + p, errMsg, err = ReadWithCheck(r.readers[len(r.readers)-1], r.verifier) + if errMsg != nil { + err = errMsg + return + } + if err == nil { + return + } + if err == io.EOF { + r.readers = r.readers[:len(r.readers)-1] + continue + } + //A marker packet MUST be ignored when received + switch p.(type) { + case *Marker: + continue + } + if _, ok := err.(errors.UnknownPacketTypeError); ok { + continue + } + if _, ok := err.(errors.UnsupportedError); ok { + switch p.(type) { + case *SymmetricallyEncrypted, *AEADEncrypted, *Compressed, *LiteralData: + return nil, err + } + continue + } + return nil, err + } + if errMsg = r.verifier.Next(EOSSymbol); errMsg != nil { + return nil, errMsg + } + if errMsg = r.verifier.AssertValid(); errMsg != nil { + return nil, errMsg + } + r.fullyRead = true + return nil, io.EOF +} + +func NewCheckReader(r io.Reader) *CheckReader { + return &CheckReader{ + Reader: Reader{ + q: nil, + readers: []io.Reader{r}, + }, + verifier: NewSequenceVerifier(), + fullyRead: false, + } +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/recipient.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/recipient.go new file mode 100644 index 00000000..fb2e362e --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/recipient.go @@ -0,0 +1,15 @@ +package packet + +// Recipient type represents a Intended Recipient Fingerprint subpacket +// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#name-intended-recipient-fingerpr +type Recipient struct { + KeyVersion int + Fingerprint []byte +} + +func (r *Recipient) Serialize() []byte { + packet := make([]byte, len(r.Fingerprint)+1) + packet[0] = byte(r.KeyVersion) + copy(packet[1:], r.Fingerprint) + return packet +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go index 9f0b1b19..ff14da31 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go @@ -15,6 +15,8 @@ import ( "time" "github.com/ProtonMail/go-crypto/openpgp/ecdsa" + "github.com/ProtonMail/go-crypto/openpgp/ed25519" + "github.com/ProtonMail/go-crypto/openpgp/ed448" "github.com/ProtonMail/go-crypto/openpgp/eddsa" "github.com/ProtonMail/go-crypto/openpgp/errors" "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm" @@ -39,6 +41,9 @@ type Signature struct { SigType SignatureType PubKeyAlgo PublicKeyAlgorithm Hash crypto.Hash + // salt contains a random salt value for v6 signatures + // See RFC the crypto refresh Section 5.2.3. + salt []byte // HashSuffix is extra data that is hashed in after the signed data. HashSuffix []byte @@ -57,6 +62,7 @@ type Signature struct { DSASigR, DSASigS encoding.Field ECDSASigR, ECDSASigS encoding.Field EdDSASigR, EdDSASigS encoding.Field + EdSig []byte // rawSubpackets contains the unparsed subpackets, in order. rawSubpackets []outputSubpacket @@ -72,16 +78,17 @@ type Signature struct { SignerUserId *string IsPrimaryId *bool Notations []*Notation + IntendedRecipients []*Recipient - // TrustLevel and TrustAmount can be set by the signer to assert that - // the key is not only valid but also trustworthy at the specified - // level. - // See RFC 4880, section 5.2.3.13 for details. - TrustLevel TrustLevel + // TrustLevel and TrustAmount can be set by the signer to assert that + // the key is not only valid but also trustworthy at the specified + // level. + // See RFC 4880, section 5.2.3.13 for details. + TrustLevel TrustLevel TrustAmount TrustAmount // TrustRegularExpression can be used in conjunction with trust Signature - // packets to limit the scope of the trust that is extended. + // packets to limit the scope of the trust that is extended. // See RFC 4880, section 5.2.3.14 for details. TrustRegularExpression *string @@ -113,26 +120,59 @@ type Signature struct { outSubpackets []outputSubpacket } +// VerifiableSignature internally keeps state if the +// the signature has been verified before. +type VerifiableSignature struct { + Valid *bool // nil if it has not been verified yet + Packet *Signature +} + +// SaltedHashSpecifier specifies that the given salt and hash are +// used by a v6 signature. +type SaltedHashSpecifier struct { + Hash crypto.Hash + Salt []byte +} + +// NewVerifiableSig returns a struct of type VerifiableSignature referencing the input signature. +func NewVerifiableSig(signature *Signature) *VerifiableSignature { + return &VerifiableSignature{ + Packet: signature, + } +} + +// Salt returns the signature salt for v6 signatures. +func (sig *Signature) Salt() []byte { + if sig == nil { + return nil + } + return sig.salt +} + func (sig *Signature) parse(r io.Reader) (err error) { // RFC 4880, section 5.2.3 - var buf [5]byte + var buf [7]byte _, err = readFull(r, buf[:1]) if err != nil { return } - if buf[0] != 4 && buf[0] != 5 { + if buf[0] != 4 && buf[0] != 5 && buf[0] != 6 { err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0]))) return } sig.Version = int(buf[0]) - _, err = readFull(r, buf[:5]) + if sig.Version == 6 { + _, err = readFull(r, buf[:7]) + } else { + _, err = readFull(r, buf[:5]) + } if err != nil { return } sig.SigType = SignatureType(buf[0]) sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1]) switch sig.PubKeyAlgo { - case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA: + case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA, PubKeyAlgoEd25519, PubKeyAlgoEd448: default: err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo))) return @@ -150,7 +190,17 @@ func (sig *Signature) parse(r io.Reader) (err error) { return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2]))) } - hashedSubpacketsLength := int(buf[3])<<8 | int(buf[4]) + var hashedSubpacketsLength int + if sig.Version == 6 { + // For a v6 signature, a four-octet length is used. + hashedSubpacketsLength = + int(buf[3])<<24 | + int(buf[4])<<16 | + int(buf[5])<<8 | + int(buf[6]) + } else { + hashedSubpacketsLength = int(buf[3])<<8 | int(buf[4]) + } hashedSubpackets := make([]byte, hashedSubpacketsLength) _, err = readFull(r, hashedSubpackets) if err != nil { @@ -166,11 +216,21 @@ func (sig *Signature) parse(r io.Reader) (err error) { return } - _, err = readFull(r, buf[:2]) + if sig.Version == 6 { + _, err = readFull(r, buf[:4]) + } else { + _, err = readFull(r, buf[:2]) + } + if err != nil { return } - unhashedSubpacketsLength := int(buf[0])<<8 | int(buf[1]) + var unhashedSubpacketsLength uint32 + if sig.Version == 6 { + unhashedSubpacketsLength = uint32(buf[0])<<24 | uint32(buf[1])<<16 | uint32(buf[2])<<8 | uint32(buf[3]) + } else { + unhashedSubpacketsLength = uint32(buf[0])<<8 | uint32(buf[1]) + } unhashedSubpackets := make([]byte, unhashedSubpacketsLength) _, err = readFull(r, unhashedSubpackets) if err != nil { @@ -186,6 +246,30 @@ func (sig *Signature) parse(r io.Reader) (err error) { return } + if sig.Version == 6 { + // Only for v6 signatures, a variable-length field containing the salt + _, err = readFull(r, buf[:1]) + if err != nil { + return + } + saltLength := int(buf[0]) + var expectedSaltLength int + expectedSaltLength, err = SaltLengthForHash(sig.Hash) + if err != nil { + return + } + if saltLength != expectedSaltLength { + err = errors.StructuralError("unexpected salt size for the given hash algorithm") + return + } + salt := make([]byte, expectedSaltLength) + _, err = readFull(r, salt) + if err != nil { + return + } + sig.salt = salt + } + switch sig.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: sig.RSASignature = new(encoding.MPI) @@ -216,6 +300,16 @@ func (sig *Signature) parse(r io.Reader) (err error) { if _, err = sig.EdDSASigS.ReadFrom(r); err != nil { return } + case PubKeyAlgoEd25519: + sig.EdSig, err = ed25519.ReadSignature(r) + if err != nil { + return + } + case PubKeyAlgoEd448: + sig.EdSig, err = ed448.ReadSignature(r) + if err != nil { + return + } default: panic("unreachable") } @@ -260,6 +354,7 @@ const ( featuresSubpacket signatureSubpacketType = 30 embeddedSignatureSubpacket signatureSubpacketType = 32 issuerFingerprintSubpacket signatureSubpacketType = 33 + intendedRecipientSubpacket signatureSubpacketType = 35 prefCipherSuitesSubpacket signatureSubpacketType = 39 ) @@ -271,6 +366,10 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r packetType signatureSubpacketType isCritical bool ) + if len(subpacket) == 0 { + err = errors.StructuralError("zero length signature subpacket") + return + } switch { case subpacket[0] < 192: length = uint32(subpacket[0]) @@ -327,10 +426,18 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r sig.SigLifetimeSecs = new(uint32) *sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket) case trustSubpacket: + if len(subpacket) != 2 { + err = errors.StructuralError("trust subpacket with bad length") + return + } // Trust level and amount, section 5.2.3.13 sig.TrustLevel = TrustLevel(subpacket[0]) sig.TrustAmount = TrustAmount(subpacket[1]) case regularExpressionSubpacket: + if len(subpacket) == 0 { + err = errors.StructuralError("regexp subpacket with bad length") + return + } // Trust regular expression, section 5.2.3.14 // RFC specifies the string should be null-terminated; remove a null byte from the end if subpacket[len(subpacket)-1] != 0x00 { @@ -353,16 +460,18 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r copy(sig.PreferredSymmetric, subpacket) case issuerSubpacket: // Issuer, section 5.2.3.5 - if sig.Version > 4 { - err = errors.StructuralError("issuer subpacket found in v5 key") + if sig.Version > 4 && isHashed { + err = errors.StructuralError("issuer subpacket found in v6 key") return } if len(subpacket) != 8 { err = errors.StructuralError("issuer subpacket with bad length") return } - sig.IssuerKeyId = new(uint64) - *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket) + if sig.Version <= 4 { + sig.IssuerKeyId = new(uint64) + *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket) + } case notationDataSubpacket: // Notation data, section 5.2.3.16 if len(subpacket) < 8 { @@ -372,16 +481,16 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r nameLength := uint32(subpacket[4])<<8 | uint32(subpacket[5]) valueLength := uint32(subpacket[6])<<8 | uint32(subpacket[7]) - if len(subpacket) != int(nameLength) + int(valueLength) + 8 { + if len(subpacket) != int(nameLength)+int(valueLength)+8 { err = errors.StructuralError("notation data subpacket with bad length") return } notation := Notation{ IsHumanReadable: (subpacket[0] & 0x80) == 0x80, - Name: string(subpacket[8: (nameLength + 8)]), - Value: subpacket[(nameLength + 8) : (valueLength + nameLength + 8)], - IsCritical: isCritical, + Name: string(subpacket[8:(nameLength + 8)]), + Value: subpacket[(nameLength + 8):(valueLength + nameLength + 8)], + IsCritical: isCritical, } sig.Notations = append(sig.Notations, ¬ation) @@ -441,7 +550,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r return } sig.RevocationReason = new(ReasonForRevocation) - *sig.RevocationReason = ReasonForRevocation(subpacket[0]) + *sig.RevocationReason = NewReasonForRevocation(subpacket[0]) sig.RevocationReasonText = string(subpacket[1:]) case featuresSubpacket: // Features subpacket, section 5.2.3.24 specifies a very general @@ -478,29 +587,46 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r // Policy URI, section 5.2.3.20 sig.PolicyURI = string(subpacket) case issuerFingerprintSubpacket: + if len(subpacket) == 0 { + err = errors.StructuralError("empty issuer fingerprint subpacket") + return + } v, l := subpacket[0], len(subpacket[1:]) - if v == 5 && l != 32 || v != 5 && l != 20 { + if v >= 5 && l != 32 || v < 5 && l != 20 { return nil, errors.StructuralError("bad fingerprint length") } sig.IssuerFingerprint = make([]byte, l) copy(sig.IssuerFingerprint, subpacket[1:]) sig.IssuerKeyId = new(uint64) - if v == 5 { + if v >= 5 { *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[1:9]) } else { *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[13:21]) } + case intendedRecipientSubpacket: + // Intended Recipient Fingerprint + // https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#name-intended-recipient-fingerpr + if len(subpacket) < 1 { + return nil, errors.StructuralError("invalid intended recipient fingerpring length") + } + version, length := subpacket[0], len(subpacket[1:]) + if version >= 5 && length != 32 || version < 5 && length != 20 { + return nil, errors.StructuralError("invalid fingerprint length") + } + fingerprint := make([]byte, length) + copy(fingerprint, subpacket[1:]) + sig.IntendedRecipients = append(sig.IntendedRecipients, &Recipient{int(version), fingerprint}) case prefCipherSuitesSubpacket: // Preferred AEAD cipher suites // See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#name-preferred-aead-ciphersuites - if len(subpacket) % 2 != 0 { + if len(subpacket)%2 != 0 { err = errors.StructuralError("invalid aead cipher suite length") return } - sig.PreferredCipherSuites = make([][2]byte, len(subpacket) / 2) + sig.PreferredCipherSuites = make([][2]byte, len(subpacket)/2) - for i := 0; i < len(subpacket) / 2; i++ { + for i := 0; i < len(subpacket)/2; i++ { sig.PreferredCipherSuites[i] = [2]uint8{subpacket[2*i], subpacket[2*i+1]} } default: @@ -534,6 +660,13 @@ func (sig *Signature) CheckKeyIdOrFingerprint(pk *PublicKey) bool { return sig.IssuerKeyId != nil && *sig.IssuerKeyId == pk.KeyId } +func (sig *Signature) CheckKeyIdOrFingerprintExplicit(fingerprint []byte, keyId uint64) bool { + if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 && fingerprint != nil { + return bytes.Equal(sig.IssuerFingerprint, fingerprint) + } + return sig.IssuerKeyId != nil && *sig.IssuerKeyId == keyId +} + // serializeSubpacketLength marshals the given length into to. func serializeSubpacketLength(to []byte, length int) int { // RFC 4880, Section 4.2.2. @@ -582,20 +715,19 @@ func serializeSubpackets(to []byte, subpackets []outputSubpacket, hashed bool) { to = to[n:] } } - return } // SigExpired returns whether sig is a signature that has expired or is created // in the future. func (sig *Signature) SigExpired(currentTime time.Time) bool { - if sig.CreationTime.After(currentTime) { + if sig.CreationTime.Unix() > currentTime.Unix() { return true } if sig.SigLifetimeSecs == nil || *sig.SigLifetimeSecs == 0 { return false } expiry := sig.CreationTime.Add(time.Duration(*sig.SigLifetimeSecs) * time.Second) - return currentTime.After(expiry) + return currentTime.Unix() > expiry.Unix() } // buildHashSuffix constructs the HashSuffix member of sig in preparation for signing. @@ -619,20 +751,36 @@ func (sig *Signature) buildHashSuffix(hashedSubpackets []byte) (err error) { uint8(sig.SigType), uint8(sig.PubKeyAlgo), uint8(hashId), - uint8(len(hashedSubpackets) >> 8), - uint8(len(hashedSubpackets)), }) + hashedSubpacketsLength := len(hashedSubpackets) + if sig.Version == 6 { + // v6 signatures store the length in 4 octets + hashedFields.Write([]byte{ + uint8(hashedSubpacketsLength >> 24), + uint8(hashedSubpacketsLength >> 16), + uint8(hashedSubpacketsLength >> 8), + uint8(hashedSubpacketsLength), + }) + } else { + hashedFields.Write([]byte{ + uint8(hashedSubpacketsLength >> 8), + uint8(hashedSubpacketsLength), + }) + } + lenPrefix := hashedFields.Len() hashedFields.Write(hashedSubpackets) - var l uint64 = uint64(6 + len(hashedSubpackets)) + var l uint64 = uint64(lenPrefix + len(hashedSubpackets)) if sig.Version == 5 { + // v5 case hashedFields.Write([]byte{0x05, 0xff}) hashedFields.Write([]byte{ uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32), uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l), }) } else { - hashedFields.Write([]byte{0x04, 0xff}) + // v4 and v6 case + hashedFields.Write([]byte{byte(sig.Version), 0xff}) hashedFields.Write([]byte{ uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l), }) @@ -660,6 +808,67 @@ func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) { return } +// PrepareSign must be called to create a hash object before Sign for v6 signatures. +// The created hash object initially hashes a randomly generated salt +// as required by v6 signatures. The generated salt is stored in sig. If the signature is not v6, +// the method returns an empty hash object. +// See RFC the crypto refresh Section 3.2.4. +func (sig *Signature) PrepareSign(config *Config) (hash.Hash, error) { + if !sig.Hash.Available() { + return nil, errors.UnsupportedError("hash function") + } + hasher := sig.Hash.New() + if sig.Version == 6 { + if sig.salt == nil { + var err error + sig.salt, err = SignatureSaltForHash(sig.Hash, config.Random()) + if err != nil { + return nil, err + } + } + hasher.Write(sig.salt) + } + return hasher, nil +} + +// SetSalt sets the signature salt for v6 signatures. +// Assumes salt is generated correctly and checks if length matches. +// If the signature is not v6, the method ignores the salt. +// Use PrepareSign whenever possible instead of generating and +// hashing the salt externally. +// See RFC the crypto refresh Section 3.2.4. +func (sig *Signature) SetSalt(salt []byte) error { + if sig.Version == 6 { + expectedSaltLength, err := SaltLengthForHash(sig.Hash) + if err != nil { + return err + } + if salt == nil || len(salt) != expectedSaltLength { + return errors.InvalidArgumentError("unexpected salt size for the given hash algorithm") + } + sig.salt = salt + } + return nil +} + +// PrepareVerify must be called to create a hash object before verifying v6 signatures. +// The created hash object initially hashes the internally stored salt. +// If the signature is not v6, the method returns an empty hash object. +// See crypto refresh Section 3.2.4. +func (sig *Signature) PrepareVerify() (hash.Hash, error) { + if !sig.Hash.Available() { + return nil, errors.UnsupportedError("hash function") + } + hasher := sig.Hash.New() + if sig.Version == 6 { + if sig.salt == nil { + return nil, errors.StructuralError("v6 requires a salt for the hash to be signed") + } + hasher.Write(sig.salt) + } + return hasher, nil +} + // Sign signs a message with a private key. The hash, h, must contain // the hash of the message to be signed and will be mutated by this function. // On success, the signature is stored in sig. Call Serialize to write it out. @@ -713,6 +922,18 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e sig.EdDSASigR = encoding.NewMPI(r) sig.EdDSASigS = encoding.NewMPI(s) } + case PubKeyAlgoEd25519: + sk := priv.PrivateKey.(*ed25519.PrivateKey) + signature, err := ed25519.Sign(sk, digest) + if err == nil { + sig.EdSig = signature + } + case PubKeyAlgoEd448: + sk := priv.PrivateKey.(*ed448.PrivateKey) + signature, err := ed448.Sign(sk, digest) + if err == nil { + sig.EdSig = signature + } default: err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo))) } @@ -728,11 +949,32 @@ func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, co if priv.Dummy() { return errors.ErrDummyPrivateKey("dummy key found") } - h, err := userIdSignatureHash(id, pub, sig.Hash) + prepareHash, err := sig.PrepareSign(config) if err != nil { return err } - return sig.Sign(h, priv, config) + if err := userIdSignatureHash(id, pub, prepareHash); err != nil { + return err + } + return sig.Sign(prepareHash, priv, config) +} + +// SignDirectKeyBinding computes a signature from priv +// On success, the signature is stored in sig. +// Call Serialize to write it out. +// If config is nil, sensible defaults will be used. +func (sig *Signature) SignDirectKeyBinding(pub *PublicKey, priv *PrivateKey, config *Config) error { + if priv.Dummy() { + return errors.ErrDummyPrivateKey("dummy key found") + } + prepareHash, err := sig.PrepareSign(config) + if err != nil { + return err + } + if err := directKeySignatureHash(pub, prepareHash); err != nil { + return err + } + return sig.Sign(prepareHash, priv, config) } // CrossSignKey computes a signature from signingKey on pub hashed using hashKey. On success, @@ -740,7 +982,11 @@ func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, co // If config is nil, sensible defaults will be used. func (sig *Signature) CrossSignKey(pub *PublicKey, hashKey *PublicKey, signingKey *PrivateKey, config *Config) error { - h, err := keySignatureHash(hashKey, pub, sig.Hash) + prepareHash, err := sig.PrepareSign(config) + if err != nil { + return err + } + h, err := keySignatureHash(hashKey, pub, prepareHash) if err != nil { return err } @@ -754,7 +1000,11 @@ func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) if priv.Dummy() { return errors.ErrDummyPrivateKey("dummy key found") } - h, err := keySignatureHash(&priv.PublicKey, pub, sig.Hash) + prepareHash, err := sig.PrepareSign(config) + if err != nil { + return err + } + h, err := keySignatureHash(&priv.PublicKey, pub, prepareHash) if err != nil { return err } @@ -765,11 +1015,14 @@ func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) // stored in sig. Call Serialize to write it out. // If config is nil, sensible defaults will be used. func (sig *Signature) RevokeKey(pub *PublicKey, priv *PrivateKey, config *Config) error { - h, err := keyRevocationHash(pub, sig.Hash) + prepareHash, err := sig.PrepareSign(config) if err != nil { return err } - return sig.Sign(h, priv, config) + if err := keyRevocationHash(pub, prepareHash); err != nil { + return err + } + return sig.Sign(prepareHash, priv, config) } // RevokeSubkey computes a subkey revocation signature of pub using priv. @@ -786,7 +1039,7 @@ func (sig *Signature) Serialize(w io.Writer) (err error) { if len(sig.outSubpackets) == 0 { sig.outSubpackets = sig.rawSubpackets } - if sig.RSASignature == nil && sig.DSASigR == nil && sig.ECDSASigR == nil && sig.EdDSASigR == nil { + if sig.RSASignature == nil && sig.DSASigR == nil && sig.ECDSASigR == nil && sig.EdDSASigR == nil && sig.EdSig == nil { return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize") } @@ -803,16 +1056,24 @@ func (sig *Signature) Serialize(w io.Writer) (err error) { case PubKeyAlgoEdDSA: sigLength = int(sig.EdDSASigR.EncodedLength()) sigLength += int(sig.EdDSASigS.EncodedLength()) + case PubKeyAlgoEd25519: + sigLength = ed25519.SignatureSize + case PubKeyAlgoEd448: + sigLength = ed448.SignatureSize default: panic("impossible") } + hashedSubpacketsLen := subpacketsLength(sig.outSubpackets, true) unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false) - length := len(sig.HashSuffix) - 6 /* trailer not included */ + + length := 4 + /* length of version|signature type|public-key algorithm|hash algorithm */ + 2 /* length of hashed subpackets */ + hashedSubpacketsLen + 2 /* length of unhashed subpackets */ + unhashedSubpacketsLen + 2 /* hash tag */ + sigLength - if sig.Version == 5 { - length -= 4 // eight-octet instead of four-octet big endian + if sig.Version == 6 { + length += 4 + /* the two length fields are four-octet instead of two */ + 1 + /* salt length */ + len(sig.salt) /* length salt */ } err = serializeHeader(w, packetTypeSignature, length) if err != nil { @@ -826,18 +1087,41 @@ func (sig *Signature) Serialize(w io.Writer) (err error) { } func (sig *Signature) serializeBody(w io.Writer) (err error) { - hashedSubpacketsLen := uint16(uint16(sig.HashSuffix[4])<<8) | uint16(sig.HashSuffix[5]) - fields := sig.HashSuffix[:6+hashedSubpacketsLen] + var fields []byte + if sig.Version == 6 { + // v6 signatures use 4 octets for length + hashedSubpacketsLen := + uint32(uint32(sig.HashSuffix[4])<<24) | + uint32(uint32(sig.HashSuffix[5])<<16) | + uint32(uint32(sig.HashSuffix[6])<<8) | + uint32(sig.HashSuffix[7]) + fields = sig.HashSuffix[:8+hashedSubpacketsLen] + } else { + hashedSubpacketsLen := uint16(uint16(sig.HashSuffix[4])<<8) | + uint16(sig.HashSuffix[5]) + fields = sig.HashSuffix[:6+hashedSubpacketsLen] + + } _, err = w.Write(fields) if err != nil { return } unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false) - unhashedSubpackets := make([]byte, 2+unhashedSubpacketsLen) - unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 8) - unhashedSubpackets[1] = byte(unhashedSubpacketsLen) - serializeSubpackets(unhashedSubpackets[2:], sig.outSubpackets, false) + var unhashedSubpackets []byte + if sig.Version == 6 { + unhashedSubpackets = make([]byte, 4+unhashedSubpacketsLen) + unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 24) + unhashedSubpackets[1] = byte(unhashedSubpacketsLen >> 16) + unhashedSubpackets[2] = byte(unhashedSubpacketsLen >> 8) + unhashedSubpackets[3] = byte(unhashedSubpacketsLen) + serializeSubpackets(unhashedSubpackets[4:], sig.outSubpackets, false) + } else { + unhashedSubpackets = make([]byte, 2+unhashedSubpacketsLen) + unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 8) + unhashedSubpackets[1] = byte(unhashedSubpacketsLen) + serializeSubpackets(unhashedSubpackets[2:], sig.outSubpackets, false) + } _, err = w.Write(unhashedSubpackets) if err != nil { @@ -848,6 +1132,18 @@ func (sig *Signature) serializeBody(w io.Writer) (err error) { return } + if sig.Version == 6 { + // write salt for v6 signatures + _, err = w.Write([]byte{uint8(len(sig.salt))}) + if err != nil { + return + } + _, err = w.Write(sig.salt) + if err != nil { + return + } + } + switch sig.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: _, err = w.Write(sig.RSASignature.EncodedBytes()) @@ -866,6 +1162,10 @@ func (sig *Signature) serializeBody(w io.Writer) (err error) { return } _, err = w.Write(sig.EdDSASigS.EncodedBytes()) + case PubKeyAlgoEd25519: + err = ed25519.WriteSignature(w, sig.EdSig) + case PubKeyAlgoEd448: + err = ed448.WriteSignature(w, sig.EdSig) default: panic("impossible") } @@ -888,11 +1188,11 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp if sig.IssuerKeyId != nil && sig.Version == 4 { keyId := make([]byte, 8) binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId) - subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, true, keyId}) + subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId}) } if sig.IssuerFingerprint != nil { contents := append([]uint8{uint8(issuer.Version)}, sig.IssuerFingerprint...) - subpackets = append(subpackets, outputSubpacket{true, issuerFingerprintSubpacket, sig.Version == 5, contents}) + subpackets = append(subpackets, outputSubpacket{true, issuerFingerprintSubpacket, sig.Version >= 5, contents}) } if sig.SignerUserId != nil { subpackets = append(subpackets, outputSubpacket{true, signerUserIdSubpacket, false, []byte(*sig.SignerUserId)}) @@ -942,6 +1242,17 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp }) } + for _, recipient := range sig.IntendedRecipients { + subpackets = append( + subpackets, + outputSubpacket{ + true, + intendedRecipientSubpacket, + false, + recipient.Serialize(), + }) + } + // The following subpackets may only appear in self-signatures. var features = byte(0x00) @@ -1039,7 +1350,7 @@ func (sig *Signature) AddMetadataToHashSuffix() { n := sig.HashSuffix[len(sig.HashSuffix)-8:] l := uint64( uint64(n[0])<<56 | uint64(n[1])<<48 | uint64(n[2])<<40 | uint64(n[3])<<32 | - uint64(n[4])<<24 | uint64(n[5])<<16 | uint64(n[6])<<8 | uint64(n[7])) + uint64(n[4])<<24 | uint64(n[5])<<16 | uint64(n[6])<<8 | uint64(n[7])) suffix := bytes.NewBuffer(nil) suffix.Write(sig.HashSuffix[:l]) @@ -1057,8 +1368,6 @@ func (sig *Signature) AddMetadataToHashSuffix() { binary.BigEndian.PutUint32(buf[:], lit.Time) suffix.Write(buf[:]) - // Update the counter and restore trailing bytes - l = uint64(suffix.Len()) suffix.Write([]byte{0x05, 0xff}) suffix.Write([]byte{ uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32), @@ -1066,3 +1375,35 @@ func (sig *Signature) AddMetadataToHashSuffix() { }) sig.HashSuffix = suffix.Bytes() } + +// SaltLengthForHash selects the required salt length for the given hash algorithm, +// as per Table 23 (Hash algorithm registry) of the crypto refresh. +// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#section-9.5|Crypto Refresh Section 9.5. +func SaltLengthForHash(hash crypto.Hash) (int, error) { + switch hash { + case crypto.SHA256, crypto.SHA224, crypto.SHA3_256: + return 16, nil + case crypto.SHA384: + return 24, nil + case crypto.SHA512, crypto.SHA3_512: + return 32, nil + default: + return 0, errors.UnsupportedError("hash function not supported for V6 signatures") + } +} + +// SignatureSaltForHash generates a random signature salt +// with the length for the given hash algorithm. +// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#section-9.5|Crypto Refresh Section 9.5. +func SignatureSaltForHash(hash crypto.Hash, randReader io.Reader) ([]byte, error) { + saltLength, err := SaltLengthForHash(hash) + if err != nil { + return nil, err + } + salt := make([]byte, saltLength) + _, err = io.ReadFull(randReader, salt) + if err != nil { + return nil, err + } + return salt, nil +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go index bc2caf0e..c97b98b9 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go @@ -41,11 +41,11 @@ func (ske *SymmetricKeyEncrypted) parse(r io.Reader) error { return err } ske.Version = int(buf[0]) - if ske.Version != 4 && ske.Version != 5 { + if ske.Version != 4 && ske.Version != 5 && ske.Version != 6 { return errors.UnsupportedError("unknown SymmetricKeyEncrypted version") } - if ske.Version == 5 { + if ske.Version > 5 { // Scalar octet count if _, err := readFull(r, buf[:]); err != nil { return err @@ -61,13 +61,15 @@ func (ske *SymmetricKeyEncrypted) parse(r io.Reader) error { return errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(buf[0]))) } - if ske.Version == 5 { + if ske.Version >= 5 { // AEAD mode if _, err := readFull(r, buf[:]); err != nil { return errors.StructuralError("cannot read AEAD octet from packet") } ske.Mode = AEADMode(buf[0]) + } + if ske.Version > 5 { // Scalar octet count if _, err := readFull(r, buf[:]); err != nil { return err @@ -82,7 +84,7 @@ func (ske *SymmetricKeyEncrypted) parse(r io.Reader) error { return err } - if ske.Version == 5 { + if ske.Version >= 5 { // AEAD IV iv := make([]byte, ske.Mode.IvLength()) _, err := readFull(r, iv) @@ -123,8 +125,8 @@ func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) ([]byte, CipherFunc case 4: plaintextKey, cipherFunc, err := ske.decryptV4(key) return plaintextKey, cipherFunc, err - case 5: - plaintextKey, err := ske.decryptV5(key) + case 5, 6: + plaintextKey, err := ske.aeadDecrypt(ske.Version, key) return plaintextKey, CipherFunction(0), err } err := errors.UnsupportedError("unknown SymmetricKeyEncrypted version") @@ -150,9 +152,9 @@ func (ske *SymmetricKeyEncrypted) decryptV4(key []byte) ([]byte, CipherFunction, return plaintextKey, cipherFunc, nil } -func (ske *SymmetricKeyEncrypted) decryptV5(key []byte) ([]byte, error) { - adata := []byte{0xc3, byte(5), byte(ske.CipherFunc), byte(ske.Mode)} - aead := getEncryptedKeyAeadInstance(ske.CipherFunc, ske.Mode, key, adata) +func (ske *SymmetricKeyEncrypted) aeadDecrypt(version int, key []byte) ([]byte, error) { + adata := []byte{0xc3, byte(version), byte(ske.CipherFunc), byte(ske.Mode)} + aead := getEncryptedKeyAeadInstance(ske.CipherFunc, ske.Mode, key, adata, version) plaintextKey, err := aead.Open(nil, ske.iv, ske.encryptedKey, adata) if err != nil { @@ -192,13 +194,13 @@ func SerializeSymmetricKeyEncrypted(w io.Writer, passphrase []byte, config *Conf func SerializeSymmetricKeyEncryptedReuseKey(w io.Writer, sessionKey []byte, passphrase []byte, config *Config) (err error) { var version int if config.AEAD() != nil { - version = 5 + version = 6 } else { version = 4 } cipherFunc := config.Cipher() // cipherFunc must be AES - if !cipherFunc.IsSupported() || cipherFunc < CipherAES128 || cipherFunc > CipherAES256 { + if !cipherFunc.IsSupported() || cipherFunc < CipherAES128 || cipherFunc > CipherAES256 { return errors.UnsupportedError("unsupported cipher: " + strconv.Itoa(int(cipherFunc))) } @@ -207,7 +209,7 @@ func SerializeSymmetricKeyEncryptedReuseKey(w io.Writer, sessionKey []byte, pass keyEncryptingKey := make([]byte, keySize) // s2k.Serialize salts and stretches the passphrase, and writes the // resulting key to keyEncryptingKey and the s2k descriptor to s2kBuf. - err = s2k.Serialize(s2kBuf, keyEncryptingKey, config.Random(), passphrase, &s2k.Config{Hash: config.Hash(), S2KCount: config.PasswordHashIterations()}) + err = s2k.Serialize(s2kBuf, keyEncryptingKey, config.Random(), passphrase, config.S2K()) if err != nil { return } @@ -217,11 +219,15 @@ func SerializeSymmetricKeyEncryptedReuseKey(w io.Writer, sessionKey []byte, pass switch version { case 4: packetLength = 2 /* header */ + len(s2kBytes) + 1 /* cipher type */ + keySize - case 5: + case 5, 6: ivLen := config.AEAD().Mode().IvLength() tagLen := config.AEAD().Mode().TagLength() - packetLength = 5 + len(s2kBytes) + ivLen + keySize + tagLen + packetLength = 3 + len(s2kBytes) + ivLen + keySize + tagLen + } + if version > 5 { + packetLength += 2 // additional octet count fields } + err = serializeHeader(w, packetTypeSymmetricKeyEncrypted, packetLength) if err != nil { return @@ -230,18 +236,19 @@ func SerializeSymmetricKeyEncryptedReuseKey(w io.Writer, sessionKey []byte, pass // Symmetric Key Encrypted Version buf := []byte{byte(version)} - if version == 5 { + if version > 5 { // Scalar octet count - buf = append(buf, byte(3 + len(s2kBytes) + config.AEAD().Mode().IvLength())) + buf = append(buf, byte(3+len(s2kBytes)+config.AEAD().Mode().IvLength())) } // Cipher function buf = append(buf, byte(cipherFunc)) - if version == 5 { + if version >= 5 { // AEAD mode buf = append(buf, byte(config.AEAD().Mode())) - + } + if version > 5 { // Scalar octet count buf = append(buf, byte(len(s2kBytes))) } @@ -265,10 +272,10 @@ func SerializeSymmetricKeyEncryptedReuseKey(w io.Writer, sessionKey []byte, pass if err != nil { return } - case 5: + case 5, 6: mode := config.AEAD().Mode() - adata := []byte{0xc3, byte(5), byte(cipherFunc), byte(mode)} - aead := getEncryptedKeyAeadInstance(cipherFunc, mode, keyEncryptingKey, adata) + adata := []byte{0xc3, byte(version), byte(cipherFunc), byte(mode)} + aead := getEncryptedKeyAeadInstance(cipherFunc, mode, keyEncryptingKey, adata, version) // Sample iv using random reader iv := make([]byte, config.AEAD().Mode().IvLength()) @@ -292,12 +299,17 @@ func SerializeSymmetricKeyEncryptedReuseKey(w io.Writer, sessionKey []byte, pass return } -func getEncryptedKeyAeadInstance(c CipherFunction, mode AEADMode, inputKey, associatedData []byte) (aead cipher.AEAD) { - hkdfReader := hkdf.New(sha256.New, inputKey, []byte{}, associatedData) +func getEncryptedKeyAeadInstance(c CipherFunction, mode AEADMode, inputKey, associatedData []byte, version int) (aead cipher.AEAD) { + var blockCipher cipher.Block + if version > 5 { + hkdfReader := hkdf.New(sha256.New, inputKey, []byte{}, associatedData) - encryptionKey := make([]byte, c.KeySize()) - _, _ = readFull(hkdfReader, encryptionKey) + encryptionKey := make([]byte, c.KeySize()) + _, _ = readFull(hkdfReader, encryptionKey) - blockCipher := c.new(encryptionKey) + blockCipher = c.new(encryptionKey) + } else { + blockCipher = c.new(inputKey) + } return mode.new(blockCipher) } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go index dc1a2403..e9bbf032 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go @@ -21,21 +21,20 @@ type SymmetricallyEncrypted struct { IntegrityProtected bool // If true it is type 18 (with MDC or AEAD). False is packet type 9 // Specific to version 1 - prefix []byte + prefix []byte // Specific to version 2 - cipher CipherFunction - mode AEADMode - chunkSizeByte byte - salt [aeadSaltSize]byte + Cipher CipherFunction + Mode AEADMode + ChunkSizeByte byte + Salt [aeadSaltSize]byte } const ( - symmetricallyEncryptedVersionMdc = 1 + symmetricallyEncryptedVersionMdc = 1 symmetricallyEncryptedVersionAead = 2 ) - func (se *SymmetricallyEncrypted) parse(r io.Reader) error { if se.IntegrityProtected { // See RFC 4880, section 5.13. diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go index 241800c0..a8ef0bbb 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go @@ -7,9 +7,10 @@ package packet import ( "crypto/cipher" "crypto/sha256" + "io" + "github.com/ProtonMail/go-crypto/openpgp/errors" "golang.org/x/crypto/hkdf" - "io" ) // parseAead parses a V2 SEIPD packet (AEAD) as specified in @@ -21,26 +22,26 @@ func (se *SymmetricallyEncrypted) parseAead(r io.Reader) error { } // Cipher - se.cipher = CipherFunction(headerData[0]) + se.Cipher = CipherFunction(headerData[0]) // cipherFunc must have block size 16 to use AEAD - if se.cipher.blockSize() != 16 { - return errors.UnsupportedError("invalid aead cipher: " + string(se.cipher)) + if se.Cipher.blockSize() != 16 { + return errors.UnsupportedError("invalid aead cipher: " + string(se.Cipher)) } // Mode - se.mode = AEADMode(headerData[1]) - if se.mode.TagLength() == 0 { - return errors.UnsupportedError("unknown aead mode: " + string(se.mode)) + se.Mode = AEADMode(headerData[1]) + if se.Mode.TagLength() == 0 { + return errors.UnsupportedError("unknown aead mode: " + string(se.Mode)) } // Chunk size - se.chunkSizeByte = headerData[2] - if se.chunkSizeByte > 16 { - return errors.UnsupportedError("invalid aead chunk size byte: " + string(se.chunkSizeByte)) + se.ChunkSizeByte = headerData[2] + if se.ChunkSizeByte > 16 { + return errors.UnsupportedError("invalid aead chunk size byte: " + string(se.ChunkSizeByte)) } // Salt - if n, err := io.ReadFull(r, se.salt[:]); n < aeadSaltSize { + if n, err := io.ReadFull(r, se.Salt[:]); n < aeadSaltSize { return errors.StructuralError("could not read aead salt: " + err.Error()) } @@ -52,19 +53,19 @@ func (se *SymmetricallyEncrypted) associatedData() []byte { return []byte{ 0xD2, symmetricallyEncryptedVersionAead, - byte(se.cipher), - byte(se.mode), - se.chunkSizeByte, + byte(se.Cipher), + byte(se.Mode), + se.ChunkSizeByte, } } // decryptAead decrypts a V2 SEIPD packet (AEAD) as specified in // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2 func (se *SymmetricallyEncrypted) decryptAead(inputKey []byte) (io.ReadCloser, error) { - aead, nonce := getSymmetricallyEncryptedAeadInstance(se.cipher, se.mode, inputKey, se.salt[:], se.associatedData()) + aead, nonce := getSymmetricallyEncryptedAeadInstance(se.Cipher, se.Mode, inputKey, se.Salt[:], se.associatedData()) // Carry the first tagLen bytes - tagLen := se.mode.TagLength() + tagLen := se.Mode.TagLength() peekedBytes := make([]byte, tagLen) n, err := io.ReadFull(se.Contents, peekedBytes) if n < tagLen || (err != nil && err != io.EOF) { @@ -74,7 +75,7 @@ func (se *SymmetricallyEncrypted) decryptAead(inputKey []byte) (io.ReadCloser, e return &aeadDecrypter{ aeadCrypter: aeadCrypter{ aead: aead, - chunkSize: decodeAEADChunkSize(se.chunkSizeByte), + chunkSize: decodeAEADChunkSize(se.ChunkSizeByte), initialNonce: nonce, associatedData: se.associatedData(), chunkIndex: make([]byte, 8), @@ -114,7 +115,7 @@ func serializeSymmetricallyEncryptedAead(ciphertext io.WriteCloser, cipherSuite // Random salt salt := make([]byte, aeadSaltSize) - if _, err := rand.Read(salt); err != nil { + if _, err := io.ReadFull(rand, salt); err != nil { return nil, err } @@ -144,7 +145,7 @@ func getSymmetricallyEncryptedAeadInstance(c CipherFunction, mode AEADMode, inpu _, _ = readFull(hkdfReader, encryptionKey) // Last 64 bits of nonce are the counter - nonce = make([]byte, mode.IvLength() - 8) + nonce = make([]byte, mode.IvLength()-8) _, _ = readFull(hkdfReader, nonce) diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_mdc.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_mdc.go index 3e070f8b..645963fa 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_mdc.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_mdc.go @@ -221,7 +221,7 @@ func (c noOpCloser) Close() error { func serializeSymmetricallyEncryptedMdc(ciphertext io.WriteCloser, c CipherFunction, key []byte, config *Config) (Contents io.WriteCloser, err error) { // Disallow old cipher suites - if !c.IsSupported() || c < CipherAES128 { + if !c.IsSupported() || c < CipherAES128 { return nil, errors.InvalidArgumentError("invalid mdc cipher function") } @@ -237,7 +237,10 @@ func serializeSymmetricallyEncryptedMdc(ciphertext io.WriteCloser, c CipherFunct block := c.new(key) blockSize := block.BlockSize() iv := make([]byte, blockSize) - _, err = config.Random().Read(iv) + _, err = io.ReadFull(config.Random(), iv) + if err != nil { + return nil, err + } if err != nil { return } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userattribute.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userattribute.go index 88ec72c6..63814ed1 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userattribute.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userattribute.go @@ -9,7 +9,6 @@ import ( "image" "image/jpeg" "io" - "io/ioutil" ) const UserAttrImageSubpacket = 1 @@ -63,7 +62,7 @@ func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute { func (uat *UserAttribute) parse(r io.Reader) (err error) { // RFC 4880, section 5.13 - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { return } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userid.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userid.go index 614fbafd..3c7451a3 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userid.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userid.go @@ -6,7 +6,6 @@ package packet import ( "io" - "io/ioutil" "strings" ) @@ -66,7 +65,7 @@ func NewUserId(name, comment, email string) *UserId { func (uid *UserId) parse(r io.Reader) (err error) { // RFC 4880, section 5.11 - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { return } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go index e910e184..ac897d70 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go @@ -6,6 +6,7 @@ package openpgp // import "github.com/ProtonMail/go-crypto/openpgp" import ( + "bytes" "crypto" _ "crypto/sha256" _ "crypto/sha512" @@ -46,6 +47,7 @@ type MessageDetails struct { DecryptedWith Key // the private key used to decrypt the message, if any. IsSigned bool // true if the message is signed. SignedByKeyId uint64 // the key id of the signer, if any. + SignedByFingerprint []byte // the key fingerprint of the signer, if any. SignedBy *Key // the key of the signer, if available. LiteralData *packet.LiteralData // the metadata of the contents UnverifiedBody io.Reader // the contents of the message. @@ -117,7 +119,7 @@ ParsePackets: // This packet contains the decryption key encrypted to a public key. md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId) switch p.Algo { - case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal, packet.PubKeyAlgoECDH: + case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal, packet.PubKeyAlgoECDH, packet.PubKeyAlgoX25519, packet.PubKeyAlgoX448: break default: continue @@ -270,13 +272,17 @@ FindLiteralData: prevLast = true } - h, wrappedHash, err = hashForSignature(p.Hash, p.SigType) + h, wrappedHash, err = hashForSignature(p.Hash, p.SigType, p.Salt) if err != nil { md.SignatureError = err } md.IsSigned = true + if p.Version == 6 { + md.SignedByFingerprint = p.KeyFingerprint + } md.SignedByKeyId = p.KeyId + if keyring != nil { keys := keyring.KeysByIdUsage(p.KeyId, packet.KeyFlagSign) if len(keys) > 0 { @@ -292,7 +298,7 @@ FindLiteralData: if md.IsSigned && md.SignatureError == nil { md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md, config} } else if md.decrypted != nil { - md.UnverifiedBody = checkReader{md} + md.UnverifiedBody = &checkReader{md, false} } else { md.UnverifiedBody = md.LiteralData.Body } @@ -300,12 +306,22 @@ FindLiteralData: return md, nil } +func wrapHashForSignature(hashFunc hash.Hash, sigType packet.SignatureType) (hash.Hash, error) { + switch sigType { + case packet.SigTypeBinary: + return hashFunc, nil + case packet.SigTypeText: + return NewCanonicalTextHash(hashFunc), nil + } + return nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType))) +} + // hashForSignature returns a pair of hashes that can be used to verify a // signature. The signature may specify that the contents of the signed message // should be preprocessed (i.e. to normalize line endings). Thus this function // returns two hashes. The second should be used to hash the message itself and // performs any needed preprocessing. -func hashForSignature(hashFunc crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) { +func hashForSignature(hashFunc crypto.Hash, sigType packet.SignatureType, sigSalt []byte) (hash.Hash, hash.Hash, error) { if _, ok := algorithm.HashToHashIdWithSha1(hashFunc); !ok { return nil, nil, errors.UnsupportedError("unsupported hash function") } @@ -313,14 +329,19 @@ func hashForSignature(hashFunc crypto.Hash, sigType packet.SignatureType) (hash. return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashFunc))) } h := hashFunc.New() - + if sigSalt != nil { + h.Write(sigSalt) + } + wrappedHash, err := wrapHashForSignature(h, sigType) + if err != nil { + return nil, nil, err + } switch sigType { case packet.SigTypeBinary: - return h, h, nil + return h, wrappedHash, nil case packet.SigTypeText: - return h, NewCanonicalTextHash(h), nil + return h, wrappedHash, nil } - return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType))) } @@ -328,16 +349,22 @@ func hashForSignature(hashFunc crypto.Hash, sigType packet.SignatureType) (hash. // it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger // MDC checks. type checkReader struct { - md *MessageDetails + md *MessageDetails + checked bool } -func (cr checkReader) Read(buf []byte) (int, error) { +func (cr *checkReader) Read(buf []byte) (int, error) { n, sensitiveParsingError := cr.md.LiteralData.Body.Read(buf) if sensitiveParsingError == io.EOF { + if cr.checked { + // Only check once + return n, io.EOF + } mdcErr := cr.md.decrypted.Close() if mdcErr != nil { return n, mdcErr } + cr.checked = true return n, io.EOF } @@ -428,14 +455,19 @@ func (scr *signatureCheckReader) Read(buf []byte) (int, error) { // if any, and a possible signature verification error. // If the signer isn't known, ErrUnknownIssuer is returned. func VerifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) { - var expectedHashes []crypto.Hash - return verifyDetachedSignature(keyring, signed, signature, expectedHashes, config) + return verifyDetachedSignature(keyring, signed, signature, nil, nil, false, config) } // VerifyDetachedSignatureAndHash performs the same actions as // VerifyDetachedSignature and checks that the expected hash functions were used. func VerifyDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) { - return verifyDetachedSignature(keyring, signed, signature, expectedHashes, config) + return verifyDetachedSignature(keyring, signed, signature, expectedHashes, nil, true, config) +} + +// VerifyDetachedSignatureAndSaltedHash performs the same actions as +// VerifyDetachedSignature and checks that the expected hash functions and salts were used. +func VerifyDetachedSignatureAndSaltedHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, expectedSaltedHashes []*packet.SaltedHashSpecifier, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) { + return verifyDetachedSignature(keyring, signed, signature, expectedHashes, expectedSaltedHashes, true, config) } // CheckDetachedSignature takes a signed file and a detached signature and @@ -443,25 +475,31 @@ func VerifyDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader // signature verification error. If the signer isn't known, // ErrUnknownIssuer is returned. func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) { - var expectedHashes []crypto.Hash - return CheckDetachedSignatureAndHash(keyring, signed, signature, expectedHashes, config) + _, signer, err = verifyDetachedSignature(keyring, signed, signature, nil, nil, false, config) + return +} + +// CheckDetachedSignatureAndSaltedHash performs the same actions as +// CheckDetachedSignature and checks that the expected hash functions or salted hash functions were used. +func CheckDetachedSignatureAndSaltedHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, expectedSaltedHashes []*packet.SaltedHashSpecifier, config *packet.Config) (signer *Entity, err error) { + _, signer, err = verifyDetachedSignature(keyring, signed, signature, expectedHashes, expectedSaltedHashes, true, config) + return } // CheckDetachedSignatureAndHash performs the same actions as // CheckDetachedSignature and checks that the expected hash functions were used. func CheckDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (signer *Entity, err error) { - _, signer, err = verifyDetachedSignature(keyring, signed, signature, expectedHashes, config) + _, signer, err = verifyDetachedSignature(keyring, signed, signature, expectedHashes, nil, true, config) return } -func verifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) { +func verifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, expectedSaltedHashes []*packet.SaltedHashSpecifier, checkHashes bool, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) { var issuerKeyId uint64 var hashFunc crypto.Hash var sigType packet.SignatureType var keys []Key var p packet.Packet - expectedHashesLen := len(expectedHashes) packets := packet.NewReader(signature) for { p, err = packets.Next() @@ -483,16 +521,30 @@ func verifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, expec issuerKeyId = *sig.IssuerKeyId hashFunc = sig.Hash sigType = sig.SigType + if checkHashes { + matchFound := false + if sig.Version == 6 { + // check for salted hashes + for _, expectedSaltedHash := range expectedSaltedHashes { + if hashFunc == expectedSaltedHash.Hash && bytes.Equal(sig.Salt(), expectedSaltedHash.Salt) { + matchFound = true + break + } + } - for i, expectedHash := range expectedHashes { - if hashFunc == expectedHash { - break + } else { + // check for hashes + for _, expectedHash := range expectedHashes { + if hashFunc == expectedHash { + matchFound = true + break + } + } } - if i+1 == expectedHashesLen { - return nil, nil, errors.StructuralError("hash algorithm mismatch with cleartext message headers") + if !matchFound { + return nil, nil, errors.StructuralError("hash algorithm or salt mismatch with cleartext message headers") } } - keys = keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign) if len(keys) > 0 { break @@ -503,7 +555,11 @@ func verifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, expec panic("unreachable") } - h, wrappedHash, err := hashForSignature(hashFunc, sigType) + h, err := sig.PrepareVerify() + if err != nil { + return nil, nil, err + } + wrappedHash, err := wrapHashForSignature(h, sigType) if err != nil { return nil, nil, err } @@ -534,30 +590,28 @@ func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader, } // checkSignatureDetails returns an error if: -// - The signature (or one of the binding signatures mentioned below) -// has a unknown critical notation data subpacket -// - The primary key of the signing entity is revoked -// The signature was signed by a subkey and: +// - The signature (or one of the binding signatures mentioned below) +// has a unknown critical notation data subpacket +// - The primary key of the signing entity is revoked +// - The primary identity is revoked +// - The signature is expired +// - The primary key of the signing entity is expired according to the +// primary identity binding signature +// +// ... or, if the signature was signed by a subkey and: // - The signing subkey is revoked -// - The primary identity is revoked -// - The signature is expired -// - The primary key of the signing entity is expired according to the -// primary identity binding signature -// The signature was signed by a subkey and: // - The signing subkey is expired according to the subkey binding signature // - The signing subkey binding signature is expired // - The signing subkey cross-signature is expired +// // NOTE: The order of these checks is important, as the caller may choose to // ignore ErrSignatureExpired or ErrKeyExpired errors, but should never // ignore any other errors. -// TODO: Also return an error if: -// - The primary key is expired according to a direct-key signature -// - (For V5 keys only:) The direct-key signature (exists and) is expired func checkSignatureDetails(key *Key, signature *packet.Signature, config *packet.Config) error { now := config.Now() - primaryIdentity := key.Entity.PrimaryIdentity() + primarySelfSignature, primaryIdentity := key.Entity.PrimarySelfSignature() signedBySubKey := key.PublicKey != key.Entity.PrimaryKey - sigsToCheck := []*packet.Signature{ signature, primaryIdentity.SelfSignature } + sigsToCheck := []*packet.Signature{signature, primarySelfSignature} if signedBySubKey { sigsToCheck = append(sigsToCheck, key.SelfSignature, key.SelfSignature.EmbeddedSignature) } @@ -570,10 +624,10 @@ func checkSignatureDetails(key *Key, signature *packet.Signature, config *packet } if key.Entity.Revoked(now) || // primary key is revoked (signedBySubKey && key.Revoked(now)) || // subkey is revoked - primaryIdentity.Revoked(now) { // primary identity is revoked + (primaryIdentity != nil && primaryIdentity.Revoked(now)) { // primary identity is revoked for v4 return errors.ErrKeyRevoked } - if key.Entity.PrimaryKey.KeyExpired(primaryIdentity.SelfSignature, now) { // primary key is expired + if key.Entity.PrimaryKey.KeyExpired(primarySelfSignature, now) { // primary key is expired return errors.ErrKeyExpired } if signedBySubKey { diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/read_write_test_data.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/read_write_test_data.go index db6dad5c..670d6022 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/read_write_test_data.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/read_write_test_data.go @@ -26,6 +26,8 @@ const testKeys1And2PrivateHex = "9501d8044d3c5c10010400b1d13382944bd5aba23a43129 const dsaElGamalTestKeysHex = "9501e1044dfcb16a110400aa3e5c1a1f43dd28c2ffae8abf5cfce555ee874134d8ba0a0f7b868ce2214beddc74e5e1e21ded354a95d18acdaf69e5e342371a71fbb9093162e0c5f3427de413a7f2c157d83f5cd2f9d791256dc4f6f0e13f13c3302af27f2384075ab3021dff7a050e14854bbde0a1094174855fc02f0bae8e00a340d94a1f22b32e48485700a0cec672ac21258fb95f61de2ce1af74b2c4fa3e6703ff698edc9be22c02ae4d916e4fa223f819d46582c0516235848a77b577ea49018dcd5e9e15cff9dbb4663a1ae6dd7580fa40946d40c05f72814b0f88481207e6c0832c3bded4853ebba0a7e3bd8e8c66df33d5a537cd4acf946d1080e7a3dcea679cb2b11a72a33a2b6a9dc85f466ad2ddf4c3db6283fa645343286971e3dd700703fc0c4e290d45767f370831a90187e74e9972aae5bff488eeff7d620af0362bfb95c1a6c3413ab5d15a2e4139e5d07a54d72583914661ed6a87cce810be28a0aa8879a2dd39e52fb6fe800f4f181ac7e328f740cde3d09a05cecf9483e4cca4253e60d4429ffd679d9996a520012aad119878c941e3cf151459873bdfc2a9563472fe0303027a728f9feb3b864260a1babe83925ce794710cfd642ee4ae0e5b9d74cee49e9c67b6cd0ea5dfbb582132195a121356a1513e1bca73e5b80c58c7ccb4164453412f456c47616d616c2054657374204b65792031886204131102002205024dfcb16a021b03060b090807030206150802090a0b0416020301021e01021780000a091033af447ccd759b09fadd00a0b8fd6f5a790bad7e9f2dbb7632046dc4493588db009c087c6a9ba9f7f49fab221587a74788c00db4889ab00200009d0157044dfcb16a1004008dec3f9291205255ccff8c532318133a6840739dd68b03ba942676f9038612071447bf07d00d559c5c0875724ea16a4c774f80d8338b55fca691a0522e530e604215b467bbc9ccfd483a1da99d7bc2648b4318fdbd27766fc8bfad3fddb37c62b8ae7ccfe9577e9b8d1e77c1d417ed2c2ef02d52f4da11600d85d3229607943700030503ff506c94c87c8cab778e963b76cf63770f0a79bf48fb49d3b4e52234620fc9f7657f9f8d56c96a2b7c7826ae6b57ebb2221a3fe154b03b6637cea7e6d98e3e45d87cf8dc432f723d3d71f89c5192ac8d7290684d2c25ce55846a80c9a7823f6acd9bb29fa6cd71f20bc90eccfca20451d0c976e460e672b000df49466408d527affe0303027a728f9feb3b864260abd761730327bca2aaa4ea0525c175e92bf240682a0e83b226f97ecb2e935b62c9a133858ce31b271fa8eb41f6a1b3cd72a63025ce1a75ee4180dcc284884904181102000905024dfcb16a021b0c000a091033af447ccd759b09dd0b009e3c3e7296092c81bee5a19929462caaf2fff3ae26009e218c437a2340e7ea628149af1ec98ec091a43992b00200009501e1044dfcb1be1104009f61faa61aa43df75d128cbe53de528c4aec49ce9360c992e70c77072ad5623de0a3a6212771b66b39a30dad6781799e92608316900518ec01184a85d872365b7d2ba4bacfb5882ea3c2473d3750dc6178cc1cf82147fb58caa28b28e9f12f6d1efcb0534abed644156c91cca4ab78834268495160b2400bc422beb37d237c2300a0cac94911b6d493bda1e1fbc6feeca7cb7421d34b03fe22cec6ccb39675bb7b94a335c2b7be888fd3906a1125f33301d8aa6ec6ee6878f46f73961c8d57a3e9544d8ef2a2cbfd4d52da665b1266928cfe4cb347a58c412815f3b2d2369dec04b41ac9a71cc9547426d5ab941cccf3b18575637ccfb42df1a802df3cfe0a999f9e7109331170e3a221991bf868543960f8c816c28097e503fe319db10fb98049f3a57d7c80c420da66d56f3644371631fad3f0ff4040a19a4fedc2d07727a1b27576f75a4d28c47d8246f27071e12d7a8de62aad216ddbae6aa02efd6b8a3e2818cda48526549791ab277e447b3a36c57cefe9b592f5eab73959743fcc8e83cbefec03a329b55018b53eec196765ae40ef9e20521a603c551efe0303020950d53a146bf9c66034d00c23130cce95576a2ff78016ca471276e8227fb30b1ffbd92e61804fb0c3eff9e30b1a826ee8f3e4730b4d86273ca977b4164453412f456c47616d616c2054657374204b65792032886204131102002205024dfcb1be021b03060b090807030206150802090a0b0416020301021e01021780000a0910a86bf526325b21b22bd9009e34511620415c974750a20df5cb56b182f3b48e6600a0a9466cb1a1305a84953445f77d461593f1d42bc1b00200009d0157044dfcb1be1004009565a951da1ee87119d600c077198f1c1bceb0f7aa54552489298e41ff788fa8f0d43a69871f0f6f77ebdfb14a4260cf9fbeb65d5844b4272a1904dd95136d06c3da745dc46327dd44a0f16f60135914368c8039a34033862261806bb2c5ce1152e2840254697872c85441ccb7321431d75a747a4bfb1d2c66362b51ce76311700030503fc0ea76601c196768070b7365a200e6ddb09307f262d5f39eec467b5f5784e22abdf1aa49226f59ab37cb49969d8f5230ea65caf56015abda62604544ed526c5c522bf92bed178a078789f6c807b6d34885688024a5bed9e9f8c58d11d4b82487b44c5f470c5606806a0443b79cadb45e0f897a561a53f724e5349b9267c75ca17fe0303020950d53a146bf9c660bc5f4ce8f072465e2d2466434320c1e712272fafc20e342fe7608101580fa1a1a367e60486a7cd1246b7ef5586cf5e10b32762b710a30144f12dd17dd4884904181102000905024dfcb1be021b0c000a0910a86bf526325b21b2904c00a0b2b66b4b39ccffda1d10f3ea8d58f827e30a8b8e009f4255b2d8112a184e40cde43a34e8655ca7809370b0020000" +const ed25519wX25519Key = "c54b0663877fe31b00000020f94da7bb48d60a61e567706a6587d0331999bb9d891a08242ead84543df895a3001972817b12be707e8d5f586ce61361201d344eb266a2c82fde6835762b65b0b7c2b1061f1b0a00000042058263877fe3030b090705150a0e080c021600029b03021e09222106cb186c4f0609a697e4d52dfa6c722b0c1f1e27c18a56708f6525ec27bad9acc905270902070200000000ad2820103e2d7d227ec0e6d7ce4471db36bfc97083253690271498a7ef0576c07faae14585b3b903b0127ec4fda2f023045a2ec76bcb4f9571a9651e14aee1137a1d668442c88f951e33c4ffd33fb9a17d511eed758fc6d9cc50cb5fd793b2039d5804c74b0663877fe319000000208693248367f9e5015db922f8f48095dda784987f2d5985b12fbad16caf5e4435004d600a4f794d44775c57a26e0feefed558e9afffd6ad0d582d57fb2ba2dcedb8c29b06181b0a0000002c050263877fe322a106cb186c4f0609a697e4d52dfa6c722b0c1f1e27c18a56708f6525ec27bad9acc9021b0c00000000defa20a6e9186d9d5935fc8fe56314cdb527486a5a5120f9b762a235a729f039010a56b89c658568341fbef3b894e9834ad9bc72afae2f4c9c47a43855e65f1cb0a3f77bbc5f61085c1f8249fe4e7ca59af5f0bcee9398e0fa8d76e522e1d8ab42bb0d" + const signedMessageHex = "a3019bc0cbccc0c4b8d8b74ee2108fe16ec6d3ca490cbe362d3f8333d3f352531472538b8b13d353b97232f352158c20943157c71c16064626063656269052062e4e01987e9b6fccff4b7df3a34c534b23e679cbec3bc0f8f6e64dfb4b55fe3f8efa9ce110ddb5cd79faf1d753c51aecfa669f7e7aa043436596cccc3359cb7dd6bbe9ecaa69e5989d9e57209571edc0b2fa7f57b9b79a64ee6e99ce1371395fee92fec2796f7b15a77c386ff668ee27f6d38f0baa6c438b561657377bf6acff3c5947befd7bf4c196252f1d6e5c524d0300" const signedTextMessageHex = "a3019bc0cbccc8c4b8d8b74ee2108fe16ec6d36a250cbece0c178233d3f352531472538b8b13d35379b97232f352158ca0b4312f57c71c1646462606365626906a062e4e019811591798ff99bf8afee860b0d8a8c2a85c3387e3bcf0bb3b17987f2bbcfab2aa526d930cbfd3d98757184df3995c9f3e7790e36e3e9779f06089d4c64e9e47dd6202cb6e9bc73c5d11bb59fbaf89d22d8dc7cf199ddf17af96e77c5f65f9bbed56f427bd8db7af37f6c9984bf9385efaf5f184f986fb3e6adb0ecfe35bbf92d16a7aa2a344fb0bc52fb7624f0200" @@ -160,18 +162,78 @@ TcIYl5/Uyoi+FOvPLcNw4hOv2nwUzSSVAw== =IiS2 -----END PGP PRIVATE KEY BLOCK-----` -// Generated with the above private key -const v5PrivKeyMsg = `-----BEGIN PGP MESSAGE----- -Version: OpenPGP.js v4.10.7 -Comment: https://openpgpjs.org +// See OpenPGP crypto refresh Section A.3. +const v6PrivKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB +exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ +BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh +RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe +7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/ +LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG +GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE +M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr +k0mXubZvyl4GBg== +-----END PGP PRIVATE KEY BLOCK-----` + +// See OpenPGP crypto refresh merge request: +// https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/304 +const v6PrivKeyMsg = `-----BEGIN PGP MESSAGE----- + +wV0GIQYSyD8ecG9jCP4VGkF3Q6HwM3kOk+mXhIjR2zeNqZMIhRmHzxjV8bU/gXzO +WgBM85PMiVi93AZfJfhK9QmxfdNnZBjeo1VDeVZheQHgaVf7yopqR6W1FT6NOrfS +aQIHAgZhZBZTW+CwcW1g4FKlbExAf56zaw76/prQoN+bAzxpohup69LA7JW/Vp0l +yZnuSj3hcFj0DfqLTGgr4/u717J+sPWbtQBfgMfG9AOIwwrUBqsFE9zW+f1zdlYo +bhF30A+IitsxxA== +-----END PGP MESSAGE-----` + +// See OpenPGP crypto refresh merge request: +// https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/305 +const v6PrivKeyInlineSignMsg = `-----BEGIN PGP MESSAGE----- -xA0DAQoWGTR7yYckZAIByxF1B21zZy50eHRfbIGSdGVzdMJ3BQEWCgAGBQJf -bIGSACMiIQUZNHvJhyRkAl+Z3z7C4AAO2YhIkuH3s+pMlACRWVabVDQvAP9G -y29VPonFXqi2zKkpZrvyvZxg+n5e8Nt9wNbuxeCd3QD/TtO2s+JvjrE4Siwv -UQdl5MlBka1QSNbMq2Bz7XwNPg4= -=6lbM +wV0GIQYSyD8ecG9jCP4VGkF3Q6HwM3kOk+mXhIjR2zeNqZMIhRmHzxjV8bU/gXzO +WgBM85PMiVi93AZfJfhK9QmxfdNnZBjeo1VDeVZheQHgaVf7yopqR6W1FT6NOrfS +aQIHAgZhZBZTW+CwcW1g4FKlbExAf56zaw76/prQoN+bAzxpohup69LA7JW/Vp0l +yZnuSj3hcFj0DfqLTGgr4/u717J+sPWbtQBfgMfG9AOIwwrUBqsFE9zW+f1zdlYo +bhF30A+IitsxxA== -----END PGP MESSAGE-----` +// See https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/274 +// decryption password: "correct horse battery staple" +const v6ArgonSealedPrivKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xYIGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laP9JgkC +FARdb9ccngltHraRe25uHuyuAQQVtKipJ0+r5jL4dacGWSAheCWPpITYiyfyIOPS +3gIDyg8f7strd1OB4+LZsUhcIjOMpVHgmiY/IutJkulneoBYwrEGHxsKAAAAQgWC +Y4d/4wMLCQcFFQoOCAwCFgACmwMCHgkiIQbLGGxPBgmml+TVLfpscisMHx4nwYpW +cI9lJewnutmsyQUnCQIHAgAAAACtKCAQPi19In7A5tfORHHbNr/JcIMlNpAnFJin +7wV2wH+q4UWFs7kDsBJ+xP2i8CMEWi7Ha8tPlXGpZR4UruETeh1mhELIj5UeM8T/ +0z+5oX1RHu11j8bZzFDLX9eTsgOdWATHggZjh3/jGQAAACCGkySDZ/nlAV25Ivj0 +gJXdp4SYfy1ZhbEvutFsr15ENf0mCQIUBA5hhGgp2oaavg6mFUXcFMwBBBUuE8qf +9Ock+xwusd+GAglBr5LVyr/lup3xxQvHXFSjjA2haXfoN6xUGRdDEHI6+uevKjVR +v5oAxgu7eJpaXNjCmwYYGwoAAAAsBYJjh3/jApsMIiEGyxhsTwYJppfk1S36bHIr +DB8eJ8GKVnCPZSXsJ7rZrMkAAAAABAEgpukYbZ1ZNfyP5WMUzbUnSGpaUSD5t2Ki +Nacp8DkBClZRa2c3AMQzSDXa9jGhYzxjzVb5scHDzTkjyRZWRdTq8U6L4da+/+Kt +ruh8m7Xo2ehSSFyWRSuTSZe5tm/KXgYG +-----END PGP PRIVATE KEY BLOCK-----` + +const v4Key25519 = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUkEZB3qzRto01j2k2pwN5ux9w70stPinAdXULLr20CRW7U7h2GSeACch0M+ +qzQg8yjFQ8VBvu3uwgKH9senoHmj72lLSCLTmhFKzQR0ZXN0wogEEBsIAD4F +gmQd6s0ECwkHCAmQIf45+TuC+xMDFQgKBBYAAgECGQECmwMCHgEWIQSWEzMi +jJUHvyIbVKIh/jn5O4L7EwAAUhaHNlgudvxARdPPETUzVgjuWi+YIz8w1xIb +lHQMvIrbe2sGCQIethpWofd0x7DHuv/ciHg+EoxJ/Td6h4pWtIoKx0kEZB3q +zRm4CyA7quliq7yx08AoOqHTuuCgvpkSdEhpp3pEyejQOgBo0p6ywIiLPllY +0t+jpNspHpAGfXID6oqjpYuJw3AfVRBlwnQEGBsIACoFgmQd6s0JkCH+Ofk7 +gvsTApsMFiEElhMzIoyVB78iG1SiIf45+TuC+xMAAGgQuN9G73446ykvJ/mL +sCZ7zGFId2gBd1EnG0FTC4npfOKpck0X8dngByrCxU8LDSfvjsEp/xDAiKsQ +aU71tdtNBQ== +=e7jT +-----END PGP PRIVATE KEY BLOCK-----` + const keyWithExpiredCrossSig = `-----BEGIN PGP PUBLIC KEY BLOCK----- xsDNBF2lnPIBDAC5cL9PQoQLTMuhjbYvb4Ncuuo0bfmgPRFywX53jPhoFf4Zg6mv @@ -272,3 +334,124 @@ AtNTq6ihLMD5v1d82ZC7tNatdlDMGWnIdvEMCv2GZcuIqDQ9rXWs49e7tq1NncLY hz3tYjKhoFTKEIq3y3Pp =h/aX -----END PGP PUBLIC KEY BLOCK-----` + +const keyv5Test = `-----BEGIN PGP PRIVATE KEY BLOCK----- +Comment: Bob's OpenPGP Transferable Secret Key + +lQVYBF2lnPIBDAC5cL9PQoQLTMuhjbYvb4Ncuuo0bfmgPRFywX53jPhoFf4Zg6mv +/seOXpgecTdOcVttfzC8ycIKrt3aQTiwOG/ctaR4Bk/t6ayNFfdUNxHWk4WCKzdz +/56fW2O0F23qIRd8UUJp5IIlN4RDdRCtdhVQIAuzvp2oVy/LaS2kxQoKvph/5pQ/ +5whqsyroEWDJoSV0yOb25B/iwk/pLUFoyhDG9bj0kIzDxrEqW+7Ba8nocQlecMF3 +X5KMN5kp2zraLv9dlBBpWW43XktjcCZgMy20SouraVma8Je/ECwUWYUiAZxLIlMv +9CurEOtxUw6N3RdOtLmYZS9uEnn5y1UkF88o8Nku890uk6BrewFzJyLAx5wRZ4F0 +qV/yq36UWQ0JB/AUGhHVPdFf6pl6eaxBwT5GXvbBUibtf8YI2og5RsgTWtXfU7eb +SGXrl5ZMpbA6mbfhd0R8aPxWfmDWiIOhBufhMCvUHh1sApMKVZnvIff9/0Dca3wb +vLIwa3T4CyshfT0AEQEAAQAL/RZqbJW2IqQDCnJi4Ozm++gPqBPiX1RhTWSjwxfM +cJKUZfzLj414rMKm6Jh1cwwGY9jekROhB9WmwaaKT8HtcIgrZNAlYzANGRCM4TLK +3VskxfSwKKna8l+s+mZglqbAjUg3wmFuf9Tj2xcUZYmyRm1DEmcN2ZzpvRtHgX7z +Wn1mAKUlSDJZSQks0zjuMNbupcpyJokdlkUg2+wBznBOTKzgMxVNC9b2g5/tMPUs +hGGWmF1UH+7AHMTaS6dlmr2ZBIyogdnfUqdNg5sZwsxSNrbglKP4sqe7X61uEAIQ +bD7rT3LonLbhkrj3I8wilUD8usIwt5IecoHhd9HziqZjRCc1BUBkboUEoyedbDV4 +i4qfsFZ6CEWoLuD5pW7dEp0M+WeuHXO164Rc+LnH6i1VQrpb1Okl4qO6ejIpIjBI +1t3GshtUu/mwGBBxs60KBX5g77mFQ9lLCRj8lSYqOsHRKBhUp4qM869VA+fD0BRP +fqPT0I9IH4Oa/A3jYJcg622GwQYA1LhnP208Waf6PkQSJ6kyr8ymY1yVh9VBE/g6 +fRDYA+pkqKnw9wfH2Qho3ysAA+OmVOX8Hldg+Pc0Zs0e5pCavb0En8iFLvTA0Q2E +LR5rLue9uD7aFuKFU/VdcddY9Ww/vo4k5p/tVGp7F8RYCFn9rSjIWbfvvZi1q5Tx ++akoZbga+4qQ4WYzB/obdX6SCmi6BndcQ1QdjCCQU6gpYx0MddVERbIp9+2SXDyL +hpxjSyz+RGsZi/9UAshT4txP4+MZBgDfK3ZqtW+h2/eMRxkANqOJpxSjMyLO/FXN +WxzTDYeWtHNYiAlOwlQZEPOydZFty9IVzzNFQCIUCGjQ/nNyhw7adSgUk3+BXEx/ +MyJPYY0BYuhLxLYcrfQ9nrhaVKxRJj25SVHj2ASsiwGJRZW4CC3uw40OYxfKEvNC +mer/VxM3kg8qqGf9KUzJ1dVdAvjyx2Hz6jY2qWCyRQ6IMjWHyd43C4r3jxooYKUC +YnstRQyb/gCSKahveSEjo07CiXMr88UGALwzEr3npFAsPW3osGaFLj49y1oRe11E +he9gCHFm+fuzbXrWmdPjYU5/ZdqdojzDqfu4ThfnipknpVUM1o6MQqkjM896FHm8 +zbKVFSMhEP6DPHSCexMFrrSgN03PdwHTO6iBaIBBFqmGY01tmJ03SxvSpiBPON9P +NVvy/6UZFedTq8A07OUAxO62YUSNtT5pmK2vzs3SAZJmbFbMh+NN204TRI72GlqT +t5hcfkuv8hrmwPS/ZR6q312mKQ6w/1pqO9qitCFCb2IgQmFiYmFnZSA8Ym9iQG9w +ZW5wZ3AuZXhhbXBsZT6JAc4EEwEKADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgEC +F4AWIQTRpm4aI7GCyZgPeIz7/MgqAV5zMAUCXaWe+gAKCRD7/MgqAV5zMG9sC/9U +2T3RrqEbw533FPNfEflhEVRIZ8gDXKM8hU6cqqEzCmzZT6xYTe6sv4y+PJBGXJFX +yhj0g6FDkSyboM5litOcTupURObVqMgA/Y4UKERznm4fzzH9qek85c4ljtLyNufe +doL2pp3vkGtn7eD0QFRaLLmnxPKQ/TlZKdLE1G3u8Uot8QHicaR6GnAdc5UXQJE3 +BiV7jZuDyWmZ1cUNwJkKL6oRtp+ZNDOQCrLNLecKHcgCqrpjSQG5oouba1I1Q6Vl +sP44dhA1nkmLHtxlTOzpeHj4jnk1FaXmyasurrrI5CgU/L2Oi39DGKTH/A/cywDN +4ZplIQ9zR8enkbXquUZvFDe+Xz+6xRXtb5MwQyWODB3nHw85HocLwRoIN9WdQEI+ +L8a/56AuOwhs8llkSuiITjR7r9SgKJC2WlAHl7E8lhJ3VDW3ELC56KH308d6mwOG +ZRAqIAKzM1T5FGjMBhq7ZV0eqdEntBh3EcOIfj2M8rg1MzJv+0mHZOIjByawikad +BVgEXaWc8gEMANYwv1xsYyunXYK0X1vY/rP1NNPvhLyLIE7NpK90YNBj+xS1ldGD +bUdZqZeef2xJe8gMQg05DoD1DF3GipZ0Ies65beh+d5hegb7N4pzh0LzrBrVNHar +29b5ExdI7i4iYD5TO6Vr/qTUOiAN/byqELEzAb+L+b2DVz/RoCm4PIp1DU9ewcc2 +WB38Ofqut3nLYA5tqJ9XvAiEQme+qAVcM3ZFcaMt4I4dXhDZZNg+D9LiTWcxdUPB +leu8iwDRjAgyAhPzpFp+nWoqWA81uIiULWD1Fj+IVoY3ZvgivoYOiEFBJ9lbb4te +g9m5UT/AaVDTWuHzbspVlbiVe+qyB77C2daWzNyx6UYBPLOo4r0t0c91kbNE5lgj +Z7xz6los0N1U8vq91EFSeQJoSQ62XWavYmlCLmdNT6BNfgh4icLsT7Vr1QMX9jzn +JtTPxdXytSdHvpSpULsqJ016l0dtmONcK3z9mj5N5z0k1tg1AH970TGYOe2aUcSx +IRDMXDOPyzEfjwARAQABAAv9F2CwsjS+Sjh1M1vegJbZjei4gF1HHpEM0K0PSXsp +SfVvpR4AoSJ4He6CXSMWg0ot8XKtDuZoV9jnJaES5UL9pMAD7JwIOqZm/DYVJM5h +OASCh1c356/wSbFbzRHPtUdZO9Q30WFNJM5pHbCJPjtNoRmRGkf71RxtvHBzy7np +Ga+W6U/NVKHw0i0CYwMI0YlKDakYW3Pm+QL+gHZFvngGweTod0f9l2VLLAmeQR/c ++EZs7lNumhuZ8mXcwhUc9JQIhOkpO+wreDysEFkAcsKbkQP3UDUsA1gFx9pbMzT0 +tr1oZq2a4QBtxShHzP/ph7KLpN+6qtjks3xB/yjTgaGmtrwM8tSe0wD1RwXS+/1o +BHpXTnQ7TfeOGUAu4KCoOQLv6ELpKWbRBLWuiPwMdbGpvVFALO8+kvKAg9/r+/ny +zM2GQHY+J3Jh5JxPiJnHfXNZjIKLbFbIPdSKNyJBuazXW8xIa//mEHMI5OcvsZBK +clAIp7LXzjEjKXIwHwDcTn9pBgDpdOKTHOtJ3JUKx0rWVsDH6wq6iKV/FTVSY5jl +zN+puOEsskF1Lfxn9JsJihAVO3yNsp6RvkKtyNlFazaCVKtDAmkjoh60XNxcNRqr +gCnwdpbgdHP6v/hvZY54ZaJjz6L2e8unNEkYLxDt8cmAyGPgH2XgL7giHIp9jrsQ +aS381gnYwNX6wE1aEikgtY91nqJjwPlibF9avSyYQoMtEqM/1UjTjB2KdD/MitK5 +fP0VpvuXpNYZedmyq4UOMwdkiNMGAOrfmOeT0olgLrTMT5H97Cn3Yxbk13uXHNu/ +ZUZZNe8s+QtuLfUlKAJtLEUutN33TlWQY522FV0m17S+b80xJib3yZVJteVurrh5 +HSWHAM+zghQAvCesg5CLXa2dNMkTCmZKgCBvfDLZuZbjFwnwCI6u/NhOY9egKuUf +SA/je/RXaT8m5VxLYMxwqQXKApzD87fv0tLPlVIEvjEsaf992tFEFSNPcG1l/jpd +5AVXw6kKuf85UkJtYR1x2MkQDrqY1QX/XMw00kt8y9kMZUre19aCArcmor+hDhRJ +E3Gt4QJrD9z/bICESw4b4z2DbgD/Xz9IXsA/r9cKiM1h5QMtXvuhyfVeM01enhxM +GbOH3gjqqGNKysx0UODGEwr6AV9hAd8RWXMchJLaExK9J5SRawSg671ObAU24SdY +vMQ9Z4kAQ2+1ReUZzf3ogSMRZtMT+d18gT6L90/y+APZIaoArLPhebIAGq39HLmJ +26x3z0WAgrpA1kNsjXEXkoiZGPLKIGoe3hqJAbYEGAEKACAWIQTRpm4aI7GCyZgP +eIz7/MgqAV5zMAUCXaWc8gIbDAAKCRD7/MgqAV5zMOn/C/9ugt+HZIwX308zI+QX +c5vDLReuzmJ3ieE0DMO/uNSC+K1XEioSIZP91HeZJ2kbT9nn9fuReuoff0T0Dief +rbwcIQQHFFkrqSp1K3VWmUGp2JrUsXFVdjy/fkBIjTd7c5boWljv/6wAsSfiv2V0 +JSM8EFU6TYXxswGjFVfc6X97tJNeIrXL+mpSmPPqy2bztcCCHkWS5lNLWQw+R7Vg +71Fe6yBSNVrqC2/imYG2J9zlowjx1XU63Wdgqp2Wxt0l8OmsB/W80S1fRF5G4SDH +s9HXglXXqPsBRZJYfP+VStm9L5P/sKjCcX6WtZR7yS6G8zj/X767MLK/djANvpPd +NVniEke6hM3CNBXYPAMhQBMWhCulcoz+0lxi8L34rMN+Dsbma96psdUrn7uLaB91 +6we0CTfF8qqm7BsVAgalon/UUiuMY80U3ueoj3okiSTiHIjD/YtpXSPioC8nMng7 +xqAY9Bwizt4FWgXuLm1a4+So4V9j1TRCXd12Uc2l2RNmgDE= +=miES +-----END PGP PRIVATE KEY BLOCK----- +` + +const certv5Test = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +lGEFXJH05BYAAAAtCSsGAQQB2kcPAQEHQFhZlVcVVtwf+21xNQPX+ecMJJBL0MPd +fj75iux+my8QAAAAAAAiAQCHZ1SnSUmWqxEsoI6facIVZQu6mph3cBFzzTvcm5lA +Ng5ctBhlbW1hLmdvbGRtYW5AZXhhbXBsZS5uZXSIlgUTFggASCIhBRk0e8mHJGQC +X5nfPsLgAA7ZiEiS4fez6kyUAJFZVptUBQJckfTkAhsDBQsJCAcCAyICAQYVCgkI +CwIEFgIDAQIeBwIXgAAA9cAA/jiR3yMsZMeEQ40u6uzEoXa6UXeV/S3wwJAXRJy9 +M8s0AP9vuL/7AyTfFXwwzSjDnYmzS0qAhbLDQ643N+MXGBJ2BZxmBVyR9OQSAAAA +MgorBgEEAZdVAQUBAQdA+nysrzml2UCweAqtpDuncSPlvrcBWKU0yfU0YvYWWAoD +AQgHAAAAAAAiAP9OdAPppjU1WwpqjIItkxr+VPQRT8Zm/Riw7U3F6v3OiBFHiHoF +GBYIACwiIQUZNHvJhyRkAl+Z3z7C4AAO2YhIkuH3s+pMlACRWVabVAUCXJH05AIb +DAAAOSQBAP4BOOIR/sGLNMOfeb5fPs/02QMieoiSjIBnijhob2U5AQC+RtOHCHx7 +TcIYl5/Uyoi+FOvPLcNw4hOv2nwUzSSVAw== +=IiS2 +-----END PGP PRIVATE KEY BLOCK----- +` + +const msgv5Test = `-----BEGIN PGP MESSAGE----- + +wcDMA3wvqk35PDeyAQv+PcQiLsoYTH30nJYQh3j3cJaO2+jErtVCrIQRIU0+ +rmgMddERYST4A9mA0DQIiTI4FQ0Lp440D3BWCgpq3LlNWewGzduaWwym5rN6 +cwHz5ccDqOcqbd9X0GXXGy/ZH/ljSgzuVMIytMAXKdF/vrRrVgH/+I7cxvm9 +HwnhjMN5dF0j4aEt996H2T7cbtzSr2GN9SWGW8Gyu7I8Zx73hgrGUI7gDiJB +Afaff+P6hfkkHSGOItr94dde8J/7AUF4VEwwxdVVPvsNEFyvv6gRIbYtOCa2 +6RE6h1V/QTxW2O7zZgzWALrE2ui0oaYr9QuqQSssd9CdgExLfdPbI+3/ZAnE +v31Idzpk3/6ILiakYHtXkElPXvf46mCNpobty8ysT34irF+fy3C1p3oGwAsx +5VDV9OSFU6z5U+UPbSPYAy9rkc5ZssuIKxCER2oTvZ2L8Q5cfUvEUiJtRGGn +CJlHrVDdp3FssKv2tlKgLkvxJLyoOjuEkj44H1qRk+D02FzmmUT/0sAHAYYx +lTir6mjHeLpcGjn4waUuWIAJyph8SxUexP60bic0L0NBa6Qp5SxxijKsPIDb +FPHxWwfJSDZRrgUyYT7089YFB/ZM4FHyH9TZcnxn0f0xIB7NS6YNDsxzN2zT +EVEYf+De4qT/dQTsdww78Chtcv9JY9r2kDm77dk2MUGHL2j7n8jasbLtgA7h +pn2DMIWLrGamMLWRmlwslolKr1sMV5x8w+5Ias6C33iBMl9phkg42an0gYmc +byVJHvLO/XErtC+GNIJeMg== +=liRq +-----END PGP MESSAGE----- +` diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go index d0b85834..f4f5c783 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go @@ -3,7 +3,8 @@ // license that can be found in the LICENSE file. // Package s2k implements the various OpenPGP string-to-key transforms as -// specified in RFC 4800 section 3.7.1. +// specified in RFC 4800 section 3.7.1, and Argon2 specified in +// draft-ietf-openpgp-crypto-refresh-08 section 3.7.1.4. package s2k // import "github.com/ProtonMail/go-crypto/openpgp/s2k" import ( @@ -14,70 +15,47 @@ import ( "github.com/ProtonMail/go-crypto/openpgp/errors" "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm" + "golang.org/x/crypto/argon2" ) -// Config collects configuration parameters for s2k key-stretching -// transformations. A nil *Config is valid and results in all default -// values. Currently, Config is used only by the Serialize function in -// this package. -type Config struct { - // S2KMode is the mode of s2k function. - // It can be 0 (simple), 1(salted), 3(iterated) - // 2(reserved) 100-110(private/experimental). - S2KMode uint8 - // Hash is the default hash function to be used. If - // nil, SHA256 is used. - Hash crypto.Hash - // S2KCount is only used for symmetric encryption. It - // determines the strength of the passphrase stretching when - // the said passphrase is hashed to produce a key. S2KCount - // should be between 65536 and 65011712, inclusive. If Config - // is nil or S2KCount is 0, the value 16777216 used. Not all - // values in the above range can be represented. S2KCount will - // be rounded up to the next representable value if it cannot - // be encoded exactly. See RFC 4880 Section 3.7.1.3. - S2KCount int -} +type Mode uint8 + +// Defines the default S2KMode constants +// +// 0 (simple), 1(salted), 3(iterated), 4(argon2) +const ( + SimpleS2K Mode = 0 + SaltedS2K Mode = 1 + IteratedSaltedS2K Mode = 3 + Argon2S2K Mode = 4 + GnuS2K Mode = 101 +) + +const Argon2SaltSize int = 16 // Params contains all the parameters of the s2k packet type Params struct { // mode is the mode of s2k function. // It can be 0 (simple), 1(salted), 3(iterated) // 2(reserved) 100-110(private/experimental). - mode uint8 + mode Mode // hashId is the ID of the hash function used in any of the modes hashId byte - // salt is a byte array to use as a salt in hashing process - salt []byte + // salt is a byte array to use as a salt in hashing process or argon2 + saltBytes [Argon2SaltSize]byte // countByte is used to determine how many rounds of hashing are to // be performed in s2k mode 3. See RFC 4880 Section 3.7.1.3. countByte byte -} - -func (c *Config) hash() crypto.Hash { - if c == nil || uint(c.Hash) == 0 { - return crypto.SHA256 - } - - return c.Hash -} - -// EncodedCount get encoded count -func (c *Config) EncodedCount() uint8 { - if c == nil || c.S2KCount == 0 { - return 224 // The common case. Corresponding to 16777216 - } - - i := c.S2KCount - - switch { - case i < 65536: - i = 65536 - case i > 65011712: - i = 65011712 - } - - return encodeCount(i) + // passes is a parameter in Argon2 to determine the number of iterations + // See RFC the crypto refresh Section 3.7.1.4. + passes byte + // parallelism is a parameter in Argon2 to determine the degree of paralellism + // See RFC the crypto refresh Section 3.7.1.4. + parallelism byte + // memoryExp is a parameter in Argon2 to determine the memory usage + // i.e., 2 ** memoryExp kibibytes + // See RFC the crypto refresh Section 3.7.1.4. + memoryExp byte } // encodeCount converts an iterative "count" in the range 1024 to @@ -106,6 +84,31 @@ func decodeCount(c uint8) int { return (16 + int(c&15)) << (uint32(c>>4) + 6) } +// encodeMemory converts the Argon2 "memory" in the range parallelism*8 to +// 2**31, inclusive, to an encoded memory. The return value is the +// octet that is actually stored in the GPG file. encodeMemory panics +// if is not in the above range +// See OpenPGP crypto refresh Section 3.7.1.4. +func encodeMemory(memory uint32, parallelism uint8) uint8 { + if memory < (8*uint32(parallelism)) || memory > uint32(2147483648) { + panic("Memory argument memory is outside the required range") + } + + for exp := 3; exp < 31; exp++ { + compare := decodeMemory(uint8(exp)) + if compare >= memory { + return uint8(exp) + } + } + + return 31 +} + +// decodeMemory computes the decoded memory in kibibytes as 2**memoryExponent +func decodeMemory(memoryExponent uint8) uint32 { + return uint32(1) << memoryExponent +} + // Simple writes to out the result of computing the Simple S2K function (RFC // 4880, section 3.7.1.1) using the given hash and input passphrase. func Simple(out []byte, h hash.Hash, in []byte) { @@ -169,25 +172,53 @@ func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int) { } } +// Argon2 writes to out the key derived from the password (in) with the Argon2 +// function (the crypto refresh, section 3.7.1.4) +func Argon2(out []byte, in []byte, salt []byte, passes uint8, paralellism uint8, memoryExp uint8) { + key := argon2.IDKey(in, salt, uint32(passes), decodeMemory(memoryExp), paralellism, uint32(len(out))) + copy(out[:], key) +} + // Generate generates valid parameters from given configuration. -// It will enforce salted + hashed s2k method +// It will enforce the Iterated and Salted or Argon2 S2K method. func Generate(rand io.Reader, c *Config) (*Params, error) { - hashId, ok := algorithm.HashToHashId(c.Hash) - if !ok { - return nil, errors.UnsupportedError("no such hash") - } + var params *Params + if c != nil && c.Mode() == Argon2S2K { + // handle Argon2 case + argonConfig := c.Argon2() + params = &Params{ + mode: Argon2S2K, + passes: argonConfig.Passes(), + parallelism: argonConfig.Parallelism(), + memoryExp: argonConfig.EncodedMemory(), + } + } else if c != nil && c.PassphraseIsHighEntropy && c.Mode() == SaltedS2K { // Allow SaltedS2K if PassphraseIsHighEntropy + hashId, ok := algorithm.HashToHashId(c.hash()) + if !ok { + return nil, errors.UnsupportedError("no such hash") + } - params := &Params{ - mode: 3, // Enforce iterared + salted method - hashId: hashId, - salt: make([]byte, 8), - countByte: c.EncodedCount(), + params = &Params{ + mode: SaltedS2K, + hashId: hashId, + } + } else { // Enforce IteratedSaltedS2K method otherwise + hashId, ok := algorithm.HashToHashId(c.hash()) + if !ok { + return nil, errors.UnsupportedError("no such hash") + } + if c != nil { + c.S2KMode = IteratedSaltedS2K + } + params = &Params{ + mode: IteratedSaltedS2K, + hashId: hashId, + countByte: c.EncodedCount(), + } } - - if _, err := io.ReadFull(rand, params.salt); err != nil { + if _, err := io.ReadFull(rand, params.salt()); err != nil { return nil, err } - return params, nil } @@ -207,45 +238,60 @@ func Parse(r io.Reader) (f func(out, in []byte), err error) { // ParseIntoParams reads a binary specification for a string-to-key // transformation from r and returns a struct describing the s2k parameters. func ParseIntoParams(r io.Reader) (params *Params, err error) { - var buf [9]byte + var buf [Argon2SaltSize + 3]byte - _, err = io.ReadFull(r, buf[:2]) + _, err = io.ReadFull(r, buf[:1]) if err != nil { return } params = &Params{ - mode: buf[0], - hashId: buf[1], + mode: Mode(buf[0]), } switch params.mode { - case 0: - return params, nil - case 1: - _, err = io.ReadFull(r, buf[:8]) + case SimpleS2K: + _, err = io.ReadFull(r, buf[:1]) if err != nil { return nil, err } - - params.salt = buf[:8] + params.hashId = buf[0] return params, nil - case 3: + case SaltedS2K: _, err = io.ReadFull(r, buf[:9]) if err != nil { return nil, err } - - params.salt = buf[:8] - params.countByte = buf[8] + params.hashId = buf[0] + copy(params.salt(), buf[1:9]) + return params, nil + case IteratedSaltedS2K: + _, err = io.ReadFull(r, buf[:10]) + if err != nil { + return nil, err + } + params.hashId = buf[0] + copy(params.salt(), buf[1:9]) + params.countByte = buf[9] + return params, nil + case Argon2S2K: + _, err = io.ReadFull(r, buf[:Argon2SaltSize+3]) + if err != nil { + return nil, err + } + copy(params.salt(), buf[:Argon2SaltSize]) + params.passes = buf[Argon2SaltSize] + params.parallelism = buf[Argon2SaltSize+1] + params.memoryExp = buf[Argon2SaltSize+2] return params, nil - case 101: + case GnuS2K: // This is a GNU extension. See // https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=doc/DETAILS;h=fe55ae16ab4e26d8356dc574c9e8bc935e71aef1;hb=23191d7851eae2217ecdac6484349849a24fd94a#l1109 - if _, err = io.ReadFull(r, buf[:4]); err != nil { + if _, err = io.ReadFull(r, buf[:5]); err != nil { return nil, err } - if buf[0] == 'G' && buf[1] == 'N' && buf[2] == 'U' && buf[3] == 1 { + params.hashId = buf[0] + if buf[1] == 'G' && buf[2] == 'N' && buf[3] == 'U' && buf[4] == 1 { return params, nil } return nil, errors.UnsupportedError("GNU S2K extension") @@ -255,39 +301,59 @@ func ParseIntoParams(r io.Reader) (params *Params, err error) { } func (params *Params) Dummy() bool { - return params != nil && params.mode == 101 + return params != nil && params.mode == GnuS2K +} + +func (params *Params) salt() []byte { + switch params.mode { + case SaltedS2K, IteratedSaltedS2K: + return params.saltBytes[:8] + case Argon2S2K: + return params.saltBytes[:Argon2SaltSize] + default: + return nil + } } func (params *Params) Function() (f func(out, in []byte), err error) { if params.Dummy() { return nil, errors.ErrDummyPrivateKey("dummy key found") } - hashObj, ok := algorithm.HashIdToHashWithSha1(params.hashId) - if !ok { - return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(params.hashId))) - } - if !hashObj.Available() { - return nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashObj))) + var hashObj crypto.Hash + if params.mode != Argon2S2K { + var ok bool + hashObj, ok = algorithm.HashIdToHashWithSha1(params.hashId) + if !ok { + return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(params.hashId))) + } + if !hashObj.Available() { + return nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashObj))) + } } switch params.mode { - case 0: + case SimpleS2K: f := func(out, in []byte) { Simple(out, hashObj.New(), in) } return f, nil - case 1: + case SaltedS2K: f := func(out, in []byte) { - Salted(out, hashObj.New(), in, params.salt) + Salted(out, hashObj.New(), in, params.salt()) } return f, nil - case 3: + case IteratedSaltedS2K: f := func(out, in []byte) { - Iterated(out, hashObj.New(), in, params.salt, decodeCount(params.countByte)) + Iterated(out, hashObj.New(), in, params.salt(), decodeCount(params.countByte)) } + return f, nil + case Argon2S2K: + f := func(out, in []byte) { + Argon2(out, in, params.salt(), params.passes, params.parallelism, params.memoryExp) + } return f, nil } @@ -295,23 +361,28 @@ func (params *Params) Function() (f func(out, in []byte), err error) { } func (params *Params) Serialize(w io.Writer) (err error) { - if _, err = w.Write([]byte{params.mode}); err != nil { + if _, err = w.Write([]byte{uint8(params.mode)}); err != nil { return } - if _, err = w.Write([]byte{params.hashId}); err != nil { - return + if params.mode != Argon2S2K { + if _, err = w.Write([]byte{params.hashId}); err != nil { + return + } } if params.Dummy() { _, err = w.Write(append([]byte("GNU"), 1)) return } if params.mode > 0 { - if _, err = w.Write(params.salt); err != nil { + if _, err = w.Write(params.salt()); err != nil { return } - if params.mode == 3 { + if params.mode == IteratedSaltedS2K { _, err = w.Write([]byte{params.countByte}) } + if params.mode == Argon2S2K { + _, err = w.Write([]byte{params.passes, params.parallelism, params.memoryExp}) + } } return } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go new file mode 100644 index 00000000..616e0d12 --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go @@ -0,0 +1,26 @@ +package s2k + +// Cache stores keys derived with s2k functions from one passphrase +// to avoid recomputation if multiple items are encrypted with +// the same parameters. +type Cache map[Params][]byte + +// GetOrComputeDerivedKey tries to retrieve the key +// for the given s2k parameters from the cache. +// If there is no hit, it derives the key with the s2k function from the passphrase, +// updates the cache, and returns the key. +func (c *Cache) GetOrComputeDerivedKey(passphrase []byte, params *Params, expectedKeySize int) ([]byte, error) { + key, found := (*c)[*params] + if !found || len(key) != expectedKeySize { + var err error + derivedKey := make([]byte, expectedKeySize) + s2k, err := params.Function() + if err != nil { + return nil, err + } + s2k(derivedKey, passphrase) + (*c)[*params] = key + return derivedKey, nil + } + return key, nil +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go new file mode 100644 index 00000000..b93db1ab --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go @@ -0,0 +1,129 @@ +package s2k + +import "crypto" + +// Config collects configuration parameters for s2k key-stretching +// transformations. A nil *Config is valid and results in all default +// values. +type Config struct { + // S2K (String to Key) mode, used for key derivation in the context of secret key encryption + // and passphrase-encrypted data. Either s2k.Argon2S2K or s2k.IteratedSaltedS2K may be used. + // If the passphrase is a high-entropy key, indicated by setting PassphraseIsHighEntropy to true, + // s2k.SaltedS2K can also be used. + // Note: Argon2 is the strongest option but not all OpenPGP implementations are compatible with it + //(pending standardisation). + // 0 (simple), 1(salted), 3(iterated), 4(argon2) + // 2(reserved) 100-110(private/experimental). + S2KMode Mode + // Only relevant if S2KMode is not set to s2k.Argon2S2K. + // Hash is the default hash function to be used. If + // nil, SHA256 is used. + Hash crypto.Hash + // Argon2 parameters for S2K (String to Key). + // Only relevant if S2KMode is set to s2k.Argon2S2K. + // If nil, default parameters are used. + // For more details on the choice of parameters, see https://tools.ietf.org/html/rfc9106#section-4. + Argon2Config *Argon2Config + // Only relevant if S2KMode is set to s2k.IteratedSaltedS2K. + // Iteration count for Iterated S2K (String to Key). It + // determines the strength of the passphrase stretching when + // the said passphrase is hashed to produce a key. S2KCount + // should be between 65536 and 65011712, inclusive. If Config + // is nil or S2KCount is 0, the value 16777216 used. Not all + // values in the above range can be represented. S2KCount will + // be rounded up to the next representable value if it cannot + // be encoded exactly. When set, it is strongly encrouraged to + // use a value that is at least 65536. See RFC 4880 Section + // 3.7.1.3. + S2KCount int + // Indicates whether the passphrase passed by the application is a + // high-entropy key (e.g. it's randomly generated or derived from + // another passphrase using a strong key derivation function). + // When true, allows the S2KMode to be s2k.SaltedS2K. + // When the passphrase is not a high-entropy key, using SaltedS2K is + // insecure, and not allowed by draft-ietf-openpgp-crypto-refresh-08. + PassphraseIsHighEntropy bool +} + +// Argon2Config stores the Argon2 parameters +// A nil *Argon2Config is valid and results in all default +type Argon2Config struct { + NumberOfPasses uint8 + DegreeOfParallelism uint8 + // Memory specifies the desired Argon2 memory usage in kibibytes. + // For example memory=64*1024 sets the memory cost to ~64 MB. + Memory uint32 +} + +func (c *Config) Mode() Mode { + if c == nil { + return IteratedSaltedS2K + } + return c.S2KMode +} + +func (c *Config) hash() crypto.Hash { + if c == nil || uint(c.Hash) == 0 { + return crypto.SHA256 + } + + return c.Hash +} + +func (c *Config) Argon2() *Argon2Config { + if c == nil || c.Argon2Config == nil { + return nil + } + return c.Argon2Config +} + +// EncodedCount get encoded count +func (c *Config) EncodedCount() uint8 { + if c == nil || c.S2KCount == 0 { + return 224 // The common case. Corresponding to 16777216 + } + + i := c.S2KCount + + switch { + case i < 65536: + i = 65536 + case i > 65011712: + i = 65011712 + } + + return encodeCount(i) +} + +func (c *Argon2Config) Passes() uint8 { + if c == nil || c.NumberOfPasses == 0 { + return 3 + } + return c.NumberOfPasses +} + +func (c *Argon2Config) Parallelism() uint8 { + if c == nil || c.DegreeOfParallelism == 0 { + return 4 + } + return c.DegreeOfParallelism +} + +func (c *Argon2Config) EncodedMemory() uint8 { + if c == nil || c.Memory == 0 { + return 16 // 64 MiB of RAM + } + + memory := c.Memory + lowerBound := uint32(c.Parallelism()) * 8 + upperBound := uint32(2147483648) + + switch { + case memory < lowerBound: + memory = lowerBound + case memory > upperBound: + memory = upperBound + } + + return encodeMemory(memory, c.Parallelism()) +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go index b3ae72f7..0db5526c 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go @@ -76,7 +76,11 @@ func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.S sig := createSignaturePacket(signingKey.PublicKey, sigType, config) - h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType) + h, err := sig.PrepareSign(config) + if err != nil { + return + } + wrappedHash, err := wrapHashForSignature(h, sig.SigType) if err != nil { return } @@ -123,7 +127,7 @@ func SymmetricallyEncrypt(ciphertext io.Writer, passphrase []byte, hints *FileHi var w io.WriteCloser cipherSuite := packet.CipherSuite{ Cipher: config.Cipher(), - Mode: config.AEAD().Mode(), + Mode: config.AEAD().Mode(), } w, err = packet.SerializeSymmetricallyEncrypted(ciphertext, config.Cipher(), config.AEAD() != nil, cipherSuite, key, config) if err != nil { @@ -275,14 +279,28 @@ func writeAndSign(payload io.WriteCloser, candidateHashes []uint8, signed *Entit return nil, errors.InvalidArgumentError("cannot encrypt because no candidate hash functions are compiled in. (Wanted " + name + " in this case.)") } + var salt []byte if signer != nil { + var opsVersion = 3 + if signer.Version == 6 { + opsVersion = signer.Version + } ops := &packet.OnePassSignature{ + Version: opsVersion, SigType: sigType, Hash: hash, PubKeyAlgo: signer.PubKeyAlgo, KeyId: signer.KeyId, IsLast: true, } + if opsVersion == 6 { + ops.KeyFingerprint = signer.Fingerprint + salt, err = packet.SignatureSaltForHash(hash, config.Random()) + if err != nil { + return nil, err + } + ops.Salt = salt + } if err := ops.Serialize(payload); err != nil { return nil, err } @@ -310,19 +328,19 @@ func writeAndSign(payload io.WriteCloser, candidateHashes []uint8, signed *Entit } if signer != nil { - h, wrappedHash, err := hashForSignature(hash, sigType) + h, wrappedHash, err := hashForSignature(hash, sigType, salt) if err != nil { return nil, err } metadata := &packet.LiteralData{ - Format: 't', + Format: 'u', FileName: hints.FileName, Time: epochSeconds, } if hints.IsBinary { metadata.Format = 'b' } - return signatureWriter{payload, literalData, hash, wrappedHash, h, signer, sigType, config, metadata}, nil + return signatureWriter{payload, literalData, hash, wrappedHash, h, salt, signer, sigType, config, metadata}, nil } return literalData, nil } @@ -380,15 +398,19 @@ func encrypt(keyWriter io.Writer, dataWriter io.Writer, to []*Entity, signed *En return nil, errors.InvalidArgumentError("cannot encrypt a message to key id " + strconv.FormatUint(to[i].PrimaryKey.KeyId, 16) + " because it has no valid encryption keys") } - sig := to[i].PrimaryIdentity().SelfSignature - if sig.SEIPDv2 == false { + primarySelfSignature, _ := to[i].PrimarySelfSignature() + if primarySelfSignature == nil { + return nil, errors.InvalidArgumentError("entity without a self-signature") + } + + if !primarySelfSignature.SEIPDv2 { aeadSupported = false } - candidateCiphers = intersectPreferences(candidateCiphers, sig.PreferredSymmetric) - candidateHashes = intersectPreferences(candidateHashes, sig.PreferredHash) - candidateCipherSuites = intersectCipherSuites(candidateCipherSuites, sig.PreferredCipherSuites) - candidateCompression = intersectPreferences(candidateCompression, sig.PreferredCompression) + candidateCiphers = intersectPreferences(candidateCiphers, primarySelfSignature.PreferredSymmetric) + candidateHashes = intersectPreferences(candidateHashes, primarySelfSignature.PreferredHash) + candidateCipherSuites = intersectCipherSuites(candidateCipherSuites, primarySelfSignature.PreferredCipherSuites) + candidateCompression = intersectPreferences(candidateCompression, primarySelfSignature.PreferredCompression) } // In the event that the intersection of supported algorithms is empty we use the ones @@ -409,7 +431,7 @@ func encrypt(keyWriter io.Writer, dataWriter io.Writer, to []*Entity, signed *En cipher := packet.CipherFunction(candidateCiphers[0]) aeadCipherSuite := packet.CipherSuite{ Cipher: packet.CipherFunction(candidateCipherSuites[0][0]), - Mode: packet.AEADMode(candidateCipherSuites[0][1]), + Mode: packet.AEADMode(candidateCipherSuites[0][1]), } // If the cipher specified by config is a candidate, we'll use that. @@ -428,7 +450,7 @@ func encrypt(keyWriter io.Writer, dataWriter io.Writer, to []*Entity, signed *En } for _, key := range encryptKeys { - if err := packet.SerializeEncryptedKey(keyWriter, key.PublicKey, cipher, symKey, config); err != nil { + if err := packet.SerializeEncryptedKeyAEAD(keyWriter, key.PublicKey, cipher, aeadSupported, symKey, config); err != nil { return nil, err } } @@ -436,8 +458,8 @@ func encrypt(keyWriter io.Writer, dataWriter io.Writer, to []*Entity, signed *En var payload io.WriteCloser payload, err = packet.SerializeSymmetricallyEncrypted(dataWriter, cipher, aeadSupported, aeadCipherSuite, symKey, config) if err != nil { - return - } + return + } payload, err = handleCompression(payload, candidateCompression, config) if err != nil { @@ -465,13 +487,17 @@ func Sign(output io.Writer, signed *Entity, hints *FileHints, config *packet.Con hashToHashId(crypto.SHA3_512), } defaultHashes := candidateHashes[0:1] - preferredHashes := signed.PrimaryIdentity().SelfSignature.PreferredHash + primarySelfSignature, _ := signed.PrimarySelfSignature() + if primarySelfSignature == nil { + return nil, errors.StructuralError("signed entity has no self-signature") + } + preferredHashes := primarySelfSignature.PreferredHash if len(preferredHashes) == 0 { preferredHashes = defaultHashes } candidateHashes = intersectPreferences(candidateHashes, preferredHashes) if len(candidateHashes) == 0 { - return nil, errors.InvalidArgumentError("cannot sign because signing key shares no common algorithms with candidate hashes") + return nil, errors.StructuralError("cannot sign because signing key shares no common algorithms with candidate hashes") } return writeAndSign(noOpCloser{output}, candidateHashes, signed, hints, packet.SigTypeBinary, config) @@ -486,6 +512,7 @@ type signatureWriter struct { hashType crypto.Hash wrappedHash hash.Hash h hash.Hash + salt []byte // v6 only signer *packet.PrivateKey sigType packet.SignatureType config *packet.Config @@ -509,6 +536,10 @@ func (s signatureWriter) Close() error { sig.Hash = s.hashType sig.Metadata = s.metadata + if err := sig.SetSalt(s.salt); err != nil { + return err + } + if err := sig.Sign(s.h, s.signer, s.config); err != nil { return err } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/x25519/x25519.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/x25519/x25519.go new file mode 100644 index 00000000..38afcc74 --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/x25519/x25519.go @@ -0,0 +1,221 @@ +package x25519 + +import ( + "crypto/sha256" + "crypto/subtle" + "io" + + "github.com/ProtonMail/go-crypto/openpgp/aes/keywrap" + "github.com/ProtonMail/go-crypto/openpgp/errors" + x25519lib "github.com/cloudflare/circl/dh/x25519" + "golang.org/x/crypto/hkdf" +) + +const ( + hkdfInfo = "OpenPGP X25519" + aes128KeySize = 16 + // The size of a public or private key in bytes. + KeySize = x25519lib.Size +) + +type PublicKey struct { + // Point represents the encoded elliptic curve point of the public key. + Point []byte +} + +type PrivateKey struct { + PublicKey + // Secret represents the secret of the private key. + Secret []byte +} + +// NewPrivateKey creates a new empty private key including the public key. +func NewPrivateKey(key PublicKey) *PrivateKey { + return &PrivateKey{ + PublicKey: key, + } +} + +// Validate validates that the provided public key matches the private key. +func Validate(pk *PrivateKey) (err error) { + var expectedPublicKey, privateKey x25519lib.Key + subtle.ConstantTimeCopy(1, privateKey[:], pk.Secret) + x25519lib.KeyGen(&expectedPublicKey, &privateKey) + if subtle.ConstantTimeCompare(expectedPublicKey[:], pk.PublicKey.Point) == 0 { + return errors.KeyInvalidError("x25519: invalid key") + } + return nil +} + +// GenerateKey generates a new x25519 key pair. +func GenerateKey(rand io.Reader) (*PrivateKey, error) { + var privateKey, publicKey x25519lib.Key + privateKeyOut := new(PrivateKey) + err := generateKey(rand, &privateKey, &publicKey) + if err != nil { + return nil, err + } + privateKeyOut.PublicKey.Point = publicKey[:] + privateKeyOut.Secret = privateKey[:] + return privateKeyOut, nil +} + +func generateKey(rand io.Reader, privateKey *x25519lib.Key, publicKey *x25519lib.Key) error { + maxRounds := 10 + isZero := true + for round := 0; isZero; round++ { + if round == maxRounds { + return errors.InvalidArgumentError("x25519: zero keys only, randomness source might be corrupt") + } + _, err := io.ReadFull(rand, privateKey[:]) + if err != nil { + return err + } + isZero = constantTimeIsZero(privateKey[:]) + } + x25519lib.KeyGen(publicKey, privateKey) + return nil +} + +// Encrypt encrypts a sessionKey with x25519 according to +// the OpenPGP crypto refresh specification section 5.1.6. The function assumes that the +// sessionKey has the correct format and padding according to the specification. +func Encrypt(rand io.Reader, publicKey *PublicKey, sessionKey []byte) (ephemeralPublicKey *PublicKey, encryptedSessionKey []byte, err error) { + var ephemeralPrivate, ephemeralPublic, staticPublic, shared x25519lib.Key + // Check that the input static public key has 32 bytes + if len(publicKey.Point) != KeySize { + err = errors.KeyInvalidError("x25519: the public key has the wrong size") + return + } + copy(staticPublic[:], publicKey.Point) + // Generate ephemeral keyPair + err = generateKey(rand, &ephemeralPrivate, &ephemeralPublic) + if err != nil { + return + } + // Compute shared key + ok := x25519lib.Shared(&shared, &ephemeralPrivate, &staticPublic) + if !ok { + err = errors.KeyInvalidError("x25519: the public key is a low order point") + return + } + // Derive the encryption key from the shared secret + encryptionKey := applyHKDF(ephemeralPublic[:], publicKey.Point[:], shared[:]) + ephemeralPublicKey = &PublicKey{ + Point: ephemeralPublic[:], + } + // Encrypt the sessionKey with aes key wrapping + encryptedSessionKey, err = keywrap.Wrap(encryptionKey, sessionKey) + return +} + +// Decrypt decrypts a session key stored in ciphertext with the provided x25519 +// private key and ephemeral public key. +func Decrypt(privateKey *PrivateKey, ephemeralPublicKey *PublicKey, ciphertext []byte) (encodedSessionKey []byte, err error) { + var ephemeralPublic, staticPrivate, shared x25519lib.Key + // Check that the input ephemeral public key has 32 bytes + if len(ephemeralPublicKey.Point) != KeySize { + err = errors.KeyInvalidError("x25519: the public key has the wrong size") + return + } + copy(ephemeralPublic[:], ephemeralPublicKey.Point) + subtle.ConstantTimeCopy(1, staticPrivate[:], privateKey.Secret) + // Compute shared key + ok := x25519lib.Shared(&shared, &staticPrivate, &ephemeralPublic) + if !ok { + err = errors.KeyInvalidError("x25519: the ephemeral public key is a low order point") + return + } + // Derive the encryption key from the shared secret + encryptionKey := applyHKDF(ephemeralPublicKey.Point[:], privateKey.PublicKey.Point[:], shared[:]) + // Decrypt the session key with aes key wrapping + encodedSessionKey, err = keywrap.Unwrap(encryptionKey, ciphertext) + return +} + +func applyHKDF(ephemeralPublicKey []byte, publicKey []byte, sharedSecret []byte) []byte { + inputKey := make([]byte, 3*KeySize) + // ephemeral public key | recipient public key | shared secret + subtle.ConstantTimeCopy(1, inputKey[:KeySize], ephemeralPublicKey) + subtle.ConstantTimeCopy(1, inputKey[KeySize:2*KeySize], publicKey) + subtle.ConstantTimeCopy(1, inputKey[2*KeySize:], sharedSecret) + hkdfReader := hkdf.New(sha256.New, inputKey, []byte{}, []byte(hkdfInfo)) + encryptionKey := make([]byte, aes128KeySize) + _, _ = io.ReadFull(hkdfReader, encryptionKey) + return encryptionKey +} + +func constantTimeIsZero(bytes []byte) bool { + isZero := byte(0) + for _, b := range bytes { + isZero |= b + } + return isZero == 0 +} + +// ENCODING/DECODING ciphertexts: + +// EncodeFieldsLength returns the length of the ciphertext encoding +// given the encrypted session key. +func EncodedFieldsLength(encryptedSessionKey []byte, v6 bool) int { + lenCipherFunction := 0 + if !v6 { + lenCipherFunction = 1 + } + return KeySize + 1 + len(encryptedSessionKey) + lenCipherFunction +} + +// EncodeField encodes x25519 session key encryption fields as +// ephemeral x25519 public key | follow byte length | cipherFunction (v3 only) | encryptedSessionKey +// and writes it to writer. +func EncodeFields(writer io.Writer, ephemeralPublicKey *PublicKey, encryptedSessionKey []byte, cipherFunction byte, v6 bool) (err error) { + lenAlgorithm := 0 + if !v6 { + lenAlgorithm = 1 + } + if _, err = writer.Write(ephemeralPublicKey.Point); err != nil { + return err + } + if _, err = writer.Write([]byte{byte(len(encryptedSessionKey) + lenAlgorithm)}); err != nil { + return err + } + if !v6 { + if _, err = writer.Write([]byte{cipherFunction}); err != nil { + return err + } + } + _, err = writer.Write(encryptedSessionKey) + return err +} + +// DecodeField decodes a x25519 session key encryption as +// ephemeral x25519 public key | follow byte length | cipherFunction (v3 only) | encryptedSessionKey. +func DecodeFields(reader io.Reader, v6 bool) (ephemeralPublicKey *PublicKey, encryptedSessionKey []byte, cipherFunction byte, err error) { + var buf [1]byte + ephemeralPublicKey = &PublicKey{ + Point: make([]byte, KeySize), + } + // 32 octets representing an ephemeral x25519 public key. + if _, err = io.ReadFull(reader, ephemeralPublicKey.Point); err != nil { + return nil, nil, 0, err + } + // A one-octet size of the following fields. + if _, err = io.ReadFull(reader, buf[:]); err != nil { + return nil, nil, 0, err + } + followingLen := buf[0] + // The one-octet algorithm identifier, if it was passed (in the case of a v3 PKESK packet). + if !v6 { + if _, err = io.ReadFull(reader, buf[:]); err != nil { + return nil, nil, 0, err + } + cipherFunction = buf[0] + followingLen -= 1 + } + // The encrypted session key. + encryptedSessionKey = make([]byte, followingLen) + if _, err = io.ReadFull(reader, encryptedSessionKey); err != nil { + return nil, nil, 0, err + } + return ephemeralPublicKey, encryptedSessionKey, cipherFunction, nil +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/x448/x448.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/x448/x448.go new file mode 100644 index 00000000..65a082da --- /dev/null +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/x448/x448.go @@ -0,0 +1,229 @@ +package x448 + +import ( + "crypto/sha512" + "crypto/subtle" + "io" + + "github.com/ProtonMail/go-crypto/openpgp/aes/keywrap" + "github.com/ProtonMail/go-crypto/openpgp/errors" + x448lib "github.com/cloudflare/circl/dh/x448" + "golang.org/x/crypto/hkdf" +) + +const ( + hkdfInfo = "OpenPGP X448" + aes256KeySize = 32 + // The size of a public or private key in bytes. + KeySize = x448lib.Size +) + +type PublicKey struct { + // Point represents the encoded elliptic curve point of the public key. + Point []byte +} + +type PrivateKey struct { + PublicKey + // Secret represents the secret of the private key. + Secret []byte +} + +// NewPrivateKey creates a new empty private key including the public key. +func NewPrivateKey(key PublicKey) *PrivateKey { + return &PrivateKey{ + PublicKey: key, + } +} + +// Validate validates that the provided public key matches +// the private key. +func Validate(pk *PrivateKey) (err error) { + var expectedPublicKey, privateKey x448lib.Key + subtle.ConstantTimeCopy(1, privateKey[:], pk.Secret) + x448lib.KeyGen(&expectedPublicKey, &privateKey) + if subtle.ConstantTimeCompare(expectedPublicKey[:], pk.PublicKey.Point) == 0 { + return errors.KeyInvalidError("x448: invalid key") + } + return nil +} + +// GenerateKey generates a new x448 key pair. +func GenerateKey(rand io.Reader) (*PrivateKey, error) { + var privateKey, publicKey x448lib.Key + privateKeyOut := new(PrivateKey) + err := generateKey(rand, &privateKey, &publicKey) + if err != nil { + return nil, err + } + privateKeyOut.PublicKey.Point = publicKey[:] + privateKeyOut.Secret = privateKey[:] + return privateKeyOut, nil +} + +func generateKey(rand io.Reader, privateKey *x448lib.Key, publicKey *x448lib.Key) error { + maxRounds := 10 + isZero := true + for round := 0; isZero; round++ { + if round == maxRounds { + return errors.InvalidArgumentError("x448: zero keys only, randomness source might be corrupt") + } + _, err := io.ReadFull(rand, privateKey[:]) + if err != nil { + return err + } + isZero = constantTimeIsZero(privateKey[:]) + } + x448lib.KeyGen(publicKey, privateKey) + return nil +} + +// Encrypt encrypts a sessionKey with x448 according to +// the OpenPGP crypto refresh specification section 5.1.7. The function assumes that the +// sessionKey has the correct format and padding according to the specification. +func Encrypt(rand io.Reader, publicKey *PublicKey, sessionKey []byte) (ephemeralPublicKey *PublicKey, encryptedSessionKey []byte, err error) { + var ephemeralPrivate, ephemeralPublic, staticPublic, shared x448lib.Key + // Check that the input static public key has 56 bytes. + if len(publicKey.Point) != KeySize { + err = errors.KeyInvalidError("x448: the public key has the wrong size") + return nil, nil, err + } + copy(staticPublic[:], publicKey.Point) + // Generate ephemeral keyPair. + if err = generateKey(rand, &ephemeralPrivate, &ephemeralPublic); err != nil { + return nil, nil, err + } + // Compute shared key. + ok := x448lib.Shared(&shared, &ephemeralPrivate, &staticPublic) + if !ok { + err = errors.KeyInvalidError("x448: the public key is a low order point") + return nil, nil, err + } + // Derive the encryption key from the shared secret. + encryptionKey := applyHKDF(ephemeralPublic[:], publicKey.Point[:], shared[:]) + ephemeralPublicKey = &PublicKey{ + Point: ephemeralPublic[:], + } + // Encrypt the sessionKey with aes key wrapping. + encryptedSessionKey, err = keywrap.Wrap(encryptionKey, sessionKey) + if err != nil { + return nil, nil, err + } + return ephemeralPublicKey, encryptedSessionKey, nil +} + +// Decrypt decrypts a session key stored in ciphertext with the provided x448 +// private key and ephemeral public key. +func Decrypt(privateKey *PrivateKey, ephemeralPublicKey *PublicKey, ciphertext []byte) (encodedSessionKey []byte, err error) { + var ephemeralPublic, staticPrivate, shared x448lib.Key + // Check that the input ephemeral public key has 56 bytes. + if len(ephemeralPublicKey.Point) != KeySize { + err = errors.KeyInvalidError("x448: the public key has the wrong size") + return nil, err + } + copy(ephemeralPublic[:], ephemeralPublicKey.Point) + subtle.ConstantTimeCopy(1, staticPrivate[:], privateKey.Secret) + // Compute shared key. + ok := x448lib.Shared(&shared, &staticPrivate, &ephemeralPublic) + if !ok { + err = errors.KeyInvalidError("x448: the ephemeral public key is a low order point") + return nil, err + } + // Derive the encryption key from the shared secret. + encryptionKey := applyHKDF(ephemeralPublicKey.Point[:], privateKey.PublicKey.Point[:], shared[:]) + // Decrypt the session key with aes key wrapping. + encodedSessionKey, err = keywrap.Unwrap(encryptionKey, ciphertext) + if err != nil { + return nil, err + } + return encodedSessionKey, nil +} + +func applyHKDF(ephemeralPublicKey []byte, publicKey []byte, sharedSecret []byte) []byte { + inputKey := make([]byte, 3*KeySize) + // ephemeral public key | recipient public key | shared secret. + subtle.ConstantTimeCopy(1, inputKey[:KeySize], ephemeralPublicKey) + subtle.ConstantTimeCopy(1, inputKey[KeySize:2*KeySize], publicKey) + subtle.ConstantTimeCopy(1, inputKey[2*KeySize:], sharedSecret) + hkdfReader := hkdf.New(sha512.New, inputKey, []byte{}, []byte(hkdfInfo)) + encryptionKey := make([]byte, aes256KeySize) + _, _ = io.ReadFull(hkdfReader, encryptionKey) + return encryptionKey +} + +func constantTimeIsZero(bytes []byte) bool { + isZero := byte(0) + for _, b := range bytes { + isZero |= b + } + return isZero == 0 +} + +// ENCODING/DECODING ciphertexts: + +// EncodeFieldsLength returns the length of the ciphertext encoding +// given the encrypted session key. +func EncodedFieldsLength(encryptedSessionKey []byte, v6 bool) int { + lenCipherFunction := 0 + if !v6 { + lenCipherFunction = 1 + } + return KeySize + 1 + len(encryptedSessionKey) + lenCipherFunction +} + +// EncodeField encodes x448 session key encryption fields as +// ephemeral x448 public key | follow byte length | cipherFunction (v3 only) | encryptedSessionKey +// and writes it to writer. +func EncodeFields(writer io.Writer, ephemeralPublicKey *PublicKey, encryptedSessionKey []byte, cipherFunction byte, v6 bool) (err error) { + lenAlgorithm := 0 + if !v6 { + lenAlgorithm = 1 + } + if _, err = writer.Write(ephemeralPublicKey.Point); err != nil { + return err + } + if _, err = writer.Write([]byte{byte(len(encryptedSessionKey) + lenAlgorithm)}); err != nil { + return err + } + if !v6 { + if _, err = writer.Write([]byte{cipherFunction}); err != nil { + return err + } + } + if _, err = writer.Write(encryptedSessionKey); err != nil { + return err + } + return nil +} + +// DecodeField decodes a x448 session key encryption as +// ephemeral x448 public key | follow byte length | cipherFunction (v3 only) | encryptedSessionKey. +func DecodeFields(reader io.Reader, v6 bool) (ephemeralPublicKey *PublicKey, encryptedSessionKey []byte, cipherFunction byte, err error) { + var buf [1]byte + ephemeralPublicKey = &PublicKey{ + Point: make([]byte, KeySize), + } + // 56 octets representing an ephemeral x448 public key. + if _, err = io.ReadFull(reader, ephemeralPublicKey.Point); err != nil { + return nil, nil, 0, err + } + // A one-octet size of the following fields. + if _, err = io.ReadFull(reader, buf[:]); err != nil { + return nil, nil, 0, err + } + followingLen := buf[0] + // The one-octet algorithm identifier, if it was passed (in the case of a v3 PKESK packet). + if !v6 { + if _, err = io.ReadFull(reader, buf[:]); err != nil { + return nil, nil, 0, err + } + cipherFunction = buf[0] + followingLen -= 1 + } + // The encrypted session key. + encryptedSessionKey = make([]byte, followingLen) + if _, err = io.ReadFull(reader, encryptedSessionKey); err != nil { + return nil, nil, 0, err + } + return ephemeralPublicKey, encryptedSessionKey, cipherFunction, nil +} diff --git a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/grapheme_clusters.go b/vendor/github.com/apparentlymart/go-textseg/v13/textseg/grapheme_clusters.go deleted file mode 100644 index 7ad1c799..00000000 --- a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/grapheme_clusters.go +++ /dev/null @@ -1,4138 +0,0 @@ -//line grapheme_clusters.rl:1 -package textseg - -import ( - "errors" - "unicode/utf8" -) - -// Generated from grapheme_clusters.rl. DO NOT EDIT - -//line grapheme_clusters.go:13 -var _graphclust_actions []byte = []byte{ - 0, 1, 0, 1, 4, 1, 10, 1, 11, - 1, 12, 1, 13, 1, 14, 1, 15, - 1, 16, 1, 17, 1, 18, 1, 19, - 1, 20, 1, 21, 1, 22, 2, 1, - 8, 2, 1, 9, 2, 2, 3, 2, - 5, 1, 3, 0, 1, 9, 3, 5, - 0, 1, 3, 5, 1, 6, 3, 5, - 1, 7, -} - -var _graphclust_key_offsets []int16 = []int16{ - 0, 0, 1, 3, 5, 7, 10, 15, - 17, 20, 28, 31, 33, 35, 38, 68, - 76, 78, 82, 85, 90, 95, 107, 119, - 127, 132, 142, 145, 152, 156, 164, 174, - 180, 188, 190, 198, 201, 203, 206, 208, - 215, 217, 225, 226, 248, 252, 258, 263, - 265, 269, 273, 275, 279, 281, 284, 288, - 290, 297, 299, 301, 305, 309, 313, 315, - 317, 325, 329, 334, 336, 338, 340, 341, - 343, 345, 347, 349, 364, 368, 370, 372, - 378, 382, 388, 390, 392, 396, 400, 402, - 406, 413, 418, 422, 425, 426, 430, 437, - 445, 446, 447, 449, 458, 460, 462, 464, - 466, 500, 504, 506, 510, 514, 517, 521, - 526, 529, 531, 537, 550, 552, 555, 557, - 561, 565, 567, 569, 571, 577, 580, 585, - 591, 594, 596, 600, 604, 611, 614, 620, - 622, 627, 629, 631, 634, 638, 641, 642, - 644, 650, 656, 662, 664, 668, 672, 677, - 682, 692, 694, 696, 698, 699, 701, 702, - 708, 710, 712, 712, 714, 721, 723, 725, - 727, 730, 735, 737, 740, 748, 751, 753, - 755, 758, 788, 796, 798, 802, 805, 810, - 815, 827, 839, 847, 852, 862, 865, 872, - 876, 884, 894, 900, 908, 910, 918, 921, - 923, 926, 928, 935, 937, 945, 946, 968, - 972, 978, 983, 985, 989, 993, 995, 999, - 1001, 1004, 1008, 1010, 1017, 1019, 1021, 1025, - 1029, 1033, 1035, 1037, 1045, 1049, 1054, 1056, - 1058, 1082, 1085, 1086, 1088, 1090, 1094, 1097, - 1098, 1103, 1104, 1107, 1110, 1116, 1118, 1122, - 1122, 1136, 1145, 1150, 1152, 1156, 1158, 1160, - 1161, 1163, 1166, 1169, 1171, 1173, 1188, 1192, - 1194, 1196, 1202, 1206, 1212, 1214, 1216, 1220, - 1224, 1226, 1230, 1237, 1242, 1246, 1249, 1250, - 1254, 1261, 1269, 1270, 1271, 1273, 1282, 1284, - 1286, 1288, 1290, 1324, 1328, 1330, 1334, 1338, - 1341, 1345, 1350, 1353, 1355, 1361, 1374, 1376, - 1379, 1381, 1385, 1389, 1391, 1393, 1395, 1401, - 1404, 1409, 1415, 1418, 1420, 1424, 1428, 1435, - 1438, 1444, 1446, 1451, 1453, 1455, 1458, 1462, - 1465, 1466, 1468, 1474, 1480, 1486, 1488, 1492, - 1496, 1501, 1506, 1516, 1518, 1520, 1522, 1562, - 1564, 1567, 1571, 1576, 1578, 1586, 1588, 1590, - 1592, 1594, 1596, 1598, 1600, 1604, 1608, 1612, - 1616, 1617, 1623, 1625, 1627, 1629, 1636, 1637, - 1639, 1644, 1646, 1648, 1650, 1653, 1658, 1660, - 1663, 1671, 1674, 1676, 1678, 1681, 1711, 1719, - 1721, 1725, 1728, 1733, 1738, 1750, 1762, 1770, - 1775, 1785, 1788, 1795, 1799, 1807, 1817, 1823, - 1831, 1833, 1841, 1844, 1846, 1849, 1851, 1858, - 1860, 1868, 1869, 1891, 1895, 1901, 1906, 1908, - 1912, 1916, 1918, 1922, 1924, 1927, 1931, 1933, - 1940, 1942, 1944, 1948, 1952, 1956, 1958, 1960, - 1968, 1972, 1977, 1979, 1981, 1983, 1984, 1986, - 1988, 1990, 1992, 2007, 2011, 2013, 2015, 2021, - 2025, 2031, 2033, 2035, 2039, 2043, 2045, 2049, - 2056, 2061, 2065, 2068, 2069, 2073, 2080, 2088, - 2089, 2090, 2092, 2101, 2103, 2105, 2107, 2109, - 2143, 2147, 2149, 2153, 2157, 2160, 2164, 2169, - 2172, 2174, 2180, 2193, 2195, 2198, 2200, 2204, - 2208, 2210, 2212, 2214, 2220, 2223, 2228, 2234, - 2237, 2239, 2243, 2247, 2254, 2257, 2263, 2265, - 2270, 2272, 2274, 2277, 2281, 2284, 2285, 2287, - 2293, 2299, 2305, 2307, 2311, 2315, 2320, 2325, - 2335, 2337, 2339, 2341, 2342, 2344, 2345, 2351, - 2353, 2355, 2355, 2357, 2363, 2365, 2367, 2369, - 2372, 2377, 2379, 2382, 2390, 2393, 2395, 2397, - 2400, 2430, 2438, 2440, 2444, 2447, 2452, 2457, - 2469, 2481, 2489, 2494, 2504, 2507, 2514, 2518, - 2526, 2536, 2542, 2550, 2552, 2560, 2563, 2565, - 2568, 2570, 2577, 2579, 2587, 2588, 2610, 2614, - 2620, 2625, 2627, 2631, 2635, 2637, 2641, 2643, - 2646, 2650, 2652, 2659, 2661, 2663, 2667, 2671, - 2675, 2677, 2679, 2687, 2691, 2696, 2698, 2700, - 2724, 2727, 2728, 2730, 2732, 2736, 2739, 2740, - 2745, 2746, 2749, 2752, 2758, 2760, 2764, 2764, - 2778, 2787, 2792, 2794, 2798, 2800, 2802, 2803, - 2805, 2808, 2811, 2813, 2815, 2830, 2834, 2836, - 2838, 2844, 2848, 2854, 2856, 2858, 2862, 2866, - 2868, 2872, 2879, 2884, 2888, 2891, 2892, 2896, - 2903, 2911, 2912, 2913, 2915, 2924, 2926, 2928, - 2930, 2932, 2966, 2970, 2972, 2976, 2980, 2983, - 2987, 2992, 2995, 2997, 3003, 3016, 3018, 3021, - 3023, 3027, 3031, 3033, 3035, 3037, 3043, 3046, - 3051, 3057, 3060, 3062, 3066, 3070, 3077, 3080, - 3086, 3088, 3093, 3095, 3097, 3100, 3104, 3107, - 3108, 3110, 3116, 3122, 3128, 3130, 3134, 3138, - 3143, 3148, 3158, 3160, 3162, 3164, 3204, 3206, - 3209, 3213, 3218, 3220, 3228, 3230, 3232, 3234, - 3236, 3238, 3240, 3242, 3246, 3250, 3254, 3258, - 3259, 3265, 3267, 3269, 3271, 3278, 3279, 3281, - 3287, 3290, 3293, 3297, 3300, 3303, 3310, 3312, - 3337, 3339, 3364, 3366, 3368, 3392, 3394, 3396, - 3397, 3399, 3401, 3403, 3409, 3411, 3443, 3447, - 3452, 3476, 3478, 3480, 3482, 3484, 3487, 3489, - 3491, 3495, 3495, 3551, 3607, 3638, 3643, 3647, - 3669, 3678, 3683, 3687, 3697, 3704, 3707, 3718, - 3721, 3728, 3734, 3738, 3744, 3760, 3775, 3784, - 3790, 3800, 3804, 3808, 3812, 3816, 3818, 3838, - 3844, 3849, 3851, 3853, 3856, 3858, 3860, 3864, - 3920, 3976, 4009, 4014, 4022, 4026, 4028, 4033, - 4040, 4050, 4053, 4056, 4062, 4065, 4068, 4071, - 4077, 4080, 4083, 4087, 4090, 4094, 4097, 4101, - 4143, 4150, 4158, 4167, 4171, 4178, 4180, 4182, - 4192, 4196, 4200, 4204, 4208, 4212, 4216, 4220, - 4226, 4236, 4244, 4249, 4252, 4254, 4257, 4262, - 4264, 4267, 4270, 4274, 4277, 4280, 4287, 4289, - 4291, 4293, 4295, 4298, 4303, 4305, 4308, 4316, - 4319, 4321, 4323, 4326, 4356, 4364, 4366, 4370, - 4373, 4378, 4383, 4395, 4407, 4415, 4420, 4430, - 4433, 4440, 4444, 4452, 4462, 4468, 4476, 4478, - 4486, 4489, 4491, 4494, 4496, 4503, 4505, 4513, - 4514, 4536, 4540, 4546, 4551, 4553, 4557, 4561, - 4563, 4567, 4569, 4572, 4576, 4578, 4585, 4587, - 4589, 4593, 4597, 4601, 4603, 4605, 4613, 4617, - 4622, 4624, 4626, 4650, 4653, 4654, 4656, 4658, - 4662, 4665, 4666, 4671, 4672, 4675, 4678, 4684, - 4686, 4690, 4690, 4704, 4713, 4718, 4720, 4724, - 4726, 4728, 4729, 4731, 4734, 4737, 4739, 4741, - 4756, 4760, 4762, 4764, 4770, 4774, 4780, 4782, - 4784, 4788, 4792, 4794, 4798, 4805, 4810, 4814, - 4817, 4818, 4822, 4829, 4837, 4838, 4839, 4841, - 4850, 4852, 4854, 4856, 4858, 4892, 4896, 4898, - 4902, 4906, 4909, 4913, 4918, 4921, 4923, 4929, - 4942, 4944, 4947, 4949, 4953, 4957, 4959, 4961, - 4963, 4969, 4972, 4977, 4983, 4986, 4988, 4992, - 4996, 5003, 5006, 5012, 5014, 5019, 5021, 5023, - 5026, 5030, 5033, 5034, 5036, 5042, 5048, 5054, - 5056, 5060, 5064, 5069, 5074, 5084, 5086, 5088, - 5090, 5130, 5132, 5135, 5139, 5144, 5146, 5154, - 5156, 5158, 5160, 5162, 5164, 5166, 5168, 5172, - 5176, 5180, 5184, 5185, 5191, 5193, 5195, 5197, - 5204, 5205, 5207, 5232, 5234, 5259, 5261, 5263, - 5287, 5289, 5291, 5292, 5294, 5296, 5298, 5304, - 5306, 5338, 5342, 5347, 5371, 5373, 5375, 5377, - 5379, 5382, 5384, 5386, 5390, 5390, 5446, 5502, - 5533, 5538, 5541, 5563, 5576, 5578, 5580, 5582, - 5585, 5590, 5592, 5595, 5603, 5606, 5608, 5610, - 5613, 5643, 5651, 5653, 5657, 5660, 5665, 5670, - 5682, 5694, 5702, 5707, 5717, 5720, 5727, 5731, - 5739, 5749, 5755, 5763, 5765, 5773, 5776, 5778, - 5781, 5783, 5790, 5792, 5800, 5801, 5823, 5827, - 5833, 5838, 5840, 5844, 5848, 5850, 5854, 5856, - 5859, 5863, 5865, 5872, 5874, 5876, 5880, 5884, - 5888, 5890, 5892, 5900, 5904, 5909, 5911, 5913, - 5915, 5916, 5918, 5920, 5922, 5924, 5939, 5943, - 5945, 5947, 5953, 5957, 5963, 5965, 5967, 5971, - 5975, 5977, 5981, 5988, 5993, 5997, 6000, 6001, - 6005, 6012, 6020, 6021, 6022, 6024, 6033, 6035, - 6037, 6039, 6041, 6075, 6079, 6081, 6085, 6089, - 6092, 6096, 6101, 6104, 6106, 6112, 6125, 6127, - 6130, 6132, 6136, 6140, 6142, 6144, 6146, 6152, - 6155, 6160, 6166, 6169, 6171, 6175, 6179, 6186, - 6189, 6195, 6197, 6202, 6204, 6206, 6209, 6213, - 6216, 6217, 6219, 6225, 6231, 6237, 6239, 6243, - 6247, 6252, 6257, 6267, 6269, 6271, 6273, 6274, - 6276, 6277, 6283, 6285, 6287, 6287, 6294, 6298, - 6308, 6315, 6318, 6329, 6332, 6339, 6345, 6349, - 6355, 6371, 6386, 6395, 6401, 6411, 6415, 6419, - 6423, 6427, 6429, 6449, 6455, 6460, 6462, 6464, - 6467, 6469, 6471, 6475, 6531, 6587, 6620, 6625, - 6633, 6637, 6640, 6647, 6654, 6664, 6667, 6670, - 6676, 6679, 6682, 6685, 6691, 6694, 6697, 6703, - 6706, 6712, 6715, 6721, 6763, 6770, 6778, 6787, - 6791, 6793, 6795, 6797, 6800, 6805, 6807, 6810, - 6818, 6821, 6823, 6825, 6828, 6858, 6866, 6868, - 6872, 6875, 6880, 6885, 6897, 6909, 6917, 6922, - 6932, 6935, 6942, 6946, 6954, 6964, 6970, 6978, - 6980, 6988, 6991, 6993, 6996, 6998, 7005, 7007, - 7015, 7016, 7038, 7042, 7048, 7053, 7055, 7059, - 7063, 7065, 7069, 7071, 7074, 7078, 7080, 7087, - 7089, 7091, 7095, 7099, 7103, 7105, 7107, 7115, - 7119, 7124, 7126, 7128, 7152, 7155, 7156, 7158, - 7160, 7164, 7167, 7168, 7173, 7174, 7177, 7180, - 7186, 7188, 7192, 7192, 7206, 7215, 7220, 7222, - 7226, 7228, 7230, 7231, 7233, 7236, 7239, 7241, - 7243, 7258, 7262, 7264, 7266, 7272, 7276, 7282, - 7284, 7286, 7290, 7294, 7296, 7300, 7307, 7312, - 7316, 7319, 7320, 7324, 7331, 7339, 7340, 7341, - 7343, 7352, 7354, 7356, 7358, 7360, 7394, 7398, - 7400, 7404, 7408, 7411, 7415, 7420, 7423, 7425, - 7431, 7444, 7446, 7449, 7451, 7455, 7459, 7461, - 7463, 7465, 7471, 7474, 7479, 7485, 7488, 7490, - 7494, 7498, 7505, 7508, 7514, 7516, 7521, 7523, - 7525, 7528, 7532, 7535, 7536, 7538, 7544, 7550, - 7556, 7558, 7562, 7566, 7571, 7576, 7586, 7588, - 7590, 7592, 7632, 7634, 7637, 7641, 7646, 7648, - 7656, 7658, 7660, 7662, 7664, 7666, 7668, 7670, - 7674, 7678, 7682, 7686, 7687, 7693, 7695, 7697, - 7699, 7706, 7707, 7709, 7716, 7718, 7720, 7730, - 7734, 7738, 7742, 7746, 7750, 7754, 7758, 7764, - 7774, 7782, 7787, 7790, 7792, 7795, 7804, 7808, - 7810, 7812, 7816, 7816, 7846, 7866, 7886, 7907, - 7930, 7950, 7970, 7991, 8014, 8035, 8056, 8077, - 8097, 8120, 8140, 8161, 8182, 8203, 8224, 8244, - 8264, 8284, -} - -var _graphclust_trans_keys []byte = []byte{ - 10, 128, 255, 176, 255, 131, 137, 191, - 145, 189, 135, 129, 130, 132, 133, 144, - 154, 176, 139, 159, 150, 156, 159, 164, - 167, 168, 170, 173, 145, 176, 255, 139, - 255, 166, 176, 189, 171, 179, 160, 161, - 163, 164, 165, 167, 169, 171, 173, 174, - 175, 176, 177, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, - 166, 170, 172, 178, 150, 153, 155, 163, - 165, 167, 169, 173, 153, 155, 147, 161, - 163, 255, 189, 132, 185, 144, 152, 161, - 164, 255, 188, 129, 131, 190, 255, 133, - 134, 137, 138, 142, 150, 152, 161, 164, - 189, 191, 255, 131, 134, 137, 138, 142, - 144, 146, 175, 178, 180, 182, 255, 134, - 138, 142, 161, 164, 185, 192, 255, 188, - 129, 131, 190, 191, 128, 132, 135, 136, - 139, 141, 149, 151, 162, 163, 130, 190, - 191, 151, 128, 130, 134, 136, 138, 141, - 128, 132, 190, 255, 133, 137, 142, 148, - 151, 161, 164, 255, 128, 132, 134, 136, - 138, 141, 149, 150, 162, 163, 128, 131, - 187, 188, 190, 255, 133, 137, 142, 150, - 152, 161, 164, 255, 129, 131, 138, 150, - 143, 148, 152, 159, 178, 179, 177, 179, - 186, 135, 142, 177, 179, 188, 136, 141, - 181, 183, 185, 152, 153, 190, 191, 177, - 191, 128, 132, 134, 135, 141, 151, 153, - 188, 134, 128, 129, 130, 141, 156, 157, - 158, 159, 160, 162, 164, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 179, 183, - 173, 183, 185, 190, 150, 153, 158, 160, - 177, 180, 130, 141, 157, 132, 134, 157, - 159, 146, 148, 178, 180, 146, 147, 178, - 179, 180, 255, 148, 156, 158, 255, 139, - 141, 169, 133, 134, 160, 171, 176, 187, - 151, 155, 160, 162, 191, 149, 158, 165, - 188, 176, 255, 129, 255, 128, 132, 180, - 255, 133, 170, 180, 255, 128, 130, 161, - 173, 166, 179, 164, 183, 173, 180, 144, - 146, 148, 168, 183, 185, 128, 185, 187, - 191, 128, 131, 179, 181, 183, 140, 141, - 144, 176, 175, 177, 191, 160, 191, 128, - 130, 170, 175, 153, 154, 153, 154, 155, - 160, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 175, 175, 178, 180, 189, - 158, 159, 176, 177, 130, 134, 139, 172, - 163, 167, 128, 129, 180, 255, 134, 159, - 178, 190, 192, 255, 166, 173, 135, 147, - 128, 131, 179, 255, 129, 164, 166, 255, - 169, 182, 131, 188, 140, 141, 176, 178, - 180, 183, 184, 190, 191, 129, 171, 175, - 181, 182, 163, 170, 172, 173, 172, 184, - 190, 158, 128, 143, 160, 175, 144, 145, - 150, 155, 157, 158, 159, 135, 139, 141, - 168, 171, 180, 186, 189, 189, 160, 182, - 186, 191, 129, 131, 133, 134, 140, 143, - 184, 186, 165, 166, 164, 167, 171, 172, - 134, 144, 128, 129, 130, 132, 133, 134, - 135, 136, 139, 140, 141, 144, 145, 146, - 147, 150, 151, 152, 153, 154, 156, 160, - 164, 165, 167, 168, 169, 170, 176, 178, - 180, 181, 182, 187, 128, 130, 184, 255, - 135, 190, 131, 175, 187, 255, 128, 130, - 167, 180, 179, 133, 134, 128, 130, 179, - 255, 141, 129, 136, 144, 255, 190, 172, - 183, 159, 170, 128, 131, 187, 188, 190, - 191, 151, 128, 132, 135, 136, 139, 141, - 162, 163, 166, 172, 176, 180, 181, 191, - 158, 128, 134, 132, 255, 175, 181, 184, - 255, 129, 155, 158, 255, 171, 183, 157, - 171, 172, 186, 176, 181, 183, 184, 187, - 190, 128, 130, 131, 164, 145, 151, 154, - 160, 129, 138, 179, 185, 187, 190, 135, - 145, 155, 138, 153, 175, 182, 184, 191, - 146, 167, 169, 182, 186, 177, 182, 188, - 189, 191, 255, 134, 136, 255, 138, 142, - 144, 145, 147, 151, 179, 182, 171, 172, - 189, 190, 191, 176, 180, 176, 182, 143, - 145, 255, 136, 142, 147, 255, 164, 176, - 177, 178, 157, 158, 133, 134, 137, 168, - 169, 170, 165, 169, 173, 178, 187, 255, - 131, 132, 140, 169, 174, 255, 130, 132, - 128, 182, 187, 255, 173, 180, 182, 255, - 132, 155, 159, 161, 175, 128, 132, 139, - 163, 165, 128, 134, 136, 152, 155, 161, - 163, 164, 166, 170, 172, 175, 144, 150, - 132, 138, 143, 187, 191, 160, 128, 129, - 132, 135, 133, 134, 160, 255, 192, 255, - 128, 191, 169, 173, 174, 128, 159, 160, - 191, 0, 127, 176, 255, 131, 137, 191, - 145, 189, 135, 129, 130, 132, 133, 144, - 154, 176, 139, 159, 150, 156, 159, 164, - 167, 168, 170, 173, 145, 176, 255, 139, - 255, 166, 176, 189, 171, 179, 160, 161, - 163, 164, 165, 167, 169, 171, 173, 174, - 175, 176, 177, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, - 166, 170, 172, 178, 150, 153, 155, 163, - 165, 167, 169, 173, 153, 155, 147, 161, - 163, 255, 189, 132, 185, 144, 152, 161, - 164, 255, 188, 129, 131, 190, 255, 133, - 134, 137, 138, 142, 150, 152, 161, 164, - 189, 191, 255, 131, 134, 137, 138, 142, - 144, 146, 175, 178, 180, 182, 255, 134, - 138, 142, 161, 164, 185, 192, 255, 188, - 129, 131, 190, 191, 128, 132, 135, 136, - 139, 141, 149, 151, 162, 163, 130, 190, - 191, 151, 128, 130, 134, 136, 138, 141, - 128, 132, 190, 255, 133, 137, 142, 148, - 151, 161, 164, 255, 128, 132, 134, 136, - 138, 141, 149, 150, 162, 163, 128, 131, - 187, 188, 190, 255, 133, 137, 142, 150, - 152, 161, 164, 255, 129, 131, 138, 150, - 143, 148, 152, 159, 178, 179, 177, 179, - 186, 135, 142, 177, 179, 188, 136, 141, - 181, 183, 185, 152, 153, 190, 191, 177, - 191, 128, 132, 134, 135, 141, 151, 153, - 188, 134, 128, 129, 130, 141, 156, 157, - 158, 159, 160, 162, 164, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 179, 183, - 173, 183, 185, 190, 150, 153, 158, 160, - 177, 180, 130, 141, 157, 132, 134, 157, - 159, 146, 148, 178, 180, 146, 147, 178, - 179, 180, 255, 148, 156, 158, 255, 139, - 141, 169, 133, 134, 160, 171, 176, 187, - 151, 155, 160, 162, 191, 149, 158, 165, - 188, 176, 255, 129, 255, 128, 132, 180, - 255, 133, 170, 180, 255, 128, 130, 161, - 173, 166, 179, 164, 183, 173, 180, 144, - 146, 148, 168, 183, 185, 128, 185, 187, - 191, 128, 131, 179, 181, 183, 140, 141, - 169, 174, 128, 129, 131, 132, 134, 140, - 142, 143, 147, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 164, 172, 173, 179, - 181, 183, 140, 141, 188, 137, 144, 176, - 162, 185, 148, 153, 169, 170, 168, 154, - 155, 136, 143, 169, 179, 184, 186, 130, - 182, 170, 171, 128, 187, 190, 128, 133, - 135, 146, 148, 191, 128, 191, 128, 133, - 144, 255, 147, 149, 134, 135, 151, 156, - 158, 160, 162, 167, 169, 178, 181, 255, - 132, 135, 140, 142, 151, 147, 149, 163, - 167, 161, 176, 191, 149, 151, 180, 181, - 133, 135, 155, 156, 144, 149, 175, 177, - 191, 160, 191, 128, 130, 138, 189, 170, - 176, 153, 154, 151, 153, 153, 154, 155, - 160, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 175, 175, 178, 180, 189, - 158, 159, 176, 177, 130, 134, 139, 172, - 163, 167, 128, 129, 180, 255, 134, 159, - 178, 190, 192, 255, 166, 173, 135, 147, - 128, 131, 179, 255, 129, 164, 166, 255, - 169, 182, 131, 188, 140, 141, 176, 178, - 180, 183, 184, 190, 191, 129, 171, 175, - 181, 182, 163, 170, 172, 173, 172, 184, - 190, 158, 128, 143, 160, 175, 144, 145, - 150, 155, 157, 158, 159, 135, 139, 141, - 168, 171, 180, 186, 189, 189, 160, 182, - 186, 191, 129, 131, 133, 134, 140, 143, - 184, 186, 165, 166, 164, 167, 171, 172, - 134, 144, 128, 129, 130, 132, 133, 134, - 135, 136, 139, 140, 141, 144, 145, 146, - 147, 150, 151, 152, 153, 154, 156, 160, - 164, 165, 167, 168, 169, 170, 176, 178, - 180, 181, 182, 187, 128, 130, 184, 255, - 135, 190, 131, 175, 187, 255, 128, 130, - 167, 180, 179, 133, 134, 128, 130, 179, - 255, 141, 129, 136, 144, 255, 190, 172, - 183, 159, 170, 128, 131, 187, 188, 190, - 191, 151, 128, 132, 135, 136, 139, 141, - 162, 163, 166, 172, 176, 180, 181, 191, - 158, 128, 134, 132, 255, 175, 181, 184, - 255, 129, 155, 158, 255, 171, 183, 157, - 171, 172, 186, 176, 181, 183, 184, 187, - 190, 128, 130, 131, 164, 145, 151, 154, - 160, 129, 138, 179, 185, 187, 190, 135, - 145, 155, 138, 153, 175, 182, 184, 191, - 146, 167, 169, 182, 186, 177, 182, 188, - 189, 191, 255, 134, 136, 255, 138, 142, - 144, 145, 147, 151, 179, 182, 171, 172, - 189, 190, 191, 176, 180, 176, 182, 143, - 145, 255, 136, 142, 147, 255, 164, 176, - 177, 178, 157, 158, 133, 134, 137, 168, - 169, 170, 165, 169, 173, 178, 187, 255, - 131, 132, 140, 169, 174, 255, 130, 132, - 128, 182, 187, 255, 173, 180, 182, 255, - 132, 155, 159, 161, 175, 128, 132, 139, - 163, 165, 128, 134, 136, 152, 155, 161, - 163, 164, 166, 170, 172, 175, 144, 150, - 132, 138, 128, 131, 132, 133, 134, 135, - 136, 137, 139, 140, 141, 142, 143, 144, - 145, 148, 149, 151, 152, 153, 157, 159, - 160, 161, 162, 163, 164, 165, 168, 169, - 176, 191, 129, 150, 154, 155, 166, 171, - 177, 190, 192, 255, 175, 141, 143, 172, - 177, 190, 191, 142, 145, 154, 173, 255, - 166, 255, 154, 175, 129, 143, 178, 186, - 188, 191, 137, 255, 190, 255, 134, 255, - 144, 255, 180, 191, 149, 191, 140, 143, - 136, 143, 154, 159, 136, 143, 174, 255, - 140, 186, 188, 191, 128, 133, 135, 191, - 160, 128, 129, 132, 135, 133, 134, 160, - 255, 128, 130, 170, 175, 144, 145, 150, - 155, 157, 158, 159, 143, 187, 191, 156, - 128, 133, 134, 191, 128, 255, 176, 255, - 131, 137, 191, 145, 189, 135, 129, 130, - 132, 133, 144, 154, 176, 139, 159, 150, - 156, 159, 164, 167, 168, 170, 173, 145, - 176, 255, 139, 255, 166, 176, 189, 171, - 179, 160, 161, 163, 164, 165, 167, 169, - 171, 173, 174, 175, 176, 177, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 166, 170, 172, 178, 150, - 153, 155, 163, 165, 167, 169, 173, 153, - 155, 147, 161, 163, 255, 189, 132, 185, - 144, 152, 161, 164, 255, 188, 129, 131, - 190, 255, 133, 134, 137, 138, 142, 150, - 152, 161, 164, 189, 191, 255, 131, 134, - 137, 138, 142, 144, 146, 175, 178, 180, - 182, 255, 134, 138, 142, 161, 164, 185, - 192, 255, 188, 129, 131, 190, 191, 128, - 132, 135, 136, 139, 141, 149, 151, 162, - 163, 130, 190, 191, 151, 128, 130, 134, - 136, 138, 141, 128, 132, 190, 255, 133, - 137, 142, 148, 151, 161, 164, 255, 128, - 132, 134, 136, 138, 141, 149, 150, 162, - 163, 128, 131, 187, 188, 190, 255, 133, - 137, 142, 150, 152, 161, 164, 255, 129, - 131, 138, 150, 143, 148, 152, 159, 178, - 179, 177, 179, 186, 135, 142, 177, 179, - 188, 136, 141, 181, 183, 185, 152, 153, - 190, 191, 177, 191, 128, 132, 134, 135, - 141, 151, 153, 188, 134, 128, 129, 130, - 141, 156, 157, 158, 159, 160, 162, 164, - 168, 169, 170, 171, 172, 173, 174, 175, - 176, 179, 183, 173, 183, 185, 190, 150, - 153, 158, 160, 177, 180, 130, 141, 157, - 132, 134, 157, 159, 146, 148, 178, 180, - 146, 147, 178, 179, 180, 255, 148, 156, - 158, 255, 139, 141, 169, 133, 134, 160, - 171, 176, 187, 151, 155, 160, 162, 191, - 149, 158, 165, 188, 176, 255, 129, 255, - 128, 132, 180, 255, 133, 170, 180, 255, - 128, 130, 161, 173, 166, 179, 164, 183, - 173, 180, 144, 146, 148, 168, 183, 185, - 128, 185, 187, 191, 128, 131, 179, 181, - 183, 140, 141, 144, 176, 175, 177, 191, - 160, 191, 128, 130, 170, 175, 153, 154, - 153, 154, 155, 160, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 175, 175, - 178, 180, 189, 158, 159, 176, 177, 130, - 134, 139, 172, 163, 167, 128, 129, 180, - 255, 134, 159, 178, 190, 192, 255, 166, - 173, 135, 147, 128, 131, 179, 255, 129, - 164, 166, 255, 169, 182, 131, 188, 140, - 141, 176, 178, 180, 183, 184, 190, 191, - 129, 171, 175, 181, 182, 163, 170, 172, - 173, 172, 184, 190, 158, 128, 143, 160, - 175, 144, 145, 150, 155, 157, 158, 159, - 135, 139, 141, 168, 171, 180, 186, 189, - 189, 160, 182, 186, 191, 129, 131, 133, - 134, 140, 143, 184, 186, 165, 166, 164, - 167, 171, 172, 134, 144, 128, 129, 130, - 132, 133, 134, 135, 136, 139, 140, 141, - 144, 145, 146, 147, 150, 151, 152, 153, - 154, 156, 160, 164, 165, 167, 168, 169, - 170, 176, 178, 180, 181, 182, 187, 128, - 130, 184, 255, 135, 190, 131, 175, 187, - 255, 128, 130, 167, 180, 179, 133, 134, - 128, 130, 179, 255, 141, 129, 136, 144, - 255, 190, 172, 183, 159, 170, 128, 131, - 187, 188, 190, 191, 151, 128, 132, 135, - 136, 139, 141, 162, 163, 166, 172, 176, - 180, 181, 191, 158, 128, 134, 132, 255, - 175, 181, 184, 255, 129, 155, 158, 255, - 171, 183, 157, 171, 172, 186, 176, 181, - 183, 184, 187, 190, 128, 130, 131, 164, - 145, 151, 154, 160, 129, 138, 179, 185, - 187, 190, 135, 145, 155, 138, 153, 175, - 182, 184, 191, 146, 167, 169, 182, 186, - 177, 182, 188, 189, 191, 255, 134, 136, - 255, 138, 142, 144, 145, 147, 151, 179, - 182, 171, 172, 189, 190, 191, 176, 180, - 176, 182, 143, 145, 255, 136, 142, 147, - 255, 164, 176, 177, 178, 157, 158, 133, - 134, 137, 168, 169, 170, 165, 169, 173, - 178, 187, 255, 131, 132, 140, 169, 174, - 255, 130, 132, 128, 182, 187, 255, 173, - 180, 182, 255, 132, 155, 159, 161, 175, - 128, 132, 139, 163, 165, 128, 134, 136, - 152, 155, 161, 163, 164, 166, 170, 172, - 175, 144, 150, 132, 138, 143, 187, 191, - 160, 128, 129, 132, 135, 133, 134, 160, - 255, 192, 255, 128, 191, 169, 174, 160, - 172, 175, 191, 128, 255, 176, 255, 131, - 137, 191, 145, 189, 135, 129, 130, 132, - 133, 144, 154, 176, 139, 159, 150, 156, - 159, 164, 167, 168, 170, 173, 145, 176, - 255, 139, 255, 166, 176, 189, 171, 179, - 160, 161, 163, 164, 165, 167, 169, 171, - 173, 174, 175, 176, 177, 179, 180, 181, - 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 166, 170, 172, 178, 150, 153, - 155, 163, 165, 167, 169, 173, 153, 155, - 147, 161, 163, 255, 189, 132, 185, 144, - 152, 161, 164, 255, 188, 129, 131, 190, - 255, 133, 134, 137, 138, 142, 150, 152, - 161, 164, 189, 191, 255, 131, 134, 137, - 138, 142, 144, 146, 175, 178, 180, 182, - 255, 134, 138, 142, 161, 164, 185, 192, - 255, 188, 129, 131, 190, 191, 128, 132, - 135, 136, 139, 141, 149, 151, 162, 163, - 130, 190, 191, 151, 128, 130, 134, 136, - 138, 141, 128, 132, 190, 255, 133, 137, - 142, 148, 151, 161, 164, 255, 128, 132, - 134, 136, 138, 141, 149, 150, 162, 163, - 128, 131, 187, 188, 190, 255, 133, 137, - 142, 150, 152, 161, 164, 255, 129, 131, - 138, 150, 143, 148, 152, 159, 178, 179, - 177, 179, 186, 135, 142, 177, 179, 188, - 136, 141, 181, 183, 185, 152, 153, 190, - 191, 177, 191, 128, 132, 134, 135, 141, - 151, 153, 188, 134, 128, 129, 130, 141, - 156, 157, 158, 159, 160, 162, 164, 168, - 169, 170, 171, 172, 173, 174, 175, 176, - 179, 183, 173, 183, 185, 190, 150, 153, - 158, 160, 177, 180, 130, 141, 157, 132, - 134, 157, 159, 146, 148, 178, 180, 146, - 147, 178, 179, 180, 255, 148, 156, 158, - 255, 139, 141, 169, 133, 134, 160, 171, - 176, 187, 151, 155, 160, 162, 191, 149, - 158, 165, 188, 176, 255, 129, 255, 128, - 132, 180, 255, 133, 170, 180, 255, 128, - 130, 161, 173, 166, 179, 164, 183, 173, - 180, 144, 146, 148, 168, 183, 185, 128, - 185, 187, 191, 128, 131, 179, 181, 183, - 140, 141, 169, 174, 128, 129, 131, 132, - 134, 140, 142, 143, 147, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 164, 172, - 173, 179, 181, 183, 140, 141, 188, 137, - 144, 176, 162, 185, 148, 153, 169, 170, - 168, 154, 155, 136, 143, 169, 179, 184, - 186, 130, 182, 170, 171, 128, 187, 190, - 128, 133, 135, 146, 148, 191, 128, 191, - 128, 133, 144, 255, 147, 149, 134, 135, - 151, 156, 158, 160, 162, 167, 169, 178, - 181, 255, 132, 135, 140, 142, 151, 147, - 149, 163, 167, 161, 176, 191, 149, 151, - 180, 181, 133, 135, 155, 156, 144, 149, - 175, 177, 191, 160, 191, 128, 130, 138, - 189, 170, 176, 153, 154, 151, 153, 153, - 154, 155, 160, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 175, 175, 178, - 180, 189, 158, 159, 176, 177, 130, 134, - 139, 172, 163, 167, 128, 129, 180, 255, - 134, 159, 178, 190, 192, 255, 166, 173, - 135, 147, 128, 131, 179, 255, 129, 164, - 166, 255, 169, 182, 131, 188, 140, 141, - 176, 178, 180, 183, 184, 190, 191, 129, - 171, 175, 181, 182, 163, 170, 172, 173, - 172, 184, 190, 158, 128, 143, 160, 175, - 144, 145, 150, 155, 157, 158, 159, 135, - 139, 141, 168, 171, 180, 186, 189, 189, - 160, 182, 186, 191, 129, 131, 133, 134, - 140, 143, 184, 186, 165, 166, 164, 167, - 171, 172, 134, 144, 128, 129, 130, 132, - 133, 134, 135, 136, 139, 140, 141, 144, - 145, 146, 147, 150, 151, 152, 153, 154, - 156, 160, 164, 165, 167, 168, 169, 170, - 176, 178, 180, 181, 182, 187, 128, 130, - 184, 255, 135, 190, 131, 175, 187, 255, - 128, 130, 167, 180, 179, 133, 134, 128, - 130, 179, 255, 141, 129, 136, 144, 255, - 190, 172, 183, 159, 170, 128, 131, 187, - 188, 190, 191, 151, 128, 132, 135, 136, - 139, 141, 162, 163, 166, 172, 176, 180, - 181, 191, 158, 128, 134, 132, 255, 175, - 181, 184, 255, 129, 155, 158, 255, 171, - 183, 157, 171, 172, 186, 176, 181, 183, - 184, 187, 190, 128, 130, 131, 164, 145, - 151, 154, 160, 129, 138, 179, 185, 187, - 190, 135, 145, 155, 138, 153, 175, 182, - 184, 191, 146, 167, 169, 182, 186, 177, - 182, 188, 189, 191, 255, 134, 136, 255, - 138, 142, 144, 145, 147, 151, 179, 182, - 171, 172, 189, 190, 191, 176, 180, 176, - 182, 143, 145, 255, 136, 142, 147, 255, - 164, 176, 177, 178, 157, 158, 133, 134, - 137, 168, 169, 170, 165, 169, 173, 178, - 187, 255, 131, 132, 140, 169, 174, 255, - 130, 132, 128, 182, 187, 255, 173, 180, - 182, 255, 132, 155, 159, 161, 175, 128, - 132, 139, 163, 165, 128, 134, 136, 152, - 155, 161, 163, 164, 166, 170, 172, 175, - 144, 150, 132, 138, 128, 131, 132, 133, - 134, 135, 136, 137, 139, 140, 141, 142, - 143, 144, 145, 148, 149, 151, 152, 153, - 157, 159, 160, 161, 162, 163, 164, 165, - 168, 169, 176, 191, 129, 150, 154, 155, - 166, 171, 177, 190, 192, 255, 175, 141, - 143, 172, 177, 190, 191, 142, 145, 154, - 173, 255, 166, 255, 154, 175, 129, 143, - 178, 186, 188, 191, 137, 255, 190, 255, - 134, 255, 144, 255, 180, 191, 149, 191, - 140, 143, 136, 143, 154, 159, 136, 143, - 174, 255, 140, 186, 188, 191, 128, 133, - 135, 191, 160, 128, 129, 132, 135, 133, - 134, 160, 255, 128, 130, 170, 175, 144, - 145, 150, 155, 157, 158, 159, 143, 187, - 191, 128, 133, 134, 155, 157, 191, 157, - 128, 191, 143, 128, 191, 163, 181, 128, - 191, 162, 128, 191, 142, 128, 191, 132, - 133, 134, 135, 160, 128, 191, 128, 255, - 128, 129, 130, 132, 133, 134, 141, 156, - 157, 158, 159, 160, 162, 164, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 179, - 183, 160, 255, 128, 129, 130, 133, 134, - 135, 141, 156, 157, 158, 159, 160, 162, - 164, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 179, 183, 160, 255, 168, 255, - 128, 129, 130, 134, 135, 141, 156, 157, - 158, 159, 160, 162, 164, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 179, 183, - 168, 255, 192, 255, 159, 139, 187, 158, - 159, 176, 255, 135, 138, 139, 187, 188, - 255, 168, 255, 153, 154, 155, 160, 162, - 163, 164, 165, 166, 167, 168, 169, 170, - 171, 175, 177, 178, 179, 180, 181, 182, - 184, 185, 186, 187, 188, 189, 191, 176, - 190, 192, 255, 135, 147, 160, 188, 128, - 156, 184, 129, 255, 128, 129, 130, 133, - 134, 141, 156, 157, 158, 159, 160, 162, - 164, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 179, 183, 158, 159, 135, 255, - 148, 176, 140, 168, 132, 160, 188, 152, - 180, 144, 172, 136, 164, 192, 255, 129, - 130, 131, 132, 133, 134, 136, 137, 138, - 139, 140, 141, 143, 144, 145, 146, 147, - 148, 150, 151, 152, 153, 154, 155, 157, - 158, 159, 160, 161, 162, 164, 165, 166, - 167, 168, 169, 171, 172, 173, 174, 175, - 176, 178, 179, 180, 181, 182, 183, 185, - 186, 187, 188, 189, 190, 128, 191, 129, - 130, 131, 132, 133, 134, 136, 137, 138, - 139, 140, 141, 143, 144, 145, 146, 147, - 148, 150, 151, 152, 153, 154, 155, 157, - 158, 159, 160, 161, 162, 164, 165, 166, - 167, 168, 169, 171, 172, 173, 174, 175, - 176, 178, 179, 180, 181, 182, 183, 185, - 186, 187, 188, 189, 190, 128, 191, 129, - 130, 131, 132, 133, 134, 136, 137, 138, - 139, 140, 141, 143, 144, 145, 146, 147, - 148, 150, 151, 152, 153, 154, 155, 157, - 158, 159, 128, 156, 160, 255, 136, 164, - 175, 176, 255, 128, 141, 143, 191, 128, - 129, 132, 134, 140, 142, 143, 147, 150, - 151, 152, 153, 154, 155, 156, 157, 158, - 164, 172, 173, 130, 191, 188, 128, 138, - 140, 141, 144, 167, 175, 191, 137, 128, - 159, 176, 191, 162, 185, 128, 191, 128, - 147, 148, 153, 154, 168, 169, 170, 171, - 191, 168, 128, 153, 154, 155, 156, 191, - 136, 128, 191, 143, 128, 168, 169, 179, - 180, 183, 184, 186, 187, 191, 130, 128, - 191, 182, 128, 169, 170, 171, 172, 191, - 128, 191, 129, 186, 187, 190, 134, 147, - 128, 191, 128, 133, 134, 143, 144, 255, - 147, 149, 134, 135, 151, 156, 158, 160, - 162, 167, 169, 178, 181, 191, 192, 255, - 132, 135, 140, 142, 150, 128, 146, 147, - 151, 152, 162, 163, 167, 168, 191, 161, - 176, 191, 128, 148, 149, 151, 152, 190, - 128, 179, 180, 181, 182, 191, 128, 132, - 133, 135, 136, 154, 155, 156, 157, 191, - 144, 149, 128, 191, 128, 138, 129, 191, - 176, 189, 128, 191, 151, 153, 128, 191, - 128, 191, 165, 177, 178, 179, 180, 181, - 182, 184, 185, 186, 187, 188, 189, 191, - 128, 175, 176, 190, 192, 255, 128, 159, - 160, 188, 189, 191, 128, 156, 184, 129, - 255, 148, 176, 140, 168, 132, 160, 188, - 152, 180, 144, 172, 136, 164, 192, 255, - 129, 130, 131, 132, 133, 134, 136, 137, - 138, 139, 140, 141, 143, 144, 145, 146, - 147, 148, 150, 151, 152, 153, 154, 155, - 157, 158, 159, 160, 161, 162, 164, 165, - 166, 167, 168, 169, 171, 172, 173, 174, - 175, 176, 178, 179, 180, 181, 182, 183, - 185, 186, 187, 188, 189, 190, 128, 191, - 129, 130, 131, 132, 133, 134, 136, 137, - 138, 139, 140, 141, 143, 144, 145, 146, - 147, 148, 150, 151, 152, 153, 154, 155, - 157, 158, 159, 160, 161, 162, 164, 165, - 166, 167, 168, 169, 171, 172, 173, 174, - 175, 176, 178, 179, 180, 181, 182, 183, - 185, 186, 187, 188, 189, 190, 128, 191, - 129, 130, 131, 132, 133, 134, 136, 137, - 138, 139, 140, 141, 143, 144, 145, 146, - 147, 148, 150, 151, 152, 153, 154, 155, - 157, 158, 159, 128, 156, 160, 191, 192, - 255, 136, 164, 175, 176, 255, 135, 138, - 139, 187, 188, 191, 192, 255, 187, 191, - 128, 190, 128, 190, 188, 128, 175, 190, - 191, 145, 147, 155, 157, 159, 128, 191, - 130, 131, 135, 164, 165, 168, 170, 181, - 128, 191, 189, 128, 191, 141, 128, 191, - 128, 129, 130, 131, 132, 191, 191, 128, - 190, 129, 128, 191, 186, 128, 191, 128, - 131, 132, 137, 138, 191, 134, 128, 191, - 144, 128, 191, 128, 175, 185, 191, 178, - 128, 191, 128, 159, 164, 191, 133, 128, - 191, 128, 178, 187, 191, 128, 131, 132, - 133, 134, 135, 136, 137, 139, 140, 141, - 142, 143, 144, 145, 148, 149, 151, 152, - 153, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 168, 169, 176, 191, 129, - 150, 154, 171, 172, 175, 177, 190, 175, - 128, 140, 141, 143, 144, 191, 128, 171, - 172, 177, 178, 189, 190, 191, 142, 128, - 144, 145, 154, 155, 172, 173, 255, 166, - 191, 192, 255, 144, 145, 150, 155, 157, - 158, 159, 135, 143, 166, 191, 128, 154, - 175, 187, 129, 143, 144, 177, 178, 191, - 128, 136, 137, 255, 187, 191, 192, 255, - 190, 191, 192, 255, 128, 133, 134, 255, - 144, 191, 192, 255, 128, 179, 180, 191, - 128, 148, 149, 191, 128, 139, 140, 143, - 144, 191, 128, 135, 136, 143, 144, 153, - 154, 159, 160, 191, 128, 135, 136, 143, - 144, 173, 174, 255, 187, 128, 139, 140, - 191, 134, 128, 191, 128, 191, 160, 128, - 191, 128, 129, 135, 132, 134, 128, 175, - 157, 128, 191, 143, 128, 191, 163, 181, - 128, 191, 162, 128, 191, 142, 128, 191, - 132, 133, 134, 135, 160, 128, 191, 128, - 255, 128, 255, 176, 255, 131, 137, 191, - 145, 189, 135, 129, 130, 132, 133, 144, - 154, 176, 139, 159, 150, 156, 159, 164, - 167, 168, 170, 173, 145, 176, 255, 139, - 255, 166, 176, 189, 171, 179, 160, 161, - 163, 164, 165, 167, 169, 171, 173, 174, - 175, 176, 177, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, - 166, 170, 172, 178, 150, 153, 155, 163, - 165, 167, 169, 173, 153, 155, 147, 161, - 163, 255, 189, 132, 185, 144, 152, 161, - 164, 255, 188, 129, 131, 190, 255, 133, - 134, 137, 138, 142, 150, 152, 161, 164, - 189, 191, 255, 131, 134, 137, 138, 142, - 144, 146, 175, 178, 180, 182, 255, 134, - 138, 142, 161, 164, 185, 192, 255, 188, - 129, 131, 190, 191, 128, 132, 135, 136, - 139, 141, 149, 151, 162, 163, 130, 190, - 191, 151, 128, 130, 134, 136, 138, 141, - 128, 132, 190, 255, 133, 137, 142, 148, - 151, 161, 164, 255, 128, 132, 134, 136, - 138, 141, 149, 150, 162, 163, 128, 131, - 187, 188, 190, 255, 133, 137, 142, 150, - 152, 161, 164, 255, 129, 131, 138, 150, - 143, 148, 152, 159, 178, 179, 177, 179, - 186, 135, 142, 177, 179, 188, 136, 141, - 181, 183, 185, 152, 153, 190, 191, 177, - 191, 128, 132, 134, 135, 141, 151, 153, - 188, 134, 128, 129, 130, 141, 156, 157, - 158, 159, 160, 162, 164, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 179, 183, - 173, 183, 185, 190, 150, 153, 158, 160, - 177, 180, 130, 141, 157, 132, 134, 157, - 159, 146, 148, 178, 180, 146, 147, 178, - 179, 180, 255, 148, 156, 158, 255, 139, - 141, 169, 133, 134, 160, 171, 176, 187, - 151, 155, 160, 162, 191, 149, 158, 165, - 188, 176, 255, 129, 255, 128, 132, 180, - 255, 133, 170, 180, 255, 128, 130, 161, - 173, 166, 179, 164, 183, 173, 180, 144, - 146, 148, 168, 183, 185, 128, 185, 187, - 191, 128, 131, 179, 181, 183, 140, 141, - 169, 174, 128, 129, 131, 132, 134, 140, - 142, 143, 147, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 164, 172, 173, 179, - 181, 183, 140, 141, 188, 137, 144, 176, - 162, 185, 148, 153, 169, 170, 168, 154, - 155, 136, 143, 169, 179, 184, 186, 130, - 182, 170, 171, 128, 187, 190, 128, 133, - 135, 146, 148, 191, 128, 191, 128, 133, - 144, 255, 147, 149, 134, 135, 151, 156, - 158, 160, 162, 167, 169, 178, 181, 255, - 132, 135, 140, 142, 151, 147, 149, 163, - 167, 161, 176, 191, 149, 151, 180, 181, - 133, 135, 155, 156, 144, 149, 175, 177, - 191, 160, 191, 128, 130, 138, 189, 170, - 176, 153, 154, 151, 153, 153, 154, 155, - 160, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 175, 175, 178, 180, 189, - 158, 159, 176, 177, 130, 134, 139, 172, - 163, 167, 128, 129, 180, 255, 134, 159, - 178, 190, 192, 255, 166, 173, 135, 147, - 128, 131, 179, 255, 129, 164, 166, 255, - 169, 182, 131, 188, 140, 141, 176, 178, - 180, 183, 184, 190, 191, 129, 171, 175, - 181, 182, 163, 170, 172, 173, 172, 184, - 190, 158, 128, 143, 160, 175, 144, 145, - 150, 155, 157, 158, 159, 135, 139, 141, - 168, 171, 180, 186, 189, 189, 160, 182, - 186, 191, 129, 131, 133, 134, 140, 143, - 184, 186, 165, 166, 164, 167, 171, 172, - 134, 144, 128, 129, 130, 132, 133, 134, - 135, 136, 139, 140, 141, 144, 145, 146, - 147, 150, 151, 152, 153, 154, 156, 160, - 164, 165, 167, 168, 169, 170, 176, 178, - 180, 181, 182, 187, 128, 130, 184, 255, - 135, 190, 131, 175, 187, 255, 128, 130, - 167, 180, 179, 133, 134, 128, 130, 179, - 255, 141, 129, 136, 144, 255, 190, 172, - 183, 159, 170, 128, 131, 187, 188, 190, - 191, 151, 128, 132, 135, 136, 139, 141, - 162, 163, 166, 172, 176, 180, 181, 191, - 158, 128, 134, 132, 255, 175, 181, 184, - 255, 129, 155, 158, 255, 171, 183, 157, - 171, 172, 186, 176, 181, 183, 184, 187, - 190, 128, 130, 131, 164, 145, 151, 154, - 160, 129, 138, 179, 185, 187, 190, 135, - 145, 155, 138, 153, 175, 182, 184, 191, - 146, 167, 169, 182, 186, 177, 182, 188, - 189, 191, 255, 134, 136, 255, 138, 142, - 144, 145, 147, 151, 179, 182, 171, 172, - 189, 190, 191, 176, 180, 176, 182, 143, - 145, 255, 136, 142, 147, 255, 164, 176, - 177, 178, 157, 158, 133, 134, 137, 168, - 169, 170, 165, 169, 173, 178, 187, 255, - 131, 132, 140, 169, 174, 255, 130, 132, - 128, 182, 187, 255, 173, 180, 182, 255, - 132, 155, 159, 161, 175, 128, 132, 139, - 163, 165, 128, 134, 136, 152, 155, 161, - 163, 164, 166, 170, 172, 175, 144, 150, - 132, 138, 128, 131, 132, 133, 134, 135, - 136, 137, 139, 140, 141, 142, 143, 144, - 145, 148, 149, 151, 152, 153, 157, 159, - 160, 161, 162, 163, 164, 165, 168, 169, - 176, 191, 129, 150, 154, 155, 166, 171, - 177, 190, 192, 255, 175, 141, 143, 172, - 177, 190, 191, 142, 145, 154, 173, 255, - 166, 255, 154, 175, 129, 143, 178, 186, - 188, 191, 137, 255, 190, 255, 134, 255, - 144, 255, 180, 191, 149, 191, 140, 143, - 136, 143, 154, 159, 136, 143, 174, 255, - 140, 186, 188, 191, 128, 133, 135, 191, - 160, 128, 129, 132, 135, 133, 134, 160, - 255, 128, 130, 170, 175, 144, 145, 150, - 155, 157, 158, 159, 143, 187, 191, 128, - 129, 130, 132, 133, 134, 141, 156, 157, - 158, 159, 160, 162, 164, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 179, 183, - 160, 255, 128, 129, 130, 133, 134, 135, - 141, 156, 157, 158, 159, 160, 162, 164, - 168, 169, 170, 171, 172, 173, 174, 175, - 176, 179, 183, 160, 255, 168, 255, 128, - 129, 130, 134, 135, 141, 156, 157, 158, - 159, 160, 162, 164, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 179, 183, 168, - 255, 192, 255, 159, 139, 187, 158, 159, - 176, 255, 135, 138, 139, 187, 188, 255, - 168, 255, 153, 154, 155, 160, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, - 175, 177, 178, 179, 180, 181, 182, 184, - 185, 186, 187, 188, 189, 191, 176, 190, - 192, 255, 135, 147, 160, 188, 128, 156, - 184, 129, 255, 128, 129, 130, 133, 134, - 141, 156, 157, 158, 159, 160, 162, 164, - 168, 169, 170, 171, 172, 173, 174, 175, - 176, 179, 183, 158, 159, 135, 255, 148, - 176, 140, 168, 132, 160, 188, 152, 180, - 144, 172, 136, 164, 192, 255, 129, 130, - 131, 132, 133, 134, 136, 137, 138, 139, - 140, 141, 143, 144, 145, 146, 147, 148, - 150, 151, 152, 153, 154, 155, 157, 158, - 159, 160, 161, 162, 164, 165, 166, 167, - 168, 169, 171, 172, 173, 174, 175, 176, - 178, 179, 180, 181, 182, 183, 185, 186, - 187, 188, 189, 190, 128, 191, 129, 130, - 131, 132, 133, 134, 136, 137, 138, 139, - 140, 141, 143, 144, 145, 146, 147, 148, - 150, 151, 152, 153, 154, 155, 157, 158, - 159, 160, 161, 162, 164, 165, 166, 167, - 168, 169, 171, 172, 173, 174, 175, 176, - 178, 179, 180, 181, 182, 183, 185, 186, - 187, 188, 189, 190, 128, 191, 129, 130, - 131, 132, 133, 134, 136, 137, 138, 139, - 140, 141, 143, 144, 145, 146, 147, 148, - 150, 151, 152, 153, 154, 155, 157, 158, - 159, 128, 156, 160, 255, 136, 164, 175, - 176, 255, 142, 128, 191, 128, 129, 132, - 134, 140, 142, 143, 147, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 164, 172, - 173, 130, 191, 139, 141, 188, 128, 140, - 142, 143, 144, 167, 168, 174, 175, 191, - 128, 255, 176, 255, 131, 137, 191, 145, - 189, 135, 129, 130, 132, 133, 144, 154, - 176, 139, 159, 150, 156, 159, 164, 167, - 168, 170, 173, 145, 176, 255, 139, 255, - 166, 176, 189, 171, 179, 160, 161, 163, - 164, 165, 167, 169, 171, 173, 174, 175, - 176, 177, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 166, - 170, 172, 178, 150, 153, 155, 163, 165, - 167, 169, 173, 153, 155, 147, 161, 163, - 255, 189, 132, 185, 144, 152, 161, 164, - 255, 188, 129, 131, 190, 255, 133, 134, - 137, 138, 142, 150, 152, 161, 164, 189, - 191, 255, 131, 134, 137, 138, 142, 144, - 146, 175, 178, 180, 182, 255, 134, 138, - 142, 161, 164, 185, 192, 255, 188, 129, - 131, 190, 191, 128, 132, 135, 136, 139, - 141, 149, 151, 162, 163, 130, 190, 191, - 151, 128, 130, 134, 136, 138, 141, 128, - 132, 190, 255, 133, 137, 142, 148, 151, - 161, 164, 255, 128, 132, 134, 136, 138, - 141, 149, 150, 162, 163, 128, 131, 187, - 188, 190, 255, 133, 137, 142, 150, 152, - 161, 164, 255, 129, 131, 138, 150, 143, - 148, 152, 159, 178, 179, 177, 179, 186, - 135, 142, 177, 179, 188, 136, 141, 181, - 183, 185, 152, 153, 190, 191, 177, 191, - 128, 132, 134, 135, 141, 151, 153, 188, - 134, 128, 129, 130, 141, 156, 157, 158, - 159, 160, 162, 164, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 179, 183, 173, - 183, 185, 190, 150, 153, 158, 160, 177, - 180, 130, 141, 157, 132, 134, 157, 159, - 146, 148, 178, 180, 146, 147, 178, 179, - 180, 255, 148, 156, 158, 255, 139, 141, - 169, 133, 134, 160, 171, 176, 187, 151, - 155, 160, 162, 191, 149, 158, 165, 188, - 176, 255, 129, 255, 128, 132, 180, 255, - 133, 170, 180, 255, 128, 130, 161, 173, - 166, 179, 164, 183, 173, 180, 144, 146, - 148, 168, 183, 185, 128, 185, 187, 191, - 128, 131, 179, 181, 183, 140, 141, 144, - 176, 175, 177, 191, 160, 191, 128, 130, - 170, 175, 153, 154, 153, 154, 155, 160, - 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 175, 175, 178, 180, 189, 158, - 159, 176, 177, 130, 134, 139, 172, 163, - 167, 128, 129, 180, 255, 134, 159, 178, - 190, 192, 255, 166, 173, 135, 147, 128, - 131, 179, 255, 129, 164, 166, 255, 169, - 182, 131, 188, 140, 141, 176, 178, 180, - 183, 184, 190, 191, 129, 171, 175, 181, - 182, 163, 170, 172, 173, 172, 184, 190, - 158, 128, 143, 160, 175, 144, 145, 150, - 155, 157, 158, 159, 135, 139, 141, 168, - 171, 180, 186, 189, 189, 160, 182, 186, - 191, 129, 131, 133, 134, 140, 143, 184, - 186, 165, 166, 164, 167, 171, 172, 134, - 144, 128, 129, 130, 132, 133, 134, 135, - 136, 139, 140, 141, 144, 145, 146, 147, - 150, 151, 152, 153, 154, 156, 160, 164, - 165, 167, 168, 169, 170, 176, 178, 180, - 181, 182, 187, 128, 130, 184, 255, 135, - 190, 131, 175, 187, 255, 128, 130, 167, - 180, 179, 133, 134, 128, 130, 179, 255, - 141, 129, 136, 144, 255, 190, 172, 183, - 159, 170, 128, 131, 187, 188, 190, 191, - 151, 128, 132, 135, 136, 139, 141, 162, - 163, 166, 172, 176, 180, 181, 191, 158, - 128, 134, 132, 255, 175, 181, 184, 255, - 129, 155, 158, 255, 171, 183, 157, 171, - 172, 186, 176, 181, 183, 184, 187, 190, - 128, 130, 131, 164, 145, 151, 154, 160, - 129, 138, 179, 185, 187, 190, 135, 145, - 155, 138, 153, 175, 182, 184, 191, 146, - 167, 169, 182, 186, 177, 182, 188, 189, - 191, 255, 134, 136, 255, 138, 142, 144, - 145, 147, 151, 179, 182, 171, 172, 189, - 190, 191, 176, 180, 176, 182, 143, 145, - 255, 136, 142, 147, 255, 164, 176, 177, - 178, 157, 158, 133, 134, 137, 168, 169, - 170, 165, 169, 173, 178, 187, 255, 131, - 132, 140, 169, 174, 255, 130, 132, 128, - 182, 187, 255, 173, 180, 182, 255, 132, - 155, 159, 161, 175, 128, 132, 139, 163, - 165, 128, 134, 136, 152, 155, 161, 163, - 164, 166, 170, 172, 175, 144, 150, 132, - 138, 143, 187, 191, 160, 128, 129, 132, - 135, 133, 134, 160, 255, 192, 255, 137, - 128, 159, 160, 175, 176, 191, 162, 185, - 128, 191, 128, 147, 148, 153, 154, 168, - 169, 170, 171, 191, 168, 128, 153, 154, - 155, 156, 191, 136, 128, 191, 143, 128, - 168, 169, 179, 180, 183, 184, 186, 187, - 191, 130, 128, 191, 182, 128, 169, 170, - 171, 172, 191, 128, 191, 129, 186, 187, - 190, 134, 147, 128, 191, 128, 133, 134, - 143, 144, 255, 147, 149, 134, 135, 151, - 156, 158, 160, 162, 167, 169, 178, 181, - 191, 192, 255, 132, 135, 140, 142, 150, - 128, 146, 147, 151, 152, 162, 163, 167, - 168, 191, 161, 176, 191, 128, 148, 149, - 151, 152, 190, 128, 179, 180, 181, 182, - 191, 128, 132, 133, 135, 136, 154, 155, - 156, 157, 191, 144, 149, 128, 191, 128, - 138, 129, 191, 176, 189, 128, 191, 151, - 153, 128, 191, 128, 191, 165, 177, 178, - 179, 180, 181, 182, 184, 185, 186, 187, - 188, 189, 191, 128, 175, 176, 190, 192, - 255, 128, 159, 160, 188, 189, 191, 128, - 156, 184, 129, 255, 148, 176, 140, 168, - 132, 160, 188, 152, 180, 144, 172, 136, - 164, 192, 255, 129, 130, 131, 132, 133, - 134, 136, 137, 138, 139, 140, 141, 143, - 144, 145, 146, 147, 148, 150, 151, 152, - 153, 154, 155, 157, 158, 159, 160, 161, - 162, 164, 165, 166, 167, 168, 169, 171, - 172, 173, 174, 175, 176, 178, 179, 180, - 181, 182, 183, 185, 186, 187, 188, 189, - 190, 128, 191, 129, 130, 131, 132, 133, - 134, 136, 137, 138, 139, 140, 141, 143, - 144, 145, 146, 147, 148, 150, 151, 152, - 153, 154, 155, 157, 158, 159, 160, 161, - 162, 164, 165, 166, 167, 168, 169, 171, - 172, 173, 174, 175, 176, 178, 179, 180, - 181, 182, 183, 185, 186, 187, 188, 189, - 190, 128, 191, 129, 130, 131, 132, 133, - 134, 136, 137, 138, 139, 140, 141, 143, - 144, 145, 146, 147, 148, 150, 151, 152, - 153, 154, 155, 157, 158, 159, 128, 156, - 160, 191, 192, 255, 136, 164, 175, 176, - 255, 135, 138, 139, 187, 188, 191, 192, - 255, 187, 191, 128, 190, 191, 128, 190, - 188, 128, 175, 176, 189, 190, 191, 145, - 147, 155, 157, 159, 128, 191, 130, 131, - 135, 164, 165, 168, 170, 181, 128, 191, - 189, 128, 191, 141, 128, 191, 128, 129, - 130, 131, 132, 191, 191, 128, 190, 129, - 128, 191, 186, 128, 191, 128, 131, 132, - 137, 138, 191, 134, 128, 191, 144, 128, - 191, 128, 175, 176, 184, 185, 191, 178, - 128, 191, 128, 159, 160, 163, 164, 191, - 133, 128, 191, 128, 178, 179, 186, 187, - 191, 128, 131, 132, 133, 134, 135, 136, - 137, 139, 140, 141, 142, 143, 144, 145, - 148, 149, 151, 152, 153, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 168, - 169, 176, 191, 129, 150, 154, 171, 172, - 175, 177, 190, 175, 128, 140, 141, 143, - 144, 191, 128, 171, 172, 177, 178, 189, - 190, 191, 142, 128, 144, 145, 154, 155, - 172, 173, 255, 166, 191, 192, 255, 128, - 255, 176, 255, 131, 137, 191, 145, 189, - 135, 129, 130, 132, 133, 144, 154, 176, - 139, 159, 150, 156, 159, 164, 167, 168, - 170, 173, 145, 176, 255, 139, 255, 166, - 176, 189, 171, 179, 160, 161, 163, 164, - 165, 167, 169, 171, 173, 174, 175, 176, - 177, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 166, 170, - 172, 178, 150, 153, 155, 163, 165, 167, - 169, 173, 153, 155, 147, 161, 163, 255, - 189, 132, 185, 144, 152, 161, 164, 255, - 188, 129, 131, 190, 255, 133, 134, 137, - 138, 142, 150, 152, 161, 164, 189, 191, - 255, 131, 134, 137, 138, 142, 144, 146, - 175, 178, 180, 182, 255, 134, 138, 142, - 161, 164, 185, 192, 255, 188, 129, 131, - 190, 191, 128, 132, 135, 136, 139, 141, - 149, 151, 162, 163, 130, 190, 191, 151, - 128, 130, 134, 136, 138, 141, 128, 132, - 190, 255, 133, 137, 142, 148, 151, 161, - 164, 255, 128, 132, 134, 136, 138, 141, - 149, 150, 162, 163, 128, 131, 187, 188, - 190, 255, 133, 137, 142, 150, 152, 161, - 164, 255, 129, 131, 138, 150, 143, 148, - 152, 159, 178, 179, 177, 179, 186, 135, - 142, 177, 179, 188, 136, 141, 181, 183, - 185, 152, 153, 190, 191, 177, 191, 128, - 132, 134, 135, 141, 151, 153, 188, 134, - 128, 129, 130, 141, 156, 157, 158, 159, - 160, 162, 164, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 179, 183, 173, 183, - 185, 190, 150, 153, 158, 160, 177, 180, - 130, 141, 157, 132, 134, 157, 159, 146, - 148, 178, 180, 146, 147, 178, 179, 180, - 255, 148, 156, 158, 255, 139, 141, 169, - 133, 134, 160, 171, 176, 187, 151, 155, - 160, 162, 191, 149, 158, 165, 188, 176, - 255, 129, 255, 128, 132, 180, 255, 133, - 170, 180, 255, 128, 130, 161, 173, 166, - 179, 164, 183, 173, 180, 144, 146, 148, - 168, 183, 185, 128, 185, 187, 191, 128, - 131, 179, 181, 183, 140, 141, 169, 174, - 128, 129, 131, 132, 134, 140, 142, 143, - 147, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 164, 172, 173, 179, 181, 183, - 140, 141, 188, 137, 144, 176, 162, 185, - 148, 153, 169, 170, 168, 154, 155, 136, - 143, 169, 179, 184, 186, 130, 182, 170, - 171, 128, 187, 190, 128, 133, 135, 146, - 148, 191, 128, 191, 128, 133, 144, 255, - 147, 149, 134, 135, 151, 156, 158, 160, - 162, 167, 169, 178, 181, 255, 132, 135, - 140, 142, 151, 147, 149, 163, 167, 161, - 176, 191, 149, 151, 180, 181, 133, 135, - 155, 156, 144, 149, 175, 177, 191, 160, - 191, 128, 130, 138, 189, 170, 176, 153, - 154, 151, 153, 153, 154, 155, 160, 162, - 163, 164, 165, 166, 167, 168, 169, 170, - 171, 175, 175, 178, 180, 189, 158, 159, - 176, 177, 130, 134, 139, 172, 163, 167, - 128, 129, 180, 255, 134, 159, 178, 190, - 192, 255, 166, 173, 135, 147, 128, 131, - 179, 255, 129, 164, 166, 255, 169, 182, - 131, 188, 140, 141, 176, 178, 180, 183, - 184, 190, 191, 129, 171, 175, 181, 182, - 163, 170, 172, 173, 172, 184, 190, 158, - 128, 143, 160, 175, 144, 145, 150, 155, - 157, 158, 159, 135, 139, 141, 168, 171, - 180, 186, 189, 189, 160, 182, 186, 191, - 129, 131, 133, 134, 140, 143, 184, 186, - 165, 166, 164, 167, 171, 172, 134, 144, - 128, 129, 130, 132, 133, 134, 135, 136, - 139, 140, 141, 144, 145, 146, 147, 150, - 151, 152, 153, 154, 156, 160, 164, 165, - 167, 168, 169, 170, 176, 178, 180, 181, - 182, 187, 128, 130, 184, 255, 135, 190, - 131, 175, 187, 255, 128, 130, 167, 180, - 179, 133, 134, 128, 130, 179, 255, 141, - 129, 136, 144, 255, 190, 172, 183, 159, - 170, 128, 131, 187, 188, 190, 191, 151, - 128, 132, 135, 136, 139, 141, 162, 163, - 166, 172, 176, 180, 181, 191, 158, 128, - 134, 132, 255, 175, 181, 184, 255, 129, - 155, 158, 255, 171, 183, 157, 171, 172, - 186, 176, 181, 183, 184, 187, 190, 128, - 130, 131, 164, 145, 151, 154, 160, 129, - 138, 179, 185, 187, 190, 135, 145, 155, - 138, 153, 175, 182, 184, 191, 146, 167, - 169, 182, 186, 177, 182, 188, 189, 191, - 255, 134, 136, 255, 138, 142, 144, 145, - 147, 151, 179, 182, 171, 172, 189, 190, - 191, 176, 180, 176, 182, 143, 145, 255, - 136, 142, 147, 255, 164, 176, 177, 178, - 157, 158, 133, 134, 137, 168, 169, 170, - 165, 169, 173, 178, 187, 255, 131, 132, - 140, 169, 174, 255, 130, 132, 128, 182, - 187, 255, 173, 180, 182, 255, 132, 155, - 159, 161, 175, 128, 132, 139, 163, 165, - 128, 134, 136, 152, 155, 161, 163, 164, - 166, 170, 172, 175, 144, 150, 132, 138, - 128, 131, 132, 133, 134, 135, 136, 137, - 139, 140, 141, 142, 143, 144, 145, 148, - 149, 151, 152, 153, 157, 159, 160, 161, - 162, 163, 164, 165, 168, 169, 176, 191, - 129, 150, 154, 155, 166, 171, 177, 190, - 192, 255, 175, 141, 143, 172, 177, 190, - 191, 142, 145, 154, 173, 255, 166, 255, - 154, 175, 129, 143, 178, 186, 188, 191, - 137, 255, 190, 255, 134, 255, 144, 255, - 180, 191, 149, 191, 140, 143, 136, 143, - 154, 159, 136, 143, 174, 255, 140, 186, - 188, 191, 128, 133, 135, 191, 160, 128, - 129, 132, 135, 133, 134, 160, 255, 128, - 130, 170, 175, 144, 145, 150, 155, 157, - 158, 159, 143, 187, 191, 144, 145, 150, - 155, 157, 158, 159, 135, 143, 166, 191, - 128, 154, 175, 187, 129, 143, 144, 177, - 178, 191, 128, 136, 137, 255, 187, 191, - 192, 255, 190, 191, 192, 255, 128, 133, - 134, 255, 144, 191, 192, 255, 128, 179, - 180, 191, 128, 148, 149, 191, 128, 139, - 140, 143, 144, 191, 128, 135, 136, 143, - 144, 153, 154, 159, 160, 191, 128, 135, - 136, 143, 144, 173, 174, 255, 187, 128, - 139, 140, 191, 134, 128, 191, 128, 191, - 160, 128, 191, 128, 130, 131, 135, 191, - 129, 134, 136, 190, 128, 159, 160, 191, - 0, 127, 192, 255, 128, 175, 176, 255, - 10, 13, 127, 194, 216, 219, 220, 224, - 225, 226, 227, 234, 235, 236, 237, 239, - 240, 243, 0, 31, 128, 191, 192, 223, - 228, 238, 241, 247, 248, 255, 204, 205, - 210, 214, 215, 216, 217, 219, 220, 221, - 222, 223, 224, 225, 226, 227, 234, 239, - 240, 243, 204, 205, 210, 214, 215, 216, - 217, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 234, 239, 240, 243, 194, 204, - 205, 210, 214, 215, 216, 217, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 234, - 239, 240, 243, 194, 216, 219, 220, 224, - 225, 226, 227, 234, 235, 236, 237, 239, - 240, 243, 32, 126, 192, 223, 228, 238, - 241, 247, 204, 205, 210, 214, 215, 216, - 217, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 234, 239, 240, 243, 204, 205, - 210, 214, 215, 216, 217, 219, 220, 221, - 222, 223, 224, 225, 226, 227, 234, 239, - 240, 243, 194, 204, 205, 210, 214, 215, - 216, 217, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 234, 239, 240, 243, 204, - 205, 210, 214, 215, 216, 217, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 234, - 235, 236, 237, 239, 240, 243, 204, 205, - 210, 214, 215, 216, 217, 219, 220, 221, - 222, 223, 224, 225, 226, 227, 234, 237, - 239, 240, 243, 204, 205, 210, 214, 215, - 216, 217, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 234, 237, 239, 240, 243, - 204, 205, 210, 214, 215, 216, 217, 219, - 220, 221, 222, 223, 224, 225, 226, 227, - 234, 237, 239, 240, 243, 204, 205, 210, - 214, 215, 216, 217, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 234, 239, 240, - 243, 204, 205, 210, 214, 215, 216, 217, - 219, 220, 221, 222, 223, 224, 225, 226, - 227, 234, 235, 236, 237, 239, 240, 243, - 204, 205, 210, 214, 215, 216, 217, 219, - 220, 221, 222, 223, 224, 225, 226, 227, - 234, 239, 240, 243, 194, 204, 205, 210, - 214, 215, 216, 217, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 234, 239, 240, - 243, 204, 205, 210, 214, 215, 216, 217, - 219, 220, 221, 222, 223, 224, 225, 226, - 227, 234, 237, 239, 240, 243, 204, 205, - 210, 214, 215, 216, 217, 219, 220, 221, - 222, 223, 224, 225, 226, 227, 234, 237, - 239, 240, 243, 204, 205, 210, 214, 215, - 216, 217, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 234, 237, 239, 240, 243, - 204, 205, 210, 214, 215, 216, 217, 219, - 220, 221, 222, 223, 224, 225, 226, 227, - 234, 239, 240, 243, 204, 205, 210, 214, - 215, 216, 217, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 234, 239, 240, 243, - 204, 205, 210, 214, 215, 216, 217, 219, - 220, 221, 222, 223, 224, 225, 226, 227, - 234, 239, 240, 243, 194, 204, 205, 210, - 214, 215, 216, 217, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 234, 239, 240, - 243, -} - -var _graphclust_single_lengths []byte = []byte{ - 0, 1, 0, 0, 0, 1, 1, 0, - 1, 0, 1, 0, 0, 1, 26, 0, - 0, 0, 1, 1, 1, 0, 0, 2, - 1, 0, 1, 1, 0, 2, 0, 0, - 2, 0, 2, 1, 0, 1, 0, 3, - 0, 0, 1, 22, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, - 2, 0, 5, 0, 0, 0, 1, 0, - 2, 0, 0, 15, 0, 0, 0, 4, - 0, 0, 0, 0, 0, 0, 0, 2, - 1, 1, 0, 3, 1, 0, 7, 8, - 1, 1, 0, 1, 0, 0, 0, 0, - 34, 0, 0, 0, 0, 1, 0, 1, - 1, 0, 0, 1, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, - 1, 0, 0, 0, 1, 1, 0, 0, - 5, 0, 0, 1, 0, 1, 1, 0, - 6, 0, 0, 0, 0, 0, 1, 5, - 0, 0, 0, 0, 1, 0, 1, 4, - 0, 0, 0, 0, 3, 0, 0, 0, - 1, 1, 0, 1, 0, 1, 0, 0, - 1, 26, 0, 0, 0, 1, 1, 1, - 0, 0, 2, 1, 0, 1, 1, 0, - 2, 0, 0, 2, 0, 2, 1, 0, - 1, 0, 3, 0, 0, 1, 22, 0, - 0, 3, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 3, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 5, 2, 2, - 24, 3, 1, 0, 2, 0, 1, 1, - 1, 1, 1, 1, 0, 0, 0, 0, - 2, 5, 3, 0, 0, 2, 0, 1, - 0, 3, 1, 0, 2, 15, 0, 0, - 0, 4, 0, 0, 0, 0, 0, 0, - 0, 2, 1, 1, 0, 3, 1, 0, - 7, 8, 1, 1, 0, 1, 0, 0, - 0, 0, 34, 0, 0, 0, 0, 1, - 0, 1, 1, 0, 0, 1, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 1, - 1, 0, 1, 0, 0, 0, 1, 1, - 0, 0, 5, 0, 0, 1, 0, 1, - 1, 0, 6, 0, 0, 0, 0, 0, - 1, 5, 0, 0, 0, 0, 32, 0, - 1, 0, 1, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 4, 0, 2, 0, 7, 1, 0, - 1, 0, 0, 0, 1, 1, 0, 1, - 0, 1, 0, 0, 1, 26, 0, 0, - 0, 1, 1, 1, 0, 0, 2, 1, - 0, 1, 1, 0, 2, 0, 0, 2, - 0, 2, 1, 0, 1, 0, 3, 0, - 0, 1, 22, 0, 0, 3, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 3, - 0, 0, 0, 0, 0, 0, 0, 2, - 0, 5, 0, 0, 0, 1, 0, 2, - 0, 0, 15, 0, 0, 0, 4, 0, - 0, 0, 0, 0, 0, 0, 2, 1, - 1, 0, 3, 1, 0, 7, 8, 1, - 1, 0, 1, 0, 0, 0, 0, 34, - 0, 0, 0, 0, 1, 0, 1, 1, - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 1, - 0, 0, 0, 1, 1, 0, 0, 5, - 0, 0, 1, 0, 1, 1, 0, 6, - 0, 0, 0, 0, 0, 1, 5, 0, - 0, 0, 0, 1, 0, 1, 4, 0, - 0, 0, 0, 2, 0, 0, 0, 1, - 1, 0, 1, 0, 1, 0, 0, 1, - 26, 0, 0, 0, 1, 1, 1, 0, - 0, 2, 1, 0, 1, 1, 0, 2, - 0, 0, 2, 0, 2, 1, 0, 1, - 0, 3, 0, 0, 1, 22, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 3, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 5, 2, 2, 24, - 3, 1, 0, 2, 0, 1, 1, 1, - 1, 1, 1, 0, 0, 0, 0, 2, - 5, 3, 0, 0, 2, 0, 1, 0, - 3, 1, 0, 2, 15, 0, 0, 0, - 4, 0, 0, 0, 0, 0, 0, 0, - 2, 1, 1, 0, 3, 1, 0, 7, - 8, 1, 1, 0, 1, 0, 0, 0, - 0, 34, 0, 0, 0, 0, 1, 0, - 1, 1, 0, 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 5, 0, 0, 1, 0, 1, 1, - 0, 6, 0, 0, 0, 0, 0, 1, - 5, 0, 0, 0, 0, 32, 0, 1, - 0, 1, 0, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, - 4, 0, 2, 0, 7, 1, 0, 0, - 1, 1, 2, 1, 1, 5, 0, 25, - 0, 25, 0, 0, 24, 0, 0, 1, - 0, 2, 0, 0, 0, 28, 0, 3, - 24, 2, 0, 2, 2, 3, 2, 2, - 2, 0, 54, 54, 27, 1, 0, 20, - 1, 1, 2, 0, 1, 1, 1, 1, - 1, 2, 2, 0, 2, 5, 3, 0, - 0, 2, 2, 2, 2, 0, 14, 0, - 3, 2, 2, 3, 2, 2, 2, 54, - 54, 27, 1, 0, 2, 0, 1, 5, - 8, 1, 1, 0, 1, 1, 1, 0, - 1, 1, 0, 1, 0, 1, 0, 34, - 1, 0, 1, 0, 7, 2, 0, 4, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 1, 3, 0, - 1, 1, 2, 1, 1, 5, 0, 0, - 0, 0, 1, 1, 0, 1, 0, 1, - 0, 0, 1, 26, 0, 0, 0, 1, - 1, 1, 0, 0, 2, 1, 0, 1, - 1, 0, 2, 0, 0, 2, 0, 2, - 1, 0, 1, 0, 3, 0, 0, 1, - 22, 0, 0, 3, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 3, 0, 0, - 0, 0, 0, 0, 0, 2, 0, 5, - 2, 2, 24, 3, 1, 0, 2, 0, - 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 2, 5, 3, 0, 0, 2, - 0, 1, 0, 3, 1, 0, 2, 15, - 0, 0, 0, 4, 0, 0, 0, 0, - 0, 0, 0, 2, 1, 1, 0, 3, - 1, 0, 7, 8, 1, 1, 0, 1, - 0, 0, 0, 0, 34, 0, 0, 0, - 0, 1, 0, 1, 1, 0, 0, 1, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 0, 0, 0, - 1, 1, 0, 0, 5, 0, 0, 1, - 0, 1, 1, 0, 6, 0, 0, 0, - 0, 0, 1, 5, 0, 0, 0, 0, - 32, 0, 1, 0, 1, 0, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 4, 0, 2, 0, 7, - 1, 0, 25, 0, 25, 0, 0, 24, - 0, 0, 1, 0, 2, 0, 0, 0, - 28, 0, 3, 24, 2, 0, 2, 2, - 3, 2, 2, 2, 0, 54, 54, 27, - 1, 1, 20, 3, 0, 0, 0, 1, - 1, 0, 1, 0, 1, 0, 0, 1, - 26, 0, 0, 0, 1, 1, 1, 0, - 0, 2, 1, 0, 1, 1, 0, 2, - 0, 0, 2, 0, 2, 1, 0, 1, - 0, 3, 0, 0, 1, 22, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 3, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 5, 0, 0, 0, - 1, 0, 2, 0, 0, 15, 0, 0, - 0, 4, 0, 0, 0, 0, 0, 0, - 0, 2, 1, 1, 0, 3, 1, 0, - 7, 8, 1, 1, 0, 1, 0, 0, - 0, 0, 34, 0, 0, 0, 0, 1, - 0, 1, 1, 0, 0, 1, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 1, - 1, 0, 1, 0, 0, 0, 1, 1, - 0, 0, 5, 0, 0, 1, 0, 1, - 1, 0, 6, 0, 0, 0, 0, 0, - 1, 5, 0, 0, 0, 0, 1, 0, - 1, 4, 0, 0, 0, 1, 2, 0, - 1, 1, 1, 1, 1, 2, 2, 0, - 2, 5, 3, 0, 0, 2, 2, 2, - 2, 0, 14, 0, 3, 2, 2, 3, - 2, 2, 2, 54, 54, 27, 1, 0, - 2, 1, 1, 5, 8, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, 1, - 0, 1, 0, 34, 1, 0, 1, 0, - 0, 0, 0, 1, 1, 0, 1, 0, - 1, 0, 0, 1, 26, 0, 0, 0, - 1, 1, 1, 0, 0, 2, 1, 0, - 1, 1, 0, 2, 0, 0, 2, 0, - 2, 1, 0, 1, 0, 3, 0, 0, - 1, 22, 0, 0, 3, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, 2, 0, - 5, 2, 2, 24, 3, 1, 0, 2, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 2, 5, 3, 0, 0, - 2, 0, 1, 0, 3, 1, 0, 2, - 15, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 2, 1, 1, 0, - 3, 1, 0, 7, 8, 1, 1, 0, - 1, 0, 0, 0, 0, 34, 0, 0, - 0, 0, 1, 0, 1, 1, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 1, 0, 0, - 0, 1, 1, 0, 0, 5, 0, 0, - 1, 0, 1, 1, 0, 6, 0, 0, - 0, 0, 0, 1, 5, 0, 0, 0, - 0, 32, 0, 1, 0, 1, 0, 2, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 4, 0, 2, 0, - 7, 1, 0, 7, 2, 0, 4, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 5, 0, 0, - 0, 0, 0, 18, 20, 20, 21, 15, - 20, 20, 21, 23, 21, 21, 21, 20, - 23, 20, 21, 21, 21, 21, 20, 20, - 20, 21, -} - -var _graphclust_range_lengths []byte = []byte{ - 0, 0, 1, 1, 1, 1, 2, 1, - 1, 4, 1, 1, 1, 1, 2, 4, - 1, 2, 1, 2, 2, 6, 6, 3, - 2, 5, 1, 3, 2, 3, 5, 3, - 3, 1, 3, 1, 1, 1, 1, 2, - 1, 4, 0, 0, 2, 3, 1, 1, - 2, 2, 1, 2, 1, 1, 2, 1, - 2, 1, 1, 2, 2, 2, 1, 1, - 3, 2, 0, 1, 1, 1, 0, 1, - 0, 1, 1, 0, 2, 1, 1, 1, - 2, 3, 1, 1, 2, 2, 1, 1, - 3, 2, 2, 0, 0, 2, 0, 0, - 0, 0, 1, 4, 1, 1, 1, 1, - 0, 2, 1, 2, 2, 1, 2, 2, - 1, 1, 3, 6, 1, 1, 1, 2, - 2, 1, 1, 1, 3, 1, 2, 3, - 1, 1, 2, 2, 3, 1, 3, 1, - 0, 1, 1, 1, 2, 1, 0, 1, - 0, 3, 3, 1, 2, 2, 2, 0, - 5, 1, 1, 1, 0, 1, 0, 1, - 1, 1, 0, 1, 2, 1, 1, 1, - 1, 2, 1, 1, 4, 1, 1, 1, - 1, 2, 4, 1, 2, 1, 2, 2, - 6, 6, 3, 2, 5, 1, 3, 2, - 3, 5, 3, 3, 1, 3, 1, 1, - 1, 1, 2, 1, 4, 0, 0, 2, - 3, 1, 1, 2, 2, 1, 2, 1, - 1, 2, 1, 2, 1, 1, 2, 2, - 2, 1, 1, 3, 2, 0, 0, 0, - 0, 0, 0, 1, 0, 2, 1, 0, - 2, 0, 1, 1, 3, 1, 2, 0, - 6, 2, 1, 1, 2, 0, 1, 0, - 1, 0, 1, 1, 0, 0, 2, 1, - 1, 1, 2, 3, 1, 1, 2, 2, - 1, 1, 3, 2, 2, 0, 0, 2, - 0, 0, 0, 0, 1, 4, 1, 1, - 1, 1, 0, 2, 1, 2, 2, 1, - 2, 2, 1, 1, 3, 6, 1, 1, - 1, 2, 2, 1, 1, 1, 3, 1, - 2, 3, 1, 1, 2, 2, 3, 1, - 3, 1, 0, 1, 1, 1, 2, 1, - 0, 1, 0, 3, 3, 1, 2, 2, - 2, 0, 5, 1, 1, 1, 4, 1, - 1, 2, 2, 1, 3, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 2, 2, - 0, 1, 1, 0, 1, 0, 0, 1, - 2, 1, 1, 1, 1, 2, 1, 1, - 4, 1, 1, 1, 1, 2, 4, 1, - 2, 1, 2, 2, 6, 6, 3, 2, - 5, 1, 3, 2, 3, 5, 3, 3, - 1, 3, 1, 1, 1, 1, 2, 1, - 4, 0, 0, 2, 3, 1, 1, 2, - 2, 1, 2, 1, 1, 2, 1, 2, - 1, 1, 2, 2, 2, 1, 1, 3, - 2, 0, 1, 1, 1, 0, 1, 0, - 1, 1, 0, 2, 1, 1, 1, 2, - 3, 1, 1, 2, 2, 1, 1, 3, - 2, 2, 0, 0, 2, 0, 0, 0, - 0, 1, 4, 1, 1, 1, 1, 0, - 2, 1, 2, 2, 1, 2, 2, 1, - 1, 3, 6, 1, 1, 1, 2, 2, - 1, 1, 1, 3, 1, 2, 3, 1, - 1, 2, 2, 3, 1, 3, 1, 0, - 1, 1, 1, 2, 1, 0, 1, 0, - 3, 3, 1, 2, 2, 2, 0, 5, - 1, 1, 1, 0, 1, 0, 1, 1, - 1, 0, 1, 2, 1, 1, 1, 1, - 2, 1, 1, 4, 1, 1, 1, 1, - 2, 4, 1, 2, 1, 2, 2, 6, - 6, 3, 2, 5, 1, 3, 2, 3, - 5, 3, 3, 1, 3, 1, 1, 1, - 1, 2, 1, 4, 0, 0, 2, 3, - 1, 1, 2, 2, 1, 2, 1, 1, - 2, 1, 2, 1, 1, 2, 2, 2, - 1, 1, 3, 2, 0, 0, 0, 0, - 0, 0, 1, 0, 2, 1, 0, 2, - 0, 1, 1, 3, 1, 2, 0, 6, - 2, 1, 1, 2, 0, 1, 0, 1, - 0, 1, 1, 0, 0, 2, 1, 1, - 1, 2, 3, 1, 1, 2, 2, 1, - 1, 3, 2, 2, 0, 0, 2, 0, - 0, 0, 0, 1, 4, 1, 1, 1, - 1, 0, 2, 1, 2, 2, 1, 2, - 2, 1, 1, 3, 6, 1, 1, 1, - 2, 2, 1, 1, 1, 3, 1, 2, - 3, 1, 1, 2, 2, 3, 1, 3, - 1, 0, 1, 1, 1, 2, 1, 0, - 1, 0, 3, 3, 1, 2, 2, 2, - 0, 5, 1, 1, 1, 4, 1, 1, - 2, 2, 1, 3, 1, 1, 1, 1, - 1, 1, 1, 2, 2, 2, 2, 0, - 1, 1, 0, 1, 0, 0, 1, 3, - 1, 1, 1, 1, 1, 1, 1, 0, - 1, 0, 1, 1, 0, 1, 1, 0, - 1, 0, 1, 3, 1, 2, 2, 1, - 0, 0, 1, 0, 0, 0, 0, 0, - 1, 0, 1, 1, 2, 2, 2, 1, - 4, 2, 1, 5, 3, 1, 5, 1, - 3, 2, 1, 3, 7, 5, 3, 3, - 5, 1, 1, 1, 1, 1, 3, 3, - 1, 0, 0, 0, 0, 0, 1, 1, - 1, 3, 2, 4, 1, 1, 2, 1, - 1, 1, 1, 3, 1, 1, 1, 3, - 1, 1, 2, 1, 2, 1, 2, 4, - 3, 4, 4, 2, 0, 0, 1, 3, - 2, 2, 2, 2, 2, 2, 2, 3, - 5, 4, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 4, 1, - 1, 1, 1, 2, 4, 1, 2, 1, - 2, 2, 6, 6, 3, 2, 5, 1, - 3, 2, 3, 5, 3, 3, 1, 3, - 1, 1, 1, 1, 2, 1, 4, 0, - 0, 2, 3, 1, 1, 2, 2, 1, - 2, 1, 1, 2, 1, 2, 1, 1, - 2, 2, 2, 1, 1, 3, 2, 0, - 0, 0, 0, 0, 0, 1, 0, 2, - 1, 0, 2, 0, 1, 1, 3, 1, - 2, 0, 6, 2, 1, 1, 2, 0, - 1, 0, 1, 0, 1, 1, 0, 0, - 2, 1, 1, 1, 2, 3, 1, 1, - 2, 2, 1, 1, 3, 2, 2, 0, - 0, 2, 0, 0, 0, 0, 1, 4, - 1, 1, 1, 1, 0, 2, 1, 2, - 2, 1, 2, 2, 1, 1, 3, 6, - 1, 1, 1, 2, 2, 1, 1, 1, - 3, 1, 2, 3, 1, 1, 2, 2, - 3, 1, 3, 1, 0, 1, 1, 1, - 2, 1, 0, 1, 0, 3, 3, 1, - 2, 2, 2, 0, 5, 1, 1, 1, - 4, 1, 1, 2, 2, 1, 3, 1, - 1, 1, 1, 1, 1, 1, 2, 2, - 2, 2, 0, 1, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 0, 1, 3, 1, - 2, 2, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0, 1, 1, 2, - 2, 1, 1, 5, 1, 1, 1, 1, - 2, 1, 1, 4, 1, 1, 1, 1, - 2, 4, 1, 2, 1, 2, 2, 6, - 6, 3, 2, 5, 1, 3, 2, 3, - 5, 3, 3, 1, 3, 1, 1, 1, - 1, 2, 1, 4, 0, 0, 2, 3, - 1, 1, 2, 2, 1, 2, 1, 1, - 2, 1, 2, 1, 1, 2, 2, 2, - 1, 1, 3, 2, 0, 1, 1, 1, - 0, 1, 0, 1, 1, 0, 2, 1, - 1, 1, 2, 3, 1, 1, 2, 2, - 1, 1, 3, 2, 2, 0, 0, 2, - 0, 0, 0, 0, 1, 4, 1, 1, - 1, 1, 0, 2, 1, 2, 2, 1, - 2, 2, 1, 1, 3, 6, 1, 1, - 1, 2, 2, 1, 1, 1, 3, 1, - 2, 3, 1, 1, 2, 2, 3, 1, - 3, 1, 0, 1, 1, 1, 2, 1, - 0, 1, 0, 3, 3, 1, 2, 2, - 2, 0, 5, 1, 1, 1, 0, 1, - 0, 1, 1, 1, 0, 3, 1, 5, - 3, 1, 5, 1, 3, 2, 1, 3, - 7, 5, 3, 3, 5, 1, 1, 1, - 1, 1, 3, 3, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 3, 2, 4, - 1, 1, 3, 1, 1, 1, 1, 3, - 1, 1, 1, 3, 1, 1, 3, 1, - 3, 1, 3, 4, 3, 4, 4, 2, - 1, 1, 1, 1, 2, 1, 1, 4, - 1, 1, 1, 1, 2, 4, 1, 2, - 1, 2, 2, 6, 6, 3, 2, 5, - 1, 3, 2, 3, 5, 3, 3, 1, - 3, 1, 1, 1, 1, 2, 1, 4, - 0, 0, 2, 3, 1, 1, 2, 2, - 1, 2, 1, 1, 2, 1, 2, 1, - 1, 2, 2, 2, 1, 1, 3, 2, - 0, 0, 0, 0, 0, 0, 1, 0, - 2, 1, 0, 2, 0, 1, 1, 3, - 1, 2, 0, 6, 2, 1, 1, 2, - 0, 1, 0, 1, 0, 1, 1, 0, - 0, 2, 1, 1, 1, 2, 3, 1, - 1, 2, 2, 1, 1, 3, 2, 2, - 0, 0, 2, 0, 0, 0, 0, 1, - 4, 1, 1, 1, 1, 0, 2, 1, - 2, 2, 1, 2, 2, 1, 1, 3, - 6, 1, 1, 1, 2, 2, 1, 1, - 1, 3, 1, 2, 3, 1, 1, 2, - 2, 3, 1, 3, 1, 0, 1, 1, - 1, 2, 1, 0, 1, 0, 3, 3, - 1, 2, 2, 2, 0, 5, 1, 1, - 1, 4, 1, 1, 2, 2, 1, 3, - 1, 1, 1, 1, 1, 1, 1, 2, - 2, 2, 2, 0, 1, 1, 0, 1, - 0, 0, 1, 0, 0, 1, 3, 2, - 2, 2, 2, 2, 2, 2, 3, 5, - 4, 2, 1, 1, 1, 2, 2, 1, - 1, 2, 0, 6, 0, 0, 0, 4, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -} - -var _graphclust_index_offsets []int16 = []int16{ - 0, 0, 2, 4, 6, 8, 11, 15, - 17, 20, 25, 28, 30, 32, 35, 64, - 69, 71, 74, 77, 81, 85, 92, 99, - 105, 109, 115, 118, 123, 126, 132, 138, - 142, 148, 150, 156, 159, 161, 164, 166, - 172, 174, 179, 181, 204, 207, 211, 216, - 218, 221, 224, 226, 229, 231, 234, 237, - 239, 245, 247, 249, 252, 255, 258, 260, - 262, 268, 271, 277, 279, 281, 283, 285, - 287, 290, 292, 294, 310, 313, 315, 317, - 323, 326, 330, 332, 334, 337, 340, 342, - 346, 351, 355, 358, 362, 364, 367, 375, - 384, 386, 388, 390, 396, 398, 400, 402, - 404, 439, 442, 444, 447, 450, 453, 456, - 460, 463, 465, 469, 477, 479, 482, 484, - 487, 490, 492, 494, 496, 500, 503, 507, - 511, 514, 516, 519, 522, 527, 530, 534, - 536, 542, 544, 546, 549, 552, 555, 557, - 559, 566, 570, 574, 576, 579, 582, 586, - 592, 598, 600, 602, 604, 606, 608, 610, - 616, 618, 620, 621, 623, 629, 631, 633, - 635, 638, 642, 644, 647, 652, 655, 657, - 659, 662, 691, 696, 698, 701, 704, 708, - 712, 719, 726, 732, 736, 742, 745, 750, - 753, 759, 765, 769, 775, 777, 783, 786, - 788, 791, 793, 799, 801, 806, 808, 831, - 834, 838, 843, 845, 848, 851, 853, 856, - 858, 861, 864, 866, 872, 874, 876, 879, - 882, 885, 887, 889, 895, 898, 904, 907, - 910, 935, 939, 941, 943, 946, 949, 952, - 954, 958, 960, 963, 966, 970, 972, 975, - 976, 985, 993, 998, 1000, 1003, 1006, 1008, - 1010, 1012, 1016, 1019, 1021, 1024, 1040, 1043, - 1045, 1047, 1053, 1056, 1060, 1062, 1064, 1067, - 1070, 1072, 1076, 1081, 1085, 1088, 1092, 1094, - 1097, 1105, 1114, 1116, 1118, 1120, 1126, 1128, - 1130, 1132, 1134, 1169, 1172, 1174, 1177, 1180, - 1183, 1186, 1190, 1193, 1195, 1199, 1207, 1209, - 1212, 1214, 1217, 1220, 1222, 1224, 1226, 1230, - 1233, 1237, 1241, 1244, 1246, 1249, 1252, 1257, - 1260, 1264, 1266, 1272, 1274, 1276, 1279, 1282, - 1285, 1287, 1289, 1296, 1300, 1304, 1306, 1309, - 1312, 1316, 1322, 1328, 1330, 1332, 1334, 1371, - 1373, 1376, 1379, 1383, 1385, 1391, 1393, 1395, - 1397, 1399, 1401, 1403, 1405, 1408, 1411, 1414, - 1417, 1419, 1425, 1427, 1430, 1432, 1440, 1442, - 1444, 1448, 1450, 1452, 1454, 1457, 1461, 1463, - 1466, 1471, 1474, 1476, 1478, 1481, 1510, 1515, - 1517, 1520, 1523, 1527, 1531, 1538, 1545, 1551, - 1555, 1561, 1564, 1569, 1572, 1578, 1584, 1588, - 1594, 1596, 1602, 1605, 1607, 1610, 1612, 1618, - 1620, 1625, 1627, 1650, 1653, 1657, 1662, 1664, - 1667, 1670, 1672, 1675, 1677, 1680, 1683, 1685, - 1691, 1693, 1695, 1698, 1701, 1704, 1706, 1708, - 1714, 1717, 1723, 1725, 1727, 1729, 1731, 1733, - 1736, 1738, 1740, 1756, 1759, 1761, 1763, 1769, - 1772, 1776, 1778, 1780, 1783, 1786, 1788, 1792, - 1797, 1801, 1804, 1808, 1810, 1813, 1821, 1830, - 1832, 1834, 1836, 1842, 1844, 1846, 1848, 1850, - 1885, 1888, 1890, 1893, 1896, 1899, 1902, 1906, - 1909, 1911, 1915, 1923, 1925, 1928, 1930, 1933, - 1936, 1938, 1940, 1942, 1946, 1949, 1953, 1957, - 1960, 1962, 1965, 1968, 1973, 1976, 1980, 1982, - 1988, 1990, 1992, 1995, 1998, 2001, 2003, 2005, - 2012, 2016, 2020, 2022, 2025, 2028, 2032, 2038, - 2044, 2046, 2048, 2050, 2052, 2054, 2056, 2062, - 2064, 2066, 2067, 2069, 2074, 2076, 2078, 2080, - 2083, 2087, 2089, 2092, 2097, 2100, 2102, 2104, - 2107, 2136, 2141, 2143, 2146, 2149, 2153, 2157, - 2164, 2171, 2177, 2181, 2187, 2190, 2195, 2198, - 2204, 2210, 2214, 2220, 2222, 2228, 2231, 2233, - 2236, 2238, 2244, 2246, 2251, 2253, 2276, 2279, - 2283, 2288, 2290, 2293, 2296, 2298, 2301, 2303, - 2306, 2309, 2311, 2317, 2319, 2321, 2324, 2327, - 2330, 2332, 2334, 2340, 2343, 2349, 2352, 2355, - 2380, 2384, 2386, 2388, 2391, 2394, 2397, 2399, - 2403, 2405, 2408, 2411, 2415, 2417, 2420, 2421, - 2430, 2438, 2443, 2445, 2448, 2451, 2453, 2455, - 2457, 2461, 2464, 2466, 2469, 2485, 2488, 2490, - 2492, 2498, 2501, 2505, 2507, 2509, 2512, 2515, - 2517, 2521, 2526, 2530, 2533, 2537, 2539, 2542, - 2550, 2559, 2561, 2563, 2565, 2571, 2573, 2575, - 2577, 2579, 2614, 2617, 2619, 2622, 2625, 2628, - 2631, 2635, 2638, 2640, 2644, 2652, 2654, 2657, - 2659, 2662, 2665, 2667, 2669, 2671, 2675, 2678, - 2682, 2686, 2689, 2691, 2694, 2697, 2702, 2705, - 2709, 2711, 2717, 2719, 2721, 2724, 2727, 2730, - 2732, 2734, 2741, 2745, 2749, 2751, 2754, 2757, - 2761, 2767, 2773, 2775, 2777, 2779, 2816, 2818, - 2821, 2824, 2828, 2830, 2836, 2838, 2840, 2842, - 2844, 2846, 2848, 2850, 2853, 2856, 2859, 2862, - 2864, 2870, 2872, 2875, 2877, 2885, 2887, 2889, - 2893, 2896, 2899, 2903, 2906, 2909, 2916, 2918, - 2944, 2946, 2972, 2974, 2976, 3001, 3003, 3005, - 3007, 3009, 3012, 3014, 3018, 3020, 3051, 3054, - 3059, 3084, 3087, 3089, 3092, 3095, 3099, 3102, - 3105, 3109, 3110, 3166, 3222, 3252, 3256, 3259, - 3281, 3287, 3291, 3295, 3301, 3306, 3309, 3316, - 3319, 3324, 3329, 3333, 3337, 3347, 3358, 3365, - 3369, 3375, 3379, 3383, 3387, 3391, 3393, 3411, - 3415, 3420, 3423, 3426, 3430, 3433, 3436, 3440, - 3496, 3552, 3583, 3587, 3592, 3596, 3598, 3602, - 3609, 3619, 3622, 3625, 3629, 3632, 3635, 3638, - 3642, 3645, 3648, 3651, 3654, 3657, 3660, 3663, - 3702, 3707, 3712, 3718, 3721, 3729, 3732, 3734, - 3742, 3745, 3748, 3751, 3754, 3757, 3760, 3763, - 3767, 3773, 3778, 3782, 3785, 3787, 3790, 3795, - 3797, 3800, 3803, 3807, 3810, 3813, 3820, 3822, - 3824, 3826, 3828, 3831, 3835, 3837, 3840, 3845, - 3848, 3850, 3852, 3855, 3884, 3889, 3891, 3894, - 3897, 3901, 3905, 3912, 3919, 3925, 3929, 3935, - 3938, 3943, 3946, 3952, 3958, 3962, 3968, 3970, - 3976, 3979, 3981, 3984, 3986, 3992, 3994, 3999, - 4001, 4024, 4027, 4031, 4036, 4038, 4041, 4044, - 4046, 4049, 4051, 4054, 4057, 4059, 4065, 4067, - 4069, 4072, 4075, 4078, 4080, 4082, 4088, 4091, - 4097, 4100, 4103, 4128, 4132, 4134, 4136, 4139, - 4142, 4145, 4147, 4151, 4153, 4156, 4159, 4163, - 4165, 4168, 4169, 4178, 4186, 4191, 4193, 4196, - 4199, 4201, 4203, 4205, 4209, 4212, 4214, 4217, - 4233, 4236, 4238, 4240, 4246, 4249, 4253, 4255, - 4257, 4260, 4263, 4265, 4269, 4274, 4278, 4281, - 4285, 4287, 4290, 4298, 4307, 4309, 4311, 4313, - 4319, 4321, 4323, 4325, 4327, 4362, 4365, 4367, - 4370, 4373, 4376, 4379, 4383, 4386, 4388, 4392, - 4400, 4402, 4405, 4407, 4410, 4413, 4415, 4417, - 4419, 4423, 4426, 4430, 4434, 4437, 4439, 4442, - 4445, 4450, 4453, 4457, 4459, 4465, 4467, 4469, - 4472, 4475, 4478, 4480, 4482, 4489, 4493, 4497, - 4499, 4502, 4505, 4509, 4515, 4521, 4523, 4525, - 4527, 4564, 4566, 4569, 4572, 4576, 4578, 4584, - 4586, 4588, 4590, 4592, 4594, 4596, 4598, 4601, - 4604, 4607, 4610, 4612, 4618, 4620, 4623, 4625, - 4633, 4635, 4637, 4663, 4665, 4691, 4693, 4695, - 4720, 4722, 4724, 4726, 4728, 4731, 4733, 4737, - 4739, 4770, 4773, 4778, 4803, 4806, 4808, 4811, - 4814, 4818, 4821, 4824, 4828, 4829, 4885, 4941, - 4971, 4975, 4978, 5000, 5009, 5011, 5013, 5015, - 5018, 5022, 5024, 5027, 5032, 5035, 5037, 5039, - 5042, 5071, 5076, 5078, 5081, 5084, 5088, 5092, - 5099, 5106, 5112, 5116, 5122, 5125, 5130, 5133, - 5139, 5145, 5149, 5155, 5157, 5163, 5166, 5168, - 5171, 5173, 5179, 5181, 5186, 5188, 5211, 5214, - 5218, 5223, 5225, 5228, 5231, 5233, 5236, 5238, - 5241, 5244, 5246, 5252, 5254, 5256, 5259, 5262, - 5265, 5267, 5269, 5275, 5278, 5284, 5286, 5288, - 5290, 5292, 5294, 5297, 5299, 5301, 5317, 5320, - 5322, 5324, 5330, 5333, 5337, 5339, 5341, 5344, - 5347, 5349, 5353, 5358, 5362, 5365, 5369, 5371, - 5374, 5382, 5391, 5393, 5395, 5397, 5403, 5405, - 5407, 5409, 5411, 5446, 5449, 5451, 5454, 5457, - 5460, 5463, 5467, 5470, 5472, 5476, 5484, 5486, - 5489, 5491, 5494, 5497, 5499, 5501, 5503, 5507, - 5510, 5514, 5518, 5521, 5523, 5526, 5529, 5534, - 5537, 5541, 5543, 5549, 5551, 5553, 5556, 5559, - 5562, 5564, 5566, 5573, 5577, 5581, 5583, 5586, - 5589, 5593, 5599, 5605, 5607, 5609, 5611, 5613, - 5615, 5617, 5623, 5625, 5627, 5628, 5633, 5637, - 5643, 5648, 5651, 5658, 5661, 5666, 5671, 5675, - 5679, 5689, 5700, 5707, 5711, 5717, 5721, 5725, - 5729, 5733, 5735, 5753, 5757, 5762, 5765, 5768, - 5772, 5775, 5778, 5782, 5838, 5894, 5925, 5929, - 5934, 5938, 5941, 5946, 5953, 5963, 5966, 5969, - 5973, 5976, 5979, 5982, 5986, 5989, 5992, 5996, - 5999, 6003, 6006, 6010, 6049, 6054, 6059, 6065, - 6068, 6070, 6072, 6074, 6077, 6081, 6083, 6086, - 6091, 6094, 6096, 6098, 6101, 6130, 6135, 6137, - 6140, 6143, 6147, 6151, 6158, 6165, 6171, 6175, - 6181, 6184, 6189, 6192, 6198, 6204, 6208, 6214, - 6216, 6222, 6225, 6227, 6230, 6232, 6238, 6240, - 6245, 6247, 6270, 6273, 6277, 6282, 6284, 6287, - 6290, 6292, 6295, 6297, 6300, 6303, 6305, 6311, - 6313, 6315, 6318, 6321, 6324, 6326, 6328, 6334, - 6337, 6343, 6346, 6349, 6374, 6378, 6380, 6382, - 6385, 6388, 6391, 6393, 6397, 6399, 6402, 6405, - 6409, 6411, 6414, 6415, 6424, 6432, 6437, 6439, - 6442, 6445, 6447, 6449, 6451, 6455, 6458, 6460, - 6463, 6479, 6482, 6484, 6486, 6492, 6495, 6499, - 6501, 6503, 6506, 6509, 6511, 6515, 6520, 6524, - 6527, 6531, 6533, 6536, 6544, 6553, 6555, 6557, - 6559, 6565, 6567, 6569, 6571, 6573, 6608, 6611, - 6613, 6616, 6619, 6622, 6625, 6629, 6632, 6634, - 6638, 6646, 6648, 6651, 6653, 6656, 6659, 6661, - 6663, 6665, 6669, 6672, 6676, 6680, 6683, 6685, - 6688, 6691, 6696, 6699, 6703, 6705, 6711, 6713, - 6715, 6718, 6721, 6724, 6726, 6728, 6735, 6739, - 6743, 6745, 6748, 6751, 6755, 6761, 6767, 6769, - 6771, 6773, 6810, 6812, 6815, 6818, 6822, 6824, - 6830, 6832, 6834, 6836, 6838, 6840, 6842, 6844, - 6847, 6850, 6853, 6856, 6858, 6864, 6866, 6869, - 6871, 6879, 6881, 6883, 6891, 6894, 6896, 6904, - 6907, 6910, 6913, 6916, 6919, 6922, 6925, 6929, - 6935, 6940, 6944, 6947, 6949, 6952, 6960, 6963, - 6965, 6967, 6970, 6971, 6996, 7017, 7038, 7060, - 7080, 7101, 7122, 7144, 7168, 7190, 7212, 7234, - 7255, 7279, 7300, 7322, 7344, 7366, 7388, 7409, - 7430, 7451, -} - -var _graphclust_indicies []int16 = []int16{ - 0, 1, 3, 2, 2, 3, 3, 2, - 3, 3, 2, 3, 3, 3, 2, 3, - 2, 3, 3, 2, 3, 3, 3, 3, - 2, 3, 3, 2, 2, 3, 3, 2, - 3, 3, 2, 4, 5, 6, 7, 8, - 10, 11, 12, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 9, 13, 2, - 3, 3, 3, 3, 2, 3, 2, 3, - 3, 2, 2, 2, 3, 2, 2, 2, - 3, 3, 3, 3, 2, 2, 2, 2, - 2, 2, 2, 3, 2, 2, 2, 2, - 2, 2, 3, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 2, 3, 3, 3, - 3, 3, 2, 3, 3, 2, 3, 3, - 3, 3, 2, 3, 3, 2, 2, 2, - 2, 2, 2, 3, 3, 3, 3, 3, - 3, 2, 3, 3, 3, 2, 2, 2, - 2, 2, 2, 3, 3, 2, 3, 3, - 3, 3, 3, 2, 3, 3, 2, 3, - 2, 3, 3, 2, 3, 2, 3, 3, - 3, 3, 3, 2, 3, 2, 3, 3, - 3, 3, 2, 3, 2, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 2, 3, 3, 2, 3, - 3, 3, 2, 3, 3, 3, 3, 2, - 3, 2, 3, 3, 2, 3, 3, 2, - 3, 2, 2, 2, 3, 3, 2, 3, - 3, 2, 3, 3, 2, 3, 2, 3, - 3, 3, 3, 3, 2, 3, 2, 2, - 3, 3, 3, 2, 2, 2, 3, 3, - 3, 2, 3, 2, 3, 2, 3, 3, - 3, 3, 3, 2, 3, 3, 2, 54, - 55, 56, 57, 58, 2, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 59, - 60, 2, 3, 2, 3, 2, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 2, 3, 3, - 2, 3, 2, 3, 2, 3, 3, 3, - 3, 3, 2, 3, 3, 2, 2, 2, - 2, 3, 3, 2, 3, 2, 3, 3, - 2, 2, 2, 3, 3, 2, 3, 3, - 3, 2, 3, 3, 3, 3, 2, 3, - 3, 3, 2, 3, 3, 2, 76, 77, - 62, 2, 3, 2, 3, 3, 2, 78, - 79, 80, 81, 82, 83, 84, 2, 85, - 86, 87, 88, 89, 90, 91, 92, 2, - 3, 2, 3, 2, 3, 2, 3, 3, - 3, 3, 3, 2, 3, 2, 3, 2, - 3, 2, 3, 2, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, - 105, 45, 106, 107, 108, 45, 46, 109, - 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 2, 3, - 3, 2, 2, 3, 2, 2, 3, 3, - 3, 2, 3, 3, 2, 3, 3, 2, - 2, 2, 2, 3, 3, 3, 2, 3, - 2, 3, 3, 3, 2, 3, 3, 3, - 3, 3, 3, 3, 2, 3, 2, 3, - 3, 2, 2, 3, 3, 3, 2, 2, - 2, 3, 3, 2, 3, 2, 3, 2, - 3, 3, 3, 2, 3, 3, 2, 3, - 3, 3, 2, 3, 3, 3, 2, 3, - 3, 2, 3, 2, 3, 3, 2, 3, - 3, 2, 3, 3, 3, 3, 2, 2, - 2, 3, 3, 3, 3, 2, 3, 2, - 124, 125, 126, 127, 128, 2, 3, 2, - 3, 2, 3, 3, 2, 2, 2, 3, - 3, 3, 2, 129, 2, 3, 2, 130, - 131, 132, 133, 134, 135, 2, 3, 3, - 3, 2, 2, 2, 2, 3, 3, 2, - 3, 3, 2, 2, 2, 3, 3, 3, - 3, 2, 136, 125, 137, 138, 139, 2, - 3, 3, 3, 3, 3, 2, 3, 2, - 3, 2, 3, 2, 140, 2, 3, 2, - 141, 2, 142, 143, 144, 146, 145, 2, - 3, 2, 2, 3, 3, 3, 1, 148, - 147, 148, 147, 3, 1, 149, 148, 150, - 148, 148, 150, 148, 148, 150, 148, 148, - 148, 150, 148, 150, 148, 148, 150, 148, - 148, 148, 148, 150, 148, 148, 150, 150, - 148, 148, 150, 148, 148, 150, 151, 152, - 153, 154, 155, 157, 158, 159, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, - 156, 160, 150, 148, 148, 148, 148, 150, - 148, 150, 148, 148, 150, 150, 150, 148, - 150, 150, 150, 148, 148, 148, 148, 150, - 150, 150, 150, 150, 150, 150, 148, 150, - 150, 150, 150, 150, 150, 148, 150, 150, - 150, 150, 150, 148, 148, 148, 148, 150, - 148, 148, 148, 148, 148, 150, 148, 148, - 150, 148, 148, 148, 148, 150, 148, 148, - 150, 150, 150, 150, 150, 150, 148, 148, - 148, 148, 148, 148, 150, 148, 148, 148, - 150, 150, 150, 150, 150, 150, 148, 148, - 150, 148, 148, 148, 148, 148, 150, 148, - 148, 150, 148, 150, 148, 148, 150, 148, - 150, 148, 148, 148, 148, 148, 150, 148, - 150, 148, 148, 148, 148, 150, 148, 150, - 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 150, 148, - 148, 150, 148, 148, 148, 150, 148, 148, - 148, 148, 150, 148, 150, 148, 148, 150, - 148, 148, 150, 148, 150, 150, 150, 148, - 148, 150, 148, 148, 150, 148, 148, 150, - 148, 150, 148, 148, 148, 148, 148, 150, - 148, 150, 150, 148, 148, 148, 150, 150, - 150, 148, 148, 148, 150, 148, 150, 148, - 150, 148, 148, 148, 148, 148, 150, 148, - 148, 150, 201, 202, 203, 204, 205, 150, - 148, 206, 150, 148, 148, 150, 207, 208, - 202, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 203, 204, 205, 150, 148, - 206, 148, 150, 148, 150, 148, 150, 148, - 148, 150, 148, 148, 150, 148, 148, 150, - 148, 150, 148, 148, 148, 150, 148, 150, - 148, 148, 150, 148, 148, 150, 148, 148, - 148, 150, 148, 149, 148, 148, 150, 148, - 150, 150, 150, 150, 150, 150, 150, 150, - 148, 148, 148, 148, 148, 148, 148, 148, - 150, 148, 148, 148, 148, 150, 148, 150, - 148, 148, 150, 148, 148, 150, 148, 150, - 148, 150, 148, 150, 227, 228, 229, 150, - 148, 148, 150, 148, 150, 148, 148, 150, - 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 150, - 148, 148, 150, 148, 150, 148, 150, 148, - 148, 148, 148, 148, 150, 148, 148, 150, - 150, 150, 150, 148, 148, 150, 148, 150, - 148, 148, 150, 150, 150, 148, 148, 150, - 148, 148, 148, 150, 148, 148, 148, 148, - 150, 148, 148, 148, 150, 148, 148, 150, - 245, 246, 231, 150, 148, 150, 148, 148, - 150, 247, 248, 249, 250, 251, 252, 253, - 150, 254, 255, 256, 257, 258, 259, 260, - 261, 150, 148, 150, 148, 150, 148, 150, - 148, 148, 148, 148, 148, 150, 148, 150, - 148, 150, 148, 150, 148, 150, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 192, 275, 276, 277, 192, - 193, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, - 150, 148, 148, 150, 150, 148, 150, 150, - 148, 148, 148, 150, 148, 148, 150, 148, - 148, 150, 150, 150, 150, 148, 148, 148, - 150, 148, 150, 148, 148, 148, 150, 148, - 148, 148, 148, 148, 148, 148, 150, 148, - 150, 148, 148, 150, 150, 148, 148, 148, - 150, 150, 150, 148, 148, 150, 148, 150, - 148, 150, 148, 148, 148, 150, 148, 148, - 150, 148, 148, 148, 150, 148, 148, 148, - 150, 148, 148, 150, 148, 150, 148, 148, - 150, 148, 148, 150, 148, 148, 148, 148, - 150, 150, 150, 148, 148, 148, 148, 150, - 148, 150, 293, 294, 295, 296, 297, 150, - 148, 150, 148, 150, 148, 148, 150, 150, - 150, 148, 148, 148, 150, 298, 150, 148, - 150, 299, 300, 301, 302, 303, 304, 150, - 148, 148, 148, 150, 150, 150, 150, 148, - 148, 150, 148, 148, 150, 150, 150, 148, - 148, 148, 148, 150, 305, 294, 306, 307, - 308, 150, 148, 148, 148, 148, 148, 150, - 148, 150, 148, 150, 148, 150, 309, 310, - 311, 312, 313, 314, 315, 316, 310, 309, - 310, 309, 310, 218, 309, 317, 318, 310, - 309, 319, 320, 321, 322, 323, 324, 310, - 325, 326, 309, 310, 309, 317, 220, 218, - 218, 220, 150, 149, 148, 148, 148, 150, - 148, 148, 150, 148, 148, 148, 150, 150, - 148, 148, 148, 148, 148, 148, 150, 148, - 150, 150, 148, 148, 150, 150, 148, 148, - 150, 148, 150, 148, 150, 148, 148, 150, - 148, 148, 150, 148, 148, 150, 148, 148, - 150, 327, 150, 328, 310, 309, 329, 220, - 150, 148, 150, 330, 228, 150, 148, 150, - 247, 248, 249, 250, 251, 252, 331, 150, - 332, 150, 148, 150, 147, 333, 3, 1, - 335, 334, 334, 335, 335, 334, 335, 335, - 334, 335, 335, 335, 334, 335, 334, 335, - 335, 334, 335, 335, 335, 335, 334, 335, - 335, 334, 334, 335, 335, 334, 335, 335, - 334, 336, 337, 338, 339, 340, 342, 343, - 344, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 341, 345, 334, 335, 335, - 335, 335, 334, 335, 334, 335, 335, 334, - 334, 334, 335, 334, 334, 334, 335, 335, - 335, 335, 334, 334, 334, 334, 334, 334, - 334, 335, 334, 334, 334, 334, 334, 334, - 335, 334, 334, 334, 334, 334, 335, 335, - 335, 335, 334, 335, 335, 335, 335, 335, - 334, 335, 335, 334, 335, 335, 335, 335, - 334, 335, 335, 334, 334, 334, 334, 334, - 334, 335, 335, 335, 335, 335, 335, 334, - 335, 335, 335, 334, 334, 334, 334, 334, - 334, 335, 335, 334, 335, 335, 335, 335, - 335, 334, 335, 335, 334, 335, 334, 335, - 335, 334, 335, 334, 335, 335, 335, 335, - 335, 334, 335, 334, 335, 335, 335, 335, - 334, 335, 334, 364, 365, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, 381, 382, 383, 384, - 385, 334, 335, 335, 334, 335, 335, 335, - 334, 335, 335, 335, 335, 334, 335, 334, - 335, 335, 334, 335, 335, 334, 335, 334, - 334, 334, 335, 335, 334, 335, 335, 334, - 335, 335, 334, 335, 334, 335, 335, 335, - 335, 335, 334, 335, 334, 334, 335, 335, - 335, 334, 334, 334, 335, 335, 335, 334, - 335, 334, 335, 334, 335, 335, 335, 335, - 335, 334, 335, 335, 334, 386, 387, 388, - 389, 390, 334, 335, 334, 335, 334, 335, - 334, 335, 334, 335, 334, 391, 392, 334, - 335, 334, 335, 334, 393, 394, 395, 396, - 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 334, 335, 335, 334, 335, - 334, 335, 334, 335, 335, 335, 335, 335, - 334, 335, 335, 334, 334, 334, 334, 335, - 335, 334, 335, 334, 335, 335, 334, 334, - 334, 335, 335, 334, 335, 335, 335, 334, - 335, 335, 335, 335, 334, 335, 335, 335, - 334, 335, 335, 334, 408, 409, 394, 334, - 335, 334, 335, 335, 334, 410, 411, 412, - 413, 414, 415, 416, 334, 417, 418, 419, - 420, 421, 422, 423, 424, 334, 335, 334, - 335, 334, 335, 334, 335, 335, 335, 335, - 335, 334, 335, 334, 335, 334, 335, 334, - 335, 334, 425, 426, 427, 428, 429, 430, - 431, 432, 433, 434, 435, 436, 437, 377, - 438, 439, 440, 377, 378, 441, 442, 443, - 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 455, 334, 335, 335, 334, - 334, 335, 334, 334, 335, 335, 335, 334, - 335, 335, 334, 335, 335, 334, 334, 334, - 334, 335, 335, 335, 334, 335, 334, 335, - 335, 335, 334, 335, 335, 335, 335, 335, - 335, 335, 334, 335, 334, 335, 335, 334, - 334, 335, 335, 335, 334, 334, 334, 335, - 335, 334, 335, 334, 335, 334, 335, 335, - 335, 334, 335, 335, 334, 335, 335, 335, - 334, 335, 335, 335, 334, 335, 335, 334, - 335, 334, 335, 335, 334, 335, 335, 334, - 335, 335, 335, 335, 334, 334, 334, 335, - 335, 335, 335, 334, 335, 334, 456, 457, - 458, 459, 460, 334, 335, 334, 335, 334, - 335, 335, 334, 334, 334, 335, 335, 335, - 334, 461, 334, 335, 334, 462, 463, 464, - 465, 466, 467, 334, 335, 335, 335, 334, - 334, 334, 334, 335, 335, 334, 335, 335, - 334, 334, 334, 335, 335, 335, 335, 334, - 468, 457, 469, 470, 471, 334, 335, 335, - 335, 335, 335, 334, 335, 334, 335, 334, - 335, 334, 472, 334, 335, 334, 473, 334, - 474, 475, 476, 478, 477, 334, 335, 334, - 334, 335, 335, 335, 334, 479, 479, 335, - 335, 334, 479, 334, 334, 479, 479, 334, - 479, 479, 334, 479, 479, 479, 334, 479, - 334, 479, 479, 334, 479, 479, 479, 479, - 334, 479, 479, 334, 334, 479, 479, 334, - 479, 479, 334, 480, 481, 482, 483, 484, - 486, 487, 488, 490, 491, 492, 493, 494, - 495, 496, 497, 498, 499, 500, 501, 502, - 503, 504, 505, 506, 507, 485, 489, 334, - 479, 479, 479, 479, 334, 479, 334, 479, - 479, 334, 334, 334, 479, 334, 334, 334, - 479, 479, 479, 479, 334, 334, 334, 334, - 334, 334, 334, 479, 334, 334, 334, 334, - 334, 334, 479, 334, 334, 334, 334, 334, - 479, 479, 479, 479, 334, 479, 479, 479, - 479, 479, 334, 479, 479, 334, 479, 479, - 479, 479, 334, 479, 479, 334, 334, 334, - 334, 334, 334, 479, 479, 479, 479, 479, - 479, 334, 479, 479, 479, 334, 334, 334, - 334, 334, 334, 479, 479, 334, 479, 479, - 479, 479, 479, 334, 479, 479, 334, 479, - 334, 479, 479, 334, 479, 334, 479, 479, - 479, 479, 479, 334, 479, 334, 479, 479, - 479, 479, 334, 479, 334, 508, 509, 510, - 511, 512, 513, 514, 515, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 529, 334, 479, 479, 334, 479, - 479, 479, 334, 479, 479, 479, 479, 334, - 479, 334, 479, 479, 334, 479, 479, 334, - 479, 334, 334, 334, 479, 479, 334, 479, - 479, 334, 479, 479, 334, 479, 334, 479, - 479, 479, 479, 479, 334, 479, 334, 334, - 479, 479, 479, 334, 334, 334, 479, 479, - 479, 334, 479, 334, 479, 334, 479, 479, - 479, 479, 479, 334, 479, 479, 334, 530, - 531, 532, 533, 534, 334, 479, 535, 334, - 479, 479, 334, 536, 537, 531, 538, 539, - 540, 541, 542, 543, 544, 545, 546, 547, - 548, 549, 550, 551, 552, 553, 554, 555, - 532, 533, 534, 334, 479, 535, 479, 334, - 479, 334, 479, 334, 479, 479, 334, 479, - 479, 334, 479, 479, 334, 479, 334, 479, - 479, 479, 334, 479, 334, 479, 479, 334, - 479, 479, 334, 479, 479, 479, 334, 479, - 334, 479, 479, 334, 479, 334, 334, 334, - 334, 334, 334, 334, 334, 479, 479, 479, - 479, 479, 479, 479, 479, 334, 479, 479, - 479, 479, 334, 479, 334, 479, 479, 334, - 479, 479, 334, 479, 334, 479, 334, 479, - 334, 556, 557, 558, 334, 479, 479, 334, - 479, 334, 479, 479, 334, 559, 560, 561, - 562, 563, 564, 565, 566, 567, 568, 569, - 570, 571, 572, 573, 334, 479, 479, 334, - 479, 334, 479, 334, 479, 479, 479, 479, - 479, 334, 479, 479, 334, 334, 334, 334, - 479, 479, 334, 479, 334, 479, 479, 334, - 334, 334, 479, 479, 334, 479, 479, 479, - 334, 479, 479, 479, 479, 334, 479, 479, - 479, 334, 479, 479, 334, 574, 575, 560, - 334, 479, 334, 479, 479, 334, 576, 577, - 578, 579, 580, 581, 582, 334, 583, 584, - 585, 586, 587, 588, 589, 590, 334, 479, - 334, 479, 334, 479, 334, 479, 479, 479, - 479, 479, 334, 479, 334, 479, 334, 479, - 334, 479, 334, 591, 592, 593, 594, 595, - 596, 597, 598, 599, 600, 601, 602, 603, - 521, 604, 605, 606, 521, 522, 607, 608, - 609, 610, 611, 612, 613, 614, 615, 616, - 617, 618, 619, 620, 621, 334, 479, 479, - 334, 334, 479, 334, 334, 479, 479, 479, - 334, 479, 479, 334, 479, 479, 334, 334, - 334, 334, 479, 479, 479, 334, 479, 334, - 479, 479, 479, 334, 479, 479, 479, 479, - 479, 479, 479, 334, 479, 334, 479, 479, - 334, 334, 479, 479, 479, 334, 334, 334, - 479, 479, 334, 479, 334, 479, 334, 479, - 479, 479, 334, 479, 479, 334, 479, 479, - 479, 334, 479, 479, 479, 334, 479, 479, - 334, 479, 334, 479, 479, 334, 479, 479, - 334, 479, 479, 479, 479, 334, 334, 334, - 479, 479, 479, 479, 334, 479, 334, 622, - 623, 624, 625, 626, 334, 479, 334, 479, - 334, 479, 479, 334, 334, 334, 479, 479, - 479, 334, 627, 334, 479, 334, 628, 629, - 630, 631, 632, 633, 334, 479, 479, 479, - 334, 334, 334, 334, 479, 479, 334, 479, - 479, 334, 334, 334, 479, 479, 479, 479, - 334, 634, 623, 635, 636, 637, 334, 479, - 479, 479, 479, 479, 334, 479, 334, 479, - 334, 479, 334, 638, 639, 640, 641, 642, - 643, 644, 645, 639, 638, 639, 638, 639, - 547, 638, 646, 647, 639, 638, 648, 649, - 650, 651, 652, 653, 639, 654, 655, 638, - 639, 638, 646, 549, 547, 547, 549, 334, - 334, 479, 479, 479, 334, 479, 479, 334, - 479, 479, 479, 334, 334, 479, 479, 479, - 479, 479, 479, 334, 479, 334, 334, 479, - 479, 334, 334, 479, 479, 334, 479, 334, - 479, 334, 479, 479, 334, 479, 479, 334, - 479, 479, 334, 479, 479, 334, 656, 334, - 657, 639, 638, 658, 549, 334, 479, 334, - 659, 557, 334, 479, 334, 576, 577, 578, - 579, 580, 581, 660, 334, 661, 334, 479, - 334, 333, 335, 335, 334, 333, 335, 334, - 333, 335, 334, 663, 664, 662, 334, 333, - 335, 334, 333, 335, 334, 665, 666, 667, - 668, 669, 662, 334, 670, 334, 508, 509, - 510, 665, 666, 671, 511, 512, 513, 514, - 515, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 529, 334, - 672, 670, 508, 509, 510, 673, 667, 668, - 511, 512, 513, 514, 515, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 529, 334, 672, 334, 674, 672, - 508, 509, 510, 675, 668, 511, 512, 513, - 514, 515, 516, 517, 518, 519, 520, 521, - 522, 523, 524, 525, 526, 527, 528, 529, - 334, 674, 334, 334, 674, 676, 334, 674, - 334, 677, 678, 334, 672, 334, 334, 674, - 334, 672, 334, 672, 559, 560, 561, 562, - 563, 564, 565, 679, 567, 568, 569, 570, - 571, 572, 573, 681, 682, 683, 684, 685, - 686, 681, 682, 683, 684, 685, 686, 681, - 680, 687, 334, 479, 670, 334, 688, 688, - 688, 674, 334, 508, 509, 510, 673, 671, - 511, 512, 513, 514, 515, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 529, 334, 677, 689, 334, 334, - 672, 688, 688, 674, 688, 688, 674, 688, - 688, 688, 674, 688, 688, 674, 688, 688, - 674, 688, 688, 334, 674, 674, 683, 684, - 685, 686, 680, 681, 683, 684, 685, 686, - 680, 681, 683, 684, 685, 686, 680, 681, - 683, 684, 685, 686, 680, 681, 683, 684, - 685, 686, 680, 681, 683, 684, 685, 686, - 680, 681, 683, 684, 685, 686, 680, 681, - 683, 684, 685, 686, 680, 681, 683, 684, - 685, 686, 680, 681, 682, 687, 684, 685, - 686, 680, 681, 682, 684, 685, 686, 680, - 681, 682, 684, 685, 686, 680, 681, 682, - 684, 685, 686, 680, 681, 682, 684, 685, - 686, 680, 681, 682, 684, 685, 686, 680, - 681, 682, 684, 685, 686, 680, 681, 682, - 684, 685, 686, 680, 681, 682, 684, 685, - 686, 680, 681, 682, 683, 687, 685, 686, - 680, 681, 682, 683, 685, 686, 680, 681, - 682, 683, 685, 686, 680, 681, 682, 683, - 685, 686, 680, 681, 682, 683, 685, 690, - 689, 684, 334, 687, 688, 334, 672, 674, - 335, 335, 334, 691, 692, 693, 694, 695, - 696, 697, 698, 699, 700, 701, 547, 702, - 549, 703, 704, 705, 706, 707, 708, 662, - 334, 479, 335, 335, 335, 335, 334, 479, - 335, 335, 334, 479, 479, 335, 334, 335, - 479, 335, 479, 335, 334, 479, 335, 479, - 335, 334, 479, 335, 334, 479, 335, 479, - 335, 479, 335, 334, 479, 335, 334, 479, - 335, 479, 335, 334, 479, 335, 335, 479, - 334, 335, 335, 479, 334, 479, 335, 479, - 334, 335, 335, 335, 335, 335, 335, 335, - 335, 334, 479, 479, 479, 479, 479, 335, - 335, 479, 335, 479, 335, 334, 479, 479, - 479, 335, 479, 335, 334, 335, 479, 335, - 334, 335, 479, 335, 479, 335, 334, 479, - 479, 335, 334, 709, 710, 662, 334, 479, - 479, 335, 334, 479, 479, 335, 334, 662, - 334, 711, 713, 714, 715, 716, 717, 718, - 713, 714, 715, 716, 717, 718, 713, 662, - 712, 687, 334, 335, 670, 335, 334, 672, - 672, 672, 674, 334, 672, 672, 674, 672, - 672, 674, 672, 672, 672, 674, 672, 672, - 674, 672, 672, 674, 672, 672, 334, 674, - 715, 716, 717, 718, 712, 713, 715, 716, - 717, 718, 712, 713, 715, 716, 717, 718, - 712, 713, 715, 716, 717, 718, 712, 713, - 715, 716, 717, 718, 712, 713, 715, 716, - 717, 718, 712, 713, 715, 716, 717, 718, - 712, 713, 715, 716, 717, 718, 712, 713, - 715, 716, 717, 718, 712, 713, 714, 687, - 716, 717, 718, 712, 713, 714, 716, 717, - 718, 712, 713, 714, 716, 717, 718, 712, - 713, 714, 716, 717, 718, 712, 713, 714, - 716, 717, 718, 712, 713, 714, 716, 717, - 718, 712, 713, 714, 716, 717, 718, 712, - 713, 714, 716, 717, 718, 712, 713, 714, - 716, 717, 718, 712, 713, 714, 715, 687, - 717, 718, 712, 713, 714, 715, 717, 718, - 712, 713, 714, 715, 717, 718, 712, 713, - 714, 715, 717, 718, 712, 713, 714, 715, - 717, 719, 720, 716, 662, 334, 687, 672, - 335, 672, 674, 335, 674, 335, 334, 672, - 721, 722, 662, 334, 335, 334, 335, 335, - 335, 334, 724, 725, 726, 727, 728, 723, - 334, 729, 730, 731, 732, 733, 734, 735, - 736, 662, 334, 333, 335, 334, 333, 335, - 334, 335, 333, 335, 334, 333, 335, 334, - 333, 335, 334, 333, 335, 334, 335, 333, - 335, 334, 333, 335, 334, 737, 662, 334, - 335, 335, 334, 738, 662, 334, 335, 335, - 334, 739, 662, 334, 335, 335, 334, 638, - 639, 740, 741, 742, 743, 744, 745, 639, - 638, 639, 638, 746, 547, 638, 747, 748, - 639, 638, 749, 662, 750, 662, 751, 752, - 753, 754, 639, 755, 756, 638, 639, 638, - 747, 549, 547, 662, 549, 334, 479, 335, - 479, 335, 334, 335, 479, 335, 479, 334, - 479, 335, 479, 335, 479, 334, 757, 334, - 479, 576, 577, 578, 579, 580, 581, 758, - 334, 759, 661, 334, 479, 334, 335, 479, - 479, 335, 479, 335, 479, 334, 335, 479, - 334, 335, 334, 479, 335, 334, 479, 335, - 479, 334, 335, 334, 479, 335, 479, 334, - 335, 479, 334, 335, 479, 335, 334, 335, - 479, 335, 479, 335, 334, 335, 479, 335, - 479, 334, 335, 335, 479, 334, 335, 479, - 334, 723, 334, 760, 723, 334, 390, 662, - 761, 662, 334, 335, 334, 333, 3, 1, - 333, 3, 1, 763, 764, 762, 1, 333, - 3, 1, 333, 3, 1, 765, 766, 767, - 768, 769, 762, 1, 770, 149, 772, 771, - 771, 772, 772, 771, 772, 772, 771, 772, - 772, 772, 771, 772, 771, 772, 772, 771, - 772, 772, 772, 772, 771, 772, 772, 771, - 771, 772, 772, 771, 772, 772, 771, 773, - 774, 775, 776, 777, 779, 780, 781, 783, - 784, 785, 786, 787, 788, 789, 790, 791, - 792, 793, 794, 795, 796, 797, 798, 799, - 800, 778, 782, 771, 772, 772, 772, 772, - 771, 772, 771, 772, 772, 771, 771, 771, - 772, 771, 771, 771, 772, 772, 772, 772, - 771, 771, 771, 771, 771, 771, 771, 772, - 771, 771, 771, 771, 771, 771, 772, 771, - 771, 771, 771, 771, 772, 772, 772, 772, - 771, 772, 772, 772, 772, 772, 771, 772, - 772, 771, 772, 772, 772, 772, 771, 772, - 772, 771, 771, 771, 771, 771, 771, 772, - 772, 772, 772, 772, 772, 771, 772, 772, - 772, 771, 771, 771, 771, 771, 771, 772, - 772, 771, 772, 772, 772, 772, 772, 771, - 772, 772, 771, 772, 771, 772, 772, 771, - 772, 771, 772, 772, 772, 772, 772, 771, - 772, 771, 772, 772, 772, 772, 771, 772, - 771, 801, 802, 803, 804, 805, 806, 807, - 808, 809, 810, 811, 812, 813, 814, 815, - 816, 817, 818, 819, 820, 821, 822, 771, - 772, 772, 771, 772, 772, 772, 771, 772, - 772, 772, 772, 771, 772, 771, 772, 772, - 771, 772, 772, 771, 772, 771, 771, 771, - 772, 772, 771, 772, 772, 771, 772, 772, - 771, 772, 771, 772, 772, 772, 772, 772, - 771, 772, 771, 771, 772, 772, 772, 771, - 771, 771, 772, 772, 772, 771, 772, 771, - 772, 771, 772, 772, 772, 772, 772, 771, - 772, 772, 771, 823, 824, 825, 826, 827, - 771, 772, 828, 771, 772, 772, 771, 829, - 830, 824, 831, 832, 833, 834, 835, 836, - 837, 838, 839, 840, 841, 842, 843, 844, - 845, 846, 847, 848, 825, 826, 827, 771, - 772, 828, 772, 771, 772, 771, 772, 771, - 772, 772, 771, 772, 772, 771, 772, 772, - 771, 772, 771, 772, 772, 772, 771, 772, - 771, 772, 772, 771, 772, 772, 771, 772, - 772, 772, 771, 772, 771, 772, 772, 771, - 772, 771, 771, 771, 771, 771, 771, 771, - 771, 772, 772, 772, 772, 772, 772, 772, - 772, 771, 772, 772, 772, 772, 771, 772, - 771, 772, 772, 771, 772, 772, 771, 772, - 771, 772, 771, 772, 771, 849, 850, 851, - 771, 772, 772, 771, 772, 771, 772, 772, - 771, 852, 853, 854, 855, 856, 857, 858, - 859, 860, 861, 862, 863, 864, 865, 866, - 771, 772, 772, 771, 772, 771, 772, 771, - 772, 772, 772, 772, 772, 771, 772, 772, - 771, 771, 771, 771, 772, 772, 771, 772, - 771, 772, 772, 771, 771, 771, 772, 772, - 771, 772, 772, 772, 771, 772, 772, 772, - 772, 771, 772, 772, 772, 771, 772, 772, - 771, 867, 868, 853, 771, 772, 771, 772, - 772, 771, 869, 870, 871, 872, 873, 874, - 875, 771, 876, 877, 878, 879, 880, 881, - 882, 883, 771, 772, 771, 772, 771, 772, - 771, 772, 772, 772, 772, 772, 771, 772, - 771, 772, 771, 772, 771, 772, 771, 884, - 885, 886, 887, 888, 889, 890, 891, 892, - 893, 894, 895, 896, 814, 897, 898, 899, - 814, 815, 900, 901, 902, 903, 904, 905, - 906, 907, 908, 909, 910, 911, 912, 913, - 914, 771, 772, 772, 771, 771, 772, 771, - 771, 772, 772, 772, 771, 772, 772, 771, - 772, 772, 771, 771, 771, 771, 772, 772, - 772, 771, 772, 771, 772, 772, 772, 771, - 772, 772, 772, 772, 772, 772, 772, 771, - 772, 771, 772, 772, 771, 771, 772, 772, - 772, 771, 771, 771, 772, 772, 771, 772, - 771, 772, 771, 772, 772, 772, 771, 772, - 772, 771, 772, 772, 772, 771, 772, 772, - 772, 771, 772, 772, 771, 772, 771, 772, - 772, 771, 772, 772, 771, 772, 772, 772, - 772, 771, 771, 771, 772, 772, 772, 772, - 771, 772, 771, 915, 916, 917, 918, 919, - 771, 772, 771, 772, 771, 772, 772, 771, - 771, 771, 772, 772, 772, 771, 920, 771, - 772, 771, 921, 922, 923, 924, 925, 926, - 771, 772, 772, 772, 771, 771, 771, 771, - 772, 772, 771, 772, 772, 771, 771, 771, - 772, 772, 772, 772, 771, 927, 916, 928, - 929, 930, 771, 772, 772, 772, 772, 772, - 771, 772, 771, 772, 771, 772, 771, 931, - 932, 933, 934, 935, 936, 937, 938, 932, - 931, 932, 931, 932, 840, 931, 939, 940, - 932, 931, 941, 942, 943, 944, 945, 946, - 932, 947, 948, 931, 932, 931, 939, 842, - 840, 840, 842, 771, 771, 772, 772, 772, - 771, 772, 772, 771, 772, 772, 772, 771, - 771, 772, 772, 772, 772, 772, 772, 771, - 772, 771, 771, 772, 772, 771, 771, 772, - 772, 771, 772, 771, 772, 771, 772, 772, - 771, 772, 772, 771, 772, 772, 771, 772, - 772, 771, 949, 771, 950, 932, 931, 951, - 842, 771, 772, 771, 952, 850, 771, 772, - 771, 869, 870, 871, 872, 873, 874, 953, - 771, 954, 771, 772, 771, 801, 802, 803, - 765, 766, 955, 804, 805, 806, 807, 808, - 809, 810, 811, 812, 813, 814, 815, 816, - 817, 818, 819, 820, 821, 822, 771, 956, - 770, 801, 802, 803, 957, 767, 768, 804, - 805, 806, 807, 808, 809, 810, 811, 812, - 813, 814, 815, 816, 817, 818, 819, 820, - 821, 822, 771, 956, 771, 958, 956, 801, - 802, 803, 959, 768, 804, 805, 806, 807, - 808, 809, 810, 811, 812, 813, 814, 815, - 816, 817, 818, 819, 820, 821, 822, 771, - 958, 771, 149, 958, 960, 771, 958, 771, - 961, 962, 771, 956, 771, 771, 958, 771, - 956, 771, 956, 852, 853, 854, 855, 856, - 857, 858, 963, 860, 861, 862, 863, 864, - 865, 866, 965, 966, 967, 968, 969, 970, - 965, 966, 967, 968, 969, 970, 965, 964, - 971, 771, 772, 770, 771, 972, 972, 972, - 958, 771, 801, 802, 803, 957, 955, 804, - 805, 806, 807, 808, 809, 810, 811, 812, - 813, 814, 815, 816, 817, 818, 819, 820, - 821, 822, 771, 961, 973, 771, 771, 956, - 972, 972, 958, 972, 972, 958, 972, 972, - 972, 958, 972, 972, 958, 972, 972, 958, - 972, 972, 771, 958, 958, 967, 968, 969, - 970, 964, 965, 967, 968, 969, 970, 964, - 965, 967, 968, 969, 970, 964, 965, 967, - 968, 969, 970, 964, 965, 967, 968, 969, - 970, 964, 965, 967, 968, 969, 970, 964, - 965, 967, 968, 969, 970, 964, 965, 967, - 968, 969, 970, 964, 965, 967, 968, 969, - 970, 964, 965, 966, 971, 968, 969, 970, - 964, 965, 966, 968, 969, 970, 964, 965, - 966, 968, 969, 970, 964, 965, 966, 968, - 969, 970, 964, 965, 966, 968, 969, 970, - 964, 965, 966, 968, 969, 970, 964, 965, - 966, 968, 969, 970, 964, 965, 966, 968, - 969, 970, 964, 965, 966, 968, 969, 970, - 964, 965, 966, 967, 971, 969, 970, 964, - 965, 966, 967, 969, 970, 964, 965, 966, - 967, 969, 970, 964, 965, 966, 967, 969, - 970, 964, 965, 966, 967, 969, 974, 973, - 968, 771, 971, 972, 771, 956, 958, 147, - 3, 1, 975, 976, 977, 978, 979, 980, - 981, 982, 983, 984, 985, 218, 986, 220, - 987, 988, 989, 990, 991, 992, 762, 1, - 147, 993, 148, 3, 147, 3, 147, 3, - 1, 993, 994, 994, 993, 993, 994, 993, - 993, 994, 993, 993, 993, 994, 993, 994, - 993, 993, 994, 993, 993, 993, 993, 994, - 993, 993, 994, 994, 993, 993, 994, 993, - 993, 994, 995, 996, 997, 998, 999, 1001, - 1002, 1003, 1005, 1006, 1007, 1008, 1009, 1010, - 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, - 1019, 1020, 1021, 1022, 1000, 1004, 994, 993, - 993, 993, 993, 994, 993, 994, 993, 993, - 994, 994, 994, 993, 994, 994, 994, 993, - 993, 993, 993, 994, 994, 994, 994, 994, - 994, 994, 993, 994, 994, 994, 994, 994, - 994, 993, 994, 994, 994, 994, 994, 993, - 993, 993, 993, 994, 993, 993, 993, 993, - 993, 994, 993, 993, 994, 993, 993, 993, - 993, 994, 993, 993, 994, 994, 994, 994, - 994, 994, 993, 993, 993, 993, 993, 993, - 994, 993, 993, 993, 994, 994, 994, 994, - 994, 994, 993, 993, 994, 993, 993, 993, - 993, 993, 994, 993, 993, 994, 993, 994, - 993, 993, 994, 993, 994, 993, 993, 993, - 993, 993, 994, 993, 994, 993, 993, 993, - 993, 994, 993, 994, 1023, 1024, 1025, 1026, - 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, - 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, - 1043, 1044, 994, 993, 993, 994, 993, 993, - 993, 994, 993, 993, 993, 993, 994, 993, - 994, 993, 993, 994, 993, 993, 994, 993, - 994, 994, 994, 993, 993, 994, 993, 993, - 994, 993, 993, 994, 993, 994, 993, 993, - 993, 993, 993, 994, 993, 994, 994, 993, - 993, 993, 994, 994, 994, 993, 993, 993, - 994, 993, 994, 993, 994, 993, 993, 993, - 993, 993, 994, 993, 993, 994, 1045, 1046, - 1047, 1048, 1049, 994, 993, 994, 993, 994, - 993, 994, 993, 994, 993, 994, 1050, 1051, - 994, 993, 994, 993, 994, 1052, 1053, 1054, - 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, - 1063, 1064, 1065, 1066, 994, 993, 993, 994, - 993, 994, 993, 994, 993, 993, 993, 993, - 993, 994, 993, 993, 994, 994, 994, 994, - 993, 993, 994, 993, 994, 993, 993, 994, - 994, 994, 993, 993, 994, 993, 993, 993, - 994, 993, 993, 993, 993, 994, 993, 993, - 993, 994, 993, 993, 994, 1067, 1068, 1053, - 994, 993, 994, 993, 993, 994, 1069, 1070, - 1071, 1072, 1073, 1074, 1075, 994, 1076, 1077, - 1078, 1079, 1080, 1081, 1082, 1083, 994, 993, - 994, 993, 994, 993, 994, 993, 993, 993, - 993, 993, 994, 993, 994, 993, 994, 993, - 994, 993, 994, 1084, 1085, 1086, 1087, 1088, - 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, - 1036, 1097, 1098, 1099, 1036, 1037, 1100, 1101, - 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, - 1110, 1111, 1112, 1113, 1114, 994, 993, 993, - 994, 994, 993, 994, 994, 993, 993, 993, - 994, 993, 993, 994, 993, 993, 994, 994, - 994, 994, 993, 993, 993, 994, 993, 994, - 993, 993, 993, 994, 993, 993, 993, 993, - 993, 993, 993, 994, 993, 994, 993, 993, - 994, 994, 993, 993, 993, 994, 994, 994, - 993, 993, 994, 993, 994, 993, 994, 993, - 993, 993, 994, 993, 993, 994, 993, 993, - 993, 994, 993, 993, 993, 994, 993, 993, - 994, 993, 994, 993, 993, 994, 993, 993, - 994, 993, 993, 993, 993, 994, 994, 994, - 993, 993, 993, 993, 994, 993, 994, 1115, - 1116, 1117, 1118, 1119, 994, 993, 994, 993, - 994, 993, 993, 994, 994, 994, 993, 993, - 993, 994, 1120, 994, 993, 994, 1121, 1122, - 1123, 1124, 1125, 1126, 994, 993, 993, 993, - 994, 994, 994, 994, 993, 993, 994, 993, - 993, 994, 994, 994, 993, 993, 993, 993, - 994, 1127, 1116, 1128, 1129, 1130, 994, 993, - 993, 993, 993, 993, 994, 993, 994, 993, - 994, 993, 994, 1131, 994, 993, 994, 1132, - 994, 1133, 1134, 1135, 1137, 1136, 994, 993, - 994, 994, 993, 993, 148, 3, 147, 3, - 1, 148, 148, 3, 1, 3, 148, 3, - 148, 3, 1, 148, 3, 148, 3, 1, - 148, 3, 1, 148, 3, 148, 3, 148, - 3, 1, 148, 3, 1, 148, 3, 148, - 3, 1, 148, 3, 3, 148, 1, 3, - 3, 148, 1, 148, 3, 148, 1, 3, - 3, 3, 3, 3, 3, 3, 3, 1, - 148, 148, 148, 148, 148, 3, 3, 148, - 3, 148, 3, 1, 148, 148, 148, 3, - 148, 3, 1, 3, 148, 3, 1, 3, - 148, 3, 148, 3, 1, 148, 148, 3, - 1, 1138, 1139, 762, 1, 148, 148, 3, - 1, 148, 148, 3, 1, 762, 1, 1140, - 1142, 1143, 1144, 1145, 1146, 1147, 1142, 1143, - 1144, 1145, 1146, 1147, 1142, 762, 1141, 971, - 1, 3, 770, 3, 1, 956, 956, 956, - 958, 1, 956, 956, 958, 956, 956, 958, - 956, 956, 956, 958, 956, 956, 958, 956, - 956, 958, 956, 956, 1, 958, 1144, 1145, - 1146, 1147, 1141, 1142, 1144, 1145, 1146, 1147, - 1141, 1142, 1144, 1145, 1146, 1147, 1141, 1142, - 1144, 1145, 1146, 1147, 1141, 1142, 1144, 1145, - 1146, 1147, 1141, 1142, 1144, 1145, 1146, 1147, - 1141, 1142, 1144, 1145, 1146, 1147, 1141, 1142, - 1144, 1145, 1146, 1147, 1141, 1142, 1144, 1145, - 1146, 1147, 1141, 1142, 1143, 971, 1145, 1146, - 1147, 1141, 1142, 1143, 1145, 1146, 1147, 1141, - 1142, 1143, 1145, 1146, 1147, 1141, 1142, 1143, - 1145, 1146, 1147, 1141, 1142, 1143, 1145, 1146, - 1147, 1141, 1142, 1143, 1145, 1146, 1147, 1141, - 1142, 1143, 1145, 1146, 1147, 1141, 1142, 1143, - 1145, 1146, 1147, 1141, 1142, 1143, 1145, 1146, - 1147, 1141, 1142, 1143, 1144, 971, 1146, 1147, - 1141, 1142, 1143, 1144, 1146, 1147, 1141, 1142, - 1143, 1144, 1146, 1147, 1141, 1142, 1143, 1144, - 1146, 1147, 1141, 1142, 1143, 1144, 1146, 1148, - 1149, 1145, 762, 1, 971, 956, 3, 956, - 958, 3, 958, 3, 1, 956, 1150, 1151, - 762, 1, 147, 3, 1, 3, 3, 147, - 3, 1, 1153, 1154, 1155, 1156, 1157, 1152, - 1, 1158, 1159, 1160, 1161, 1162, 1163, 1164, - 1165, 762, 1, 333, 3, 1, 333, 3, - 1, 3, 333, 3, 1, 333, 3, 1, - 333, 3, 1, 333, 3, 1, 3, 333, - 3, 1, 333, 3, 1, 1166, 762, 1, - 3, 147, 3, 1, 1167, 762, 1, 3, - 147, 3, 1, 1168, 762, 1, 3, 147, - 3, 1, 309, 310, 1169, 1170, 1171, 1172, - 1173, 1174, 310, 309, 310, 309, 1175, 218, - 309, 1176, 1177, 310, 309, 1178, 762, 1179, - 762, 1180, 1181, 1182, 1183, 310, 1184, 1185, - 309, 310, 309, 1176, 220, 218, 762, 220, - 1, 148, 3, 148, 3, 1, 3, 148, - 3, 148, 1, 148, 3, 148, 3, 148, - 1, 1186, 1, 148, 1188, 1187, 1187, 1188, - 1188, 1187, 1188, 1188, 1187, 1188, 1188, 1188, - 1187, 1188, 1187, 1188, 1188, 1187, 1188, 1188, - 1188, 1188, 1187, 1188, 1188, 1187, 1187, 1188, - 1188, 1187, 1188, 1188, 1187, 1189, 1190, 1191, - 1192, 1193, 1195, 1196, 1197, 1199, 1200, 1201, - 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, - 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1194, - 1198, 1187, 1188, 1188, 1188, 1188, 1187, 1188, - 1187, 1188, 1188, 1187, 1187, 1187, 1188, 1187, - 1187, 1187, 1188, 1188, 1188, 1188, 1187, 1187, - 1187, 1187, 1187, 1187, 1187, 1188, 1187, 1187, - 1187, 1187, 1187, 1187, 1188, 1187, 1187, 1187, - 1187, 1187, 1188, 1188, 1188, 1188, 1187, 1188, - 1188, 1188, 1188, 1188, 1187, 1188, 1188, 1187, - 1188, 1188, 1188, 1188, 1187, 1188, 1188, 1187, - 1187, 1187, 1187, 1187, 1187, 1188, 1188, 1188, - 1188, 1188, 1188, 1187, 1188, 1188, 1188, 1187, - 1187, 1187, 1187, 1187, 1187, 1188, 1188, 1187, - 1188, 1188, 1188, 1188, 1188, 1187, 1188, 1188, - 1187, 1188, 1187, 1188, 1188, 1187, 1188, 1187, - 1188, 1188, 1188, 1188, 1188, 1187, 1188, 1187, - 1188, 1188, 1188, 1188, 1187, 1188, 1187, 1217, - 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, - 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, - 1234, 1235, 1236, 1237, 1238, 1187, 1188, 1188, - 1187, 1188, 1188, 1188, 1187, 1188, 1188, 1188, - 1188, 1187, 1188, 1187, 1188, 1188, 1187, 1188, - 1188, 1187, 1188, 1187, 1187, 1187, 1188, 1188, - 1187, 1188, 1188, 1187, 1188, 1188, 1187, 1188, - 1187, 1188, 1188, 1188, 1188, 1188, 1187, 1188, - 1187, 1187, 1188, 1188, 1188, 1187, 1187, 1187, - 1188, 1188, 1188, 1187, 1188, 1187, 1188, 1187, - 1188, 1188, 1188, 1188, 1188, 1187, 1188, 1188, - 1187, 1239, 1240, 1241, 1242, 1243, 1187, 1188, - 1244, 1187, 1188, 1188, 1187, 1245, 1246, 1240, - 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, - 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, - 1263, 1264, 1241, 1242, 1243, 1187, 1188, 1244, - 1188, 1187, 1188, 1187, 1188, 1187, 1188, 1188, - 1187, 1188, 1188, 1187, 1188, 1188, 1187, 1188, - 1187, 1188, 1188, 1188, 1187, 1188, 1187, 1188, - 1188, 1187, 1188, 1188, 1187, 1188, 1188, 1188, - 1187, 1188, 1187, 1188, 1188, 1187, 1188, 1187, - 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1187, - 1188, 1188, 1188, 1188, 1187, 1188, 1187, 1188, - 1188, 1187, 1188, 1188, 1187, 1188, 1187, 1188, - 1187, 1188, 1187, 1265, 1266, 1267, 1187, 1188, - 1188, 1187, 1188, 1187, 1188, 1188, 1187, 1268, - 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, - 1277, 1278, 1279, 1280, 1281, 1282, 1187, 1188, - 1188, 1187, 1188, 1187, 1188, 1187, 1188, 1188, - 1188, 1188, 1188, 1187, 1188, 1188, 1187, 1187, - 1187, 1187, 1188, 1188, 1187, 1188, 1187, 1188, - 1188, 1187, 1187, 1187, 1188, 1188, 1187, 1188, - 1188, 1188, 1187, 1188, 1188, 1188, 1188, 1187, - 1188, 1188, 1188, 1187, 1188, 1188, 1187, 1283, - 1284, 1269, 1187, 1188, 1187, 1188, 1188, 1187, - 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1187, - 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, - 1187, 1188, 1187, 1188, 1187, 1188, 1187, 1188, - 1188, 1188, 1188, 1188, 1187, 1188, 1187, 1188, - 1187, 1188, 1187, 1188, 1187, 1300, 1301, 1302, - 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, - 1311, 1312, 1230, 1313, 1314, 1315, 1230, 1231, - 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, - 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1187, - 1188, 1188, 1187, 1187, 1188, 1187, 1187, 1188, - 1188, 1188, 1187, 1188, 1188, 1187, 1188, 1188, - 1187, 1187, 1187, 1187, 1188, 1188, 1188, 1187, - 1188, 1187, 1188, 1188, 1188, 1187, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1187, 1188, 1187, - 1188, 1188, 1187, 1187, 1188, 1188, 1188, 1187, - 1187, 1187, 1188, 1188, 1187, 1188, 1187, 1188, - 1187, 1188, 1188, 1188, 1187, 1188, 1188, 1187, - 1188, 1188, 1188, 1187, 1188, 1188, 1188, 1187, - 1188, 1188, 1187, 1188, 1187, 1188, 1188, 1187, - 1188, 1188, 1187, 1188, 1188, 1188, 1188, 1187, - 1187, 1187, 1188, 1188, 1188, 1188, 1187, 1188, - 1187, 1331, 1332, 1333, 1334, 1335, 1187, 1188, - 1187, 1188, 1187, 1188, 1188, 1187, 1187, 1187, - 1188, 1188, 1188, 1187, 1336, 1187, 1188, 1187, - 1337, 1338, 1339, 1340, 1341, 1342, 1187, 1188, - 1188, 1188, 1187, 1187, 1187, 1187, 1188, 1188, - 1187, 1188, 1188, 1187, 1187, 1187, 1188, 1188, - 1188, 1188, 1187, 1343, 1332, 1344, 1345, 1346, - 1187, 1188, 1188, 1188, 1188, 1188, 1187, 1188, - 1187, 1188, 1187, 1188, 1187, 1347, 1348, 1349, - 1350, 1351, 1352, 1353, 1354, 1348, 1347, 1348, - 1347, 1348, 1256, 1347, 1355, 1356, 1348, 1347, - 1357, 1358, 1359, 1360, 1361, 1362, 1348, 1363, - 1364, 1347, 1348, 1347, 1355, 1258, 1256, 1256, - 1258, 1187, 1187, 1188, 1188, 1188, 1187, 1188, - 1188, 1187, 1188, 1188, 1188, 1187, 1187, 1188, - 1188, 1188, 1188, 1188, 1188, 1187, 1188, 1187, - 1187, 1188, 1188, 1187, 1187, 1188, 1188, 1187, - 1188, 1187, 1188, 1187, 1188, 1188, 1187, 1188, - 1188, 1187, 1188, 1188, 1187, 1188, 1188, 1187, - 1365, 1187, 1366, 1348, 1347, 1367, 1258, 1187, - 1188, 1187, 1368, 1266, 1187, 1188, 1187, 1285, - 1286, 1287, 1288, 1289, 1290, 1369, 1187, 1370, - 1187, 1188, 1187, 1285, 1286, 1287, 1288, 1289, - 1290, 1371, 1187, 1372, 1370, 1187, 1188, 1187, - 3, 148, 148, 3, 148, 3, 148, 1, - 3, 148, 1, 3, 1, 148, 3, 1, - 148, 3, 148, 1, 3, 1, 148, 3, - 148, 1, 3, 148, 1, 3, 148, 3, - 1, 3, 148, 3, 148, 3, 1, 3, - 148, 3, 148, 1, 3, 3, 148, 1, - 3, 148, 1, 1152, 1, 1373, 1152, 1, - 1374, 1375, 1376, 1377, 1376, 762, 1378, 1, - 147, 3, 1, 1, 147, 1, 147, 3, - 147, 1, 147, 1, 1380, 1379, 1383, 1384, - 1385, 1386, 1387, 1388, 1389, 1390, 1392, 1393, - 1394, 1395, 1396, 1397, 1399, 1379, 1, 1382, - 1391, 1398, 1, 1381, 144, 146, 1401, 1402, - 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, - 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, - 1400, 309, 329, 1420, 1421, 1422, 1423, 1424, - 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, - 1433, 1434, 1435, 1436, 1437, 1419, 1438, 309, - 329, 1420, 1421, 1422, 1423, 1424, 1425, 1426, - 1427, 1428, 1429, 1430, 1431, 1439, 1440, 1434, - 1435, 1441, 1437, 1419, 1443, 1444, 1445, 1446, - 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, - 1455, 1456, 1458, 335, 662, 723, 1457, 1442, - 476, 478, 1459, 1460, 1461, 1462, 1463, 1464, - 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, - 1473, 1474, 1475, 1476, 1442, 638, 658, 1477, - 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, - 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, - 1494, 1442, 1495, 638, 658, 1477, 1478, 1479, - 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, - 1488, 1496, 1497, 1491, 1492, 1498, 1494, 1442, - 638, 658, 1477, 1478, 1479, 1480, 1481, 1482, - 1483, 1484, 1485, 1486, 1487, 1499, 1489, 1490, - 1500, 1501, 1502, 1503, 1492, 1493, 1494, 1442, - 638, 658, 1477, 1478, 1479, 1480, 1481, 1482, - 1483, 1484, 1485, 1486, 1487, 1504, 1489, 1490, - 1491, 1505, 1492, 1493, 1494, 1442, 638, 658, - 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, - 1485, 1486, 1487, 1506, 1489, 1490, 1491, 1507, - 1492, 1493, 1494, 1442, 638, 658, 1477, 1478, - 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, - 1487, 1508, 1489, 1490, 1491, 1509, 1492, 1493, - 1494, 1442, 638, 658, 1477, 1478, 1479, 1480, - 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, - 1489, 1490, 1491, 1492, 1510, 1494, 1442, 931, - 951, 1512, 1513, 1514, 1515, 1516, 1517, 1518, - 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, - 1527, 1528, 1529, 1530, 1531, 1532, 1511, 931, - 951, 1512, 1513, 1514, 1515, 1516, 1517, 1518, - 1519, 1520, 1521, 1522, 1533, 1524, 1525, 1534, - 1530, 1531, 1532, 1511, 1535, 931, 951, 1512, - 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, - 1521, 1522, 1533, 1536, 1537, 1534, 1530, 1538, - 1532, 1511, 931, 951, 1512, 1513, 1514, 1515, - 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1539, - 1524, 1525, 1534, 1540, 1530, 1531, 1532, 1511, - 931, 951, 1512, 1513, 1514, 1515, 1516, 1517, - 1518, 1519, 1520, 1521, 1522, 1541, 1524, 1525, - 1534, 1542, 1530, 1531, 1532, 1511, 931, 951, - 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, - 1520, 1521, 1522, 1543, 1524, 1525, 1534, 1544, - 1530, 1531, 1532, 1511, 1135, 1137, 1546, 1547, - 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, - 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, - 1545, 1347, 1367, 1565, 1566, 1567, 1568, 1569, - 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, - 1578, 1579, 1580, 1581, 1582, 1564, 1347, 1367, - 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, - 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, - 1583, 1582, 1564, 1584, 1347, 1367, 1565, 1566, - 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, - 1575, 1576, 1585, 1586, 1579, 1580, 1587, 1582, - 1564, -} - -var _graphclust_trans_targs []int16 = []int16{ - 1547, 0, 1547, 1548, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, - 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 67, 68, - 69, 70, 71, 73, 74, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 92, 93, 95, 104, - 136, 142, 144, 151, 156, 96, 97, 98, - 99, 100, 101, 102, 103, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 137, 138, 139, 140, - 141, 143, 145, 146, 147, 148, 149, 150, - 152, 153, 154, 155, 157, 159, 160, 161, - 2, 162, 3, 1547, 1549, 1547, 1547, 178, - 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, - 228, 230, 235, 254, 255, 256, 1550, 233, - 234, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 258, 259, 260, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 278, 279, 281, - 290, 322, 328, 330, 337, 342, 282, 283, - 284, 285, 286, 287, 288, 289, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 323, 324, 325, - 326, 327, 329, 331, 332, 333, 334, 335, - 336, 338, 339, 340, 341, 165, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 361, - 362, 166, 364, 366, 367, 1551, 1547, 1552, - 382, 383, 384, 385, 386, 387, 388, 389, - 390, 391, 392, 393, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 411, 412, 413, 414, - 415, 416, 417, 418, 419, 420, 421, 422, - 423, 424, 425, 426, 427, 428, 429, 430, - 431, 432, 434, 435, 436, 437, 438, 440, - 441, 443, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 455, 456, 457, - 459, 460, 462, 471, 503, 509, 511, 518, - 523, 463, 464, 465, 466, 467, 468, 469, - 470, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 486, - 487, 488, 489, 490, 491, 492, 493, 494, - 495, 496, 497, 498, 499, 500, 501, 502, - 504, 505, 506, 507, 508, 510, 512, 513, - 514, 515, 516, 517, 519, 520, 521, 522, - 524, 526, 527, 528, 369, 529, 370, 1553, - 545, 546, 547, 548, 549, 550, 551, 552, - 553, 554, 555, 556, 557, 558, 559, 560, - 561, 562, 563, 564, 565, 566, 567, 568, - 569, 570, 571, 572, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 592, 593, - 594, 595, 597, 602, 621, 622, 623, 1554, - 600, 601, 603, 604, 605, 606, 607, 608, - 609, 610, 611, 612, 613, 614, 615, 616, - 617, 618, 619, 620, 625, 626, 627, 629, - 630, 631, 632, 633, 634, 635, 636, 637, - 638, 639, 640, 641, 642, 643, 645, 646, - 648, 657, 689, 695, 697, 704, 709, 649, - 650, 651, 652, 653, 654, 655, 656, 658, - 659, 660, 661, 662, 663, 664, 665, 666, - 667, 668, 669, 670, 671, 672, 673, 674, - 675, 676, 677, 678, 679, 680, 681, 682, - 683, 684, 685, 686, 687, 688, 690, 691, - 692, 693, 694, 696, 698, 699, 700, 701, - 702, 703, 705, 706, 707, 708, 532, 710, - 711, 712, 713, 714, 715, 716, 717, 718, - 719, 720, 721, 722, 723, 724, 725, 726, - 728, 729, 533, 731, 733, 734, 530, 739, - 740, 742, 744, 747, 750, 774, 1555, 756, - 1556, 746, 1557, 749, 752, 754, 755, 758, - 759, 763, 764, 765, 766, 767, 768, 769, - 1558, 762, 773, 776, 777, 778, 779, 780, - 781, 782, 783, 784, 785, 786, 787, 788, - 789, 790, 791, 792, 793, 795, 796, 799, - 800, 801, 802, 803, 804, 805, 806, 810, - 811, 813, 814, 797, 816, 825, 827, 829, - 831, 817, 818, 819, 820, 821, 822, 823, - 824, 826, 828, 830, 832, 833, 834, 835, - 839, 840, 841, 842, 843, 844, 845, 846, - 847, 848, 849, 850, 851, 1559, 837, 838, - 854, 855, 163, 859, 860, 862, 1067, 1070, - 1073, 1097, 1560, 1547, 1561, 876, 877, 878, - 879, 880, 881, 882, 883, 884, 885, 886, - 887, 888, 889, 890, 891, 892, 893, 894, - 895, 896, 897, 898, 899, 900, 901, 902, - 903, 905, 906, 907, 908, 909, 910, 911, - 912, 913, 914, 915, 916, 917, 918, 919, - 920, 921, 922, 923, 924, 925, 926, 928, - 933, 952, 953, 954, 1562, 931, 932, 934, - 935, 936, 937, 938, 939, 940, 941, 942, - 943, 944, 945, 946, 947, 948, 949, 950, - 951, 956, 957, 958, 960, 961, 962, 963, - 964, 965, 966, 967, 968, 969, 970, 971, - 972, 973, 974, 976, 977, 979, 988, 1020, - 1026, 1028, 1035, 1040, 980, 981, 982, 983, - 984, 985, 986, 987, 989, 990, 991, 992, - 993, 994, 995, 996, 997, 998, 999, 1000, - 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, - 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, - 1017, 1018, 1019, 1021, 1022, 1023, 1024, 1025, - 1027, 1029, 1030, 1031, 1032, 1033, 1034, 1036, - 1037, 1038, 1039, 863, 1041, 1042, 1043, 1044, - 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, - 1053, 1054, 1055, 1056, 1057, 1059, 1060, 864, - 1062, 1064, 1065, 1079, 1563, 1069, 1564, 1072, - 1075, 1077, 1078, 1081, 1082, 1086, 1087, 1088, - 1089, 1090, 1091, 1092, 1565, 1085, 1096, 1099, - 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, - 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, - 1277, 1566, 1547, 1113, 1114, 1115, 1116, 1117, - 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, - 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, - 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1142, - 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, - 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, - 1159, 1160, 1161, 1162, 1163, 1165, 1166, 1167, - 1168, 1169, 1171, 1172, 1174, 1175, 1176, 1177, - 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, - 1186, 1187, 1188, 1190, 1191, 1193, 1202, 1234, - 1240, 1242, 1249, 1254, 1194, 1195, 1196, 1197, - 1198, 1199, 1200, 1201, 1203, 1204, 1205, 1206, - 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, - 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, - 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, - 1231, 1232, 1233, 1235, 1236, 1237, 1238, 1239, - 1241, 1243, 1244, 1245, 1246, 1247, 1248, 1250, - 1251, 1252, 1253, 1255, 1257, 1258, 1259, 1100, - 1260, 1101, 1279, 1280, 1283, 1284, 1285, 1286, - 1287, 1288, 1289, 1290, 1294, 1295, 1297, 1298, - 1281, 1300, 1309, 1311, 1313, 1315, 1301, 1302, - 1303, 1304, 1305, 1306, 1307, 1308, 1310, 1312, - 1314, 1316, 1317, 1318, 1319, 1526, 1527, 1528, - 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, - 1537, 1538, 1567, 1547, 1568, 1333, 1334, 1335, - 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, - 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, - 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, - 1360, 1362, 1363, 1364, 1365, 1366, 1367, 1368, - 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, - 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1385, - 1390, 1409, 1410, 1411, 1569, 1388, 1389, 1391, - 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, - 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, - 1408, 1413, 1414, 1415, 1417, 1418, 1419, 1420, - 1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, - 1429, 1430, 1431, 1433, 1434, 1436, 1445, 1477, - 1483, 1485, 1492, 1497, 1437, 1438, 1439, 1440, - 1441, 1442, 1443, 1444, 1446, 1447, 1448, 1449, - 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, - 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, - 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, - 1474, 1475, 1476, 1478, 1479, 1480, 1481, 1482, - 1484, 1486, 1487, 1488, 1489, 1490, 1491, 1493, - 1494, 1495, 1496, 1320, 1498, 1499, 1500, 1501, - 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, - 1510, 1511, 1512, 1513, 1514, 1516, 1517, 1321, - 1519, 1521, 1522, 1524, 1525, 1541, 1542, 1543, - 1544, 1545, 1546, 1547, 1, 1548, 163, 164, - 368, 856, 857, 858, 861, 1098, 1278, 1281, - 1282, 1291, 1292, 1293, 1296, 1299, 1539, 1540, - 1547, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 43, 66, 72, 75, - 91, 94, 158, 1547, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 206, - 229, 363, 261, 277, 365, 360, 231, 232, - 257, 280, 1547, 531, 735, 736, 737, 738, - 741, 775, 794, 798, 807, 808, 809, 812, - 815, 852, 853, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 410, 433, - 439, 442, 458, 461, 525, 534, 535, 536, - 537, 538, 539, 540, 541, 542, 543, 544, - 573, 596, 730, 628, 644, 732, 727, 598, - 599, 624, 647, 743, 757, 770, 771, 772, - 745, 753, 748, 751, 760, 761, 836, 1547, - 865, 866, 867, 868, 869, 870, 871, 872, - 873, 874, 875, 1066, 927, 1061, 1080, 1093, - 1094, 1095, 975, 1063, 1058, 904, 959, 929, - 930, 955, 978, 1068, 1076, 1071, 1074, 1083, - 1084, 1547, 1102, 1103, 1104, 1105, 1106, 1107, - 1108, 1109, 1110, 1111, 1112, 1141, 1164, 1170, - 1173, 1189, 1192, 1256, 1547, 1322, 1323, 1324, - 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, - 1361, 1384, 1518, 1416, 1432, 1523, 1515, 1520, - 1386, 1387, 1412, 1435, -} - -var _graphclust_trans_actions []byte = []byte{ - 31, 0, 27, 40, 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, 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, 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, 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 34, 55, 29, 19, 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, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 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, 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, 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, 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, 40, 25, 40, - 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, - 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, - 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, - 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, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 40, - 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, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 40, - 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, - 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, - 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, - 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, - 0, 0, 0, 0, 0, 0, 40, 0, - 40, 0, 40, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 40, 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, 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, 0, 0, 0, 0, 40, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 51, 17, 40, 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, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 40, 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, 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, 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, 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, 51, 0, 51, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 40, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 40, 21, 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, 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, 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, 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, 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, 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, 40, 23, 40, 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, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 40, 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, 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, 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, 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, 0, 0, 0, - 0, 0, 0, 43, 1, 47, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 15, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 13, 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, 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, 0, 0, 0, 0, 5, - 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, - 0, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 11, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -} - -var _graphclust_to_state_actions []byte = []byte{ - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 37, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -} - -var _graphclust_from_state_actions []byte = []byte{ - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -} - -var _graphclust_eof_trans []int16 = []int16{ - 0, 0, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 0, 0, 150, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 150, 151, 150, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 150, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 0, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 0, 0, 0, 0, 0, 0, 150, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 150, 772, 772, 150, 772, - 772, 150, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 150, 772, 772, 772, - 772, 0, 0, 0, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 995, 995, 995, - 995, 995, 995, 995, 995, 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, 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, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - 1188, 1188, 1188, 1188, 1188, 1188, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1401, 1420, 1420, 1443, - 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, - 1512, 1512, 1512, 1512, 1512, 1512, 1546, 1565, - 1565, 1565, -} - -const graphclust_start int = 1547 -const graphclust_first_final int = 1547 -const graphclust_error int = 0 - -const graphclust_en_main int = 1547 - -//line grapheme_clusters.rl:14 - -var Error = errors.New("invalid UTF8 text") - -// ScanGraphemeClusters is a split function for bufio.Scanner that splits -// on grapheme cluster boundaries. -func ScanGraphemeClusters(data []byte, atEOF bool) (int, []byte, error) { - if len(data) == 0 { - return 0, nil, nil - } - - // Ragel state - cs := 0 // Current State - p := 0 // "Pointer" into data - pe := len(data) // End-of-data "pointer" - ts := 0 - te := 0 - act := 0 - eof := pe - - // Make Go compiler happy - _ = ts - _ = te - _ = act - _ = eof - - startPos := 0 - endPos := 0 - -//line grapheme_clusters.go:3847 - { - cs = graphclust_start - ts = 0 - te = 0 - act = 0 - } - -//line grapheme_clusters.go:3855 - { - var _klen int - var _trans int - var _acts int - var _nacts uint - var _keys int - if p == pe { - goto _test_eof - } - if cs == 0 { - goto _out - } - _resume: - _acts = int(_graphclust_from_state_actions[cs]) - _nacts = uint(_graphclust_actions[_acts]) - _acts++ - for ; _nacts > 0; _nacts-- { - _acts++ - switch _graphclust_actions[_acts-1] { - case 4: -//line NONE:1 - ts = p - -//line grapheme_clusters.go:3878 - } - } - - _keys = int(_graphclust_key_offsets[cs]) - _trans = int(_graphclust_index_offsets[cs]) - - _klen = int(_graphclust_single_lengths[cs]) - if _klen > 0 { - _lower := int(_keys) - var _mid int - _upper := int(_keys + _klen - 1) - for { - if _upper < _lower { - break - } - - _mid = _lower + ((_upper - _lower) >> 1) - switch { - case data[p] < _graphclust_trans_keys[_mid]: - _upper = _mid - 1 - case data[p] > _graphclust_trans_keys[_mid]: - _lower = _mid + 1 - default: - _trans += int(_mid - int(_keys)) - goto _match - } - } - _keys += _klen - _trans += _klen - } - - _klen = int(_graphclust_range_lengths[cs]) - if _klen > 0 { - _lower := int(_keys) - var _mid int - _upper := int(_keys + (_klen << 1) - 2) - for { - if _upper < _lower { - break - } - - _mid = _lower + (((_upper - _lower) >> 1) & ^1) - switch { - case data[p] < _graphclust_trans_keys[_mid]: - _upper = _mid - 2 - case data[p] > _graphclust_trans_keys[_mid+1]: - _lower = _mid + 2 - default: - _trans += int((_mid - int(_keys)) >> 1) - goto _match - } - } - _trans += _klen - } - - _match: - _trans = int(_graphclust_indicies[_trans]) - _eof_trans: - cs = int(_graphclust_trans_targs[_trans]) - - if _graphclust_trans_actions[_trans] == 0 { - goto _again - } - - _acts = int(_graphclust_trans_actions[_trans]) - _nacts = uint(_graphclust_actions[_acts]) - _acts++ - for ; _nacts > 0; _nacts-- { - _acts++ - switch _graphclust_actions[_acts-1] { - case 0: -//line grapheme_clusters.rl:47 - - startPos = p - - case 1: -//line grapheme_clusters.rl:51 - - endPos = p - - case 5: -//line NONE:1 - te = p + 1 - - case 6: -//line grapheme_clusters.rl:55 - act = 3 - case 7: -//line grapheme_clusters.rl:55 - act = 4 - case 8: -//line grapheme_clusters.rl:55 - te = p + 1 - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 9: -//line grapheme_clusters.rl:55 - te = p + 1 - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 10: -//line grapheme_clusters.rl:55 - te = p - p-- - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 11: -//line grapheme_clusters.rl:55 - te = p - p-- - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 12: -//line grapheme_clusters.rl:55 - te = p - p-- - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 13: -//line grapheme_clusters.rl:55 - te = p - p-- - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 14: -//line grapheme_clusters.rl:55 - te = p - p-- - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 15: -//line grapheme_clusters.rl:55 - te = p - p-- - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 16: -//line grapheme_clusters.rl:55 - p = (te) - 1 - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 17: -//line grapheme_clusters.rl:55 - p = (te) - 1 - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 18: -//line grapheme_clusters.rl:55 - p = (te) - 1 - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 19: -//line grapheme_clusters.rl:55 - p = (te) - 1 - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 20: -//line grapheme_clusters.rl:55 - p = (te) - 1 - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 21: -//line grapheme_clusters.rl:55 - p = (te) - 1 - { - return endPos + 1, data[startPos : endPos+1], nil - } - case 22: -//line NONE:1 - switch act { - case 0: - { - cs = 0 - goto _again - } - case 3: - { - p = (te) - 1 - - return endPos + 1, data[startPos : endPos+1], nil - } - case 4: - { - p = (te) - 1 - - return endPos + 1, data[startPos : endPos+1], nil - } - } - -//line grapheme_clusters.go:4077 - } - } - - _again: - _acts = int(_graphclust_to_state_actions[cs]) - _nacts = uint(_graphclust_actions[_acts]) - _acts++ - for ; _nacts > 0; _nacts-- { - _acts++ - switch _graphclust_actions[_acts-1] { - case 2: -//line NONE:1 - ts = 0 - - case 3: -//line NONE:1 - act = 0 - -//line grapheme_clusters.go:4095 - } - } - - if cs == 0 { - goto _out - } - p++ - if p != pe { - goto _resume - } - _test_eof: - { - } - if p == eof { - if _graphclust_eof_trans[cs] > 0 { - _trans = int(_graphclust_eof_trans[cs] - 1) - goto _eof_trans - } - } - - _out: - { - } - } - -//line grapheme_clusters.rl:117 - - // If we fall out here then we were unable to complete a sequence. - // If we weren't able to complete a sequence then either we've - // reached the end of a partial buffer (so there's more data to come) - // or we have an isolated symbol that would normally be part of a - // grapheme cluster but has appeared in isolation here. - - if !atEOF { - // Request more - return 0, nil, nil - } - - // Just take the first UTF-8 sequence and return that. - _, seqLen := utf8.DecodeRune(data) - return seqLen, data[:seqLen], nil -} diff --git a/vendor/github.com/apparentlymart/go-textseg/v13/LICENSE b/vendor/github.com/apparentlymart/go-textseg/v15/LICENSE similarity index 100% rename from vendor/github.com/apparentlymart/go-textseg/v13/LICENSE rename to vendor/github.com/apparentlymart/go-textseg/v15/LICENSE diff --git a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/all_tokens.go b/vendor/github.com/apparentlymart/go-textseg/v15/textseg/all_tokens.go similarity index 100% rename from vendor/github.com/apparentlymart/go-textseg/v13/textseg/all_tokens.go rename to vendor/github.com/apparentlymart/go-textseg/v15/textseg/all_tokens.go diff --git a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/emoji_table.rl b/vendor/github.com/apparentlymart/go-textseg/v15/textseg/emoji_table.rl similarity index 93% rename from vendor/github.com/apparentlymart/go-textseg/v13/textseg/emoji_table.rl rename to vendor/github.com/apparentlymart/go-textseg/v15/textseg/emoji_table.rl index f2cb484a..10b93e47 100644 --- a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/emoji_table.rl +++ b/vendor/github.com/apparentlymart/go-textseg/v15/textseg/emoji_table.rl @@ -1,5 +1,5 @@ # The following Ragel file was autogenerated with unicode2ragel.rb -# from: https://www.unicode.org/Public/13.0.0/ucd/emoji/emoji-data.txt +# from: https://www.unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt # # It defines ["Extended_Pictographic"]. # @@ -150,8 +150,8 @@ | 0xE2 0x9D 0x87 #E0.6 [1] (❇️) sparkle | 0xE2 0x9D 0x8C #E0.6 [1] (❌) cross mark | 0xE2 0x9D 0x8E #E0.6 [1] (❎) cross mark button - | 0xE2 0x9D 0x93..0x95 #E0.6 [3] (❓..❕) question mark..white e... - | 0xE2 0x9D 0x97 #E0.6 [1] (❗) exclamation mark + | 0xE2 0x9D 0x93..0x95 #E0.6 [3] (❓..❕) red question mark..whi... + | 0xE2 0x9D 0x97 #E0.6 [1] (❗) red exclamation mark | 0xE2 0x9D 0xA3 #E1.0 [1] (❣️) heart exclamation | 0xE2 0x9D 0xA4 #E0.6 [1] (❤️) red heart | 0xE2 0x9D 0xA5..0xA7 #E0.0 [3] (❥..❧) ROTATED HEAVY BLACK HE... @@ -299,7 +299,7 @@ | 0xF0 0x9F 0x94 0x89 #E1.0 [1] (🔉) speaker medium volume | 0xF0 0x9F 0x94 0x8A..0x94 #E0.6 [11] (🔊..🔔) speaker high volume... | 0xF0 0x9F 0x94 0x95 #E1.0 [1] (🔕) bell with slash - | 0xF0 0x9F 0x94 0x96..0xAB #E0.6 [22] (🔖..🔫) bookmark..pistol + | 0xF0 0x9F 0x94 0x96..0xAB #E0.6 [22] (🔖..🔫) bookmark..water pistol | 0xF0 0x9F 0x94 0xAC..0xAD #E1.0 [2] (🔬..🔭) microscope..telescope | 0xF0 0x9F 0x94 0xAE..0xBD #E0.6 [16] (🔮..🔽) crystal ball..downw... | 0xF0 0x9F 0x95 0x86..0x88 #E0.0 [3] (🕆..🕈) WHITE LATIN CROSS..... @@ -377,7 +377,7 @@ | 0xF0 0x9F 0x98 0xAE..0xAF #E1.0 [2] (😮..😯) face with open mout... | 0xF0 0x9F 0x98 0xB0..0xB3 #E0.6 [4] (😰..😳) anxious face with s... | 0xF0 0x9F 0x98 0xB4 #E1.0 [1] (😴) sleeping face - | 0xF0 0x9F 0x98 0xB5 #E0.6 [1] (😵) dizzy face + | 0xF0 0x9F 0x98 0xB5 #E0.6 [1] (😵) face with crossed-out ... | 0xF0 0x9F 0x98 0xB6 #E1.0 [1] (😶) face without mouth | 0xF0 0x9F 0x98 0xB7..0xFF #E0.6 [10] (😷..🙀) face with medical m... | 0xF0 0x9F 0x99 0x00..0x80 # @@ -427,7 +427,9 @@ | 0xF0 0x9F 0x9B 0x93..0x94 #E0.0 [2] (🛓..🛔) STUPA..PAGODA | 0xF0 0x9F 0x9B 0x95 #E12.0 [1] (🛕) hindu temple | 0xF0 0x9F 0x9B 0x96..0x97 #E13.0 [2] (🛖..🛗) hut..elevator - | 0xF0 0x9F 0x9B 0x98..0x9F #E0.0 [8] (🛘..🛟) ..<... + | 0xF0 0x9F 0x9B 0x98..0x9B #E0.0 [4] (🛘..🛛) ..<... + | 0xF0 0x9F 0x9B 0x9C #E15.0 [1] (🛜) wireless + | 0xF0 0x9F 0x9B 0x9D..0x9F #E14.0 [3] (🛝..🛟) playground slide..r... | 0xF0 0x9F 0x9B 0xA0..0xA5 #E0.7 [6] (🛠️..🛥️) hammer and wrench... | 0xF0 0x9F 0x9B 0xA6..0xA8 #E0.0 [3] (🛦..🛨) UP-POINTING MILITAR... | 0xF0 0x9F 0x9B 0xA9 #E0.7 [1] (🛩️) small airplane @@ -443,10 +445,12 @@ | 0xF0 0x9F 0x9B 0xBA #E12.0 [1] (🛺) auto rickshaw | 0xF0 0x9F 0x9B 0xBB..0xBC #E13.0 [2] (🛻..🛼) pickup truck..rolle... | 0xF0 0x9F 0x9B 0xBD..0xBF #E0.0 [3] (🛽..🛿) ..<... - | 0xF0 0x9F 0x9D 0xB4..0xBF #E0.0 [12] (🝴..🝿) ..<... + | 0xF0 0x9F 0x9D 0xB4..0xBF #E0.0 [12] (🝴..🝿) LOT OF FORTUNE..ORCUS | 0xF0 0x9F 0x9F 0x95..0x9F #E0.0 [11] (🟕..🟟) CIRCLED TRIANGLE..<... | 0xF0 0x9F 0x9F 0xA0..0xAB #E12.0 [12] (🟠..🟫) orange circle..brow... - | 0xF0 0x9F 0x9F 0xAC..0xBF #E0.0 [20] (🟬..🟿) ..<... + | 0xF0 0x9F 0x9F 0xAC..0xAF #E0.0 [4] (🟬..🟯) ..<... + | 0xF0 0x9F 0x9F 0xB0 #E14.0 [1] (🟰) heavy equals sign + | 0xF0 0x9F 0x9F 0xB1..0xBF #E0.0 [15] (🟱..🟿) ..<... | 0xF0 0x9F 0xA0 0x8C..0x8F #E0.0 [4] (🠌..🠏) ..<... | 0xF0 0x9F 0xA1 0x88..0x8F #E0.0 [8] (🡈..🡏) ..<... | 0xF0 0x9F 0xA1 0x9A..0x9F #E0.0 [6] (🡚..🡟) ..<... @@ -476,7 +480,7 @@ | 0xF0 0x9F 0xA5 0xB2 #E13.0 [1] (🥲) smiling face with tear | 0xF0 0x9F 0xA5 0xB3..0xB6 #E11.0 [4] (🥳..🥶) partying face..cold... | 0xF0 0x9F 0xA5 0xB7..0xB8 #E13.0 [2] (🥷..🥸) ninja..disguised face - | 0xF0 0x9F 0xA5 0xB9 #E0.0 [1] (🥹) + | 0xF0 0x9F 0xA5 0xB9 #E14.0 [1] (🥹) face holding back tears | 0xF0 0x9F 0xA5 0xBA #E11.0 [1] (🥺) pleading face | 0xF0 0x9F 0xA5 0xBB #E12.0 [1] (🥻) sari | 0xF0 0x9F 0xA5 0xBC..0xBF #E11.0 [4] (🥼..🥿) lab coat..flat shoe @@ -494,7 +498,7 @@ | 0xF0 0x9F 0xA7 0x81..0x82 #E11.0 [2] (🧁..🧂) cupcake..salt | 0xF0 0x9F 0xA7 0x83..0x8A #E12.0 [8] (🧃..🧊) beverage box..ice | 0xF0 0x9F 0xA7 0x8B #E13.0 [1] (🧋) bubble tea - | 0xF0 0x9F 0xA7 0x8C #E0.0 [1] (🧌) + | 0xF0 0x9F 0xA7 0x8C #E14.0 [1] (🧌) troll | 0xF0 0x9F 0xA7 0x8D..0x8F #E12.0 [3] (🧍..🧏) person standing..de... | 0xF0 0x9F 0xA7 0x90..0xA6 #E5.0 [23] (🧐..🧦) face with monocle..... | 0xF0 0x9F 0xA7 0xA7..0xBF #E11.0 [25] (🧧..🧿) red envelope..nazar... @@ -502,21 +506,37 @@ | 0xF0 0x9F 0xA9 0x00..0xAF # | 0xF0 0x9F 0xA9 0xB0..0xB3 #E12.0 [4] (🩰..🩳) ballet shoes..shorts | 0xF0 0x9F 0xA9 0xB4 #E13.0 [1] (🩴) thong sandal - | 0xF0 0x9F 0xA9 0xB5..0xB7 #E0.0 [3] (🩵..🩷) ..<... + | 0xF0 0x9F 0xA9 0xB5..0xB7 #E15.0 [3] (🩵..🩷) light blue heart..p... | 0xF0 0x9F 0xA9 0xB8..0xBA #E12.0 [3] (🩸..🩺) drop of blood..stet... - | 0xF0 0x9F 0xA9 0xBB..0xBF #E0.0 [5] (🩻..🩿) ..<... + | 0xF0 0x9F 0xA9 0xBB..0xBC #E14.0 [2] (🩻..🩼) x-ray..crutch + | 0xF0 0x9F 0xA9 0xBD..0xBF #E0.0 [3] (🩽..🩿) ..<... | 0xF0 0x9F 0xAA 0x80..0x82 #E12.0 [3] (🪀..🪂) yo-yo..parachute | 0xF0 0x9F 0xAA 0x83..0x86 #E13.0 [4] (🪃..🪆) boomerang..nesting ... - | 0xF0 0x9F 0xAA 0x87..0x8F #E0.0 [9] (🪇..🪏) ..<... + | 0xF0 0x9F 0xAA 0x87..0x88 #E15.0 [2] (🪇..🪈) maracas..flute + | 0xF0 0x9F 0xAA 0x89..0x8F #E0.0 [7] (🪉..🪏) ..<... | 0xF0 0x9F 0xAA 0x90..0x95 #E12.0 [6] (🪐..🪕) ringed planet..banjo | 0xF0 0x9F 0xAA 0x96..0xA8 #E13.0 [19] (🪖..🪨) military helmet..rock - | 0xF0 0x9F 0xAA 0xA9..0xAF #E0.0 [7] (🪩..🪯) ..<... + | 0xF0 0x9F 0xAA 0xA9..0xAC #E14.0 [4] (🪩..🪬) mirror ball..hamsa + | 0xF0 0x9F 0xAA 0xAD..0xAF #E15.0 [3] (🪭..🪯) folding hand fan..k... | 0xF0 0x9F 0xAA 0xB0..0xB6 #E13.0 [7] (🪰..🪶) fly..feather - | 0xF0 0x9F 0xAA 0xB7..0xBF #E0.0 [9] (🪷..🪿) ..<... + | 0xF0 0x9F 0xAA 0xB7..0xBA #E14.0 [4] (🪷..🪺) lotus..nest with eggs + | 0xF0 0x9F 0xAA 0xBB..0xBD #E15.0 [3] (🪻..🪽) hyacinth..wing + | 0xF0 0x9F 0xAA 0xBE #E0.0 [1] (🪾) + | 0xF0 0x9F 0xAA 0xBF #E15.0 [1] (🪿) goose | 0xF0 0x9F 0xAB 0x80..0x82 #E13.0 [3] (🫀..🫂) anatomical heart..p... - | 0xF0 0x9F 0xAB 0x83..0x8F #E0.0 [13] (🫃..🫏) ..<... + | 0xF0 0x9F 0xAB 0x83..0x85 #E14.0 [3] (🫃..🫅) pregnant man..perso... + | 0xF0 0x9F 0xAB 0x86..0x8D #E0.0 [8] (🫆..🫍) ..<... + | 0xF0 0x9F 0xAB 0x8E..0x8F #E15.0 [2] (🫎..🫏) moose..donkey | 0xF0 0x9F 0xAB 0x90..0x96 #E13.0 [7] (🫐..🫖) blueberries..teapot - | 0xF0 0x9F 0xAB 0x97..0xBF #E0.0 [41] (🫗..🫿) ..<... + | 0xF0 0x9F 0xAB 0x97..0x99 #E14.0 [3] (🫗..🫙) pouring liquid..jar + | 0xF0 0x9F 0xAB 0x9A..0x9B #E15.0 [2] (🫚..🫛) ginger root..pea pod + | 0xF0 0x9F 0xAB 0x9C..0x9F #E0.0 [4] (🫜..🫟) ..<... + | 0xF0 0x9F 0xAB 0xA0..0xA7 #E14.0 [8] (🫠..🫧) melting face..bubbles + | 0xF0 0x9F 0xAB 0xA8 #E15.0 [1] (🫨) shaking face + | 0xF0 0x9F 0xAB 0xA9..0xAF #E0.0 [7] (🫩..🫯) ..<... + | 0xF0 0x9F 0xAB 0xB0..0xB6 #E14.0 [7] (🫰..🫶) hand with index fin... + | 0xF0 0x9F 0xAB 0xB7..0xB8 #E15.0 [2] (🫷..🫸) leftwards pushing h... + | 0xF0 0x9F 0xAB 0xB9..0xBF #E0.0 [7] (🫹..🫿) ..<... | 0xF0 0x9F 0xB0 0x80..0xFF #E0.0[1022] (🰀..🿽) 0; _nacts-- { + _acts++ + switch _graphclust_actions[_acts-1] { + case 4: +//line NONE:1 + ts = p + +//line grapheme_clusters.go:4080 + } + } + + _keys = int(_graphclust_key_offsets[cs]) + _trans = int(_graphclust_index_offsets[cs]) + + _klen = int(_graphclust_single_lengths[cs]) + if _klen > 0 { + _lower := int(_keys) + var _mid int + _upper := int(_keys + _klen - 1) + for { + if _upper < _lower { + break + } + + _mid = _lower + ((_upper - _lower) >> 1) + switch { + case data[p] < _graphclust_trans_keys[_mid]: + _upper = _mid - 1 + case data[p] > _graphclust_trans_keys[_mid]: + _lower = _mid + 1 + default: + _trans += int(_mid - int(_keys)) + goto _match + } + } + _keys += _klen + _trans += _klen + } + + _klen = int(_graphclust_range_lengths[cs]) + if _klen > 0 { + _lower := int(_keys) + var _mid int + _upper := int(_keys + (_klen << 1) - 2) + for { + if _upper < _lower { + break + } + + _mid = _lower + (((_upper - _lower) >> 1) & ^1) + switch { + case data[p] < _graphclust_trans_keys[_mid]: + _upper = _mid - 2 + case data[p] > _graphclust_trans_keys[_mid+1]: + _lower = _mid + 2 + default: + _trans += int((_mid - int(_keys)) >> 1) + goto _match + } + } + _trans += _klen + } + + _match: + _trans = int(_graphclust_indicies[_trans]) + _eof_trans: + cs = int(_graphclust_trans_targs[_trans]) + + if _graphclust_trans_actions[_trans] == 0 { + goto _again + } + + _acts = int(_graphclust_trans_actions[_trans]) + _nacts = uint(_graphclust_actions[_acts]) + _acts++ + for ; _nacts > 0; _nacts-- { + _acts++ + switch _graphclust_actions[_acts-1] { + case 0: +//line grapheme_clusters.rl:47 + + startPos = p + + case 1: +//line grapheme_clusters.rl:51 + + endPos = p + + case 5: +//line NONE:1 + te = p + 1 + + case 6: +//line grapheme_clusters.rl:55 + act = 3 + case 7: +//line grapheme_clusters.rl:55 + act = 4 + case 8: +//line grapheme_clusters.rl:55 + act = 8 + case 9: +//line grapheme_clusters.rl:55 + te = p + 1 + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 10: +//line grapheme_clusters.rl:55 + te = p + 1 + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 11: +//line grapheme_clusters.rl:55 + te = p + p-- + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 12: +//line grapheme_clusters.rl:55 + te = p + p-- + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 13: +//line grapheme_clusters.rl:55 + te = p + p-- + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 14: +//line grapheme_clusters.rl:55 + te = p + p-- + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 15: +//line grapheme_clusters.rl:55 + te = p + p-- + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 16: +//line grapheme_clusters.rl:55 + te = p + p-- + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 17: +//line grapheme_clusters.rl:55 + p = (te) - 1 + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 18: +//line grapheme_clusters.rl:55 + p = (te) - 1 + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 19: +//line grapheme_clusters.rl:55 + p = (te) - 1 + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 20: +//line grapheme_clusters.rl:55 + p = (te) - 1 + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 21: +//line grapheme_clusters.rl:55 + p = (te) - 1 + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 22: +//line grapheme_clusters.rl:55 + p = (te) - 1 + { + return endPos + 1, data[startPos : endPos+1], nil + } + case 23: +//line NONE:1 + switch act { + case 0: + { + cs = 0 + goto _again + } + case 3: + { + p = (te) - 1 + + return endPos + 1, data[startPos : endPos+1], nil + } + case 4: + { + p = (te) - 1 + + return endPos + 1, data[startPos : endPos+1], nil + } + case 8: + { + p = (te) - 1 + + return endPos + 1, data[startPos : endPos+1], nil + } + } + +//line grapheme_clusters.go:4287 + } + } + + _again: + _acts = int(_graphclust_to_state_actions[cs]) + _nacts = uint(_graphclust_actions[_acts]) + _acts++ + for ; _nacts > 0; _nacts-- { + _acts++ + switch _graphclust_actions[_acts-1] { + case 2: +//line NONE:1 + ts = 0 + + case 3: +//line NONE:1 + act = 0 + +//line grapheme_clusters.go:4305 + } + } + + if cs == 0 { + goto _out + } + p++ + if p != pe { + goto _resume + } + _test_eof: + { + } + if p == eof { + if _graphclust_eof_trans[cs] > 0 { + _trans = int(_graphclust_eof_trans[cs] - 1) + goto _eof_trans + } + } + + _out: + { + } + } + +//line grapheme_clusters.rl:117 + + // If we fall out here then we were unable to complete a sequence. + // If we weren't able to complete a sequence then either we've + // reached the end of a partial buffer (so there's more data to come) + // or we have an isolated symbol that would normally be part of a + // grapheme cluster but has appeared in isolation here. + + if !atEOF { + // Request more + return 0, nil, nil + } + + // Just take the first UTF-8 sequence and return that. + _, seqLen := utf8.DecodeRune(data) + return seqLen, data[:seqLen], nil +} diff --git a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/grapheme_clusters.rl b/vendor/github.com/apparentlymart/go-textseg/v15/textseg/grapheme_clusters.rl similarity index 100% rename from vendor/github.com/apparentlymart/go-textseg/v13/textseg/grapheme_clusters.rl rename to vendor/github.com/apparentlymart/go-textseg/v15/textseg/grapheme_clusters.rl diff --git a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/grapheme_clusters_table.rl b/vendor/github.com/apparentlymart/go-textseg/v15/textseg/grapheme_clusters_table.rl similarity index 97% rename from vendor/github.com/apparentlymart/go-textseg/v13/textseg/grapheme_clusters_table.rl rename to vendor/github.com/apparentlymart/go-textseg/v15/textseg/grapheme_clusters_table.rl index 803dca19..3cff4291 100644 --- a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/grapheme_clusters_table.rl +++ b/vendor/github.com/apparentlymart/go-textseg/v15/textseg/grapheme_clusters_table.rl @@ -1,5 +1,5 @@ # The following Ragel file was autogenerated with unicode2ragel.rb -# from: https://www.unicode.org/Public/13.0.0/ucd/auxiliary/GraphemeBreakProperty.txt +# from: https://www.unicode.org/Public/15.0.0/ucd/auxiliary/GraphemeBreakProperty.txt # # It defines ["Prepend", "CR", "LF", "Control", "Extend", "Regional_Indicator", "SpacingMark", "L", "V", "T", "LV", "LVT", "ZWJ"]. # @@ -13,6 +13,7 @@ 0xD8 0x80..0x85 #Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER ... | 0xDB 0x9D #Cf ARABIC END OF AYAH | 0xDC 0x8F #Cf SYRIAC ABBREVIATION MARK + | 0xE0 0xA2 0x90..0x91 #Cf [2] ARABIC POUND MARK ABOVE..ARABIC PI... | 0xE0 0xA3 0xA2 #Cf ARABIC DISPUTED END OF AYAH | 0xE0 0xB5 0x8E #Lo MALAYALAM LETTER DOT REPH | 0xF0 0x91 0x82 0xBD #Cf KAITHI NUMBER SIGN @@ -23,6 +24,7 @@ | 0xF0 0x91 0xA8 0xBA #Lo ZANABAZAR SQUARE CLUSTER-INITIAL L... | 0xF0 0x91 0xAA 0x84..0x89 #Lo [6] SOYOMBO SIGN JIHVAMULIYA..SOYOM... | 0xF0 0x91 0xB5 0x86 #Lo MASARAM GONDI REPHA + | 0xF0 0x91 0xBC 0x82 #Lo KAWI SIGN REPHA ; CR = @@ -53,7 +55,7 @@ | 0xEF 0xBB 0xBF #Cf ZERO WIDTH NO-BREAK SPACE | 0xEF 0xBF 0xB0..0xB8 #Cn [9] .. | 0xEF 0xBF 0xB9..0xBB #Cf [3] INTERLINEAR ANNOTATION ANCHOR..INT... - | 0xF0 0x93 0x90 0xB0..0xB8 #Cf [9] EGYPTIAN HIEROGLYPH VERTICAL JO... + | 0xF0 0x93 0x90 0xB0..0xBF #Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JO... | 0xF0 0x9B 0xB2 0xA0..0xA3 #Cf [4] SHORTHAND FORMAT LETTER OVERLAP... | 0xF0 0x9D 0x85 0xB3..0xBA #Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSI... | 0xF3 0xA0 0x80 0x80 #Cn @@ -94,7 +96,8 @@ | 0xE0 0xA0 0xA5..0xA7 #Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMA... | 0xE0 0xA0 0xA9..0xAD #Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMAR... | 0xE0 0xA1 0x99..0x9B #Mn [3] MANDAIC AFFRICATION MARK..MANDAIC ... - | 0xE0 0xA3 0x93..0xA1 #Mn [15] ARABIC SMALL LOW WAW..ARABIC SMALL... + | 0xE0 0xA2 0x98..0x9F #Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARA... + | 0xE0 0xA3 0x8A..0xA1 #Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABI... | 0xE0 0xA3 0xA3..0xFF #Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAG... | 0xE0 0xA4 0x00..0x82 # | 0xE0 0xA4 0xBA #Mn DEVANAGARI VOWEL SIGN OE @@ -142,6 +145,7 @@ | 0xE0 0xAF 0x97 #Mc TAMIL AU LENGTH MARK | 0xE0 0xB0 0x80 #Mn TELUGU SIGN COMBINING CANDRABINDU ... | 0xE0 0xB0 0x84 #Mn TELUGU SIGN COMBINING ANUSVARA ABOVE + | 0xE0 0xB0 0xBC #Mn TELUGU SIGN NUKTA | 0xE0 0xB0 0xBE..0xFF #Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL... | 0xE0 0xB1 0x00..0x80 # | 0xE0 0xB1 0x86..0x88 #Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL ... @@ -174,7 +178,7 @@ | 0xE0 0xB9 0x87..0x8E #Mn [8] THAI CHARACTER MAITAIKHU..THAI CHA... | 0xE0 0xBA 0xB1 #Mn LAO VOWEL SIGN MAI KAN | 0xE0 0xBA 0xB4..0xBC #Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SI... - | 0xE0 0xBB 0x88..0x8D #Mn [6] LAO TONE MAI EK..LAO NIGGAHITA + | 0xE0 0xBB 0x88..0x8E #Mn [7] LAO TONE MAI EK..LAO YAMAKKAN | 0xE0 0xBC 0x98..0x99 #Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD P... | 0xE0 0xBC 0xB5 #Mn TIBETAN MARK NGAS BZUNG NYI ZLA | 0xE0 0xBC 0xB7 #Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS @@ -198,7 +202,7 @@ | 0xE1 0x82 0x9D #Mn MYANMAR VOWEL SIGN AITON AI | 0xE1 0x8D 0x9D..0x9F #Mn [3] ETHIOPIC COMBINING GEMINATION AND ... | 0xE1 0x9C 0x92..0x94 #Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN... - | 0xE1 0x9C 0xB2..0xB4 #Mn [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN... + | 0xE1 0x9C 0xB2..0xB3 #Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWE... | 0xE1 0x9D 0x92..0x93 #Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SI... | 0xE1 0x9D 0xB2..0xB3 #Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VO... | 0xE1 0x9E 0xB4..0xB5 #Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOW... @@ -207,6 +211,7 @@ | 0xE1 0x9F 0x89..0x93 #Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN... | 0xE1 0x9F 0x9D #Mn KHMER SIGN ATTHACAN | 0xE1 0xA0 0x8B..0x8D #Mn [3] MONGOLIAN FREE VARIATION SELECTOR ... + | 0xE1 0xA0 0x8F #Mn MONGOLIAN FREE VARIATION SELECTOR ... | 0xE1 0xA2 0x85..0x86 #Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..... | 0xE1 0xA2 0xA9 #Mn MONGOLIAN LETTER ALI GALI DAGALGA | 0xE1 0xA4 0xA0..0xA2 #Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SI... @@ -224,8 +229,8 @@ | 0xE1 0xA9 0xBF #Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT | 0xE1 0xAA 0xB0..0xBD #Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCEN... | 0xE1 0xAA 0xBE #Me COMBINING PARENTHESES OVERLAY - | 0xE1 0xAA 0xBF..0xFF #Mn [2] COMBINING LATIN SMALL LETTER W BEL... - | 0xE1 0xAB 0x00..0x80 # + | 0xE1 0xAA 0xBF..0xFF #Mn [16] COMBINING LATIN SMALL LETTER W BEL... + | 0xE1 0xAB 0x00..0x8E # | 0xE1 0xAC 0x80..0x83 #Mn [4] BALINESE SIGN ULU RICEM..BALINESE ... | 0xE1 0xAC 0xB4 #Mn BALINESE SIGN REREKAN | 0xE1 0xAC 0xB5 #Mc BALINESE VOWEL SIGN TEDUNG @@ -249,8 +254,7 @@ | 0xE1 0xB3 0xAD #Mn VEDIC SIGN TIRYAK | 0xE1 0xB3 0xB4 #Mn VEDIC TONE CANDRA ABOVE | 0xE1 0xB3 0xB8..0xB9 #Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE ... - | 0xE1 0xB7 0x80..0xB9 #Mn [58] COMBINING DOTTED GRAVE ACCENT..COM... - | 0xE1 0xB7 0xBB..0xBF #Mn [5] COMBINING DELETION MARK..COMBINING... + | 0xE1 0xB7 0x80..0xBF #Mn [64] COMBINING DOTTED GRAVE ACCENT..COM... | 0xE2 0x80 0x8C #Cf ZERO WIDTH NON-JOINER | 0xE2 0x83 0x90..0x9C #Mn [13] COMBINING LEFT HARPOON ABOVE..COMB... | 0xE2 0x83 0x9D..0xA0 #Me [4] COMBINING ENCLOSING CIRCLE..COMBIN... @@ -314,14 +318,19 @@ | 0xF0 0x90 0xAB 0xA5..0xA6 #Mn [2] MANICHAEAN ABBREVIATION MARK AB... | 0xF0 0x90 0xB4 0xA4..0xA7 #Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..... | 0xF0 0x90 0xBA 0xAB..0xAC #Mn [2] YEZIDI COMBINING HAMZA MARK..YE... + | 0xF0 0x90 0xBB 0xBD..0xBF #Mn [3] ARABIC SMALL LOW WORD SAKTA..AR... | 0xF0 0x90 0xBD 0x86..0x90 #Mn [11] SOGDIAN COMBINING DOT BELOW..SO... + | 0xF0 0x90 0xBE 0x82..0x85 #Mn [4] OLD UYGHUR COMBINING DOT ABOVE.... | 0xF0 0x91 0x80 0x81 #Mn BRAHMI SIGN ANUSVARA | 0xF0 0x91 0x80 0xB8..0xFF #Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VI... | 0xF0 0x91 0x81 0x00..0x86 # + | 0xF0 0x91 0x81 0xB0 #Mn BRAHMI SIGN OLD TAMIL VIRAMA + | 0xF0 0x91 0x81 0xB3..0xB4 #Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHO... | 0xF0 0x91 0x81 0xBF..0xFF #Mn [3] BRAHMI NUMBER JOINER..KAITHI SI... | 0xF0 0x91 0x82 0x00..0x81 # | 0xF0 0x91 0x82 0xB3..0xB6 #Mn [4] KAITHI VOWEL SIGN U..KAITHI VOW... | 0xF0 0x91 0x82 0xB9..0xBA #Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN... + | 0xF0 0x91 0x83 0x82 #Mn KAITHI VOWEL SIGN VOCALIC R | 0xF0 0x91 0x84 0x80..0x82 #Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA... | 0xF0 0x91 0x84 0xA7..0xAB #Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOW... | 0xF0 0x91 0x84 0xAD..0xB4 #Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MA... @@ -334,6 +343,7 @@ | 0xF0 0x91 0x88 0xB4 #Mn KHOJKI SIGN ANUSVARA | 0xF0 0x91 0x88 0xB6..0xB7 #Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN ... | 0xF0 0x91 0x88 0xBE #Mn KHOJKI SIGN SUKUN + | 0xF0 0x91 0x89 0x81 #Mn KHOJKI VOWEL SIGN VOCALIC R | 0xF0 0x91 0x8B 0x9F #Mn KHUDAWADI SIGN ANUSVARA | 0xF0 0x91 0x8B 0xA3..0xAA #Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWA... | 0xF0 0x91 0x8C 0x80..0x81 #Mn [2] GRANTHA SIGN COMBINING ANUSVARA... @@ -405,12 +415,21 @@ | 0xF0 0x91 0xB6 0x95 #Mn GUNJALA GONDI SIGN ANUSVARA | 0xF0 0x91 0xB6 0x97 #Mn GUNJALA GONDI VIRAMA | 0xF0 0x91 0xBB 0xB3..0xB4 #Mn [2] MAKASAR VOWEL SIGN I..MAKASAR V... + | 0xF0 0x91 0xBC 0x80..0x81 #Mn [2] KAWI SIGN CANDRABINDU..KAWI SIG... + | 0xF0 0x91 0xBC 0xB6..0xBA #Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL S... + | 0xF0 0x91 0xBD 0x80 #Mn KAWI VOWEL SIGN EU + | 0xF0 0x91 0xBD 0x82 #Mn KAWI CONJOINER + | 0xF0 0x93 0x91 0x80 #Mn EGYPTIAN HIEROGLYPH MIRROR HORIZON... + | 0xF0 0x93 0x91 0x87..0x95 #Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DA... | 0xF0 0x96 0xAB 0xB0..0xB4 #Mn [5] BASSA VAH COMBINING HIGH TONE..... | 0xF0 0x96 0xAC 0xB0..0xB6 #Mn [7] PAHAWH HMONG MARK CIM TUB..PAHA... | 0xF0 0x96 0xBD 0x8F #Mn MIAO SIGN CONSONANT MODIFIER BAR | 0xF0 0x96 0xBE 0x8F..0x92 #Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW | 0xF0 0x96 0xBF 0xA4 #Mn KHITAN SMALL SCRIPT FILLER | 0xF0 0x9B 0xB2 0x9D..0x9E #Mn [2] DUPLOYAN THICK LETTER SELECTOR.... + | 0xF0 0x9C 0xBC 0x80..0xAD #Mn [46] ZNAMENNY COMBINING MARK GORAZDO... + | 0xF0 0x9C 0xBC 0xB0..0xFF #Mn [23] ZNAMENNY COMBINING TONAL RANGE ... + | 0xF0 0x9C 0xBD 0x00..0x86 # | 0xF0 0x9D 0x85 0xA5 #Mc MUSICAL SYMBOL COMBINING STEM | 0xF0 0x9D 0x85 0xA7..0xA9 #Mn [3] MUSICAL SYMBOL COMBINING TREMOL... | 0xF0 0x9D 0x85 0xAE..0xB2 #Mc [5] MUSICAL SYMBOL COMBINING FLAG-1... @@ -431,8 +450,11 @@ | 0xF0 0x9E 0x80 0x9B..0xA1 #Mn [7] COMBINING GLAGOLITIC LETTER SHT... | 0xF0 0x9E 0x80 0xA3..0xA4 #Mn [2] COMBINING GLAGOLITIC LETTER YU.... | 0xF0 0x9E 0x80 0xA6..0xAA #Mn [5] COMBINING GLAGOLITIC LETTER YO.... + | 0xF0 0x9E 0x82 0x8F #Mn COMBINING CYRILLIC SMALL LETTER BY... | 0xF0 0x9E 0x84 0xB0..0xB6 #Mn [7] NYIAKENG PUACHUE HMONG TONE-B..... + | 0xF0 0x9E 0x8A 0xAE #Mn TOTO SIGN RISING TONE | 0xF0 0x9E 0x8B 0xAC..0xAF #Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI + | 0xF0 0x9E 0x93 0xAC..0xAF #Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUN... | 0xF0 0x9E 0xA3 0x90..0x96 #Mn [7] MENDE KIKAKUI COMBINING NUMBER ... | 0xF0 0x9E 0xA5 0x84..0x8A #Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA | 0xF0 0x9F 0x8F 0xBB..0xBF #Sk [5] EMOJI MODIFIER FITZPATRICK TYPE... @@ -483,6 +505,7 @@ | 0xE0 0xB3 0x83..0x84 #Mc [2] KANNADA VOWEL SIGN VOCALIC R..KANN... | 0xE0 0xB3 0x87..0x88 #Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOW... | 0xE0 0xB3 0x8A..0x8B #Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWE... + | 0xE0 0xB3 0xB3 #Mc KANNADA SIGN COMBINING ANUSVARA AB... | 0xE0 0xB4 0x82..0x83 #Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM... | 0xE0 0xB4 0xBF..0xFF #Mc [2] MALAYALAM VOWEL SIGN I..MALAYALAM ... | 0xE0 0xB5 0x00..0x80 # @@ -500,6 +523,8 @@ | 0xE1 0x80 0xBB..0xBC #Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..... | 0xE1 0x81 0x96..0x97 #Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYAN... | 0xE1 0x82 0x84 #Mc MYANMAR VOWEL SIGN SHAN E + | 0xE1 0x9C 0x95 #Mc TAGALOG SIGN PAMUDPOD + | 0xE1 0x9C 0xB4 #Mc HANUNOO SIGN PAMUDPOD | 0xE1 0x9E 0xB6 #Mc KHMER VOWEL SIGN AA | 0xE1 0x9E 0xBE..0xFF #Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL S... | 0xE1 0x9F 0x00..0x85 # @@ -589,7 +614,6 @@ | 0xF0 0x91 0x9A 0xAC #Mc TAKRI SIGN VISARGA | 0xF0 0x91 0x9A 0xAE..0xAF #Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL... | 0xF0 0x91 0x9A 0xB6 #Mc TAKRI SIGN VIRAMA - | 0xF0 0x91 0x9C 0xA0..0xA1 #Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL S... | 0xF0 0x91 0x9C 0xA6 #Mc AHOM VOWEL SIGN E | 0xF0 0x91 0xA0 0xAC..0xAE #Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWE... | 0xF0 0x91 0xA0 0xB8 #Mc DOGRA SIGN VISARGA @@ -613,6 +637,10 @@ | 0xF0 0x91 0xB6 0x93..0x94 #Mc [2] GUNJALA GONDI VOWEL SIGN OO..GU... | 0xF0 0x91 0xB6 0x96 #Mc GUNJALA GONDI SIGN VISARGA | 0xF0 0x91 0xBB 0xB5..0xB6 #Mc [2] MAKASAR VOWEL SIGN E..MAKASAR V... + | 0xF0 0x91 0xBC 0x83 #Mc KAWI SIGN VISARGA + | 0xF0 0x91 0xBC 0xB4..0xB5 #Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL ... + | 0xF0 0x91 0xBC 0xBE..0xBF #Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL S... + | 0xF0 0x91 0xBD 0x81 #Mc KAWI SIGN KILLER | 0xF0 0x96 0xBD 0x91..0xFF #Mc [55] MIAO SIGN ASPIRATION..MIAO VOWE... | 0xF0 0x96 0xBE 0x00..0x87 # | 0xF0 0x96 0xBF 0xB0..0xB1 #Mc [2] VIETNAMESE ALTERNATE READING MA... diff --git a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/tables.go b/vendor/github.com/apparentlymart/go-textseg/v15/textseg/tables.go similarity index 93% rename from vendor/github.com/apparentlymart/go-textseg/v13/textseg/tables.go rename to vendor/github.com/apparentlymart/go-textseg/v15/textseg/tables.go index b3f22ad4..864268d5 100644 --- a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/tables.go +++ b/vendor/github.com/apparentlymart/go-textseg/v15/textseg/tables.go @@ -1,5 +1,5 @@ // Generated by running -// maketables --url=http://www.unicode.org/Public/12.0.0/ucd/auxiliary/ +// maketables --url=http://www.unicode.org/Public/15.0.0/ucd/auxiliary/ // DO NOT EDIT package textseg @@ -37,7 +37,7 @@ var _GraphemeControl = &unicode.RangeTable{ unicode.Range16{Lo: 0xfff9, Hi: 0xfffb, Stride: 0x1}, }, R32: []unicode.Range32{ - unicode.Range32{Lo: 0x13430, Hi: 0x13438, Stride: 0x1}, + unicode.Range32{Lo: 0x13430, Hi: 0x1343f, Stride: 0x1}, unicode.Range32{Lo: 0x1bca0, Hi: 0x1bca3, Stride: 0x1}, unicode.Range32{Lo: 0x1d173, Hi: 0x1d17a, Stride: 0x1}, unicode.Range32{Lo: 0xe0000, Hi: 0xe0000, Stride: 0x1}, @@ -76,7 +76,8 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x825, Hi: 0x827, Stride: 0x1}, unicode.Range16{Lo: 0x829, Hi: 0x82d, Stride: 0x1}, unicode.Range16{Lo: 0x859, Hi: 0x85b, Stride: 0x1}, - unicode.Range16{Lo: 0x8d3, Hi: 0x8e1, Stride: 0x1}, + unicode.Range16{Lo: 0x898, Hi: 0x89f, Stride: 0x1}, + unicode.Range16{Lo: 0x8ca, Hi: 0x8e1, Stride: 0x1}, unicode.Range16{Lo: 0x8e3, Hi: 0x902, Stride: 0x1}, unicode.Range16{Lo: 0x93a, Hi: 0x93a, Stride: 0x1}, unicode.Range16{Lo: 0x93c, Hi: 0x93c, Stride: 0x1}, @@ -113,7 +114,7 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xb3f, Hi: 0xb3f, Stride: 0x1}, unicode.Range16{Lo: 0xb41, Hi: 0xb44, Stride: 0x1}, unicode.Range16{Lo: 0xb4d, Hi: 0xb4d, Stride: 0x1}, - unicode.Range16{Lo: 0xb56, Hi: 0xb56, Stride: 0x1}, + unicode.Range16{Lo: 0xb55, Hi: 0xb56, Stride: 0x1}, unicode.Range16{Lo: 0xb57, Hi: 0xb57, Stride: 0x1}, unicode.Range16{Lo: 0xb62, Hi: 0xb63, Stride: 0x1}, unicode.Range16{Lo: 0xb82, Hi: 0xb82, Stride: 0x1}, @@ -123,6 +124,7 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xbd7, Hi: 0xbd7, Stride: 0x1}, unicode.Range16{Lo: 0xc00, Hi: 0xc00, Stride: 0x1}, unicode.Range16{Lo: 0xc04, Hi: 0xc04, Stride: 0x1}, + unicode.Range16{Lo: 0xc3c, Hi: 0xc3c, Stride: 0x1}, unicode.Range16{Lo: 0xc3e, Hi: 0xc40, Stride: 0x1}, unicode.Range16{Lo: 0xc46, Hi: 0xc48, Stride: 0x1}, unicode.Range16{Lo: 0xc4a, Hi: 0xc4d, Stride: 0x1}, @@ -143,6 +145,7 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xd4d, Hi: 0xd4d, Stride: 0x1}, unicode.Range16{Lo: 0xd57, Hi: 0xd57, Stride: 0x1}, unicode.Range16{Lo: 0xd62, Hi: 0xd63, Stride: 0x1}, + unicode.Range16{Lo: 0xd81, Hi: 0xd81, Stride: 0x1}, unicode.Range16{Lo: 0xdca, Hi: 0xdca, Stride: 0x1}, unicode.Range16{Lo: 0xdcf, Hi: 0xdcf, Stride: 0x1}, unicode.Range16{Lo: 0xdd2, Hi: 0xdd4, Stride: 0x1}, @@ -153,7 +156,7 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xe47, Hi: 0xe4e, Stride: 0x1}, unicode.Range16{Lo: 0xeb1, Hi: 0xeb1, Stride: 0x1}, unicode.Range16{Lo: 0xeb4, Hi: 0xebc, Stride: 0x1}, - unicode.Range16{Lo: 0xec8, Hi: 0xecd, Stride: 0x1}, + unicode.Range16{Lo: 0xec8, Hi: 0xece, Stride: 0x1}, unicode.Range16{Lo: 0xf18, Hi: 0xf19, Stride: 0x1}, unicode.Range16{Lo: 0xf35, Hi: 0xf35, Stride: 0x1}, unicode.Range16{Lo: 0xf37, Hi: 0xf37, Stride: 0x1}, @@ -177,7 +180,7 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x109d, Hi: 0x109d, Stride: 0x1}, unicode.Range16{Lo: 0x135d, Hi: 0x135f, Stride: 0x1}, unicode.Range16{Lo: 0x1712, Hi: 0x1714, Stride: 0x1}, - unicode.Range16{Lo: 0x1732, Hi: 0x1734, Stride: 0x1}, + unicode.Range16{Lo: 0x1732, Hi: 0x1733, Stride: 0x1}, unicode.Range16{Lo: 0x1752, Hi: 0x1753, Stride: 0x1}, unicode.Range16{Lo: 0x1772, Hi: 0x1773, Stride: 0x1}, unicode.Range16{Lo: 0x17b4, Hi: 0x17b5, Stride: 0x1}, @@ -186,6 +189,7 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x17c9, Hi: 0x17d3, Stride: 0x1}, unicode.Range16{Lo: 0x17dd, Hi: 0x17dd, Stride: 0x1}, unicode.Range16{Lo: 0x180b, Hi: 0x180d, Stride: 0x1}, + unicode.Range16{Lo: 0x180f, Hi: 0x180f, Stride: 0x1}, unicode.Range16{Lo: 0x1885, Hi: 0x1886, Stride: 0x1}, unicode.Range16{Lo: 0x18a9, Hi: 0x18a9, Stride: 0x1}, unicode.Range16{Lo: 0x1920, Hi: 0x1922, Stride: 0x1}, @@ -203,6 +207,7 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x1a7f, Hi: 0x1a7f, Stride: 0x1}, unicode.Range16{Lo: 0x1ab0, Hi: 0x1abd, Stride: 0x1}, unicode.Range16{Lo: 0x1abe, Hi: 0x1abe, Stride: 0x1}, + unicode.Range16{Lo: 0x1abf, Hi: 0x1ace, Stride: 0x1}, unicode.Range16{Lo: 0x1b00, Hi: 0x1b03, Stride: 0x1}, unicode.Range16{Lo: 0x1b34, Hi: 0x1b34, Stride: 0x1}, unicode.Range16{Lo: 0x1b35, Hi: 0x1b35, Stride: 0x1}, @@ -226,8 +231,7 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x1ced, Hi: 0x1ced, Stride: 0x1}, unicode.Range16{Lo: 0x1cf4, Hi: 0x1cf4, Stride: 0x1}, unicode.Range16{Lo: 0x1cf8, Hi: 0x1cf9, Stride: 0x1}, - unicode.Range16{Lo: 0x1dc0, Hi: 0x1df9, Stride: 0x1}, - unicode.Range16{Lo: 0x1dfb, Hi: 0x1dff, Stride: 0x1}, + unicode.Range16{Lo: 0x1dc0, Hi: 0x1dff, Stride: 0x1}, unicode.Range16{Lo: 0x200c, Hi: 0x200c, Stride: 0x1}, unicode.Range16{Lo: 0x20d0, Hi: 0x20dc, Stride: 0x1}, unicode.Range16{Lo: 0x20dd, Hi: 0x20e0, Stride: 0x1}, @@ -249,6 +253,7 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xa806, Hi: 0xa806, Stride: 0x1}, unicode.Range16{Lo: 0xa80b, Hi: 0xa80b, Stride: 0x1}, unicode.Range16{Lo: 0xa825, Hi: 0xa826, Stride: 0x1}, + unicode.Range16{Lo: 0xa82c, Hi: 0xa82c, Stride: 0x1}, unicode.Range16{Lo: 0xa8c4, Hi: 0xa8c5, Stride: 0x1}, unicode.Range16{Lo: 0xa8e0, Hi: 0xa8f1, Stride: 0x1}, unicode.Range16{Lo: 0xa8ff, Hi: 0xa8ff, Stride: 0x1}, @@ -291,12 +296,18 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x10a3f, Hi: 0x10a3f, Stride: 0x1}, unicode.Range32{Lo: 0x10ae5, Hi: 0x10ae6, Stride: 0x1}, unicode.Range32{Lo: 0x10d24, Hi: 0x10d27, Stride: 0x1}, + unicode.Range32{Lo: 0x10eab, Hi: 0x10eac, Stride: 0x1}, + unicode.Range32{Lo: 0x10efd, Hi: 0x10eff, Stride: 0x1}, unicode.Range32{Lo: 0x10f46, Hi: 0x10f50, Stride: 0x1}, + unicode.Range32{Lo: 0x10f82, Hi: 0x10f85, Stride: 0x1}, unicode.Range32{Lo: 0x11001, Hi: 0x11001, Stride: 0x1}, unicode.Range32{Lo: 0x11038, Hi: 0x11046, Stride: 0x1}, + unicode.Range32{Lo: 0x11070, Hi: 0x11070, Stride: 0x1}, + unicode.Range32{Lo: 0x11073, Hi: 0x11074, Stride: 0x1}, unicode.Range32{Lo: 0x1107f, Hi: 0x11081, Stride: 0x1}, unicode.Range32{Lo: 0x110b3, Hi: 0x110b6, Stride: 0x1}, unicode.Range32{Lo: 0x110b9, Hi: 0x110ba, Stride: 0x1}, + unicode.Range32{Lo: 0x110c2, Hi: 0x110c2, Stride: 0x1}, unicode.Range32{Lo: 0x11100, Hi: 0x11102, Stride: 0x1}, unicode.Range32{Lo: 0x11127, Hi: 0x1112b, Stride: 0x1}, unicode.Range32{Lo: 0x1112d, Hi: 0x11134, Stride: 0x1}, @@ -304,10 +315,12 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x11180, Hi: 0x11181, Stride: 0x1}, unicode.Range32{Lo: 0x111b6, Hi: 0x111be, Stride: 0x1}, unicode.Range32{Lo: 0x111c9, Hi: 0x111cc, Stride: 0x1}, + unicode.Range32{Lo: 0x111cf, Hi: 0x111cf, Stride: 0x1}, unicode.Range32{Lo: 0x1122f, Hi: 0x11231, Stride: 0x1}, unicode.Range32{Lo: 0x11234, Hi: 0x11234, Stride: 0x1}, unicode.Range32{Lo: 0x11236, Hi: 0x11237, Stride: 0x1}, unicode.Range32{Lo: 0x1123e, Hi: 0x1123e, Stride: 0x1}, + unicode.Range32{Lo: 0x11241, Hi: 0x11241, Stride: 0x1}, unicode.Range32{Lo: 0x112df, Hi: 0x112df, Stride: 0x1}, unicode.Range32{Lo: 0x112e3, Hi: 0x112ea, Stride: 0x1}, unicode.Range32{Lo: 0x11300, Hi: 0x11301, Stride: 0x1}, @@ -344,6 +357,10 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x11727, Hi: 0x1172b, Stride: 0x1}, unicode.Range32{Lo: 0x1182f, Hi: 0x11837, Stride: 0x1}, unicode.Range32{Lo: 0x11839, Hi: 0x1183a, Stride: 0x1}, + unicode.Range32{Lo: 0x11930, Hi: 0x11930, Stride: 0x1}, + unicode.Range32{Lo: 0x1193b, Hi: 0x1193c, Stride: 0x1}, + unicode.Range32{Lo: 0x1193e, Hi: 0x1193e, Stride: 0x1}, + unicode.Range32{Lo: 0x11943, Hi: 0x11943, Stride: 0x1}, unicode.Range32{Lo: 0x119d4, Hi: 0x119d7, Stride: 0x1}, unicode.Range32{Lo: 0x119da, Hi: 0x119db, Stride: 0x1}, unicode.Range32{Lo: 0x119e0, Hi: 0x119e0, Stride: 0x1}, @@ -371,11 +388,20 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x11d95, Hi: 0x11d95, Stride: 0x1}, unicode.Range32{Lo: 0x11d97, Hi: 0x11d97, Stride: 0x1}, unicode.Range32{Lo: 0x11ef3, Hi: 0x11ef4, Stride: 0x1}, + unicode.Range32{Lo: 0x11f00, Hi: 0x11f01, Stride: 0x1}, + unicode.Range32{Lo: 0x11f36, Hi: 0x11f3a, Stride: 0x1}, + unicode.Range32{Lo: 0x11f40, Hi: 0x11f40, Stride: 0x1}, + unicode.Range32{Lo: 0x11f42, Hi: 0x11f42, Stride: 0x1}, + unicode.Range32{Lo: 0x13440, Hi: 0x13440, Stride: 0x1}, + unicode.Range32{Lo: 0x13447, Hi: 0x13455, Stride: 0x1}, unicode.Range32{Lo: 0x16af0, Hi: 0x16af4, Stride: 0x1}, unicode.Range32{Lo: 0x16b30, Hi: 0x16b36, Stride: 0x1}, unicode.Range32{Lo: 0x16f4f, Hi: 0x16f4f, Stride: 0x1}, unicode.Range32{Lo: 0x16f8f, Hi: 0x16f92, Stride: 0x1}, + unicode.Range32{Lo: 0x16fe4, Hi: 0x16fe4, Stride: 0x1}, unicode.Range32{Lo: 0x1bc9d, Hi: 0x1bc9e, Stride: 0x1}, + unicode.Range32{Lo: 0x1cf00, Hi: 0x1cf2d, Stride: 0x1}, + unicode.Range32{Lo: 0x1cf30, Hi: 0x1cf46, Stride: 0x1}, unicode.Range32{Lo: 0x1d165, Hi: 0x1d165, Stride: 0x1}, unicode.Range32{Lo: 0x1d167, Hi: 0x1d169, Stride: 0x1}, unicode.Range32{Lo: 0x1d16e, Hi: 0x1d172, Stride: 0x1}, @@ -394,8 +420,11 @@ var _GraphemeExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x1e01b, Hi: 0x1e021, Stride: 0x1}, unicode.Range32{Lo: 0x1e023, Hi: 0x1e024, Stride: 0x1}, unicode.Range32{Lo: 0x1e026, Hi: 0x1e02a, Stride: 0x1}, + unicode.Range32{Lo: 0x1e08f, Hi: 0x1e08f, Stride: 0x1}, unicode.Range32{Lo: 0x1e130, Hi: 0x1e136, Stride: 0x1}, + unicode.Range32{Lo: 0x1e2ae, Hi: 0x1e2ae, Stride: 0x1}, unicode.Range32{Lo: 0x1e2ec, Hi: 0x1e2ef, Stride: 0x1}, + unicode.Range32{Lo: 0x1e4ec, Hi: 0x1e4ef, Stride: 0x1}, unicode.Range32{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 0x1}, unicode.Range32{Lo: 0x1e944, Hi: 0x1e94a, Stride: 0x1}, unicode.Range32{Lo: 0x1f3fb, Hi: 0x1f3ff, Stride: 0x1}, @@ -1235,6 +1264,7 @@ var _GraphemePrepend = &unicode.RangeTable{ unicode.Range16{Lo: 0x600, Hi: 0x605, Stride: 0x1}, unicode.Range16{Lo: 0x6dd, Hi: 0x6dd, Stride: 0x1}, unicode.Range16{Lo: 0x70f, Hi: 0x70f, Stride: 0x1}, + unicode.Range16{Lo: 0x890, Hi: 0x891, Stride: 0x1}, unicode.Range16{Lo: 0x8e2, Hi: 0x8e2, Stride: 0x1}, unicode.Range16{Lo: 0xd4e, Hi: 0xd4e, Stride: 0x1}, }, @@ -1242,9 +1272,12 @@ var _GraphemePrepend = &unicode.RangeTable{ unicode.Range32{Lo: 0x110bd, Hi: 0x110bd, Stride: 0x1}, unicode.Range32{Lo: 0x110cd, Hi: 0x110cd, Stride: 0x1}, unicode.Range32{Lo: 0x111c2, Hi: 0x111c3, Stride: 0x1}, + unicode.Range32{Lo: 0x1193f, Hi: 0x1193f, Stride: 0x1}, + unicode.Range32{Lo: 0x11941, Hi: 0x11941, Stride: 0x1}, unicode.Range32{Lo: 0x11a3a, Hi: 0x11a3a, Stride: 0x1}, unicode.Range32{Lo: 0x11a84, Hi: 0x11a89, Stride: 0x1}, unicode.Range32{Lo: 0x11d46, Hi: 0x11d46, Stride: 0x1}, + unicode.Range32{Lo: 0x11f02, Hi: 0x11f02, Stride: 0x1}, }, LatinOffset: 0, } @@ -1289,6 +1322,7 @@ var _GraphemeSpacingMark = &unicode.RangeTable{ unicode.Range16{Lo: 0xcc3, Hi: 0xcc4, Stride: 0x1}, unicode.Range16{Lo: 0xcc7, Hi: 0xcc8, Stride: 0x1}, unicode.Range16{Lo: 0xcca, Hi: 0xccb, Stride: 0x1}, + unicode.Range16{Lo: 0xcf3, Hi: 0xcf3, Stride: 0x1}, unicode.Range16{Lo: 0xd02, Hi: 0xd03, Stride: 0x1}, unicode.Range16{Lo: 0xd3f, Hi: 0xd40, Stride: 0x1}, unicode.Range16{Lo: 0xd46, Hi: 0xd48, Stride: 0x1}, @@ -1305,6 +1339,8 @@ var _GraphemeSpacingMark = &unicode.RangeTable{ unicode.Range16{Lo: 0x103b, Hi: 0x103c, Stride: 0x1}, unicode.Range16{Lo: 0x1056, Hi: 0x1057, Stride: 0x1}, unicode.Range16{Lo: 0x1084, Hi: 0x1084, Stride: 0x1}, + unicode.Range16{Lo: 0x1715, Hi: 0x1715, Stride: 0x1}, + unicode.Range16{Lo: 0x1734, Hi: 0x1734, Stride: 0x1}, unicode.Range16{Lo: 0x17b6, Hi: 0x17b6, Stride: 0x1}, unicode.Range16{Lo: 0x17be, Hi: 0x17c5, Stride: 0x1}, unicode.Range16{Lo: 0x17c7, Hi: 0x17c8, Stride: 0x1}, @@ -1363,6 +1399,7 @@ var _GraphemeSpacingMark = &unicode.RangeTable{ unicode.Range32{Lo: 0x11182, Hi: 0x11182, Stride: 0x1}, unicode.Range32{Lo: 0x111b3, Hi: 0x111b5, Stride: 0x1}, unicode.Range32{Lo: 0x111bf, Hi: 0x111c0, Stride: 0x1}, + unicode.Range32{Lo: 0x111ce, Hi: 0x111ce, Stride: 0x1}, unicode.Range32{Lo: 0x1122c, Hi: 0x1122e, Stride: 0x1}, unicode.Range32{Lo: 0x11232, Hi: 0x11233, Stride: 0x1}, unicode.Range32{Lo: 0x11235, Hi: 0x11235, Stride: 0x1}, @@ -1390,10 +1427,14 @@ var _GraphemeSpacingMark = &unicode.RangeTable{ unicode.Range32{Lo: 0x116ac, Hi: 0x116ac, Stride: 0x1}, unicode.Range32{Lo: 0x116ae, Hi: 0x116af, Stride: 0x1}, unicode.Range32{Lo: 0x116b6, Hi: 0x116b6, Stride: 0x1}, - unicode.Range32{Lo: 0x11720, Hi: 0x11721, Stride: 0x1}, unicode.Range32{Lo: 0x11726, Hi: 0x11726, Stride: 0x1}, unicode.Range32{Lo: 0x1182c, Hi: 0x1182e, Stride: 0x1}, unicode.Range32{Lo: 0x11838, Hi: 0x11838, Stride: 0x1}, + unicode.Range32{Lo: 0x11931, Hi: 0x11935, Stride: 0x1}, + unicode.Range32{Lo: 0x11937, Hi: 0x11938, Stride: 0x1}, + unicode.Range32{Lo: 0x1193d, Hi: 0x1193d, Stride: 0x1}, + unicode.Range32{Lo: 0x11940, Hi: 0x11940, Stride: 0x1}, + unicode.Range32{Lo: 0x11942, Hi: 0x11942, Stride: 0x1}, unicode.Range32{Lo: 0x119d1, Hi: 0x119d3, Stride: 0x1}, unicode.Range32{Lo: 0x119dc, Hi: 0x119df, Stride: 0x1}, unicode.Range32{Lo: 0x119e4, Hi: 0x119e4, Stride: 0x1}, @@ -1409,7 +1450,12 @@ var _GraphemeSpacingMark = &unicode.RangeTable{ unicode.Range32{Lo: 0x11d93, Hi: 0x11d94, Stride: 0x1}, unicode.Range32{Lo: 0x11d96, Hi: 0x11d96, Stride: 0x1}, unicode.Range32{Lo: 0x11ef5, Hi: 0x11ef6, Stride: 0x1}, + unicode.Range32{Lo: 0x11f03, Hi: 0x11f03, Stride: 0x1}, + unicode.Range32{Lo: 0x11f34, Hi: 0x11f35, Stride: 0x1}, + unicode.Range32{Lo: 0x11f3e, Hi: 0x11f3f, Stride: 0x1}, + unicode.Range32{Lo: 0x11f41, Hi: 0x11f41, Stride: 0x1}, unicode.Range32{Lo: 0x16f51, Hi: 0x16f87, Stride: 0x1}, + unicode.Range32{Lo: 0x16ff0, Hi: 0x16ff1, Stride: 0x1}, unicode.Range32{Lo: 0x1d166, Hi: 0x1d166, Stride: 0x1}, unicode.Range32{Lo: 0x1d16d, Hi: 0x1d16d, Stride: 0x1}, }, @@ -1528,6 +1574,7 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x2d2, Hi: 0x2d7, Stride: 0x1}, unicode.Range16{Lo: 0x2de, Hi: 0x2df, Stride: 0x1}, unicode.Range16{Lo: 0x2e0, Hi: 0x2e4, Stride: 0x1}, + unicode.Range16{Lo: 0x2e5, Hi: 0x2eb, Stride: 0x1}, unicode.Range16{Lo: 0x2ec, Hi: 0x2ec, Stride: 0x1}, unicode.Range16{Lo: 0x2ed, Hi: 0x2ed, Stride: 0x1}, unicode.Range16{Lo: 0x2ee, Hi: 0x2ee, Stride: 0x1}, @@ -1547,9 +1594,10 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x48a, Hi: 0x52f, Stride: 0x1}, unicode.Range16{Lo: 0x531, Hi: 0x556, Stride: 0x1}, unicode.Range16{Lo: 0x559, Hi: 0x559, Stride: 0x1}, - unicode.Range16{Lo: 0x55b, Hi: 0x55c, Stride: 0x1}, + unicode.Range16{Lo: 0x55a, Hi: 0x55c, Stride: 0x1}, unicode.Range16{Lo: 0x55e, Hi: 0x55e, Stride: 0x1}, unicode.Range16{Lo: 0x560, Hi: 0x588, Stride: 0x1}, + unicode.Range16{Lo: 0x58a, Hi: 0x58a, Stride: 0x1}, unicode.Range16{Lo: 0x5f3, Hi: 0x5f3, Stride: 0x1}, unicode.Range16{Lo: 0x620, Hi: 0x63f, Stride: 0x1}, unicode.Range16{Lo: 0x640, Hi: 0x640, Stride: 0x1}, @@ -1574,8 +1622,10 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x828, Hi: 0x828, Stride: 0x1}, unicode.Range16{Lo: 0x840, Hi: 0x858, Stride: 0x1}, unicode.Range16{Lo: 0x860, Hi: 0x86a, Stride: 0x1}, - unicode.Range16{Lo: 0x8a0, Hi: 0x8b4, Stride: 0x1}, - unicode.Range16{Lo: 0x8b6, Hi: 0x8bd, Stride: 0x1}, + unicode.Range16{Lo: 0x870, Hi: 0x887, Stride: 0x1}, + unicode.Range16{Lo: 0x889, Hi: 0x88e, Stride: 0x1}, + unicode.Range16{Lo: 0x8a0, Hi: 0x8c8, Stride: 0x1}, + unicode.Range16{Lo: 0x8c9, Hi: 0x8c9, Stride: 0x1}, unicode.Range16{Lo: 0x904, Hi: 0x939, Stride: 0x1}, unicode.Range16{Lo: 0x93d, Hi: 0x93d, Stride: 0x1}, unicode.Range16{Lo: 0x950, Hi: 0x950, Stride: 0x1}, @@ -1641,6 +1691,7 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0xc2a, Hi: 0xc39, Stride: 0x1}, unicode.Range16{Lo: 0xc3d, Hi: 0xc3d, Stride: 0x1}, unicode.Range16{Lo: 0xc58, Hi: 0xc5a, Stride: 0x1}, + unicode.Range16{Lo: 0xc5d, Hi: 0xc5d, Stride: 0x1}, unicode.Range16{Lo: 0xc60, Hi: 0xc61, Stride: 0x1}, unicode.Range16{Lo: 0xc80, Hi: 0xc80, Stride: 0x1}, unicode.Range16{Lo: 0xc85, Hi: 0xc8c, Stride: 0x1}, @@ -1649,10 +1700,10 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0xcaa, Hi: 0xcb3, Stride: 0x1}, unicode.Range16{Lo: 0xcb5, Hi: 0xcb9, Stride: 0x1}, unicode.Range16{Lo: 0xcbd, Hi: 0xcbd, Stride: 0x1}, - unicode.Range16{Lo: 0xcde, Hi: 0xcde, Stride: 0x1}, + unicode.Range16{Lo: 0xcdd, Hi: 0xcde, Stride: 0x1}, unicode.Range16{Lo: 0xce0, Hi: 0xce1, Stride: 0x1}, unicode.Range16{Lo: 0xcf1, Hi: 0xcf2, Stride: 0x1}, - unicode.Range16{Lo: 0xd05, Hi: 0xd0c, Stride: 0x1}, + unicode.Range16{Lo: 0xd04, Hi: 0xd0c, Stride: 0x1}, unicode.Range16{Lo: 0xd0e, Hi: 0xd10, Stride: 0x1}, unicode.Range16{Lo: 0xd12, Hi: 0xd3a, Stride: 0x1}, unicode.Range16{Lo: 0xd3d, Hi: 0xd3d, Stride: 0x1}, @@ -1700,9 +1751,8 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x16a0, Hi: 0x16ea, Stride: 0x1}, unicode.Range16{Lo: 0x16ee, Hi: 0x16f0, Stride: 0x1}, unicode.Range16{Lo: 0x16f1, Hi: 0x16f8, Stride: 0x1}, - unicode.Range16{Lo: 0x1700, Hi: 0x170c, Stride: 0x1}, - unicode.Range16{Lo: 0x170e, Hi: 0x1711, Stride: 0x1}, - unicode.Range16{Lo: 0x1720, Hi: 0x1731, Stride: 0x1}, + unicode.Range16{Lo: 0x1700, Hi: 0x1711, Stride: 0x1}, + unicode.Range16{Lo: 0x171f, Hi: 0x1731, Stride: 0x1}, unicode.Range16{Lo: 0x1740, Hi: 0x1751, Stride: 0x1}, unicode.Range16{Lo: 0x1760, Hi: 0x176c, Stride: 0x1}, unicode.Range16{Lo: 0x176e, Hi: 0x1770, Stride: 0x1}, @@ -1716,7 +1766,7 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x1900, Hi: 0x191e, Stride: 0x1}, unicode.Range16{Lo: 0x1a00, Hi: 0x1a16, Stride: 0x1}, unicode.Range16{Lo: 0x1b05, Hi: 0x1b33, Stride: 0x1}, - unicode.Range16{Lo: 0x1b45, Hi: 0x1b4b, Stride: 0x1}, + unicode.Range16{Lo: 0x1b45, Hi: 0x1b4c, Stride: 0x1}, unicode.Range16{Lo: 0x1b83, Hi: 0x1ba0, Stride: 0x1}, unicode.Range16{Lo: 0x1bae, Hi: 0x1baf, Stride: 0x1}, unicode.Range16{Lo: 0x1bba, Hi: 0x1be5, Stride: 0x1}, @@ -1778,9 +1828,7 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x2183, Hi: 0x2184, Stride: 0x1}, unicode.Range16{Lo: 0x2185, Hi: 0x2188, Stride: 0x1}, unicode.Range16{Lo: 0x24b6, Hi: 0x24e9, Stride: 0x1}, - unicode.Range16{Lo: 0x2c00, Hi: 0x2c2e, Stride: 0x1}, - unicode.Range16{Lo: 0x2c30, Hi: 0x2c5e, Stride: 0x1}, - unicode.Range16{Lo: 0x2c60, Hi: 0x2c7b, Stride: 0x1}, + unicode.Range16{Lo: 0x2c00, Hi: 0x2c7b, Stride: 0x1}, unicode.Range16{Lo: 0x2c7c, Hi: 0x2c7d, Stride: 0x1}, unicode.Range16{Lo: 0x2c7e, Hi: 0x2ce4, Stride: 0x1}, unicode.Range16{Lo: 0x2ceb, Hi: 0x2cee, Stride: 0x1}, @@ -1805,7 +1853,7 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x303c, Hi: 0x303c, Stride: 0x1}, unicode.Range16{Lo: 0x3105, Hi: 0x312f, Stride: 0x1}, unicode.Range16{Lo: 0x3131, Hi: 0x318e, Stride: 0x1}, - unicode.Range16{Lo: 0x31a0, Hi: 0x31ba, Stride: 0x1}, + unicode.Range16{Lo: 0x31a0, Hi: 0x31bf, Stride: 0x1}, unicode.Range16{Lo: 0xa000, Hi: 0xa014, Stride: 0x1}, unicode.Range16{Lo: 0xa015, Hi: 0xa015, Stride: 0x1}, unicode.Range16{Lo: 0xa016, Hi: 0xa48c, Stride: 0x1}, @@ -1822,6 +1870,7 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0xa69c, Hi: 0xa69d, Stride: 0x1}, unicode.Range16{Lo: 0xa6a0, Hi: 0xa6e5, Stride: 0x1}, unicode.Range16{Lo: 0xa6e6, Hi: 0xa6ef, Stride: 0x1}, + unicode.Range16{Lo: 0xa708, Hi: 0xa716, Stride: 0x1}, unicode.Range16{Lo: 0xa717, Hi: 0xa71f, Stride: 0x1}, unicode.Range16{Lo: 0xa720, Hi: 0xa721, Stride: 0x1}, unicode.Range16{Lo: 0xa722, Hi: 0xa76f, Stride: 0x1}, @@ -1831,8 +1880,12 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0xa789, Hi: 0xa78a, Stride: 0x1}, unicode.Range16{Lo: 0xa78b, Hi: 0xa78e, Stride: 0x1}, unicode.Range16{Lo: 0xa78f, Hi: 0xa78f, Stride: 0x1}, - unicode.Range16{Lo: 0xa790, Hi: 0xa7bf, Stride: 0x1}, - unicode.Range16{Lo: 0xa7c2, Hi: 0xa7c6, Stride: 0x1}, + unicode.Range16{Lo: 0xa790, Hi: 0xa7ca, Stride: 0x1}, + unicode.Range16{Lo: 0xa7d0, Hi: 0xa7d1, Stride: 0x1}, + unicode.Range16{Lo: 0xa7d3, Hi: 0xa7d3, Stride: 0x1}, + unicode.Range16{Lo: 0xa7d5, Hi: 0xa7d9, Stride: 0x1}, + unicode.Range16{Lo: 0xa7f2, Hi: 0xa7f4, Stride: 0x1}, + unicode.Range16{Lo: 0xa7f5, Hi: 0xa7f6, Stride: 0x1}, unicode.Range16{Lo: 0xa7f7, Hi: 0xa7f7, Stride: 0x1}, unicode.Range16{Lo: 0xa7f8, Hi: 0xa7f9, Stride: 0x1}, unicode.Range16{Lo: 0xa7fa, Hi: 0xa7fa, Stride: 0x1}, @@ -1864,7 +1917,8 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range16{Lo: 0xab30, Hi: 0xab5a, Stride: 0x1}, unicode.Range16{Lo: 0xab5b, Hi: 0xab5b, Stride: 0x1}, unicode.Range16{Lo: 0xab5c, Hi: 0xab5f, Stride: 0x1}, - unicode.Range16{Lo: 0xab60, Hi: 0xab67, Stride: 0x1}, + unicode.Range16{Lo: 0xab60, Hi: 0xab68, Stride: 0x1}, + unicode.Range16{Lo: 0xab69, Hi: 0xab69, Stride: 0x1}, unicode.Range16{Lo: 0xab70, Hi: 0xabbf, Stride: 0x1}, unicode.Range16{Lo: 0xabc0, Hi: 0xabe2, Stride: 0x1}, unicode.Range16{Lo: 0xac00, Hi: 0xd7a3, Stride: 0x1}, @@ -1914,9 +1968,20 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x104d8, Hi: 0x104fb, Stride: 0x1}, unicode.Range32{Lo: 0x10500, Hi: 0x10527, Stride: 0x1}, unicode.Range32{Lo: 0x10530, Hi: 0x10563, Stride: 0x1}, + unicode.Range32{Lo: 0x10570, Hi: 0x1057a, Stride: 0x1}, + unicode.Range32{Lo: 0x1057c, Hi: 0x1058a, Stride: 0x1}, + unicode.Range32{Lo: 0x1058c, Hi: 0x10592, Stride: 0x1}, + unicode.Range32{Lo: 0x10594, Hi: 0x10595, Stride: 0x1}, + unicode.Range32{Lo: 0x10597, Hi: 0x105a1, Stride: 0x1}, + unicode.Range32{Lo: 0x105a3, Hi: 0x105b1, Stride: 0x1}, + unicode.Range32{Lo: 0x105b3, Hi: 0x105b9, Stride: 0x1}, + unicode.Range32{Lo: 0x105bb, Hi: 0x105bc, Stride: 0x1}, unicode.Range32{Lo: 0x10600, Hi: 0x10736, Stride: 0x1}, unicode.Range32{Lo: 0x10740, Hi: 0x10755, Stride: 0x1}, unicode.Range32{Lo: 0x10760, Hi: 0x10767, Stride: 0x1}, + unicode.Range32{Lo: 0x10780, Hi: 0x10785, Stride: 0x1}, + unicode.Range32{Lo: 0x10787, Hi: 0x107b0, Stride: 0x1}, + unicode.Range32{Lo: 0x107b2, Hi: 0x107ba, Stride: 0x1}, unicode.Range32{Lo: 0x10800, Hi: 0x10805, Stride: 0x1}, unicode.Range32{Lo: 0x10808, Hi: 0x10808, Stride: 0x1}, unicode.Range32{Lo: 0x1080a, Hi: 0x10835, Stride: 0x1}, @@ -1947,15 +2012,22 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x10c80, Hi: 0x10cb2, Stride: 0x1}, unicode.Range32{Lo: 0x10cc0, Hi: 0x10cf2, Stride: 0x1}, unicode.Range32{Lo: 0x10d00, Hi: 0x10d23, Stride: 0x1}, + unicode.Range32{Lo: 0x10e80, Hi: 0x10ea9, Stride: 0x1}, + unicode.Range32{Lo: 0x10eb0, Hi: 0x10eb1, Stride: 0x1}, unicode.Range32{Lo: 0x10f00, Hi: 0x10f1c, Stride: 0x1}, unicode.Range32{Lo: 0x10f27, Hi: 0x10f27, Stride: 0x1}, unicode.Range32{Lo: 0x10f30, Hi: 0x10f45, Stride: 0x1}, + unicode.Range32{Lo: 0x10f70, Hi: 0x10f81, Stride: 0x1}, + unicode.Range32{Lo: 0x10fb0, Hi: 0x10fc4, Stride: 0x1}, unicode.Range32{Lo: 0x10fe0, Hi: 0x10ff6, Stride: 0x1}, unicode.Range32{Lo: 0x11003, Hi: 0x11037, Stride: 0x1}, + unicode.Range32{Lo: 0x11071, Hi: 0x11072, Stride: 0x1}, + unicode.Range32{Lo: 0x11075, Hi: 0x11075, Stride: 0x1}, unicode.Range32{Lo: 0x11083, Hi: 0x110af, Stride: 0x1}, unicode.Range32{Lo: 0x110d0, Hi: 0x110e8, Stride: 0x1}, unicode.Range32{Lo: 0x11103, Hi: 0x11126, Stride: 0x1}, unicode.Range32{Lo: 0x11144, Hi: 0x11144, Stride: 0x1}, + unicode.Range32{Lo: 0x11147, Hi: 0x11147, Stride: 0x1}, unicode.Range32{Lo: 0x11150, Hi: 0x11172, Stride: 0x1}, unicode.Range32{Lo: 0x11176, Hi: 0x11176, Stride: 0x1}, unicode.Range32{Lo: 0x11183, Hi: 0x111b2, Stride: 0x1}, @@ -1964,6 +2036,7 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x111dc, Hi: 0x111dc, Stride: 0x1}, unicode.Range32{Lo: 0x11200, Hi: 0x11211, Stride: 0x1}, unicode.Range32{Lo: 0x11213, Hi: 0x1122b, Stride: 0x1}, + unicode.Range32{Lo: 0x1123f, Hi: 0x11240, Stride: 0x1}, unicode.Range32{Lo: 0x11280, Hi: 0x11286, Stride: 0x1}, unicode.Range32{Lo: 0x11288, Hi: 0x11288, Stride: 0x1}, unicode.Range32{Lo: 0x1128a, Hi: 0x1128d, Stride: 0x1}, @@ -1981,7 +2054,7 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x1135d, Hi: 0x11361, Stride: 0x1}, unicode.Range32{Lo: 0x11400, Hi: 0x11434, Stride: 0x1}, unicode.Range32{Lo: 0x11447, Hi: 0x1144a, Stride: 0x1}, - unicode.Range32{Lo: 0x1145f, Hi: 0x1145f, Stride: 0x1}, + unicode.Range32{Lo: 0x1145f, Hi: 0x11461, Stride: 0x1}, unicode.Range32{Lo: 0x11480, Hi: 0x114af, Stride: 0x1}, unicode.Range32{Lo: 0x114c4, Hi: 0x114c5, Stride: 0x1}, unicode.Range32{Lo: 0x114c7, Hi: 0x114c7, Stride: 0x1}, @@ -1993,7 +2066,13 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x116b8, Hi: 0x116b8, Stride: 0x1}, unicode.Range32{Lo: 0x11800, Hi: 0x1182b, Stride: 0x1}, unicode.Range32{Lo: 0x118a0, Hi: 0x118df, Stride: 0x1}, - unicode.Range32{Lo: 0x118ff, Hi: 0x118ff, Stride: 0x1}, + unicode.Range32{Lo: 0x118ff, Hi: 0x11906, Stride: 0x1}, + unicode.Range32{Lo: 0x11909, Hi: 0x11909, Stride: 0x1}, + unicode.Range32{Lo: 0x1190c, Hi: 0x11913, Stride: 0x1}, + unicode.Range32{Lo: 0x11915, Hi: 0x11916, Stride: 0x1}, + unicode.Range32{Lo: 0x11918, Hi: 0x1192f, Stride: 0x1}, + unicode.Range32{Lo: 0x1193f, Hi: 0x1193f, Stride: 0x1}, + unicode.Range32{Lo: 0x11941, Hi: 0x11941, Stride: 0x1}, unicode.Range32{Lo: 0x119a0, Hi: 0x119a7, Stride: 0x1}, unicode.Range32{Lo: 0x119aa, Hi: 0x119d0, Stride: 0x1}, unicode.Range32{Lo: 0x119e1, Hi: 0x119e1, Stride: 0x1}, @@ -2004,7 +2083,7 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x11a50, Hi: 0x11a50, Stride: 0x1}, unicode.Range32{Lo: 0x11a5c, Hi: 0x11a89, Stride: 0x1}, unicode.Range32{Lo: 0x11a9d, Hi: 0x11a9d, Stride: 0x1}, - unicode.Range32{Lo: 0x11ac0, Hi: 0x11af8, Stride: 0x1}, + unicode.Range32{Lo: 0x11ab0, Hi: 0x11af8, Stride: 0x1}, unicode.Range32{Lo: 0x11c00, Hi: 0x11c08, Stride: 0x1}, unicode.Range32{Lo: 0x11c0a, Hi: 0x11c2e, Stride: 0x1}, unicode.Range32{Lo: 0x11c40, Hi: 0x11c40, Stride: 0x1}, @@ -2018,13 +2097,20 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x11d6a, Hi: 0x11d89, Stride: 0x1}, unicode.Range32{Lo: 0x11d98, Hi: 0x11d98, Stride: 0x1}, unicode.Range32{Lo: 0x11ee0, Hi: 0x11ef2, Stride: 0x1}, + unicode.Range32{Lo: 0x11f02, Hi: 0x11f02, Stride: 0x1}, + unicode.Range32{Lo: 0x11f04, Hi: 0x11f10, Stride: 0x1}, + unicode.Range32{Lo: 0x11f12, Hi: 0x11f33, Stride: 0x1}, + unicode.Range32{Lo: 0x11fb0, Hi: 0x11fb0, Stride: 0x1}, unicode.Range32{Lo: 0x12000, Hi: 0x12399, Stride: 0x1}, unicode.Range32{Lo: 0x12400, Hi: 0x1246e, Stride: 0x1}, unicode.Range32{Lo: 0x12480, Hi: 0x12543, Stride: 0x1}, - unicode.Range32{Lo: 0x13000, Hi: 0x1342e, Stride: 0x1}, + unicode.Range32{Lo: 0x12f90, Hi: 0x12ff0, Stride: 0x1}, + unicode.Range32{Lo: 0x13000, Hi: 0x1342f, Stride: 0x1}, + unicode.Range32{Lo: 0x13441, Hi: 0x13446, Stride: 0x1}, unicode.Range32{Lo: 0x14400, Hi: 0x14646, Stride: 0x1}, unicode.Range32{Lo: 0x16800, Hi: 0x16a38, Stride: 0x1}, unicode.Range32{Lo: 0x16a40, Hi: 0x16a5e, Stride: 0x1}, + unicode.Range32{Lo: 0x16a70, Hi: 0x16abe, Stride: 0x1}, unicode.Range32{Lo: 0x16ad0, Hi: 0x16aed, Stride: 0x1}, unicode.Range32{Lo: 0x16b00, Hi: 0x16b2f, Stride: 0x1}, unicode.Range32{Lo: 0x16b40, Hi: 0x16b43, Stride: 0x1}, @@ -2070,10 +2156,22 @@ var _WordALetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x1d78a, Hi: 0x1d7a8, Stride: 0x1}, unicode.Range32{Lo: 0x1d7aa, Hi: 0x1d7c2, Stride: 0x1}, unicode.Range32{Lo: 0x1d7c4, Hi: 0x1d7cb, Stride: 0x1}, + unicode.Range32{Lo: 0x1df00, Hi: 0x1df09, Stride: 0x1}, + unicode.Range32{Lo: 0x1df0a, Hi: 0x1df0a, Stride: 0x1}, + unicode.Range32{Lo: 0x1df0b, Hi: 0x1df1e, Stride: 0x1}, + unicode.Range32{Lo: 0x1df25, Hi: 0x1df2a, Stride: 0x1}, + unicode.Range32{Lo: 0x1e030, Hi: 0x1e06d, Stride: 0x1}, unicode.Range32{Lo: 0x1e100, Hi: 0x1e12c, Stride: 0x1}, unicode.Range32{Lo: 0x1e137, Hi: 0x1e13d, Stride: 0x1}, unicode.Range32{Lo: 0x1e14e, Hi: 0x1e14e, Stride: 0x1}, + unicode.Range32{Lo: 0x1e290, Hi: 0x1e2ad, Stride: 0x1}, unicode.Range32{Lo: 0x1e2c0, Hi: 0x1e2eb, Stride: 0x1}, + unicode.Range32{Lo: 0x1e4d0, Hi: 0x1e4ea, Stride: 0x1}, + unicode.Range32{Lo: 0x1e4eb, Hi: 0x1e4eb, Stride: 0x1}, + unicode.Range32{Lo: 0x1e7e0, Hi: 0x1e7e6, Stride: 0x1}, + unicode.Range32{Lo: 0x1e7e8, Hi: 0x1e7eb, Stride: 0x1}, + unicode.Range32{Lo: 0x1e7ed, Hi: 0x1e7ee, Stride: 0x1}, + unicode.Range32{Lo: 0x1e7f0, Hi: 0x1e7fe, Stride: 0x1}, unicode.Range32{Lo: 0x1e800, Hi: 0x1e8c4, Stride: 0x1}, unicode.Range32{Lo: 0x1e900, Hi: 0x1e943, Stride: 0x1}, unicode.Range32{Lo: 0x1e94b, Hi: 0x1e94b, Stride: 0x1}, @@ -2158,7 +2256,8 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x825, Hi: 0x827, Stride: 0x1}, unicode.Range16{Lo: 0x829, Hi: 0x82d, Stride: 0x1}, unicode.Range16{Lo: 0x859, Hi: 0x85b, Stride: 0x1}, - unicode.Range16{Lo: 0x8d3, Hi: 0x8e1, Stride: 0x1}, + unicode.Range16{Lo: 0x898, Hi: 0x89f, Stride: 0x1}, + unicode.Range16{Lo: 0x8ca, Hi: 0x8e1, Stride: 0x1}, unicode.Range16{Lo: 0x8e3, Hi: 0x902, Stride: 0x1}, unicode.Range16{Lo: 0x903, Hi: 0x903, Stride: 0x1}, unicode.Range16{Lo: 0x93a, Hi: 0x93a, Stride: 0x1}, @@ -2213,7 +2312,7 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xb47, Hi: 0xb48, Stride: 0x1}, unicode.Range16{Lo: 0xb4b, Hi: 0xb4c, Stride: 0x1}, unicode.Range16{Lo: 0xb4d, Hi: 0xb4d, Stride: 0x1}, - unicode.Range16{Lo: 0xb56, Hi: 0xb56, Stride: 0x1}, + unicode.Range16{Lo: 0xb55, Hi: 0xb56, Stride: 0x1}, unicode.Range16{Lo: 0xb57, Hi: 0xb57, Stride: 0x1}, unicode.Range16{Lo: 0xb62, Hi: 0xb63, Stride: 0x1}, unicode.Range16{Lo: 0xb82, Hi: 0xb82, Stride: 0x1}, @@ -2227,6 +2326,7 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xc00, Hi: 0xc00, Stride: 0x1}, unicode.Range16{Lo: 0xc01, Hi: 0xc03, Stride: 0x1}, unicode.Range16{Lo: 0xc04, Hi: 0xc04, Stride: 0x1}, + unicode.Range16{Lo: 0xc3c, Hi: 0xc3c, Stride: 0x1}, unicode.Range16{Lo: 0xc3e, Hi: 0xc40, Stride: 0x1}, unicode.Range16{Lo: 0xc41, Hi: 0xc44, Stride: 0x1}, unicode.Range16{Lo: 0xc46, Hi: 0xc48, Stride: 0x1}, @@ -2245,6 +2345,7 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xccc, Hi: 0xccd, Stride: 0x1}, unicode.Range16{Lo: 0xcd5, Hi: 0xcd6, Stride: 0x1}, unicode.Range16{Lo: 0xce2, Hi: 0xce3, Stride: 0x1}, + unicode.Range16{Lo: 0xcf3, Hi: 0xcf3, Stride: 0x1}, unicode.Range16{Lo: 0xd00, Hi: 0xd01, Stride: 0x1}, unicode.Range16{Lo: 0xd02, Hi: 0xd03, Stride: 0x1}, unicode.Range16{Lo: 0xd3b, Hi: 0xd3c, Stride: 0x1}, @@ -2255,6 +2356,7 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xd4d, Hi: 0xd4d, Stride: 0x1}, unicode.Range16{Lo: 0xd57, Hi: 0xd57, Stride: 0x1}, unicode.Range16{Lo: 0xd62, Hi: 0xd63, Stride: 0x1}, + unicode.Range16{Lo: 0xd81, Hi: 0xd81, Stride: 0x1}, unicode.Range16{Lo: 0xd82, Hi: 0xd83, Stride: 0x1}, unicode.Range16{Lo: 0xdca, Hi: 0xdca, Stride: 0x1}, unicode.Range16{Lo: 0xdcf, Hi: 0xdd1, Stride: 0x1}, @@ -2267,7 +2369,7 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xe47, Hi: 0xe4e, Stride: 0x1}, unicode.Range16{Lo: 0xeb1, Hi: 0xeb1, Stride: 0x1}, unicode.Range16{Lo: 0xeb4, Hi: 0xebc, Stride: 0x1}, - unicode.Range16{Lo: 0xec8, Hi: 0xecd, Stride: 0x1}, + unicode.Range16{Lo: 0xec8, Hi: 0xece, Stride: 0x1}, unicode.Range16{Lo: 0xf18, Hi: 0xf19, Stride: 0x1}, unicode.Range16{Lo: 0xf35, Hi: 0xf35, Stride: 0x1}, unicode.Range16{Lo: 0xf37, Hi: 0xf37, Stride: 0x1}, @@ -2304,7 +2406,9 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x109d, Hi: 0x109d, Stride: 0x1}, unicode.Range16{Lo: 0x135d, Hi: 0x135f, Stride: 0x1}, unicode.Range16{Lo: 0x1712, Hi: 0x1714, Stride: 0x1}, - unicode.Range16{Lo: 0x1732, Hi: 0x1734, Stride: 0x1}, + unicode.Range16{Lo: 0x1715, Hi: 0x1715, Stride: 0x1}, + unicode.Range16{Lo: 0x1732, Hi: 0x1733, Stride: 0x1}, + unicode.Range16{Lo: 0x1734, Hi: 0x1734, Stride: 0x1}, unicode.Range16{Lo: 0x1752, Hi: 0x1753, Stride: 0x1}, unicode.Range16{Lo: 0x1772, Hi: 0x1773, Stride: 0x1}, unicode.Range16{Lo: 0x17b4, Hi: 0x17b5, Stride: 0x1}, @@ -2316,6 +2420,7 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x17c9, Hi: 0x17d3, Stride: 0x1}, unicode.Range16{Lo: 0x17dd, Hi: 0x17dd, Stride: 0x1}, unicode.Range16{Lo: 0x180b, Hi: 0x180d, Stride: 0x1}, + unicode.Range16{Lo: 0x180f, Hi: 0x180f, Stride: 0x1}, unicode.Range16{Lo: 0x1885, Hi: 0x1886, Stride: 0x1}, unicode.Range16{Lo: 0x18a9, Hi: 0x18a9, Stride: 0x1}, unicode.Range16{Lo: 0x1920, Hi: 0x1922, Stride: 0x1}, @@ -2343,6 +2448,7 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x1a7f, Hi: 0x1a7f, Stride: 0x1}, unicode.Range16{Lo: 0x1ab0, Hi: 0x1abd, Stride: 0x1}, unicode.Range16{Lo: 0x1abe, Hi: 0x1abe, Stride: 0x1}, + unicode.Range16{Lo: 0x1abf, Hi: 0x1ace, Stride: 0x1}, unicode.Range16{Lo: 0x1b00, Hi: 0x1b03, Stride: 0x1}, unicode.Range16{Lo: 0x1b04, Hi: 0x1b04, Stride: 0x1}, unicode.Range16{Lo: 0x1b34, Hi: 0x1b34, Stride: 0x1}, @@ -2382,8 +2488,7 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x1cf4, Hi: 0x1cf4, Stride: 0x1}, unicode.Range16{Lo: 0x1cf7, Hi: 0x1cf7, Stride: 0x1}, unicode.Range16{Lo: 0x1cf8, Hi: 0x1cf9, Stride: 0x1}, - unicode.Range16{Lo: 0x1dc0, Hi: 0x1df9, Stride: 0x1}, - unicode.Range16{Lo: 0x1dfb, Hi: 0x1dff, Stride: 0x1}, + unicode.Range16{Lo: 0x1dc0, Hi: 0x1dff, Stride: 0x1}, unicode.Range16{Lo: 0x200c, Hi: 0x200c, Stride: 0x1}, unicode.Range16{Lo: 0x20d0, Hi: 0x20dc, Stride: 0x1}, unicode.Range16{Lo: 0x20dd, Hi: 0x20e0, Stride: 0x1}, @@ -2407,6 +2512,7 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xa823, Hi: 0xa824, Stride: 0x1}, unicode.Range16{Lo: 0xa825, Hi: 0xa826, Stride: 0x1}, unicode.Range16{Lo: 0xa827, Hi: 0xa827, Stride: 0x1}, + unicode.Range16{Lo: 0xa82c, Hi: 0xa82c, Stride: 0x1}, unicode.Range16{Lo: 0xa880, Hi: 0xa881, Stride: 0x1}, unicode.Range16{Lo: 0xa8b4, Hi: 0xa8c3, Stride: 0x1}, unicode.Range16{Lo: 0xa8c4, Hi: 0xa8c5, Stride: 0x1}, @@ -2468,17 +2574,23 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x10a3f, Hi: 0x10a3f, Stride: 0x1}, unicode.Range32{Lo: 0x10ae5, Hi: 0x10ae6, Stride: 0x1}, unicode.Range32{Lo: 0x10d24, Hi: 0x10d27, Stride: 0x1}, + unicode.Range32{Lo: 0x10eab, Hi: 0x10eac, Stride: 0x1}, + unicode.Range32{Lo: 0x10efd, Hi: 0x10eff, Stride: 0x1}, unicode.Range32{Lo: 0x10f46, Hi: 0x10f50, Stride: 0x1}, + unicode.Range32{Lo: 0x10f82, Hi: 0x10f85, Stride: 0x1}, unicode.Range32{Lo: 0x11000, Hi: 0x11000, Stride: 0x1}, unicode.Range32{Lo: 0x11001, Hi: 0x11001, Stride: 0x1}, unicode.Range32{Lo: 0x11002, Hi: 0x11002, Stride: 0x1}, unicode.Range32{Lo: 0x11038, Hi: 0x11046, Stride: 0x1}, + unicode.Range32{Lo: 0x11070, Hi: 0x11070, Stride: 0x1}, + unicode.Range32{Lo: 0x11073, Hi: 0x11074, Stride: 0x1}, unicode.Range32{Lo: 0x1107f, Hi: 0x11081, Stride: 0x1}, unicode.Range32{Lo: 0x11082, Hi: 0x11082, Stride: 0x1}, unicode.Range32{Lo: 0x110b0, Hi: 0x110b2, Stride: 0x1}, unicode.Range32{Lo: 0x110b3, Hi: 0x110b6, Stride: 0x1}, unicode.Range32{Lo: 0x110b7, Hi: 0x110b8, Stride: 0x1}, unicode.Range32{Lo: 0x110b9, Hi: 0x110ba, Stride: 0x1}, + unicode.Range32{Lo: 0x110c2, Hi: 0x110c2, Stride: 0x1}, unicode.Range32{Lo: 0x11100, Hi: 0x11102, Stride: 0x1}, unicode.Range32{Lo: 0x11127, Hi: 0x1112b, Stride: 0x1}, unicode.Range32{Lo: 0x1112c, Hi: 0x1112c, Stride: 0x1}, @@ -2491,6 +2603,8 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x111b6, Hi: 0x111be, Stride: 0x1}, unicode.Range32{Lo: 0x111bf, Hi: 0x111c0, Stride: 0x1}, unicode.Range32{Lo: 0x111c9, Hi: 0x111cc, Stride: 0x1}, + unicode.Range32{Lo: 0x111ce, Hi: 0x111ce, Stride: 0x1}, + unicode.Range32{Lo: 0x111cf, Hi: 0x111cf, Stride: 0x1}, unicode.Range32{Lo: 0x1122c, Hi: 0x1122e, Stride: 0x1}, unicode.Range32{Lo: 0x1122f, Hi: 0x11231, Stride: 0x1}, unicode.Range32{Lo: 0x11232, Hi: 0x11233, Stride: 0x1}, @@ -2498,6 +2612,7 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x11235, Hi: 0x11235, Stride: 0x1}, unicode.Range32{Lo: 0x11236, Hi: 0x11237, Stride: 0x1}, unicode.Range32{Lo: 0x1123e, Hi: 0x1123e, Stride: 0x1}, + unicode.Range32{Lo: 0x11241, Hi: 0x11241, Stride: 0x1}, unicode.Range32{Lo: 0x112df, Hi: 0x112df, Stride: 0x1}, unicode.Range32{Lo: 0x112e0, Hi: 0x112e2, Stride: 0x1}, unicode.Range32{Lo: 0x112e3, Hi: 0x112ea, Stride: 0x1}, @@ -2557,6 +2672,14 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x1182f, Hi: 0x11837, Stride: 0x1}, unicode.Range32{Lo: 0x11838, Hi: 0x11838, Stride: 0x1}, unicode.Range32{Lo: 0x11839, Hi: 0x1183a, Stride: 0x1}, + unicode.Range32{Lo: 0x11930, Hi: 0x11935, Stride: 0x1}, + unicode.Range32{Lo: 0x11937, Hi: 0x11938, Stride: 0x1}, + unicode.Range32{Lo: 0x1193b, Hi: 0x1193c, Stride: 0x1}, + unicode.Range32{Lo: 0x1193d, Hi: 0x1193d, Stride: 0x1}, + unicode.Range32{Lo: 0x1193e, Hi: 0x1193e, Stride: 0x1}, + unicode.Range32{Lo: 0x11940, Hi: 0x11940, Stride: 0x1}, + unicode.Range32{Lo: 0x11942, Hi: 0x11942, Stride: 0x1}, + unicode.Range32{Lo: 0x11943, Hi: 0x11943, Stride: 0x1}, unicode.Range32{Lo: 0x119d1, Hi: 0x119d3, Stride: 0x1}, unicode.Range32{Lo: 0x119d4, Hi: 0x119d7, Stride: 0x1}, unicode.Range32{Lo: 0x119da, Hi: 0x119db, Stride: 0x1}, @@ -2599,12 +2722,26 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x11d97, Hi: 0x11d97, Stride: 0x1}, unicode.Range32{Lo: 0x11ef3, Hi: 0x11ef4, Stride: 0x1}, unicode.Range32{Lo: 0x11ef5, Hi: 0x11ef6, Stride: 0x1}, + unicode.Range32{Lo: 0x11f00, Hi: 0x11f01, Stride: 0x1}, + unicode.Range32{Lo: 0x11f03, Hi: 0x11f03, Stride: 0x1}, + unicode.Range32{Lo: 0x11f34, Hi: 0x11f35, Stride: 0x1}, + unicode.Range32{Lo: 0x11f36, Hi: 0x11f3a, Stride: 0x1}, + unicode.Range32{Lo: 0x11f3e, Hi: 0x11f3f, Stride: 0x1}, + unicode.Range32{Lo: 0x11f40, Hi: 0x11f40, Stride: 0x1}, + unicode.Range32{Lo: 0x11f41, Hi: 0x11f41, Stride: 0x1}, + unicode.Range32{Lo: 0x11f42, Hi: 0x11f42, Stride: 0x1}, + unicode.Range32{Lo: 0x13440, Hi: 0x13440, Stride: 0x1}, + unicode.Range32{Lo: 0x13447, Hi: 0x13455, Stride: 0x1}, unicode.Range32{Lo: 0x16af0, Hi: 0x16af4, Stride: 0x1}, unicode.Range32{Lo: 0x16b30, Hi: 0x16b36, Stride: 0x1}, unicode.Range32{Lo: 0x16f4f, Hi: 0x16f4f, Stride: 0x1}, unicode.Range32{Lo: 0x16f51, Hi: 0x16f87, Stride: 0x1}, unicode.Range32{Lo: 0x16f8f, Hi: 0x16f92, Stride: 0x1}, + unicode.Range32{Lo: 0x16fe4, Hi: 0x16fe4, Stride: 0x1}, + unicode.Range32{Lo: 0x16ff0, Hi: 0x16ff1, Stride: 0x1}, unicode.Range32{Lo: 0x1bc9d, Hi: 0x1bc9e, Stride: 0x1}, + unicode.Range32{Lo: 0x1cf00, Hi: 0x1cf2d, Stride: 0x1}, + unicode.Range32{Lo: 0x1cf30, Hi: 0x1cf46, Stride: 0x1}, unicode.Range32{Lo: 0x1d165, Hi: 0x1d166, Stride: 0x1}, unicode.Range32{Lo: 0x1d167, Hi: 0x1d169, Stride: 0x1}, unicode.Range32{Lo: 0x1d16d, Hi: 0x1d172, Stride: 0x1}, @@ -2623,8 +2760,11 @@ var _WordExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x1e01b, Hi: 0x1e021, Stride: 0x1}, unicode.Range32{Lo: 0x1e023, Hi: 0x1e024, Stride: 0x1}, unicode.Range32{Lo: 0x1e026, Hi: 0x1e02a, Stride: 0x1}, + unicode.Range32{Lo: 0x1e08f, Hi: 0x1e08f, Stride: 0x1}, unicode.Range32{Lo: 0x1e130, Hi: 0x1e136, Stride: 0x1}, + unicode.Range32{Lo: 0x1e2ae, Hi: 0x1e2ae, Stride: 0x1}, unicode.Range32{Lo: 0x1e2ec, Hi: 0x1e2ef, Stride: 0x1}, + unicode.Range32{Lo: 0x1e4ec, Hi: 0x1e4ef, Stride: 0x1}, unicode.Range32{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 0x1}, unicode.Range32{Lo: 0x1e944, Hi: 0x1e94a, Stride: 0x1}, unicode.Range32{Lo: 0x1f3fb, Hi: 0x1f3ff, Stride: 0x1}, @@ -2654,6 +2794,7 @@ var _WordFormat = &unicode.RangeTable{ unicode.Range16{Lo: 0x61c, Hi: 0x61c, Stride: 0x1}, unicode.Range16{Lo: 0x6dd, Hi: 0x6dd, Stride: 0x1}, unicode.Range16{Lo: 0x70f, Hi: 0x70f, Stride: 0x1}, + unicode.Range16{Lo: 0x890, Hi: 0x891, Stride: 0x1}, unicode.Range16{Lo: 0x8e2, Hi: 0x8e2, Stride: 0x1}, unicode.Range16{Lo: 0x180e, Hi: 0x180e, Stride: 0x1}, unicode.Range16{Lo: 0x200e, Hi: 0x200f, Stride: 0x1}, @@ -2666,7 +2807,7 @@ var _WordFormat = &unicode.RangeTable{ R32: []unicode.Range32{ unicode.Range32{Lo: 0x110bd, Hi: 0x110bd, Stride: 0x1}, unicode.Range32{Lo: 0x110cd, Hi: 0x110cd, Stride: 0x1}, - unicode.Range32{Lo: 0x13430, Hi: 0x13438, Stride: 0x1}, + unicode.Range32{Lo: 0x13430, Hi: 0x1343f, Stride: 0x1}, unicode.Range32{Lo: 0x1bca0, Hi: 0x1bca3, Stride: 0x1}, unicode.Range32{Lo: 0x1d173, Hi: 0x1d17a, Stride: 0x1}, unicode.Range32{Lo: 0xe0001, Hi: 0xe0001, Stride: 0x1}, @@ -2706,7 +2847,12 @@ var _WordKatakana = &unicode.RangeTable{ unicode.Range16{Lo: 0xff71, Hi: 0xff9d, Stride: 0x1}, }, R32: []unicode.Range32{ + unicode.Range32{Lo: 0x1aff0, Hi: 0x1aff3, Stride: 0x1}, + unicode.Range32{Lo: 0x1aff5, Hi: 0x1affb, Stride: 0x1}, + unicode.Range32{Lo: 0x1affd, Hi: 0x1affe, Stride: 0x1}, unicode.Range32{Lo: 0x1b000, Hi: 0x1b000, Stride: 0x1}, + unicode.Range32{Lo: 0x1b120, Hi: 0x1b122, Stride: 0x1}, + unicode.Range32{Lo: 0x1b155, Hi: 0x1b155, Stride: 0x1}, unicode.Range32{Lo: 0x1b164, Hi: 0x1b167, Stride: 0x1}, }, LatinOffset: 0, @@ -2724,6 +2870,7 @@ var _WordMidLetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x3a, Hi: 0x3a, Stride: 0x1}, unicode.Range16{Lo: 0xb7, Hi: 0xb7, Stride: 0x1}, unicode.Range16{Lo: 0x387, Hi: 0x387, Stride: 0x1}, + unicode.Range16{Lo: 0x55f, Hi: 0x55f, Stride: 0x1}, unicode.Range16{Lo: 0x5f4, Hi: 0x5f4, Stride: 0x1}, unicode.Range16{Lo: 0x2027, Hi: 0x2027, Stride: 0x1}, unicode.Range16{Lo: 0xfe13, Hi: 0xfe13, Stride: 0x1}, @@ -2831,15 +2978,20 @@ var _WordNumeric = &unicode.RangeTable{ unicode.Range32{Lo: 0x116c0, Hi: 0x116c9, Stride: 0x1}, unicode.Range32{Lo: 0x11730, Hi: 0x11739, Stride: 0x1}, unicode.Range32{Lo: 0x118e0, Hi: 0x118e9, Stride: 0x1}, + unicode.Range32{Lo: 0x11950, Hi: 0x11959, Stride: 0x1}, unicode.Range32{Lo: 0x11c50, Hi: 0x11c59, Stride: 0x1}, unicode.Range32{Lo: 0x11d50, Hi: 0x11d59, Stride: 0x1}, unicode.Range32{Lo: 0x11da0, Hi: 0x11da9, Stride: 0x1}, + unicode.Range32{Lo: 0x11f50, Hi: 0x11f59, Stride: 0x1}, unicode.Range32{Lo: 0x16a60, Hi: 0x16a69, Stride: 0x1}, + unicode.Range32{Lo: 0x16ac0, Hi: 0x16ac9, Stride: 0x1}, unicode.Range32{Lo: 0x16b50, Hi: 0x16b59, Stride: 0x1}, unicode.Range32{Lo: 0x1d7ce, Hi: 0x1d7ff, Stride: 0x1}, unicode.Range32{Lo: 0x1e140, Hi: 0x1e149, Stride: 0x1}, unicode.Range32{Lo: 0x1e2f0, Hi: 0x1e2f9, Stride: 0x1}, + unicode.Range32{Lo: 0x1e4f0, Hi: 0x1e4f9, Stride: 0x1}, unicode.Range32{Lo: 0x1e950, Hi: 0x1e959, Stride: 0x1}, + unicode.Range32{Lo: 0x1fbf0, Hi: 0x1fbf9, Stride: 0x1}, }, LatinOffset: 1, } @@ -3099,6 +3251,14 @@ var _SentenceClose = &unicode.RangeTable{ unicode.Range16{Lo: 0x2e28, Hi: 0x2e28, Stride: 0x1}, unicode.Range16{Lo: 0x2e29, Hi: 0x2e29, Stride: 0x1}, unicode.Range16{Lo: 0x2e42, Hi: 0x2e42, Stride: 0x1}, + unicode.Range16{Lo: 0x2e55, Hi: 0x2e55, Stride: 0x1}, + unicode.Range16{Lo: 0x2e56, Hi: 0x2e56, Stride: 0x1}, + unicode.Range16{Lo: 0x2e57, Hi: 0x2e57, Stride: 0x1}, + unicode.Range16{Lo: 0x2e58, Hi: 0x2e58, Stride: 0x1}, + unicode.Range16{Lo: 0x2e59, Hi: 0x2e59, Stride: 0x1}, + unicode.Range16{Lo: 0x2e5a, Hi: 0x2e5a, Stride: 0x1}, + unicode.Range16{Lo: 0x2e5b, Hi: 0x2e5b, Stride: 0x1}, + unicode.Range16{Lo: 0x2e5c, Hi: 0x2e5c, Stride: 0x1}, unicode.Range16{Lo: 0x3008, Hi: 0x3008, Stride: 0x1}, unicode.Range16{Lo: 0x3009, Hi: 0x3009, Stride: 0x1}, unicode.Range16{Lo: 0x300a, Hi: 0x300a, Stride: 0x1}, @@ -3191,7 +3351,8 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x825, Hi: 0x827, Stride: 0x1}, unicode.Range16{Lo: 0x829, Hi: 0x82d, Stride: 0x1}, unicode.Range16{Lo: 0x859, Hi: 0x85b, Stride: 0x1}, - unicode.Range16{Lo: 0x8d3, Hi: 0x8e1, Stride: 0x1}, + unicode.Range16{Lo: 0x898, Hi: 0x89f, Stride: 0x1}, + unicode.Range16{Lo: 0x8ca, Hi: 0x8e1, Stride: 0x1}, unicode.Range16{Lo: 0x8e3, Hi: 0x902, Stride: 0x1}, unicode.Range16{Lo: 0x903, Hi: 0x903, Stride: 0x1}, unicode.Range16{Lo: 0x93a, Hi: 0x93a, Stride: 0x1}, @@ -3246,7 +3407,7 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xb47, Hi: 0xb48, Stride: 0x1}, unicode.Range16{Lo: 0xb4b, Hi: 0xb4c, Stride: 0x1}, unicode.Range16{Lo: 0xb4d, Hi: 0xb4d, Stride: 0x1}, - unicode.Range16{Lo: 0xb56, Hi: 0xb56, Stride: 0x1}, + unicode.Range16{Lo: 0xb55, Hi: 0xb56, Stride: 0x1}, unicode.Range16{Lo: 0xb57, Hi: 0xb57, Stride: 0x1}, unicode.Range16{Lo: 0xb62, Hi: 0xb63, Stride: 0x1}, unicode.Range16{Lo: 0xb82, Hi: 0xb82, Stride: 0x1}, @@ -3260,6 +3421,7 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xc00, Hi: 0xc00, Stride: 0x1}, unicode.Range16{Lo: 0xc01, Hi: 0xc03, Stride: 0x1}, unicode.Range16{Lo: 0xc04, Hi: 0xc04, Stride: 0x1}, + unicode.Range16{Lo: 0xc3c, Hi: 0xc3c, Stride: 0x1}, unicode.Range16{Lo: 0xc3e, Hi: 0xc40, Stride: 0x1}, unicode.Range16{Lo: 0xc41, Hi: 0xc44, Stride: 0x1}, unicode.Range16{Lo: 0xc46, Hi: 0xc48, Stride: 0x1}, @@ -3278,6 +3440,7 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xccc, Hi: 0xccd, Stride: 0x1}, unicode.Range16{Lo: 0xcd5, Hi: 0xcd6, Stride: 0x1}, unicode.Range16{Lo: 0xce2, Hi: 0xce3, Stride: 0x1}, + unicode.Range16{Lo: 0xcf3, Hi: 0xcf3, Stride: 0x1}, unicode.Range16{Lo: 0xd00, Hi: 0xd01, Stride: 0x1}, unicode.Range16{Lo: 0xd02, Hi: 0xd03, Stride: 0x1}, unicode.Range16{Lo: 0xd3b, Hi: 0xd3c, Stride: 0x1}, @@ -3288,6 +3451,7 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xd4d, Hi: 0xd4d, Stride: 0x1}, unicode.Range16{Lo: 0xd57, Hi: 0xd57, Stride: 0x1}, unicode.Range16{Lo: 0xd62, Hi: 0xd63, Stride: 0x1}, + unicode.Range16{Lo: 0xd81, Hi: 0xd81, Stride: 0x1}, unicode.Range16{Lo: 0xd82, Hi: 0xd83, Stride: 0x1}, unicode.Range16{Lo: 0xdca, Hi: 0xdca, Stride: 0x1}, unicode.Range16{Lo: 0xdcf, Hi: 0xdd1, Stride: 0x1}, @@ -3300,7 +3464,7 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xe47, Hi: 0xe4e, Stride: 0x1}, unicode.Range16{Lo: 0xeb1, Hi: 0xeb1, Stride: 0x1}, unicode.Range16{Lo: 0xeb4, Hi: 0xebc, Stride: 0x1}, - unicode.Range16{Lo: 0xec8, Hi: 0xecd, Stride: 0x1}, + unicode.Range16{Lo: 0xec8, Hi: 0xece, Stride: 0x1}, unicode.Range16{Lo: 0xf18, Hi: 0xf19, Stride: 0x1}, unicode.Range16{Lo: 0xf35, Hi: 0xf35, Stride: 0x1}, unicode.Range16{Lo: 0xf37, Hi: 0xf37, Stride: 0x1}, @@ -3337,7 +3501,9 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x109d, Hi: 0x109d, Stride: 0x1}, unicode.Range16{Lo: 0x135d, Hi: 0x135f, Stride: 0x1}, unicode.Range16{Lo: 0x1712, Hi: 0x1714, Stride: 0x1}, - unicode.Range16{Lo: 0x1732, Hi: 0x1734, Stride: 0x1}, + unicode.Range16{Lo: 0x1715, Hi: 0x1715, Stride: 0x1}, + unicode.Range16{Lo: 0x1732, Hi: 0x1733, Stride: 0x1}, + unicode.Range16{Lo: 0x1734, Hi: 0x1734, Stride: 0x1}, unicode.Range16{Lo: 0x1752, Hi: 0x1753, Stride: 0x1}, unicode.Range16{Lo: 0x1772, Hi: 0x1773, Stride: 0x1}, unicode.Range16{Lo: 0x17b4, Hi: 0x17b5, Stride: 0x1}, @@ -3349,6 +3515,7 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x17c9, Hi: 0x17d3, Stride: 0x1}, unicode.Range16{Lo: 0x17dd, Hi: 0x17dd, Stride: 0x1}, unicode.Range16{Lo: 0x180b, Hi: 0x180d, Stride: 0x1}, + unicode.Range16{Lo: 0x180f, Hi: 0x180f, Stride: 0x1}, unicode.Range16{Lo: 0x1885, Hi: 0x1886, Stride: 0x1}, unicode.Range16{Lo: 0x18a9, Hi: 0x18a9, Stride: 0x1}, unicode.Range16{Lo: 0x1920, Hi: 0x1922, Stride: 0x1}, @@ -3376,6 +3543,7 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x1a7f, Hi: 0x1a7f, Stride: 0x1}, unicode.Range16{Lo: 0x1ab0, Hi: 0x1abd, Stride: 0x1}, unicode.Range16{Lo: 0x1abe, Hi: 0x1abe, Stride: 0x1}, + unicode.Range16{Lo: 0x1abf, Hi: 0x1ace, Stride: 0x1}, unicode.Range16{Lo: 0x1b00, Hi: 0x1b03, Stride: 0x1}, unicode.Range16{Lo: 0x1b04, Hi: 0x1b04, Stride: 0x1}, unicode.Range16{Lo: 0x1b34, Hi: 0x1b34, Stride: 0x1}, @@ -3415,8 +3583,7 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0x1cf4, Hi: 0x1cf4, Stride: 0x1}, unicode.Range16{Lo: 0x1cf7, Hi: 0x1cf7, Stride: 0x1}, unicode.Range16{Lo: 0x1cf8, Hi: 0x1cf9, Stride: 0x1}, - unicode.Range16{Lo: 0x1dc0, Hi: 0x1df9, Stride: 0x1}, - unicode.Range16{Lo: 0x1dfb, Hi: 0x1dff, Stride: 0x1}, + unicode.Range16{Lo: 0x1dc0, Hi: 0x1dff, Stride: 0x1}, unicode.Range16{Lo: 0x200c, Hi: 0x200d, Stride: 0x1}, unicode.Range16{Lo: 0x20d0, Hi: 0x20dc, Stride: 0x1}, unicode.Range16{Lo: 0x20dd, Hi: 0x20e0, Stride: 0x1}, @@ -3440,6 +3607,7 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range16{Lo: 0xa823, Hi: 0xa824, Stride: 0x1}, unicode.Range16{Lo: 0xa825, Hi: 0xa826, Stride: 0x1}, unicode.Range16{Lo: 0xa827, Hi: 0xa827, Stride: 0x1}, + unicode.Range16{Lo: 0xa82c, Hi: 0xa82c, Stride: 0x1}, unicode.Range16{Lo: 0xa880, Hi: 0xa881, Stride: 0x1}, unicode.Range16{Lo: 0xa8b4, Hi: 0xa8c3, Stride: 0x1}, unicode.Range16{Lo: 0xa8c4, Hi: 0xa8c5, Stride: 0x1}, @@ -3501,17 +3669,23 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x10a3f, Hi: 0x10a3f, Stride: 0x1}, unicode.Range32{Lo: 0x10ae5, Hi: 0x10ae6, Stride: 0x1}, unicode.Range32{Lo: 0x10d24, Hi: 0x10d27, Stride: 0x1}, + unicode.Range32{Lo: 0x10eab, Hi: 0x10eac, Stride: 0x1}, + unicode.Range32{Lo: 0x10efd, Hi: 0x10eff, Stride: 0x1}, unicode.Range32{Lo: 0x10f46, Hi: 0x10f50, Stride: 0x1}, + unicode.Range32{Lo: 0x10f82, Hi: 0x10f85, Stride: 0x1}, unicode.Range32{Lo: 0x11000, Hi: 0x11000, Stride: 0x1}, unicode.Range32{Lo: 0x11001, Hi: 0x11001, Stride: 0x1}, unicode.Range32{Lo: 0x11002, Hi: 0x11002, Stride: 0x1}, unicode.Range32{Lo: 0x11038, Hi: 0x11046, Stride: 0x1}, + unicode.Range32{Lo: 0x11070, Hi: 0x11070, Stride: 0x1}, + unicode.Range32{Lo: 0x11073, Hi: 0x11074, Stride: 0x1}, unicode.Range32{Lo: 0x1107f, Hi: 0x11081, Stride: 0x1}, unicode.Range32{Lo: 0x11082, Hi: 0x11082, Stride: 0x1}, unicode.Range32{Lo: 0x110b0, Hi: 0x110b2, Stride: 0x1}, unicode.Range32{Lo: 0x110b3, Hi: 0x110b6, Stride: 0x1}, unicode.Range32{Lo: 0x110b7, Hi: 0x110b8, Stride: 0x1}, unicode.Range32{Lo: 0x110b9, Hi: 0x110ba, Stride: 0x1}, + unicode.Range32{Lo: 0x110c2, Hi: 0x110c2, Stride: 0x1}, unicode.Range32{Lo: 0x11100, Hi: 0x11102, Stride: 0x1}, unicode.Range32{Lo: 0x11127, Hi: 0x1112b, Stride: 0x1}, unicode.Range32{Lo: 0x1112c, Hi: 0x1112c, Stride: 0x1}, @@ -3524,6 +3698,8 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x111b6, Hi: 0x111be, Stride: 0x1}, unicode.Range32{Lo: 0x111bf, Hi: 0x111c0, Stride: 0x1}, unicode.Range32{Lo: 0x111c9, Hi: 0x111cc, Stride: 0x1}, + unicode.Range32{Lo: 0x111ce, Hi: 0x111ce, Stride: 0x1}, + unicode.Range32{Lo: 0x111cf, Hi: 0x111cf, Stride: 0x1}, unicode.Range32{Lo: 0x1122c, Hi: 0x1122e, Stride: 0x1}, unicode.Range32{Lo: 0x1122f, Hi: 0x11231, Stride: 0x1}, unicode.Range32{Lo: 0x11232, Hi: 0x11233, Stride: 0x1}, @@ -3531,6 +3707,7 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x11235, Hi: 0x11235, Stride: 0x1}, unicode.Range32{Lo: 0x11236, Hi: 0x11237, Stride: 0x1}, unicode.Range32{Lo: 0x1123e, Hi: 0x1123e, Stride: 0x1}, + unicode.Range32{Lo: 0x11241, Hi: 0x11241, Stride: 0x1}, unicode.Range32{Lo: 0x112df, Hi: 0x112df, Stride: 0x1}, unicode.Range32{Lo: 0x112e0, Hi: 0x112e2, Stride: 0x1}, unicode.Range32{Lo: 0x112e3, Hi: 0x112ea, Stride: 0x1}, @@ -3590,6 +3767,14 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x1182f, Hi: 0x11837, Stride: 0x1}, unicode.Range32{Lo: 0x11838, Hi: 0x11838, Stride: 0x1}, unicode.Range32{Lo: 0x11839, Hi: 0x1183a, Stride: 0x1}, + unicode.Range32{Lo: 0x11930, Hi: 0x11935, Stride: 0x1}, + unicode.Range32{Lo: 0x11937, Hi: 0x11938, Stride: 0x1}, + unicode.Range32{Lo: 0x1193b, Hi: 0x1193c, Stride: 0x1}, + unicode.Range32{Lo: 0x1193d, Hi: 0x1193d, Stride: 0x1}, + unicode.Range32{Lo: 0x1193e, Hi: 0x1193e, Stride: 0x1}, + unicode.Range32{Lo: 0x11940, Hi: 0x11940, Stride: 0x1}, + unicode.Range32{Lo: 0x11942, Hi: 0x11942, Stride: 0x1}, + unicode.Range32{Lo: 0x11943, Hi: 0x11943, Stride: 0x1}, unicode.Range32{Lo: 0x119d1, Hi: 0x119d3, Stride: 0x1}, unicode.Range32{Lo: 0x119d4, Hi: 0x119d7, Stride: 0x1}, unicode.Range32{Lo: 0x119da, Hi: 0x119db, Stride: 0x1}, @@ -3632,12 +3817,26 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x11d97, Hi: 0x11d97, Stride: 0x1}, unicode.Range32{Lo: 0x11ef3, Hi: 0x11ef4, Stride: 0x1}, unicode.Range32{Lo: 0x11ef5, Hi: 0x11ef6, Stride: 0x1}, + unicode.Range32{Lo: 0x11f00, Hi: 0x11f01, Stride: 0x1}, + unicode.Range32{Lo: 0x11f03, Hi: 0x11f03, Stride: 0x1}, + unicode.Range32{Lo: 0x11f34, Hi: 0x11f35, Stride: 0x1}, + unicode.Range32{Lo: 0x11f36, Hi: 0x11f3a, Stride: 0x1}, + unicode.Range32{Lo: 0x11f3e, Hi: 0x11f3f, Stride: 0x1}, + unicode.Range32{Lo: 0x11f40, Hi: 0x11f40, Stride: 0x1}, + unicode.Range32{Lo: 0x11f41, Hi: 0x11f41, Stride: 0x1}, + unicode.Range32{Lo: 0x11f42, Hi: 0x11f42, Stride: 0x1}, + unicode.Range32{Lo: 0x13440, Hi: 0x13440, Stride: 0x1}, + unicode.Range32{Lo: 0x13447, Hi: 0x13455, Stride: 0x1}, unicode.Range32{Lo: 0x16af0, Hi: 0x16af4, Stride: 0x1}, unicode.Range32{Lo: 0x16b30, Hi: 0x16b36, Stride: 0x1}, unicode.Range32{Lo: 0x16f4f, Hi: 0x16f4f, Stride: 0x1}, unicode.Range32{Lo: 0x16f51, Hi: 0x16f87, Stride: 0x1}, unicode.Range32{Lo: 0x16f8f, Hi: 0x16f92, Stride: 0x1}, + unicode.Range32{Lo: 0x16fe4, Hi: 0x16fe4, Stride: 0x1}, + unicode.Range32{Lo: 0x16ff0, Hi: 0x16ff1, Stride: 0x1}, unicode.Range32{Lo: 0x1bc9d, Hi: 0x1bc9e, Stride: 0x1}, + unicode.Range32{Lo: 0x1cf00, Hi: 0x1cf2d, Stride: 0x1}, + unicode.Range32{Lo: 0x1cf30, Hi: 0x1cf46, Stride: 0x1}, unicode.Range32{Lo: 0x1d165, Hi: 0x1d166, Stride: 0x1}, unicode.Range32{Lo: 0x1d167, Hi: 0x1d169, Stride: 0x1}, unicode.Range32{Lo: 0x1d16d, Hi: 0x1d172, Stride: 0x1}, @@ -3656,8 +3855,11 @@ var _SentenceExtend = &unicode.RangeTable{ unicode.Range32{Lo: 0x1e01b, Hi: 0x1e021, Stride: 0x1}, unicode.Range32{Lo: 0x1e023, Hi: 0x1e024, Stride: 0x1}, unicode.Range32{Lo: 0x1e026, Hi: 0x1e02a, Stride: 0x1}, + unicode.Range32{Lo: 0x1e08f, Hi: 0x1e08f, Stride: 0x1}, unicode.Range32{Lo: 0x1e130, Hi: 0x1e136, Stride: 0x1}, + unicode.Range32{Lo: 0x1e2ae, Hi: 0x1e2ae, Stride: 0x1}, unicode.Range32{Lo: 0x1e2ec, Hi: 0x1e2ef, Stride: 0x1}, + unicode.Range32{Lo: 0x1e4ec, Hi: 0x1e4ef, Stride: 0x1}, unicode.Range32{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 0x1}, unicode.Range32{Lo: 0x1e944, Hi: 0x1e94a, Stride: 0x1}, unicode.Range32{Lo: 0xe0020, Hi: 0xe007f, Stride: 0x1}, @@ -3673,6 +3875,7 @@ var _SentenceFormat = &unicode.RangeTable{ unicode.Range16{Lo: 0x61c, Hi: 0x61c, Stride: 0x1}, unicode.Range16{Lo: 0x6dd, Hi: 0x6dd, Stride: 0x1}, unicode.Range16{Lo: 0x70f, Hi: 0x70f, Stride: 0x1}, + unicode.Range16{Lo: 0x890, Hi: 0x891, Stride: 0x1}, unicode.Range16{Lo: 0x8e2, Hi: 0x8e2, Stride: 0x1}, unicode.Range16{Lo: 0x180e, Hi: 0x180e, Stride: 0x1}, unicode.Range16{Lo: 0x200b, Hi: 0x200b, Stride: 0x1}, @@ -3686,7 +3889,7 @@ var _SentenceFormat = &unicode.RangeTable{ R32: []unicode.Range32{ unicode.Range32{Lo: 0x110bd, Hi: 0x110bd, Stride: 0x1}, unicode.Range32{Lo: 0x110cd, Hi: 0x110cd, Stride: 0x1}, - unicode.Range32{Lo: 0x13430, Hi: 0x13438, Stride: 0x1}, + unicode.Range32{Lo: 0x13430, Hi: 0x1343f, Stride: 0x1}, unicode.Range32{Lo: 0x1bca0, Hi: 0x1bca3, Stride: 0x1}, unicode.Range32{Lo: 0x1d173, Hi: 0x1d17a, Stride: 0x1}, unicode.Range32{Lo: 0xe0001, Hi: 0xe0001, Stride: 0x1}, @@ -3979,6 +4182,7 @@ var _SentenceLower = &unicode.RangeTable{ unicode.Range16{Lo: 0x52d, Hi: 0x52d, Stride: 0x1}, unicode.Range16{Lo: 0x52f, Hi: 0x52f, Stride: 0x1}, unicode.Range16{Lo: 0x560, Hi: 0x588, Stride: 0x1}, + unicode.Range16{Lo: 0x10fc, Hi: 0x10fc, Stride: 0x1}, unicode.Range16{Lo: 0x13f8, Hi: 0x13fd, Stride: 0x1}, unicode.Range16{Lo: 0x1c80, Hi: 0x1c88, Stride: 0x1}, unicode.Range16{Lo: 0x1d00, Hi: 0x1d2b, Stride: 0x1}, @@ -4146,7 +4350,7 @@ var _SentenceLower = &unicode.RangeTable{ unicode.Range16{Lo: 0x2170, Hi: 0x217f, Stride: 0x1}, unicode.Range16{Lo: 0x2184, Hi: 0x2184, Stride: 0x1}, unicode.Range16{Lo: 0x24d0, Hi: 0x24e9, Stride: 0x1}, - unicode.Range16{Lo: 0x2c30, Hi: 0x2c5e, Stride: 0x1}, + unicode.Range16{Lo: 0x2c30, Hi: 0x2c5f, Stride: 0x1}, unicode.Range16{Lo: 0x2c61, Hi: 0x2c61, Stride: 0x1}, unicode.Range16{Lo: 0x2c65, Hi: 0x2c66, Stride: 0x1}, unicode.Range16{Lo: 0x2c68, Hi: 0x2c68, Stride: 0x1}, @@ -4318,12 +4522,23 @@ var _SentenceLower = &unicode.RangeTable{ unicode.Range16{Lo: 0xa7bb, Hi: 0xa7bb, Stride: 0x1}, unicode.Range16{Lo: 0xa7bd, Hi: 0xa7bd, Stride: 0x1}, unicode.Range16{Lo: 0xa7bf, Hi: 0xa7bf, Stride: 0x1}, + unicode.Range16{Lo: 0xa7c1, Hi: 0xa7c1, Stride: 0x1}, unicode.Range16{Lo: 0xa7c3, Hi: 0xa7c3, Stride: 0x1}, + unicode.Range16{Lo: 0xa7c8, Hi: 0xa7c8, Stride: 0x1}, + unicode.Range16{Lo: 0xa7ca, Hi: 0xa7ca, Stride: 0x1}, + unicode.Range16{Lo: 0xa7d1, Hi: 0xa7d1, Stride: 0x1}, + unicode.Range16{Lo: 0xa7d3, Hi: 0xa7d3, Stride: 0x1}, + unicode.Range16{Lo: 0xa7d5, Hi: 0xa7d5, Stride: 0x1}, + unicode.Range16{Lo: 0xa7d7, Hi: 0xa7d7, Stride: 0x1}, + unicode.Range16{Lo: 0xa7d9, Hi: 0xa7d9, Stride: 0x1}, + unicode.Range16{Lo: 0xa7f2, Hi: 0xa7f4, Stride: 0x1}, + unicode.Range16{Lo: 0xa7f6, Hi: 0xa7f6, Stride: 0x1}, unicode.Range16{Lo: 0xa7f8, Hi: 0xa7f9, Stride: 0x1}, unicode.Range16{Lo: 0xa7fa, Hi: 0xa7fa, Stride: 0x1}, unicode.Range16{Lo: 0xab30, Hi: 0xab5a, Stride: 0x1}, unicode.Range16{Lo: 0xab5c, Hi: 0xab5f, Stride: 0x1}, - unicode.Range16{Lo: 0xab60, Hi: 0xab67, Stride: 0x1}, + unicode.Range16{Lo: 0xab60, Hi: 0xab68, Stride: 0x1}, + unicode.Range16{Lo: 0xab69, Hi: 0xab69, Stride: 0x1}, unicode.Range16{Lo: 0xab70, Hi: 0xabbf, Stride: 0x1}, unicode.Range16{Lo: 0xfb00, Hi: 0xfb06, Stride: 0x1}, unicode.Range16{Lo: 0xfb13, Hi: 0xfb17, Stride: 0x1}, @@ -4332,6 +4547,14 @@ var _SentenceLower = &unicode.RangeTable{ R32: []unicode.Range32{ unicode.Range32{Lo: 0x10428, Hi: 0x1044f, Stride: 0x1}, unicode.Range32{Lo: 0x104d8, Hi: 0x104fb, Stride: 0x1}, + unicode.Range32{Lo: 0x10597, Hi: 0x105a1, Stride: 0x1}, + unicode.Range32{Lo: 0x105a3, Hi: 0x105b1, Stride: 0x1}, + unicode.Range32{Lo: 0x105b3, Hi: 0x105b9, Stride: 0x1}, + unicode.Range32{Lo: 0x105bb, Hi: 0x105bc, Stride: 0x1}, + unicode.Range32{Lo: 0x10780, Hi: 0x10780, Stride: 0x1}, + unicode.Range32{Lo: 0x10783, Hi: 0x10785, Stride: 0x1}, + unicode.Range32{Lo: 0x10787, Hi: 0x107b0, Stride: 0x1}, + unicode.Range32{Lo: 0x107b2, Hi: 0x107ba, Stride: 0x1}, unicode.Range32{Lo: 0x10cc0, Hi: 0x10cf2, Stride: 0x1}, unicode.Range32{Lo: 0x118c0, Hi: 0x118df, Stride: 0x1}, unicode.Range32{Lo: 0x16e60, Hi: 0x16e7f, Stride: 0x1}, @@ -4363,6 +4586,10 @@ var _SentenceLower = &unicode.RangeTable{ unicode.Range32{Lo: 0x1d7aa, Hi: 0x1d7c2, Stride: 0x1}, unicode.Range32{Lo: 0x1d7c4, Hi: 0x1d7c9, Stride: 0x1}, unicode.Range32{Lo: 0x1d7cb, Hi: 0x1d7cb, Stride: 0x1}, + unicode.Range32{Lo: 0x1df00, Hi: 0x1df09, Stride: 0x1}, + unicode.Range32{Lo: 0x1df0b, Hi: 0x1df1e, Stride: 0x1}, + unicode.Range32{Lo: 0x1df25, Hi: 0x1df2a, Stride: 0x1}, + unicode.Range32{Lo: 0x1e030, Hi: 0x1e06d, Stride: 0x1}, unicode.Range32{Lo: 0x1e922, Hi: 0x1e943, Stride: 0x1}, }, LatinOffset: 6, @@ -4423,15 +4650,20 @@ var _SentenceNumeric = &unicode.RangeTable{ unicode.Range32{Lo: 0x116c0, Hi: 0x116c9, Stride: 0x1}, unicode.Range32{Lo: 0x11730, Hi: 0x11739, Stride: 0x1}, unicode.Range32{Lo: 0x118e0, Hi: 0x118e9, Stride: 0x1}, + unicode.Range32{Lo: 0x11950, Hi: 0x11959, Stride: 0x1}, unicode.Range32{Lo: 0x11c50, Hi: 0x11c59, Stride: 0x1}, unicode.Range32{Lo: 0x11d50, Hi: 0x11d59, Stride: 0x1}, unicode.Range32{Lo: 0x11da0, Hi: 0x11da9, Stride: 0x1}, + unicode.Range32{Lo: 0x11f50, Hi: 0x11f59, Stride: 0x1}, unicode.Range32{Lo: 0x16a60, Hi: 0x16a69, Stride: 0x1}, + unicode.Range32{Lo: 0x16ac0, Hi: 0x16ac9, Stride: 0x1}, unicode.Range32{Lo: 0x16b50, Hi: 0x16b59, Stride: 0x1}, unicode.Range32{Lo: 0x1d7ce, Hi: 0x1d7ff, Stride: 0x1}, unicode.Range32{Lo: 0x1e140, Hi: 0x1e149, Stride: 0x1}, unicode.Range32{Lo: 0x1e2f0, Hi: 0x1e2f9, Stride: 0x1}, + unicode.Range32{Lo: 0x1e4f0, Hi: 0x1e4f9, Stride: 0x1}, unicode.Range32{Lo: 0x1e950, Hi: 0x1e959, Stride: 0x1}, + unicode.Range32{Lo: 0x1fbf0, Hi: 0x1fbf9, Stride: 0x1}, }, LatinOffset: 1, } @@ -4473,8 +4705,10 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x828, Hi: 0x828, Stride: 0x1}, unicode.Range16{Lo: 0x840, Hi: 0x858, Stride: 0x1}, unicode.Range16{Lo: 0x860, Hi: 0x86a, Stride: 0x1}, - unicode.Range16{Lo: 0x8a0, Hi: 0x8b4, Stride: 0x1}, - unicode.Range16{Lo: 0x8b6, Hi: 0x8bd, Stride: 0x1}, + unicode.Range16{Lo: 0x870, Hi: 0x887, Stride: 0x1}, + unicode.Range16{Lo: 0x889, Hi: 0x88e, Stride: 0x1}, + unicode.Range16{Lo: 0x8a0, Hi: 0x8c8, Stride: 0x1}, + unicode.Range16{Lo: 0x8c9, Hi: 0x8c9, Stride: 0x1}, unicode.Range16{Lo: 0x904, Hi: 0x939, Stride: 0x1}, unicode.Range16{Lo: 0x93d, Hi: 0x93d, Stride: 0x1}, unicode.Range16{Lo: 0x950, Hi: 0x950, Stride: 0x1}, @@ -4540,6 +4774,7 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range16{Lo: 0xc2a, Hi: 0xc39, Stride: 0x1}, unicode.Range16{Lo: 0xc3d, Hi: 0xc3d, Stride: 0x1}, unicode.Range16{Lo: 0xc58, Hi: 0xc5a, Stride: 0x1}, + unicode.Range16{Lo: 0xc5d, Hi: 0xc5d, Stride: 0x1}, unicode.Range16{Lo: 0xc60, Hi: 0xc61, Stride: 0x1}, unicode.Range16{Lo: 0xc80, Hi: 0xc80, Stride: 0x1}, unicode.Range16{Lo: 0xc85, Hi: 0xc8c, Stride: 0x1}, @@ -4548,10 +4783,10 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range16{Lo: 0xcaa, Hi: 0xcb3, Stride: 0x1}, unicode.Range16{Lo: 0xcb5, Hi: 0xcb9, Stride: 0x1}, unicode.Range16{Lo: 0xcbd, Hi: 0xcbd, Stride: 0x1}, - unicode.Range16{Lo: 0xcde, Hi: 0xcde, Stride: 0x1}, + unicode.Range16{Lo: 0xcdd, Hi: 0xcde, Stride: 0x1}, unicode.Range16{Lo: 0xce0, Hi: 0xce1, Stride: 0x1}, unicode.Range16{Lo: 0xcf1, Hi: 0xcf2, Stride: 0x1}, - unicode.Range16{Lo: 0xd05, Hi: 0xd0c, Stride: 0x1}, + unicode.Range16{Lo: 0xd04, Hi: 0xd0c, Stride: 0x1}, unicode.Range16{Lo: 0xd0e, Hi: 0xd10, Stride: 0x1}, unicode.Range16{Lo: 0xd12, Hi: 0xd3a, Stride: 0x1}, unicode.Range16{Lo: 0xd3d, Hi: 0xd3d, Stride: 0x1}, @@ -4593,7 +4828,6 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x1075, Hi: 0x1081, Stride: 0x1}, unicode.Range16{Lo: 0x108e, Hi: 0x108e, Stride: 0x1}, unicode.Range16{Lo: 0x10d0, Hi: 0x10fa, Stride: 0x1}, - unicode.Range16{Lo: 0x10fc, Hi: 0x10fc, Stride: 0x1}, unicode.Range16{Lo: 0x10fd, Hi: 0x10ff, Stride: 0x1}, unicode.Range16{Lo: 0x1100, Hi: 0x1248, Stride: 0x1}, unicode.Range16{Lo: 0x124a, Hi: 0x124d, Stride: 0x1}, @@ -4618,9 +4852,8 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x16a0, Hi: 0x16ea, Stride: 0x1}, unicode.Range16{Lo: 0x16ee, Hi: 0x16f0, Stride: 0x1}, unicode.Range16{Lo: 0x16f1, Hi: 0x16f8, Stride: 0x1}, - unicode.Range16{Lo: 0x1700, Hi: 0x170c, Stride: 0x1}, - unicode.Range16{Lo: 0x170e, Hi: 0x1711, Stride: 0x1}, - unicode.Range16{Lo: 0x1720, Hi: 0x1731, Stride: 0x1}, + unicode.Range16{Lo: 0x1700, Hi: 0x1711, Stride: 0x1}, + unicode.Range16{Lo: 0x171f, Hi: 0x1731, Stride: 0x1}, unicode.Range16{Lo: 0x1740, Hi: 0x1751, Stride: 0x1}, unicode.Range16{Lo: 0x1760, Hi: 0x176c, Stride: 0x1}, unicode.Range16{Lo: 0x176e, Hi: 0x1770, Stride: 0x1}, @@ -4643,7 +4876,7 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x1a20, Hi: 0x1a54, Stride: 0x1}, unicode.Range16{Lo: 0x1aa7, Hi: 0x1aa7, Stride: 0x1}, unicode.Range16{Lo: 0x1b05, Hi: 0x1b33, Stride: 0x1}, - unicode.Range16{Lo: 0x1b45, Hi: 0x1b4b, Stride: 0x1}, + unicode.Range16{Lo: 0x1b45, Hi: 0x1b4c, Stride: 0x1}, unicode.Range16{Lo: 0x1b83, Hi: 0x1ba0, Stride: 0x1}, unicode.Range16{Lo: 0x1bae, Hi: 0x1baf, Stride: 0x1}, unicode.Range16{Lo: 0x1bba, Hi: 0x1be5, Stride: 0x1}, @@ -4688,11 +4921,10 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range16{Lo: 0x30ff, Hi: 0x30ff, Stride: 0x1}, unicode.Range16{Lo: 0x3105, Hi: 0x312f, Stride: 0x1}, unicode.Range16{Lo: 0x3131, Hi: 0x318e, Stride: 0x1}, - unicode.Range16{Lo: 0x31a0, Hi: 0x31ba, Stride: 0x1}, + unicode.Range16{Lo: 0x31a0, Hi: 0x31bf, Stride: 0x1}, unicode.Range16{Lo: 0x31f0, Hi: 0x31ff, Stride: 0x1}, - unicode.Range16{Lo: 0x3400, Hi: 0x4db5, Stride: 0x1}, - unicode.Range16{Lo: 0x4e00, Hi: 0x9fef, Stride: 0x1}, - unicode.Range16{Lo: 0xa000, Hi: 0xa014, Stride: 0x1}, + unicode.Range16{Lo: 0x3400, Hi: 0x4dbf, Stride: 0x1}, + unicode.Range16{Lo: 0x4e00, Hi: 0xa014, Stride: 0x1}, unicode.Range16{Lo: 0xa015, Hi: 0xa015, Stride: 0x1}, unicode.Range16{Lo: 0xa016, Hi: 0xa48c, Stride: 0x1}, unicode.Range16{Lo: 0xa4d0, Hi: 0xa4f7, Stride: 0x1}, @@ -4806,6 +5038,7 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x10600, Hi: 0x10736, Stride: 0x1}, unicode.Range32{Lo: 0x10740, Hi: 0x10755, Stride: 0x1}, unicode.Range32{Lo: 0x10760, Hi: 0x10767, Stride: 0x1}, + unicode.Range32{Lo: 0x10781, Hi: 0x10782, Stride: 0x1}, unicode.Range32{Lo: 0x10800, Hi: 0x10805, Stride: 0x1}, unicode.Range32{Lo: 0x10808, Hi: 0x10808, Stride: 0x1}, unicode.Range32{Lo: 0x1080a, Hi: 0x10835, Stride: 0x1}, @@ -4834,15 +5067,22 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x10b80, Hi: 0x10b91, Stride: 0x1}, unicode.Range32{Lo: 0x10c00, Hi: 0x10c48, Stride: 0x1}, unicode.Range32{Lo: 0x10d00, Hi: 0x10d23, Stride: 0x1}, + unicode.Range32{Lo: 0x10e80, Hi: 0x10ea9, Stride: 0x1}, + unicode.Range32{Lo: 0x10eb0, Hi: 0x10eb1, Stride: 0x1}, unicode.Range32{Lo: 0x10f00, Hi: 0x10f1c, Stride: 0x1}, unicode.Range32{Lo: 0x10f27, Hi: 0x10f27, Stride: 0x1}, unicode.Range32{Lo: 0x10f30, Hi: 0x10f45, Stride: 0x1}, + unicode.Range32{Lo: 0x10f70, Hi: 0x10f81, Stride: 0x1}, + unicode.Range32{Lo: 0x10fb0, Hi: 0x10fc4, Stride: 0x1}, unicode.Range32{Lo: 0x10fe0, Hi: 0x10ff6, Stride: 0x1}, unicode.Range32{Lo: 0x11003, Hi: 0x11037, Stride: 0x1}, + unicode.Range32{Lo: 0x11071, Hi: 0x11072, Stride: 0x1}, + unicode.Range32{Lo: 0x11075, Hi: 0x11075, Stride: 0x1}, unicode.Range32{Lo: 0x11083, Hi: 0x110af, Stride: 0x1}, unicode.Range32{Lo: 0x110d0, Hi: 0x110e8, Stride: 0x1}, unicode.Range32{Lo: 0x11103, Hi: 0x11126, Stride: 0x1}, unicode.Range32{Lo: 0x11144, Hi: 0x11144, Stride: 0x1}, + unicode.Range32{Lo: 0x11147, Hi: 0x11147, Stride: 0x1}, unicode.Range32{Lo: 0x11150, Hi: 0x11172, Stride: 0x1}, unicode.Range32{Lo: 0x11176, Hi: 0x11176, Stride: 0x1}, unicode.Range32{Lo: 0x11183, Hi: 0x111b2, Stride: 0x1}, @@ -4851,6 +5091,7 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x111dc, Hi: 0x111dc, Stride: 0x1}, unicode.Range32{Lo: 0x11200, Hi: 0x11211, Stride: 0x1}, unicode.Range32{Lo: 0x11213, Hi: 0x1122b, Stride: 0x1}, + unicode.Range32{Lo: 0x1123f, Hi: 0x11240, Stride: 0x1}, unicode.Range32{Lo: 0x11280, Hi: 0x11286, Stride: 0x1}, unicode.Range32{Lo: 0x11288, Hi: 0x11288, Stride: 0x1}, unicode.Range32{Lo: 0x1128a, Hi: 0x1128d, Stride: 0x1}, @@ -4868,7 +5109,7 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x1135d, Hi: 0x11361, Stride: 0x1}, unicode.Range32{Lo: 0x11400, Hi: 0x11434, Stride: 0x1}, unicode.Range32{Lo: 0x11447, Hi: 0x1144a, Stride: 0x1}, - unicode.Range32{Lo: 0x1145f, Hi: 0x1145f, Stride: 0x1}, + unicode.Range32{Lo: 0x1145f, Hi: 0x11461, Stride: 0x1}, unicode.Range32{Lo: 0x11480, Hi: 0x114af, Stride: 0x1}, unicode.Range32{Lo: 0x114c4, Hi: 0x114c5, Stride: 0x1}, unicode.Range32{Lo: 0x114c7, Hi: 0x114c7, Stride: 0x1}, @@ -4879,8 +5120,15 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x11680, Hi: 0x116aa, Stride: 0x1}, unicode.Range32{Lo: 0x116b8, Hi: 0x116b8, Stride: 0x1}, unicode.Range32{Lo: 0x11700, Hi: 0x1171a, Stride: 0x1}, + unicode.Range32{Lo: 0x11740, Hi: 0x11746, Stride: 0x1}, unicode.Range32{Lo: 0x11800, Hi: 0x1182b, Stride: 0x1}, - unicode.Range32{Lo: 0x118ff, Hi: 0x118ff, Stride: 0x1}, + unicode.Range32{Lo: 0x118ff, Hi: 0x11906, Stride: 0x1}, + unicode.Range32{Lo: 0x11909, Hi: 0x11909, Stride: 0x1}, + unicode.Range32{Lo: 0x1190c, Hi: 0x11913, Stride: 0x1}, + unicode.Range32{Lo: 0x11915, Hi: 0x11916, Stride: 0x1}, + unicode.Range32{Lo: 0x11918, Hi: 0x1192f, Stride: 0x1}, + unicode.Range32{Lo: 0x1193f, Hi: 0x1193f, Stride: 0x1}, + unicode.Range32{Lo: 0x11941, Hi: 0x11941, Stride: 0x1}, unicode.Range32{Lo: 0x119a0, Hi: 0x119a7, Stride: 0x1}, unicode.Range32{Lo: 0x119aa, Hi: 0x119d0, Stride: 0x1}, unicode.Range32{Lo: 0x119e1, Hi: 0x119e1, Stride: 0x1}, @@ -4891,7 +5139,7 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x11a50, Hi: 0x11a50, Stride: 0x1}, unicode.Range32{Lo: 0x11a5c, Hi: 0x11a89, Stride: 0x1}, unicode.Range32{Lo: 0x11a9d, Hi: 0x11a9d, Stride: 0x1}, - unicode.Range32{Lo: 0x11ac0, Hi: 0x11af8, Stride: 0x1}, + unicode.Range32{Lo: 0x11ab0, Hi: 0x11af8, Stride: 0x1}, unicode.Range32{Lo: 0x11c00, Hi: 0x11c08, Stride: 0x1}, unicode.Range32{Lo: 0x11c0a, Hi: 0x11c2e, Stride: 0x1}, unicode.Range32{Lo: 0x11c40, Hi: 0x11c40, Stride: 0x1}, @@ -4905,13 +5153,20 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x11d6a, Hi: 0x11d89, Stride: 0x1}, unicode.Range32{Lo: 0x11d98, Hi: 0x11d98, Stride: 0x1}, unicode.Range32{Lo: 0x11ee0, Hi: 0x11ef2, Stride: 0x1}, + unicode.Range32{Lo: 0x11f02, Hi: 0x11f02, Stride: 0x1}, + unicode.Range32{Lo: 0x11f04, Hi: 0x11f10, Stride: 0x1}, + unicode.Range32{Lo: 0x11f12, Hi: 0x11f33, Stride: 0x1}, + unicode.Range32{Lo: 0x11fb0, Hi: 0x11fb0, Stride: 0x1}, unicode.Range32{Lo: 0x12000, Hi: 0x12399, Stride: 0x1}, unicode.Range32{Lo: 0x12400, Hi: 0x1246e, Stride: 0x1}, unicode.Range32{Lo: 0x12480, Hi: 0x12543, Stride: 0x1}, - unicode.Range32{Lo: 0x13000, Hi: 0x1342e, Stride: 0x1}, + unicode.Range32{Lo: 0x12f90, Hi: 0x12ff0, Stride: 0x1}, + unicode.Range32{Lo: 0x13000, Hi: 0x1342f, Stride: 0x1}, + unicode.Range32{Lo: 0x13441, Hi: 0x13446, Stride: 0x1}, unicode.Range32{Lo: 0x14400, Hi: 0x14646, Stride: 0x1}, unicode.Range32{Lo: 0x16800, Hi: 0x16a38, Stride: 0x1}, unicode.Range32{Lo: 0x16a40, Hi: 0x16a5e, Stride: 0x1}, + unicode.Range32{Lo: 0x16a70, Hi: 0x16abe, Stride: 0x1}, unicode.Range32{Lo: 0x16ad0, Hi: 0x16aed, Stride: 0x1}, unicode.Range32{Lo: 0x16b00, Hi: 0x16b2f, Stride: 0x1}, unicode.Range32{Lo: 0x16b40, Hi: 0x16b43, Stride: 0x1}, @@ -4923,19 +5178,33 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x16fe0, Hi: 0x16fe1, Stride: 0x1}, unicode.Range32{Lo: 0x16fe3, Hi: 0x16fe3, Stride: 0x1}, unicode.Range32{Lo: 0x17000, Hi: 0x187f7, Stride: 0x1}, - unicode.Range32{Lo: 0x18800, Hi: 0x18af2, Stride: 0x1}, - unicode.Range32{Lo: 0x1b000, Hi: 0x1b11e, Stride: 0x1}, + unicode.Range32{Lo: 0x18800, Hi: 0x18cd5, Stride: 0x1}, + unicode.Range32{Lo: 0x18d00, Hi: 0x18d08, Stride: 0x1}, + unicode.Range32{Lo: 0x1aff0, Hi: 0x1aff3, Stride: 0x1}, + unicode.Range32{Lo: 0x1aff5, Hi: 0x1affb, Stride: 0x1}, + unicode.Range32{Lo: 0x1affd, Hi: 0x1affe, Stride: 0x1}, + unicode.Range32{Lo: 0x1b000, Hi: 0x1b122, Stride: 0x1}, + unicode.Range32{Lo: 0x1b132, Hi: 0x1b132, Stride: 0x1}, unicode.Range32{Lo: 0x1b150, Hi: 0x1b152, Stride: 0x1}, + unicode.Range32{Lo: 0x1b155, Hi: 0x1b155, Stride: 0x1}, unicode.Range32{Lo: 0x1b164, Hi: 0x1b167, Stride: 0x1}, unicode.Range32{Lo: 0x1b170, Hi: 0x1b2fb, Stride: 0x1}, unicode.Range32{Lo: 0x1bc00, Hi: 0x1bc6a, Stride: 0x1}, unicode.Range32{Lo: 0x1bc70, Hi: 0x1bc7c, Stride: 0x1}, unicode.Range32{Lo: 0x1bc80, Hi: 0x1bc88, Stride: 0x1}, unicode.Range32{Lo: 0x1bc90, Hi: 0x1bc99, Stride: 0x1}, + unicode.Range32{Lo: 0x1df0a, Hi: 0x1df0a, Stride: 0x1}, unicode.Range32{Lo: 0x1e100, Hi: 0x1e12c, Stride: 0x1}, unicode.Range32{Lo: 0x1e137, Hi: 0x1e13d, Stride: 0x1}, unicode.Range32{Lo: 0x1e14e, Hi: 0x1e14e, Stride: 0x1}, + unicode.Range32{Lo: 0x1e290, Hi: 0x1e2ad, Stride: 0x1}, unicode.Range32{Lo: 0x1e2c0, Hi: 0x1e2eb, Stride: 0x1}, + unicode.Range32{Lo: 0x1e4d0, Hi: 0x1e4ea, Stride: 0x1}, + unicode.Range32{Lo: 0x1e4eb, Hi: 0x1e4eb, Stride: 0x1}, + unicode.Range32{Lo: 0x1e7e0, Hi: 0x1e7e6, Stride: 0x1}, + unicode.Range32{Lo: 0x1e7e8, Hi: 0x1e7eb, Stride: 0x1}, + unicode.Range32{Lo: 0x1e7ed, Hi: 0x1e7ee, Stride: 0x1}, + unicode.Range32{Lo: 0x1e7f0, Hi: 0x1e7fe, Stride: 0x1}, unicode.Range32{Lo: 0x1e800, Hi: 0x1e8c4, Stride: 0x1}, unicode.Range32{Lo: 0x1e94b, Hi: 0x1e94b, Stride: 0x1}, unicode.Range32{Lo: 0x1ee00, Hi: 0x1ee03, Stride: 0x1}, @@ -4971,12 +5240,14 @@ var _SentenceOLetter = &unicode.RangeTable{ unicode.Range32{Lo: 0x1eea1, Hi: 0x1eea3, Stride: 0x1}, unicode.Range32{Lo: 0x1eea5, Hi: 0x1eea9, Stride: 0x1}, unicode.Range32{Lo: 0x1eeab, Hi: 0x1eebb, Stride: 0x1}, - unicode.Range32{Lo: 0x20000, Hi: 0x2a6d6, Stride: 0x1}, - unicode.Range32{Lo: 0x2a700, Hi: 0x2b734, Stride: 0x1}, + unicode.Range32{Lo: 0x20000, Hi: 0x2a6df, Stride: 0x1}, + unicode.Range32{Lo: 0x2a700, Hi: 0x2b739, Stride: 0x1}, unicode.Range32{Lo: 0x2b740, Hi: 0x2b81d, Stride: 0x1}, unicode.Range32{Lo: 0x2b820, Hi: 0x2cea1, Stride: 0x1}, unicode.Range32{Lo: 0x2ceb0, Hi: 0x2ebe0, Stride: 0x1}, unicode.Range32{Lo: 0x2f800, Hi: 0x2fa1d, Stride: 0x1}, + unicode.Range32{Lo: 0x30000, Hi: 0x3134a, Stride: 0x1}, + unicode.Range32{Lo: 0x31350, Hi: 0x323af, Stride: 0x1}, }, LatinOffset: 0, } @@ -5013,7 +5284,7 @@ var _SentenceSTerm = &unicode.RangeTable{ unicode.Range16{Lo: 0x21, Hi: 0x21, Stride: 0x1}, unicode.Range16{Lo: 0x3f, Hi: 0x3f, Stride: 0x1}, unicode.Range16{Lo: 0x589, Hi: 0x589, Stride: 0x1}, - unicode.Range16{Lo: 0x61e, Hi: 0x61f, Stride: 0x1}, + unicode.Range16{Lo: 0x61d, Hi: 0x61f, Stride: 0x1}, unicode.Range16{Lo: 0x6d4, Hi: 0x6d4, Stride: 0x1}, unicode.Range16{Lo: 0x700, Hi: 0x702, Stride: 0x1}, unicode.Range16{Lo: 0x7f9, Hi: 0x7f9, Stride: 0x1}, @@ -5032,12 +5303,14 @@ var _SentenceSTerm = &unicode.RangeTable{ unicode.Range16{Lo: 0x1aa8, Hi: 0x1aab, Stride: 0x1}, unicode.Range16{Lo: 0x1b5a, Hi: 0x1b5b, Stride: 0x1}, unicode.Range16{Lo: 0x1b5e, Hi: 0x1b5f, Stride: 0x1}, + unicode.Range16{Lo: 0x1b7d, Hi: 0x1b7e, Stride: 0x1}, unicode.Range16{Lo: 0x1c3b, Hi: 0x1c3c, Stride: 0x1}, unicode.Range16{Lo: 0x1c7e, Hi: 0x1c7f, Stride: 0x1}, unicode.Range16{Lo: 0x203c, Hi: 0x203d, Stride: 0x1}, unicode.Range16{Lo: 0x2047, Hi: 0x2049, Stride: 0x1}, unicode.Range16{Lo: 0x2e2e, Hi: 0x2e2e, Stride: 0x1}, unicode.Range16{Lo: 0x2e3c, Hi: 0x2e3c, Stride: 0x1}, + unicode.Range16{Lo: 0x2e53, Hi: 0x2e54, Stride: 0x1}, unicode.Range16{Lo: 0x3002, Hi: 0x3002, Stride: 0x1}, unicode.Range16{Lo: 0xa4ff, Hi: 0xa4ff, Stride: 0x1}, unicode.Range16{Lo: 0xa60e, Hi: 0xa60f, Stride: 0x1}, @@ -5058,6 +5331,7 @@ var _SentenceSTerm = &unicode.RangeTable{ R32: []unicode.Range32{ unicode.Range32{Lo: 0x10a56, Hi: 0x10a57, Stride: 0x1}, unicode.Range32{Lo: 0x10f55, Hi: 0x10f59, Stride: 0x1}, + unicode.Range32{Lo: 0x10f86, Hi: 0x10f89, Stride: 0x1}, unicode.Range32{Lo: 0x11047, Hi: 0x11048, Stride: 0x1}, unicode.Range32{Lo: 0x110be, Hi: 0x110c1, Stride: 0x1}, unicode.Range32{Lo: 0x11141, Hi: 0x11143, Stride: 0x1}, @@ -5072,10 +5346,13 @@ var _SentenceSTerm = &unicode.RangeTable{ unicode.Range32{Lo: 0x115c9, Hi: 0x115d7, Stride: 0x1}, unicode.Range32{Lo: 0x11641, Hi: 0x11642, Stride: 0x1}, unicode.Range32{Lo: 0x1173c, Hi: 0x1173e, Stride: 0x1}, + unicode.Range32{Lo: 0x11944, Hi: 0x11944, Stride: 0x1}, + unicode.Range32{Lo: 0x11946, Hi: 0x11946, Stride: 0x1}, unicode.Range32{Lo: 0x11a42, Hi: 0x11a43, Stride: 0x1}, unicode.Range32{Lo: 0x11a9b, Hi: 0x11a9c, Stride: 0x1}, unicode.Range32{Lo: 0x11c41, Hi: 0x11c42, Stride: 0x1}, unicode.Range32{Lo: 0x11ef7, Hi: 0x11ef8, Stride: 0x1}, + unicode.Range32{Lo: 0x11f43, Hi: 0x11f44, Stride: 0x1}, unicode.Range32{Lo: 0x16a6e, Hi: 0x16a6f, Stride: 0x1}, unicode.Range32{Lo: 0x16af5, Hi: 0x16af5, Stride: 0x1}, unicode.Range32{Lo: 0x16b37, Hi: 0x16b38, Stride: 0x1}, @@ -5547,7 +5824,7 @@ var _SentenceUpper = &unicode.RangeTable{ unicode.Range16{Lo: 0x2160, Hi: 0x216f, Stride: 0x1}, unicode.Range16{Lo: 0x2183, Hi: 0x2183, Stride: 0x1}, unicode.Range16{Lo: 0x24b6, Hi: 0x24cf, Stride: 0x1}, - unicode.Range16{Lo: 0x2c00, Hi: 0x2c2e, Stride: 0x1}, + unicode.Range16{Lo: 0x2c00, Hi: 0x2c2f, Stride: 0x1}, unicode.Range16{Lo: 0x2c60, Hi: 0x2c60, Stride: 0x1}, unicode.Range16{Lo: 0x2c62, Hi: 0x2c64, Stride: 0x1}, unicode.Range16{Lo: 0x2c67, Hi: 0x2c67, Stride: 0x1}, @@ -5712,13 +5989,23 @@ var _SentenceUpper = &unicode.RangeTable{ unicode.Range16{Lo: 0xa7ba, Hi: 0xa7ba, Stride: 0x1}, unicode.Range16{Lo: 0xa7bc, Hi: 0xa7bc, Stride: 0x1}, unicode.Range16{Lo: 0xa7be, Hi: 0xa7be, Stride: 0x1}, + unicode.Range16{Lo: 0xa7c0, Hi: 0xa7c0, Stride: 0x1}, unicode.Range16{Lo: 0xa7c2, Hi: 0xa7c2, Stride: 0x1}, - unicode.Range16{Lo: 0xa7c4, Hi: 0xa7c6, Stride: 0x1}, + unicode.Range16{Lo: 0xa7c4, Hi: 0xa7c7, Stride: 0x1}, + unicode.Range16{Lo: 0xa7c9, Hi: 0xa7c9, Stride: 0x1}, + unicode.Range16{Lo: 0xa7d0, Hi: 0xa7d0, Stride: 0x1}, + unicode.Range16{Lo: 0xa7d6, Hi: 0xa7d6, Stride: 0x1}, + unicode.Range16{Lo: 0xa7d8, Hi: 0xa7d8, Stride: 0x1}, + unicode.Range16{Lo: 0xa7f5, Hi: 0xa7f5, Stride: 0x1}, unicode.Range16{Lo: 0xff21, Hi: 0xff3a, Stride: 0x1}, }, R32: []unicode.Range32{ unicode.Range32{Lo: 0x10400, Hi: 0x10427, Stride: 0x1}, unicode.Range32{Lo: 0x104b0, Hi: 0x104d3, Stride: 0x1}, + unicode.Range32{Lo: 0x10570, Hi: 0x1057a, Stride: 0x1}, + unicode.Range32{Lo: 0x1057c, Hi: 0x1058a, Stride: 0x1}, + unicode.Range32{Lo: 0x1058c, Hi: 0x10592, Stride: 0x1}, + unicode.Range32{Lo: 0x10594, Hi: 0x10595, Stride: 0x1}, unicode.Range32{Lo: 0x10c80, Hi: 0x10cb2, Stride: 0x1}, unicode.Range32{Lo: 0x118a0, Hi: 0x118bf, Stride: 0x1}, unicode.Range32{Lo: 0x16e40, Hi: 0x16e5f, Stride: 0x1}, diff --git a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/unicode2ragel.rb b/vendor/github.com/apparentlymart/go-textseg/v15/textseg/unicode2ragel.rb similarity index 100% rename from vendor/github.com/apparentlymart/go-textseg/v13/textseg/unicode2ragel.rb rename to vendor/github.com/apparentlymart/go-textseg/v15/textseg/unicode2ragel.rb diff --git a/vendor/github.com/apparentlymart/go-textseg/v13/textseg/utf8_seqs.go b/vendor/github.com/apparentlymart/go-textseg/v15/textseg/utf8_seqs.go similarity index 100% rename from vendor/github.com/apparentlymart/go-textseg/v13/textseg/utf8_seqs.go rename to vendor/github.com/apparentlymart/go-textseg/v15/textseg/utf8_seqs.go diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go index 889f9e77..c4234287 100644 --- a/vendor/github.com/fatih/color/color.go +++ b/vendor/github.com/fatih/color/color.go @@ -65,6 +65,29 @@ const ( CrossedOut ) +const ( + ResetBold Attribute = iota + 22 + ResetItalic + ResetUnderline + ResetBlinking + _ + ResetReversed + ResetConcealed + ResetCrossedOut +) + +var mapResetAttributes map[Attribute]Attribute = map[Attribute]Attribute{ + Bold: ResetBold, + Faint: ResetBold, + Italic: ResetItalic, + Underline: ResetUnderline, + BlinkSlow: ResetBlinking, + BlinkRapid: ResetBlinking, + ReverseVideo: ResetReversed, + Concealed: ResetConcealed, + CrossedOut: ResetCrossedOut, +} + // Foreground text colors const ( FgBlack Attribute = iota + 30 @@ -246,10 +269,7 @@ func (c *Color) Printf(format string, a ...interface{}) (n int, err error) { // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - c.SetWriter(w) - defer c.UnsetWriter(w) - - return fmt.Fprintln(w, a...) + return fmt.Fprintln(w, c.wrap(fmt.Sprint(a...))) } // Println formats using the default formats for its operands and writes to @@ -258,10 +278,7 @@ func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { // encountered. This is the standard fmt.Print() method wrapped with the given // color. func (c *Color) Println(a ...interface{}) (n int, err error) { - c.Set() - defer c.unset() - - return fmt.Fprintln(Output, a...) + return fmt.Fprintln(Output, c.wrap(fmt.Sprint(a...))) } // Sprint is just like Print, but returns a string instead of printing it. @@ -271,7 +288,7 @@ func (c *Color) Sprint(a ...interface{}) string { // Sprintln is just like Println, but returns a string instead of printing it. func (c *Color) Sprintln(a ...interface{}) string { - return c.wrap(fmt.Sprintln(a...)) + return fmt.Sprintln(c.Sprint(a...)) } // Sprintf is just like Printf, but returns a string instead of printing it. @@ -353,7 +370,7 @@ func (c *Color) SprintfFunc() func(format string, a ...interface{}) string { // string. Windows users should use this in conjunction with color.Output. func (c *Color) SprintlnFunc() func(a ...interface{}) string { return func(a ...interface{}) string { - return c.wrap(fmt.Sprintln(a...)) + return fmt.Sprintln(c.Sprint(a...)) } } @@ -383,7 +400,18 @@ func (c *Color) format() string { } func (c *Color) unformat() string { - return fmt.Sprintf("%s[%dm", escape, Reset) + //return fmt.Sprintf("%s[%dm", escape, Reset) + //for each element in sequence let's use the speficic reset escape, ou the generic one if not found + format := make([]string, len(c.params)) + for i, v := range c.params { + format[i] = strconv.Itoa(int(Reset)) + ra, ok := mapResetAttributes[v] + if ok { + format[i] = strconv.Itoa(int(ra)) + } + } + + return fmt.Sprintf("%s[%sm", escape, strings.Join(format, ";")) } // DisableColor disables the color output. Useful to not change any existing @@ -411,6 +439,12 @@ func (c *Color) isNoColorSet() bool { // Equals returns a boolean value indicating whether two colors are equal. func (c *Color) Equals(c2 *Color) bool { + if c == nil && c2 == nil { + return true + } + if c == nil || c2 == nil { + return false + } if len(c.params) != len(c2.params) { return false } diff --git a/vendor/github.com/golang/protobuf/jsonpb/decode.go b/vendor/github.com/golang/protobuf/jsonpb/decode.go deleted file mode 100644 index 6c16c255..00000000 --- a/vendor/github.com/golang/protobuf/jsonpb/decode.go +++ /dev/null @@ -1,530 +0,0 @@ -// Copyright 2015 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 jsonpb - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "math" - "reflect" - "strconv" - "strings" - "time" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/encoding/protojson" - protoV2 "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" -) - -const wrapJSONUnmarshalV2 = false - -// UnmarshalNext unmarshals the next JSON object from d into m. -func UnmarshalNext(d *json.Decoder, m proto.Message) error { - return new(Unmarshaler).UnmarshalNext(d, m) -} - -// Unmarshal unmarshals a JSON object from r into m. -func Unmarshal(r io.Reader, m proto.Message) error { - return new(Unmarshaler).Unmarshal(r, m) -} - -// UnmarshalString unmarshals a JSON object from s into m. -func UnmarshalString(s string, m proto.Message) error { - return new(Unmarshaler).Unmarshal(strings.NewReader(s), m) -} - -// Unmarshaler is a configurable object for converting from a JSON -// representation to a protocol buffer object. -type Unmarshaler struct { - // AllowUnknownFields specifies whether to allow messages to contain - // unknown JSON fields, as opposed to failing to unmarshal. - AllowUnknownFields bool - - // AnyResolver is used to resolve the google.protobuf.Any well-known type. - // If unset, the global registry is used by default. - AnyResolver AnyResolver -} - -// JSONPBUnmarshaler is implemented by protobuf messages that customize the way -// they are unmarshaled from JSON. Messages that implement this should also -// implement JSONPBMarshaler so that the custom format can be produced. -// -// The JSON unmarshaling must follow the JSON to proto specification: -// https://developers.google.com/protocol-buffers/docs/proto3#json -// -// Deprecated: Custom types should implement protobuf reflection instead. -type JSONPBUnmarshaler interface { - UnmarshalJSONPB(*Unmarshaler, []byte) error -} - -// Unmarshal unmarshals a JSON object from r into m. -func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error { - return u.UnmarshalNext(json.NewDecoder(r), m) -} - -// UnmarshalNext unmarshals the next JSON object from d into m. -func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error { - if m == nil { - return errors.New("invalid nil message") - } - - // Parse the next JSON object from the stream. - raw := json.RawMessage{} - if err := d.Decode(&raw); err != nil { - return err - } - - // Check for custom unmarshalers first since they may not properly - // implement protobuf reflection that the logic below relies on. - if jsu, ok := m.(JSONPBUnmarshaler); ok { - return jsu.UnmarshalJSONPB(u, raw) - } - - mr := proto.MessageReflect(m) - - // NOTE: For historical reasons, a top-level null is treated as a noop. - // This is incorrect, but kept for compatibility. - if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" { - return nil - } - - if wrapJSONUnmarshalV2 { - // NOTE: If input message is non-empty, we need to preserve merge semantics - // of the old jsonpb implementation. These semantics are not supported by - // the protobuf JSON specification. - isEmpty := true - mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool { - isEmpty = false // at least one iteration implies non-empty - return false - }) - if !isEmpty { - // Perform unmarshaling into a newly allocated, empty message. - mr = mr.New() - - // Use a defer to copy all unmarshaled fields into the original message. - dst := proto.MessageReflect(m) - defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - dst.Set(fd, v) - return true - }) - } - - // Unmarshal using the v2 JSON unmarshaler. - opts := protojson.UnmarshalOptions{ - DiscardUnknown: u.AllowUnknownFields, - } - if u.AnyResolver != nil { - opts.Resolver = anyResolver{u.AnyResolver} - } - return opts.Unmarshal(raw, mr.Interface()) - } else { - if err := u.unmarshalMessage(mr, raw); err != nil { - return err - } - return protoV2.CheckInitialized(mr.Interface()) - } -} - -func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error { - md := m.Descriptor() - fds := md.Fields() - - if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok { - return jsu.UnmarshalJSONPB(u, in) - } - - if string(in) == "null" && md.FullName() != "google.protobuf.Value" { - return nil - } - - switch wellKnownType(md.FullName()) { - case "Any": - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return err - } - - rawTypeURL, ok := jsonObject["@type"] - if !ok { - return errors.New("Any JSON doesn't have '@type'") - } - typeURL, err := unquoteString(string(rawTypeURL)) - if err != nil { - return fmt.Errorf("can't unmarshal Any's '@type': %q", rawTypeURL) - } - m.Set(fds.ByNumber(1), protoreflect.ValueOfString(typeURL)) - - var m2 protoreflect.Message - if u.AnyResolver != nil { - mi, err := u.AnyResolver.Resolve(typeURL) - if err != nil { - return err - } - m2 = proto.MessageReflect(mi) - } else { - mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL) - if err != nil { - if err == protoregistry.NotFound { - return fmt.Errorf("could not resolve Any message type: %v", typeURL) - } - return err - } - m2 = mt.New() - } - - if wellKnownType(m2.Descriptor().FullName()) != "" { - rawValue, ok := jsonObject["value"] - if !ok { - return errors.New("Any JSON doesn't have 'value'") - } - if err := u.unmarshalMessage(m2, rawValue); err != nil { - return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err) - } - } else { - delete(jsonObject, "@type") - rawJSON, err := json.Marshal(jsonObject) - if err != nil { - return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err) - } - if err = u.unmarshalMessage(m2, rawJSON); err != nil { - return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err) - } - } - - rawWire, err := protoV2.Marshal(m2.Interface()) - if err != nil { - return fmt.Errorf("can't marshal proto %v into Any.Value: %v", typeURL, err) - } - m.Set(fds.ByNumber(2), protoreflect.ValueOfBytes(rawWire)) - return nil - case "BoolValue", "BytesValue", "StringValue", - "Int32Value", "UInt32Value", "FloatValue", - "Int64Value", "UInt64Value", "DoubleValue": - fd := fds.ByNumber(1) - v, err := u.unmarshalValue(m.NewField(fd), in, fd) - if err != nil { - return err - } - m.Set(fd, v) - return nil - case "Duration": - v, err := unquoteString(string(in)) - if err != nil { - return err - } - d, err := time.ParseDuration(v) - if err != nil { - return fmt.Errorf("bad Duration: %v", err) - } - - sec := d.Nanoseconds() / 1e9 - nsec := d.Nanoseconds() % 1e9 - m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec))) - m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec))) - return nil - case "Timestamp": - v, err := unquoteString(string(in)) - if err != nil { - return err - } - t, err := time.Parse(time.RFC3339Nano, v) - if err != nil { - return fmt.Errorf("bad Timestamp: %v", err) - } - - sec := t.Unix() - nsec := t.Nanosecond() - m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec))) - m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec))) - return nil - case "Value": - switch { - case string(in) == "null": - m.Set(fds.ByNumber(1), protoreflect.ValueOfEnum(0)) - case string(in) == "true": - m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(true)) - case string(in) == "false": - m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(false)) - case hasPrefixAndSuffix('"', in, '"'): - s, err := unquoteString(string(in)) - if err != nil { - return fmt.Errorf("unrecognized type for Value %q", in) - } - m.Set(fds.ByNumber(3), protoreflect.ValueOfString(s)) - case hasPrefixAndSuffix('[', in, ']'): - v := m.Mutable(fds.ByNumber(6)) - return u.unmarshalMessage(v.Message(), in) - case hasPrefixAndSuffix('{', in, '}'): - v := m.Mutable(fds.ByNumber(5)) - return u.unmarshalMessage(v.Message(), in) - default: - f, err := strconv.ParseFloat(string(in), 0) - if err != nil { - return fmt.Errorf("unrecognized type for Value %q", in) - } - m.Set(fds.ByNumber(2), protoreflect.ValueOfFloat64(f)) - } - return nil - case "ListValue": - var jsonArray []json.RawMessage - if err := json.Unmarshal(in, &jsonArray); err != nil { - return fmt.Errorf("bad ListValue: %v", err) - } - - lv := m.Mutable(fds.ByNumber(1)).List() - for _, raw := range jsonArray { - ve := lv.NewElement() - if err := u.unmarshalMessage(ve.Message(), raw); err != nil { - return err - } - lv.Append(ve) - } - return nil - case "Struct": - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return fmt.Errorf("bad StructValue: %v", err) - } - - mv := m.Mutable(fds.ByNumber(1)).Map() - for key, raw := range jsonObject { - kv := protoreflect.ValueOf(key).MapKey() - vv := mv.NewValue() - if err := u.unmarshalMessage(vv.Message(), raw); err != nil { - return fmt.Errorf("bad value in StructValue for key %q: %v", key, err) - } - mv.Set(kv, vv) - } - return nil - } - - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return err - } - - // Handle known fields. - for i := 0; i < fds.Len(); i++ { - fd := fds.Get(i) - if fd.IsWeak() && fd.Message().IsPlaceholder() { - continue // weak reference is not linked in - } - - // Search for any raw JSON value associated with this field. - var raw json.RawMessage - name := string(fd.Name()) - if fd.Kind() == protoreflect.GroupKind { - name = string(fd.Message().Name()) - } - if v, ok := jsonObject[name]; ok { - delete(jsonObject, name) - raw = v - } - name = string(fd.JSONName()) - if v, ok := jsonObject[name]; ok { - delete(jsonObject, name) - raw = v - } - - field := m.NewField(fd) - // Unmarshal the field value. - if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) { - continue - } - v, err := u.unmarshalValue(field, raw, fd) - if err != nil { - return err - } - m.Set(fd, v) - } - - // Handle extension fields. - for name, raw := range jsonObject { - if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") { - continue - } - - // Resolve the extension field by name. - xname := protoreflect.FullName(name[len("[") : len(name)-len("]")]) - xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname) - if xt == nil && isMessageSet(md) { - xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension")) - } - if xt == nil { - continue - } - delete(jsonObject, name) - fd := xt.TypeDescriptor() - if fd.ContainingMessage().FullName() != m.Descriptor().FullName() { - return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName()) - } - - field := m.NewField(fd) - // Unmarshal the field value. - if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) { - continue - } - v, err := u.unmarshalValue(field, raw, fd) - if err != nil { - return err - } - m.Set(fd, v) - } - - if !u.AllowUnknownFields && len(jsonObject) > 0 { - for name := range jsonObject { - return fmt.Errorf("unknown field %q in %v", name, md.FullName()) - } - } - return nil -} - -func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool { - if fd.Cardinality() == protoreflect.Repeated { - return false - } - if md := fd.Message(); md != nil { - return md.FullName() == "google.protobuf.Value" - } - if ed := fd.Enum(); ed != nil { - return ed.FullName() == "google.protobuf.NullValue" - } - return false -} - -func isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.FieldDescriptor) bool { - if fd.Message() != nil && fd.Cardinality() != protoreflect.Repeated { - _, ok := proto.MessageV1(v.Interface()).(JSONPBUnmarshaler) - return ok - } - return false -} - -func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { - switch { - case fd.IsList(): - var jsonArray []json.RawMessage - if err := json.Unmarshal(in, &jsonArray); err != nil { - return v, err - } - lv := v.List() - for _, raw := range jsonArray { - ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd) - if err != nil { - return v, err - } - lv.Append(ve) - } - return v, nil - case fd.IsMap(): - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return v, err - } - kfd := fd.MapKey() - vfd := fd.MapValue() - mv := v.Map() - for key, raw := range jsonObject { - var kv protoreflect.MapKey - if kfd.Kind() == protoreflect.StringKind { - kv = protoreflect.ValueOf(key).MapKey() - } else { - v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd) - if err != nil { - return v, err - } - kv = v.MapKey() - } - - vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd) - if err != nil { - return v, err - } - mv.Set(kv, vv) - } - return v, nil - default: - return u.unmarshalSingularValue(v, in, fd) - } -} - -var nonFinite = map[string]float64{ - `"NaN"`: math.NaN(), - `"Infinity"`: math.Inf(+1), - `"-Infinity"`: math.Inf(-1), -} - -func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { - switch fd.Kind() { - case protoreflect.BoolKind: - return unmarshalValue(in, new(bool)) - case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: - return unmarshalValue(trimQuote(in), new(int32)) - case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: - return unmarshalValue(trimQuote(in), new(int64)) - case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: - return unmarshalValue(trimQuote(in), new(uint32)) - case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: - return unmarshalValue(trimQuote(in), new(uint64)) - case protoreflect.FloatKind: - if f, ok := nonFinite[string(in)]; ok { - return protoreflect.ValueOfFloat32(float32(f)), nil - } - return unmarshalValue(trimQuote(in), new(float32)) - case protoreflect.DoubleKind: - if f, ok := nonFinite[string(in)]; ok { - return protoreflect.ValueOfFloat64(float64(f)), nil - } - return unmarshalValue(trimQuote(in), new(float64)) - case protoreflect.StringKind: - return unmarshalValue(in, new(string)) - case protoreflect.BytesKind: - return unmarshalValue(in, new([]byte)) - case protoreflect.EnumKind: - if hasPrefixAndSuffix('"', in, '"') { - vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in))) - if vd == nil { - return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName()) - } - return protoreflect.ValueOfEnum(vd.Number()), nil - } - return unmarshalValue(in, new(protoreflect.EnumNumber)) - case protoreflect.MessageKind, protoreflect.GroupKind: - err := u.unmarshalMessage(v.Message(), in) - return v, err - default: - panic(fmt.Sprintf("invalid kind %v", fd.Kind())) - } -} - -func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) { - err := json.Unmarshal(in, v) - return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err -} - -func unquoteString(in string) (out string, err error) { - err = json.Unmarshal([]byte(in), &out) - return out, err -} - -func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool { - if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix { - return true - } - return false -} - -// trimQuote is like unquoteString but simply strips surrounding quotes. -// This is incorrect, but is behavior done by the legacy implementation. -func trimQuote(in []byte) []byte { - if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' { - in = in[1 : len(in)-1] - } - return in -} diff --git a/vendor/github.com/golang/protobuf/jsonpb/encode.go b/vendor/github.com/golang/protobuf/jsonpb/encode.go deleted file mode 100644 index 685c80a6..00000000 --- a/vendor/github.com/golang/protobuf/jsonpb/encode.go +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright 2015 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 jsonpb - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "math" - "reflect" - "sort" - "strconv" - "strings" - "time" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/encoding/protojson" - protoV2 "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" -) - -const wrapJSONMarshalV2 = false - -// Marshaler is a configurable object for marshaling protocol buffer messages -// to the specified JSON representation. -type Marshaler struct { - // OrigName specifies whether to use the original protobuf name for fields. - OrigName bool - - // EnumsAsInts specifies whether to render enum values as integers, - // as opposed to string values. - EnumsAsInts bool - - // EmitDefaults specifies whether to render fields with zero values. - EmitDefaults bool - - // Indent controls whether the output is compact or not. - // If empty, the output is compact JSON. Otherwise, every JSON object - // entry and JSON array value will be on its own line. - // Each line will be preceded by repeated copies of Indent, where the - // number of copies is the current indentation depth. - Indent string - - // AnyResolver is used to resolve the google.protobuf.Any well-known type. - // If unset, the global registry is used by default. - AnyResolver AnyResolver -} - -// JSONPBMarshaler is implemented by protobuf messages that customize the -// way they are marshaled to JSON. Messages that implement this should also -// implement JSONPBUnmarshaler so that the custom format can be parsed. -// -// The JSON marshaling must follow the proto to JSON specification: -// https://developers.google.com/protocol-buffers/docs/proto3#json -// -// Deprecated: Custom types should implement protobuf reflection instead. -type JSONPBMarshaler interface { - MarshalJSONPB(*Marshaler) ([]byte, error) -} - -// Marshal serializes a protobuf message as JSON into w. -func (jm *Marshaler) Marshal(w io.Writer, m proto.Message) error { - b, err := jm.marshal(m) - if len(b) > 0 { - if _, err := w.Write(b); err != nil { - return err - } - } - return err -} - -// MarshalToString serializes a protobuf message as JSON in string form. -func (jm *Marshaler) MarshalToString(m proto.Message) (string, error) { - b, err := jm.marshal(m) - if err != nil { - return "", err - } - return string(b), nil -} - -func (jm *Marshaler) marshal(m proto.Message) ([]byte, error) { - v := reflect.ValueOf(m) - if m == nil || (v.Kind() == reflect.Ptr && v.IsNil()) { - return nil, errors.New("Marshal called with nil") - } - - // Check for custom marshalers first since they may not properly - // implement protobuf reflection that the logic below relies on. - if jsm, ok := m.(JSONPBMarshaler); ok { - return jsm.MarshalJSONPB(jm) - } - - if wrapJSONMarshalV2 { - opts := protojson.MarshalOptions{ - UseProtoNames: jm.OrigName, - UseEnumNumbers: jm.EnumsAsInts, - EmitUnpopulated: jm.EmitDefaults, - Indent: jm.Indent, - } - if jm.AnyResolver != nil { - opts.Resolver = anyResolver{jm.AnyResolver} - } - return opts.Marshal(proto.MessageReflect(m).Interface()) - } else { - // Check for unpopulated required fields first. - m2 := proto.MessageReflect(m) - if err := protoV2.CheckInitialized(m2.Interface()); err != nil { - return nil, err - } - - w := jsonWriter{Marshaler: jm} - err := w.marshalMessage(m2, "", "") - return w.buf, err - } -} - -type jsonWriter struct { - *Marshaler - buf []byte -} - -func (w *jsonWriter) write(s string) { - w.buf = append(w.buf, s...) -} - -func (w *jsonWriter) marshalMessage(m protoreflect.Message, indent, typeURL string) error { - if jsm, ok := proto.MessageV1(m.Interface()).(JSONPBMarshaler); ok { - b, err := jsm.MarshalJSONPB(w.Marshaler) - if err != nil { - return err - } - if typeURL != "" { - // we are marshaling this object to an Any type - var js map[string]*json.RawMessage - if err = json.Unmarshal(b, &js); err != nil { - return fmt.Errorf("type %T produced invalid JSON: %v", m.Interface(), err) - } - turl, err := json.Marshal(typeURL) - if err != nil { - return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err) - } - js["@type"] = (*json.RawMessage)(&turl) - if b, err = json.Marshal(js); err != nil { - return err - } - } - w.write(string(b)) - return nil - } - - md := m.Descriptor() - fds := md.Fields() - - // Handle well-known types. - const secondInNanos = int64(time.Second / time.Nanosecond) - switch wellKnownType(md.FullName()) { - case "Any": - return w.marshalAny(m, indent) - case "BoolValue", "BytesValue", "StringValue", - "Int32Value", "UInt32Value", "FloatValue", - "Int64Value", "UInt64Value", "DoubleValue": - fd := fds.ByNumber(1) - return w.marshalValue(fd, m.Get(fd), indent) - case "Duration": - const maxSecondsInDuration = 315576000000 - // "Generated output always contains 0, 3, 6, or 9 fractional digits, - // depending on required precision." - s := m.Get(fds.ByNumber(1)).Int() - ns := m.Get(fds.ByNumber(2)).Int() - if s < -maxSecondsInDuration || s > maxSecondsInDuration { - return fmt.Errorf("seconds out of range %v", s) - } - if ns <= -secondInNanos || ns >= secondInNanos { - return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos) - } - if (s > 0 && ns < 0) || (s < 0 && ns > 0) { - return errors.New("signs of seconds and nanos do not match") - } - var sign string - if s < 0 || ns < 0 { - sign, s, ns = "-", -1*s, -1*ns - } - x := fmt.Sprintf("%s%d.%09d", sign, s, ns) - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, ".000") - w.write(fmt.Sprintf(`"%vs"`, x)) - return nil - case "Timestamp": - // "RFC 3339, where generated output will always be Z-normalized - // and uses 0, 3, 6 or 9 fractional digits." - s := m.Get(fds.ByNumber(1)).Int() - ns := m.Get(fds.ByNumber(2)).Int() - if ns < 0 || ns >= secondInNanos { - return fmt.Errorf("ns out of range [0, %v)", secondInNanos) - } - t := time.Unix(s, ns).UTC() - // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits). - x := t.Format("2006-01-02T15:04:05.000000000") - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, ".000") - w.write(fmt.Sprintf(`"%vZ"`, x)) - return nil - case "Value": - // JSON value; which is a null, number, string, bool, object, or array. - od := md.Oneofs().Get(0) - fd := m.WhichOneof(od) - if fd == nil { - return errors.New("nil Value") - } - return w.marshalValue(fd, m.Get(fd), indent) - case "Struct", "ListValue": - // JSON object or array. - fd := fds.ByNumber(1) - return w.marshalValue(fd, m.Get(fd), indent) - } - - w.write("{") - if w.Indent != "" { - w.write("\n") - } - - firstField := true - if typeURL != "" { - if err := w.marshalTypeURL(indent, typeURL); err != nil { - return err - } - firstField = false - } - - for i := 0; i < fds.Len(); { - fd := fds.Get(i) - if od := fd.ContainingOneof(); od != nil { - fd = m.WhichOneof(od) - i += od.Fields().Len() - if fd == nil { - continue - } - } else { - i++ - } - - v := m.Get(fd) - - if !m.Has(fd) { - if !w.EmitDefaults || fd.ContainingOneof() != nil { - continue - } - if fd.Cardinality() != protoreflect.Repeated && (fd.Message() != nil || fd.Syntax() == protoreflect.Proto2) { - v = protoreflect.Value{} // use "null" for singular messages or proto2 scalars - } - } - - if !firstField { - w.writeComma() - } - if err := w.marshalField(fd, v, indent); err != nil { - return err - } - firstField = false - } - - // Handle proto2 extensions. - if md.ExtensionRanges().Len() > 0 { - // Collect a sorted list of all extension descriptor and values. - type ext struct { - desc protoreflect.FieldDescriptor - val protoreflect.Value - } - var exts []ext - m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - if fd.IsExtension() { - exts = append(exts, ext{fd, v}) - } - return true - }) - sort.Slice(exts, func(i, j int) bool { - return exts[i].desc.Number() < exts[j].desc.Number() - }) - - for _, ext := range exts { - if !firstField { - w.writeComma() - } - if err := w.marshalField(ext.desc, ext.val, indent); err != nil { - return err - } - firstField = false - } - } - - if w.Indent != "" { - w.write("\n") - w.write(indent) - } - w.write("}") - return nil -} - -func (w *jsonWriter) writeComma() { - if w.Indent != "" { - w.write(",\n") - } else { - w.write(",") - } -} - -func (w *jsonWriter) marshalAny(m protoreflect.Message, indent string) error { - // "If the Any contains a value that has a special JSON mapping, - // it will be converted as follows: {"@type": xxx, "value": yyy}. - // Otherwise, the value will be converted into a JSON object, - // and the "@type" field will be inserted to indicate the actual data type." - md := m.Descriptor() - typeURL := m.Get(md.Fields().ByNumber(1)).String() - rawVal := m.Get(md.Fields().ByNumber(2)).Bytes() - - var m2 protoreflect.Message - if w.AnyResolver != nil { - mi, err := w.AnyResolver.Resolve(typeURL) - if err != nil { - return err - } - m2 = proto.MessageReflect(mi) - } else { - mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL) - if err != nil { - return err - } - m2 = mt.New() - } - - if err := protoV2.Unmarshal(rawVal, m2.Interface()); err != nil { - return err - } - - if wellKnownType(m2.Descriptor().FullName()) == "" { - return w.marshalMessage(m2, indent, typeURL) - } - - w.write("{") - if w.Indent != "" { - w.write("\n") - } - if err := w.marshalTypeURL(indent, typeURL); err != nil { - return err - } - w.writeComma() - if w.Indent != "" { - w.write(indent) - w.write(w.Indent) - w.write(`"value": `) - } else { - w.write(`"value":`) - } - if err := w.marshalMessage(m2, indent+w.Indent, ""); err != nil { - return err - } - if w.Indent != "" { - w.write("\n") - w.write(indent) - } - w.write("}") - return nil -} - -func (w *jsonWriter) marshalTypeURL(indent, typeURL string) error { - if w.Indent != "" { - w.write(indent) - w.write(w.Indent) - } - w.write(`"@type":`) - if w.Indent != "" { - w.write(" ") - } - b, err := json.Marshal(typeURL) - if err != nil { - return err - } - w.write(string(b)) - return nil -} - -// marshalField writes field description and value to the Writer. -func (w *jsonWriter) marshalField(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { - if w.Indent != "" { - w.write(indent) - w.write(w.Indent) - } - w.write(`"`) - switch { - case fd.IsExtension(): - // For message set, use the fname of the message as the extension name. - name := string(fd.FullName()) - if isMessageSet(fd.ContainingMessage()) { - name = strings.TrimSuffix(name, ".message_set_extension") - } - - w.write("[" + name + "]") - case w.OrigName: - name := string(fd.Name()) - if fd.Kind() == protoreflect.GroupKind { - name = string(fd.Message().Name()) - } - w.write(name) - default: - w.write(string(fd.JSONName())) - } - w.write(`":`) - if w.Indent != "" { - w.write(" ") - } - return w.marshalValue(fd, v, indent) -} - -func (w *jsonWriter) marshalValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { - switch { - case fd.IsList(): - w.write("[") - comma := "" - lv := v.List() - for i := 0; i < lv.Len(); i++ { - w.write(comma) - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - w.write(w.Indent) - } - if err := w.marshalSingularValue(fd, lv.Get(i), indent+w.Indent); err != nil { - return err - } - comma = "," - } - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - } - w.write("]") - return nil - case fd.IsMap(): - kfd := fd.MapKey() - vfd := fd.MapValue() - mv := v.Map() - - // Collect a sorted list of all map keys and values. - type entry struct{ key, val protoreflect.Value } - var entries []entry - mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { - entries = append(entries, entry{k.Value(), v}) - return true - }) - sort.Slice(entries, func(i, j int) bool { - switch kfd.Kind() { - case protoreflect.BoolKind: - return !entries[i].key.Bool() && entries[j].key.Bool() - case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: - return entries[i].key.Int() < entries[j].key.Int() - case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind: - return entries[i].key.Uint() < entries[j].key.Uint() - case protoreflect.StringKind: - return entries[i].key.String() < entries[j].key.String() - default: - panic("invalid kind") - } - }) - - w.write(`{`) - comma := "" - for _, entry := range entries { - w.write(comma) - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - w.write(w.Indent) - } - - s := fmt.Sprint(entry.key.Interface()) - b, err := json.Marshal(s) - if err != nil { - return err - } - w.write(string(b)) - - w.write(`:`) - if w.Indent != "" { - w.write(` `) - } - - if err := w.marshalSingularValue(vfd, entry.val, indent+w.Indent); err != nil { - return err - } - comma = "," - } - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - } - w.write(`}`) - return nil - default: - return w.marshalSingularValue(fd, v, indent) - } -} - -func (w *jsonWriter) marshalSingularValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { - switch { - case !v.IsValid(): - w.write("null") - return nil - case fd.Message() != nil: - return w.marshalMessage(v.Message(), indent+w.Indent, "") - case fd.Enum() != nil: - if fd.Enum().FullName() == "google.protobuf.NullValue" { - w.write("null") - return nil - } - - vd := fd.Enum().Values().ByNumber(v.Enum()) - if vd == nil || w.EnumsAsInts { - w.write(strconv.Itoa(int(v.Enum()))) - } else { - w.write(`"` + string(vd.Name()) + `"`) - } - return nil - default: - switch v.Interface().(type) { - case float32, float64: - switch { - case math.IsInf(v.Float(), +1): - w.write(`"Infinity"`) - return nil - case math.IsInf(v.Float(), -1): - w.write(`"-Infinity"`) - return nil - case math.IsNaN(v.Float()): - w.write(`"NaN"`) - return nil - } - case int64, uint64: - w.write(fmt.Sprintf(`"%d"`, v.Interface())) - return nil - } - - b, err := json.Marshal(v.Interface()) - if err != nil { - return err - } - w.write(string(b)) - return nil - } -} diff --git a/vendor/github.com/golang/protobuf/jsonpb/json.go b/vendor/github.com/golang/protobuf/jsonpb/json.go deleted file mode 100644 index 480e2448..00000000 --- a/vendor/github.com/golang/protobuf/jsonpb/json.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2015 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 jsonpb provides functionality to marshal and unmarshal between a -// protocol buffer message and JSON. It follows the specification at -// https://developers.google.com/protocol-buffers/docs/proto3#json. -// -// Do not rely on the default behavior of the standard encoding/json package -// when called on generated message types as it does not operate correctly. -// -// Deprecated: Use the "google.golang.org/protobuf/encoding/protojson" -// package instead. -package jsonpb - -import ( - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - "google.golang.org/protobuf/runtime/protoimpl" -) - -// AnyResolver takes a type URL, present in an Any message, -// and resolves it into an instance of the associated message. -type AnyResolver interface { - Resolve(typeURL string) (proto.Message, error) -} - -type anyResolver struct{ AnyResolver } - -func (r anyResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) { - return r.FindMessageByURL(string(message)) -} - -func (r anyResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) { - m, err := r.Resolve(url) - if err != nil { - return nil, err - } - return protoimpl.X.MessageTypeOf(m), nil -} - -func (r anyResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { - return protoregistry.GlobalTypes.FindExtensionByName(field) -} - -func (r anyResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { - return protoregistry.GlobalTypes.FindExtensionByNumber(message, field) -} - -func wellKnownType(s protoreflect.FullName) string { - if s.Parent() == "google.protobuf" { - switch s.Name() { - case "Empty", "Any", - "BoolValue", "BytesValue", "StringValue", - "Int32Value", "UInt32Value", "FloatValue", - "Int64Value", "UInt64Value", "DoubleValue", - "Duration", "Timestamp", - "NullValue", "Struct", "Value", "ListValue": - return string(s.Name()) - } - } - return "" -} - -func isMessageSet(md protoreflect.MessageDescriptor) bool { - ms, ok := md.(interface{ IsMessageSet() bool }) - return ok && ms.IsMessageSet() -} diff --git a/vendor/github.com/golang/protobuf/ptypes/any.go b/vendor/github.com/golang/protobuf/ptypes/any.go deleted file mode 100644 index 85f9f573..00000000 --- a/vendor/github.com/golang/protobuf/ptypes/any.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2016 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 ptypes - -import ( - "fmt" - "strings" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - - anypb "github.com/golang/protobuf/ptypes/any" -) - -const urlPrefix = "type.googleapis.com/" - -// AnyMessageName returns the message name contained in an anypb.Any message. -// Most type assertions should use the Is function instead. -// -// Deprecated: Call the any.MessageName method instead. -func AnyMessageName(any *anypb.Any) (string, error) { - name, err := anyMessageName(any) - return string(name), err -} -func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) { - if any == nil { - return "", fmt.Errorf("message is nil") - } - name := protoreflect.FullName(any.TypeUrl) - if i := strings.LastIndex(any.TypeUrl, "/"); i >= 0 { - name = name[i+len("/"):] - } - if !name.IsValid() { - return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl) - } - return name, nil -} - -// MarshalAny marshals the given message m into an anypb.Any message. -// -// Deprecated: Call the anypb.New function instead. -func MarshalAny(m proto.Message) (*anypb.Any, error) { - switch dm := m.(type) { - case DynamicAny: - m = dm.Message - case *DynamicAny: - if dm == nil { - return nil, proto.ErrNil - } - m = dm.Message - } - b, err := proto.Marshal(m) - if err != nil { - return nil, err - } - return &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil -} - -// Empty returns a new message of the type specified in an anypb.Any message. -// It returns protoregistry.NotFound if the corresponding message type could not -// be resolved in the global registry. -// -// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead -// to resolve the message name and create a new instance of it. -func Empty(any *anypb.Any) (proto.Message, error) { - name, err := anyMessageName(any) - if err != nil { - return nil, err - } - mt, err := protoregistry.GlobalTypes.FindMessageByName(name) - if err != nil { - return nil, err - } - return proto.MessageV1(mt.New().Interface()), nil -} - -// UnmarshalAny unmarshals the encoded value contained in the anypb.Any message -// into the provided message m. It returns an error if the target message -// does not match the type in the Any message or if an unmarshal error occurs. -// -// The target message m may be a *DynamicAny message. If the underlying message -// type could not be resolved, then this returns protoregistry.NotFound. -// -// Deprecated: Call the any.UnmarshalTo method instead. -func UnmarshalAny(any *anypb.Any, m proto.Message) error { - if dm, ok := m.(*DynamicAny); ok { - if dm.Message == nil { - var err error - dm.Message, err = Empty(any) - if err != nil { - return err - } - } - m = dm.Message - } - - anyName, err := AnyMessageName(any) - if err != nil { - return err - } - msgName := proto.MessageName(m) - if anyName != msgName { - return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName) - } - return proto.Unmarshal(any.Value, m) -} - -// Is reports whether the Any message contains a message of the specified type. -// -// Deprecated: Call the any.MessageIs method instead. -func Is(any *anypb.Any, m proto.Message) bool { - if any == nil || m == nil { - return false - } - name := proto.MessageName(m) - if !strings.HasSuffix(any.TypeUrl, name) { - return false - } - return len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/' -} - -// DynamicAny is a value that can be passed to UnmarshalAny to automatically -// allocate a proto.Message for the type specified in an anypb.Any message. -// The allocated message is stored in the embedded proto.Message. -// -// Example: -// var x ptypes.DynamicAny -// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... } -// fmt.Printf("unmarshaled message: %v", x.Message) -// -// Deprecated: Use the any.UnmarshalNew method instead to unmarshal -// the any message contents into a new instance of the underlying message. -type DynamicAny struct{ proto.Message } - -func (m DynamicAny) String() string { - if m.Message == nil { - return "" - } - return m.Message.String() -} -func (m DynamicAny) Reset() { - if m.Message == nil { - return - } - m.Message.Reset() -} -func (m DynamicAny) ProtoMessage() { - return -} -func (m DynamicAny) ProtoReflect() protoreflect.Message { - if m.Message == nil { - return nil - } - return dynamicAny{proto.MessageReflect(m.Message)} -} - -type dynamicAny struct{ protoreflect.Message } - -func (m dynamicAny) Type() protoreflect.MessageType { - return dynamicAnyType{m.Message.Type()} -} -func (m dynamicAny) New() protoreflect.Message { - return dynamicAnyType{m.Message.Type()}.New() -} -func (m dynamicAny) Interface() protoreflect.ProtoMessage { - return DynamicAny{proto.MessageV1(m.Message.Interface())} -} - -type dynamicAnyType struct{ protoreflect.MessageType } - -func (t dynamicAnyType) New() protoreflect.Message { - return dynamicAny{t.MessageType.New()} -} -func (t dynamicAnyType) Zero() protoreflect.Message { - return dynamicAny{t.MessageType.Zero()} -} diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go deleted file mode 100644 index 0ef27d33..00000000 --- a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go +++ /dev/null @@ -1,62 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/ptypes/any/any.proto - -package any - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/any.proto. - -type Any = anypb.Any - -var File_github_com_golang_protobuf_ptypes_any_any_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = []byte{ - 0x0a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x2b, 0x5a, 0x29, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, - 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x3b, 0x61, 0x6e, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} - -var file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_ptypes_any_any_proto_init() } -func file_github_com_golang_protobuf_ptypes_any_any_proto_init() { - if File_github_com_golang_protobuf_ptypes_any_any_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_ptypes_any_any_proto = out.File - file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = nil - file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = nil - file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = nil -} diff --git a/vendor/github.com/golang/protobuf/ptypes/doc.go b/vendor/github.com/golang/protobuf/ptypes/doc.go deleted file mode 100644 index d3c33259..00000000 --- a/vendor/github.com/golang/protobuf/ptypes/doc.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2016 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 ptypes provides functionality for interacting with well-known types. -// -// Deprecated: Well-known types have specialized functionality directly -// injected into the generated packages for each message type. -// See the deprecation notice for each function for the suggested alternative. -package ptypes diff --git a/vendor/github.com/golang/protobuf/ptypes/duration.go b/vendor/github.com/golang/protobuf/ptypes/duration.go deleted file mode 100644 index b2b55dd8..00000000 --- a/vendor/github.com/golang/protobuf/ptypes/duration.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2016 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 ptypes - -import ( - "errors" - "fmt" - "time" - - durationpb "github.com/golang/protobuf/ptypes/duration" -) - -// Range of google.protobuf.Duration as specified in duration.proto. -// This is about 10,000 years in seconds. -const ( - maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) - minSeconds = -maxSeconds -) - -// Duration converts a durationpb.Duration to a time.Duration. -// Duration returns an error if dur is invalid or overflows a time.Duration. -// -// Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead. -func Duration(dur *durationpb.Duration) (time.Duration, error) { - if err := validateDuration(dur); err != nil { - return 0, err - } - d := time.Duration(dur.Seconds) * time.Second - if int64(d/time.Second) != dur.Seconds { - return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) - } - if dur.Nanos != 0 { - d += time.Duration(dur.Nanos) * time.Nanosecond - if (d < 0) != (dur.Nanos < 0) { - return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) - } - } - return d, nil -} - -// DurationProto converts a time.Duration to a durationpb.Duration. -// -// Deprecated: Call the durationpb.New function instead. -func DurationProto(d time.Duration) *durationpb.Duration { - nanos := d.Nanoseconds() - secs := nanos / 1e9 - nanos -= secs * 1e9 - return &durationpb.Duration{ - Seconds: int64(secs), - Nanos: int32(nanos), - } -} - -// validateDuration determines whether the durationpb.Duration is valid -// according to the definition in google/protobuf/duration.proto. -// A valid durpb.Duration may still be too large to fit into a time.Duration -// Note that the range of durationpb.Duration is about 10,000 years, -// while the range of time.Duration is about 290 years. -func validateDuration(dur *durationpb.Duration) error { - if dur == nil { - return errors.New("duration: nil Duration") - } - if dur.Seconds < minSeconds || dur.Seconds > maxSeconds { - return fmt.Errorf("duration: %v: seconds out of range", dur) - } - if dur.Nanos <= -1e9 || dur.Nanos >= 1e9 { - return fmt.Errorf("duration: %v: nanos out of range", dur) - } - // Seconds and Nanos must have the same sign, unless d.Nanos is zero. - if (dur.Seconds < 0 && dur.Nanos > 0) || (dur.Seconds > 0 && dur.Nanos < 0) { - return fmt.Errorf("duration: %v: seconds and nanos have different signs", dur) - } - return nil -} diff --git a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go deleted file mode 100644 index d0079ee3..00000000 --- a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go +++ /dev/null @@ -1,63 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/ptypes/duration/duration.proto - -package duration - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/duration.proto. - -type Duration = durationpb.Duration - -var File_github_com_golang_protobuf_ptypes_duration_duration_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = []byte{ - 0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() } -func file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() { - if File_github_com_golang_protobuf_ptypes_duration_duration_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_ptypes_duration_duration_proto = out.File - file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = nil - file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = nil - file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = nil -} diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp.go b/vendor/github.com/golang/protobuf/ptypes/timestamp.go deleted file mode 100644 index 8368a3f7..00000000 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2016 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 ptypes - -import ( - "errors" - "fmt" - "time" - - timestamppb "github.com/golang/protobuf/ptypes/timestamp" -) - -// Range of google.protobuf.Duration as specified in timestamp.proto. -const ( - // Seconds field of the earliest valid Timestamp. - // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - minValidSeconds = -62135596800 - // Seconds field just after the latest valid Timestamp. - // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - maxValidSeconds = 253402300800 -) - -// Timestamp converts a timestamppb.Timestamp to a time.Time. -// It returns an error if the argument is invalid. -// -// Unlike most Go functions, if Timestamp returns an error, the first return -// value is not the zero time.Time. Instead, it is the value obtained from the -// time.Unix function when passed the contents of the Timestamp, in the UTC -// locale. This may or may not be a meaningful time; many invalid Timestamps -// do map to valid time.Times. -// -// A nil Timestamp returns an error. The first return value in that case is -// undefined. -// -// Deprecated: Call the ts.AsTime and ts.CheckValid methods instead. -func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) { - // Don't return the zero value on error, because corresponds to a valid - // timestamp. Instead return whatever time.Unix gives us. - var t time.Time - if ts == nil { - t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp - } else { - t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() - } - return t, validateTimestamp(ts) -} - -// TimestampNow returns a google.protobuf.Timestamp for the current time. -// -// Deprecated: Call the timestamppb.Now function instead. -func TimestampNow() *timestamppb.Timestamp { - ts, err := TimestampProto(time.Now()) - if err != nil { - panic("ptypes: time.Now() out of Timestamp range") - } - return ts -} - -// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. -// It returns an error if the resulting Timestamp is invalid. -// -// Deprecated: Call the timestamppb.New function instead. -func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) { - ts := ×tamppb.Timestamp{ - Seconds: t.Unix(), - Nanos: int32(t.Nanosecond()), - } - if err := validateTimestamp(ts); err != nil { - return nil, err - } - return ts, nil -} - -// TimestampString returns the RFC 3339 string for valid Timestamps. -// For invalid Timestamps, it returns an error message in parentheses. -// -// Deprecated: Call the ts.AsTime method instead, -// followed by a call to the Format method on the time.Time value. -func TimestampString(ts *timestamppb.Timestamp) string { - t, err := Timestamp(ts) - if err != nil { - return fmt.Sprintf("(%v)", err) - } - return t.Format(time.RFC3339Nano) -} - -// validateTimestamp determines whether a Timestamp is valid. -// A valid timestamp represents a time in the range [0001-01-01, 10000-01-01) -// and has a Nanos field in the range [0, 1e9). -// -// If the Timestamp is valid, validateTimestamp returns nil. -// Otherwise, it returns an error that describes the problem. -// -// Every valid Timestamp can be represented by a time.Time, -// but the converse is not true. -func validateTimestamp(ts *timestamppb.Timestamp) error { - if ts == nil { - return errors.New("timestamp: nil Timestamp") - } - if ts.Seconds < minValidSeconds { - return fmt.Errorf("timestamp: %v before 0001-01-01", ts) - } - if ts.Seconds >= maxValidSeconds { - return fmt.Errorf("timestamp: %v after 10000-01-01", ts) - } - if ts.Nanos < 0 || ts.Nanos >= 1e9 { - return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts) - } - return nil -} diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go deleted file mode 100644 index a76f8076..00000000 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go +++ /dev/null @@ -1,64 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto - -package timestamp - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/timestamp.proto. - -type Timestamp = timestamppb.Timestamp - -var File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = []byte{ - 0x0a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x37, - 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x3b, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() } -func file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() { - if File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto = out.File - file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = nil - file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = nil - file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = nil -} diff --git a/vendor/github.com/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go index 087320da..0f5b8a48 100644 --- a/vendor/github.com/google/go-cmp/cmp/compare.go +++ b/vendor/github.com/google/go-cmp/cmp/compare.go @@ -5,7 +5,7 @@ // Package cmp determines equality of values. // // This package is intended to be a more powerful and safer alternative to -// reflect.DeepEqual for comparing whether two values are semantically equal. +// [reflect.DeepEqual] for comparing whether two values are semantically equal. // It is intended to only be used in tests, as performance is not a goal and // it may panic if it cannot compare the values. Its propensity towards // panicking means that its unsuitable for production environments where a @@ -18,16 +18,17 @@ // For example, an equality function may report floats as equal so long as // they are within some tolerance of each other. // -// - Types with an Equal method may use that method to determine equality. -// This allows package authors to determine the equality operation -// for the types that they define. +// - Types with an Equal method (e.g., [time.Time.Equal]) may use that method +// to determine equality. This allows package authors to determine +// the equality operation for the types that they define. // // - If no custom equality functions are used and no Equal method is defined, // equality is determined by recursively comparing the primitive kinds on -// both values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, +// both values, much like [reflect.DeepEqual]. Unlike [reflect.DeepEqual], // unexported fields are not compared by default; they result in panics -// unless suppressed by using an Ignore option (see cmpopts.IgnoreUnexported) -// or explicitly compared using the Exporter option. +// unless suppressed by using an [Ignore] option +// (see [github.com/google/go-cmp/cmp/cmpopts.IgnoreUnexported]) +// or explicitly compared using the [Exporter] option. package cmp import ( @@ -45,14 +46,14 @@ import ( // Equal reports whether x and y are equal by recursively applying the // following rules in the given order to x and y and all of their sub-values: // -// - Let S be the set of all Ignore, Transformer, and Comparer options that +// - Let S be the set of all [Ignore], [Transformer], and [Comparer] options that // remain after applying all path filters, value filters, and type filters. -// If at least one Ignore exists in S, then the comparison is ignored. -// If the number of Transformer and Comparer options in S is non-zero, +// If at least one [Ignore] exists in S, then the comparison is ignored. +// If the number of [Transformer] and [Comparer] options in S is non-zero, // then Equal panics because it is ambiguous which option to use. -// If S contains a single Transformer, then use that to transform +// If S contains a single [Transformer], then use that to transform // the current values and recursively call Equal on the output values. -// If S contains a single Comparer, then use that to compare the current values. +// If S contains a single [Comparer], then use that to compare the current values. // Otherwise, evaluation proceeds to the next rule. // // - If the values have an Equal method of the form "(T) Equal(T) bool" or @@ -66,21 +67,22 @@ import ( // Functions are only equal if they are both nil, otherwise they are unequal. // // Structs are equal if recursively calling Equal on all fields report equal. -// If a struct contains unexported fields, Equal panics unless an Ignore option -// (e.g., cmpopts.IgnoreUnexported) ignores that field or the Exporter option -// explicitly permits comparing the unexported field. +// If a struct contains unexported fields, Equal panics unless an [Ignore] option +// (e.g., [github.com/google/go-cmp/cmp/cmpopts.IgnoreUnexported]) ignores that field +// or the [Exporter] option explicitly permits comparing the unexported field. // // Slices are equal if they are both nil or both non-nil, where recursively // calling Equal on all non-ignored slice or array elements report equal. // Empty non-nil slices and nil slices are not equal; to equate empty slices, -// consider using cmpopts.EquateEmpty. +// consider using [github.com/google/go-cmp/cmp/cmpopts.EquateEmpty]. // // Maps are equal if they are both nil or both non-nil, where recursively // calling Equal on all non-ignored map entries report equal. // Map keys are equal according to the == operator. -// To use custom comparisons for map keys, consider using cmpopts.SortMaps. +// To use custom comparisons for map keys, consider using +// [github.com/google/go-cmp/cmp/cmpopts.SortMaps]. // Empty non-nil maps and nil maps are not equal; to equate empty maps, -// consider using cmpopts.EquateEmpty. +// consider using [github.com/google/go-cmp/cmp/cmpopts.EquateEmpty]. // // Pointers and interfaces are equal if they are both nil or both non-nil, // where they have the same underlying concrete type and recursively diff --git a/vendor/github.com/google/go-cmp/cmp/export_unsafe.go b/vendor/github.com/google/go-cmp/cmp/export.go similarity index 94% rename from vendor/github.com/google/go-cmp/cmp/export_unsafe.go rename to vendor/github.com/google/go-cmp/cmp/export.go index e2c0f74e..29f82fe6 100644 --- a/vendor/github.com/google/go-cmp/cmp/export_unsafe.go +++ b/vendor/github.com/google/go-cmp/cmp/export.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !purego -// +build !purego - package cmp import ( @@ -12,8 +9,6 @@ import ( "unsafe" ) -const supportExporters = true - // retrieveUnexportedField uses unsafe to forcibly retrieve any field from // a struct such that the value has read-write permissions. // diff --git a/vendor/github.com/google/go-cmp/cmp/export_panic.go b/vendor/github.com/google/go-cmp/cmp/export_panic.go deleted file mode 100644 index ae851fe5..00000000 --- a/vendor/github.com/google/go-cmp/cmp/export_panic.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017, The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build purego -// +build purego - -package cmp - -import "reflect" - -const supportExporters = false - -func retrieveUnexportedField(reflect.Value, reflect.StructField, bool) reflect.Value { - panic("no support for forcibly accessing unexported fields") -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer.go similarity index 95% rename from vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go rename to vendor/github.com/google/go-cmp/cmp/internal/value/pointer.go index 16e6860a..e5dfff69 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !purego -// +build !purego - package value import ( diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go deleted file mode 100644 index 1a71bfcb..00000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go +++ /dev/null @@ -1,34 +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. - -//go:build purego -// +build purego - -package value - -import "reflect" - -// Pointer is an opaque typed pointer and is guaranteed to be comparable. -type Pointer struct { - p uintptr - t reflect.Type -} - -// PointerOf returns a Pointer from v, which must be a -// reflect.Ptr, reflect.Slice, or reflect.Map. -func PointerOf(v reflect.Value) Pointer { - // NOTE: Storing a pointer as an uintptr is technically incorrect as it - // assumes that the GC implementation does not use a moving collector. - return Pointer{v.Pointer(), v.Type()} -} - -// IsNil reports whether the pointer is nil. -func (p Pointer) IsNil() bool { - return p.p == 0 -} - -// Uintptr returns the pointer as a uintptr. -func (p Pointer) Uintptr() uintptr { - return p.p -} diff --git a/vendor/github.com/google/go-cmp/cmp/options.go b/vendor/github.com/google/go-cmp/cmp/options.go index 1f9ca9c4..754496f3 100644 --- a/vendor/github.com/google/go-cmp/cmp/options.go +++ b/vendor/github.com/google/go-cmp/cmp/options.go @@ -13,15 +13,15 @@ import ( "github.com/google/go-cmp/cmp/internal/function" ) -// Option configures for specific behavior of Equal and Diff. In particular, -// the fundamental Option functions (Ignore, Transformer, and Comparer), +// Option configures for specific behavior of [Equal] and [Diff]. In particular, +// the fundamental Option functions ([Ignore], [Transformer], and [Comparer]), // configure how equality is determined. // -// The fundamental options may be composed with filters (FilterPath and -// FilterValues) to control the scope over which they are applied. +// The fundamental options may be composed with filters ([FilterPath] and +// [FilterValues]) to control the scope over which they are applied. // -// The cmp/cmpopts package provides helper functions for creating options that -// may be used with Equal and Diff. +// The [github.com/google/go-cmp/cmp/cmpopts] package provides helper functions +// for creating options that may be used with [Equal] and [Diff]. type Option interface { // filter applies all filters and returns the option that remains. // Each option may only read s.curPath and call s.callTTBFunc. @@ -56,9 +56,9 @@ type core struct{} func (core) isCore() {} -// Options is a list of Option values that also satisfies the Option interface. +// Options is a list of [Option] values that also satisfies the [Option] interface. // Helper comparison packages may return an Options value when packing multiple -// Option values into a single Option. When this package processes an Options, +// [Option] values into a single [Option]. When this package processes an Options, // it will be implicitly expanded into a flat list. // // Applying a filter on an Options is equivalent to applying that same filter @@ -105,16 +105,16 @@ func (opts Options) String() string { return fmt.Sprintf("Options{%s}", strings.Join(ss, ", ")) } -// FilterPath returns a new Option where opt is only evaluated if filter f -// returns true for the current Path in the value tree. +// FilterPath returns a new [Option] where opt is only evaluated if filter f +// returns true for the current [Path] in the value tree. // // This filter is called even if a slice element or map entry is missing and // provides an opportunity to ignore such cases. The filter function must be // symmetric such that the filter result is identical regardless of whether the // missing value is from x or y. // -// The option passed in may be an Ignore, Transformer, Comparer, Options, or -// a previously filtered Option. +// The option passed in may be an [Ignore], [Transformer], [Comparer], [Options], or +// a previously filtered [Option]. func FilterPath(f func(Path) bool, opt Option) Option { if f == nil { panic("invalid path filter function") @@ -142,7 +142,7 @@ func (f pathFilter) String() string { return fmt.Sprintf("FilterPath(%s, %v)", function.NameOf(reflect.ValueOf(f.fnc)), f.opt) } -// FilterValues returns a new Option where opt is only evaluated if filter f, +// FilterValues returns a new [Option] where opt is only evaluated if filter f, // which is a function of the form "func(T, T) bool", returns true for the // current pair of values being compared. If either value is invalid or // the type of the values is not assignable to T, then this filter implicitly @@ -154,8 +154,8 @@ func (f pathFilter) String() string { // If T is an interface, it is possible that f is called with two values with // different concrete types that both implement T. // -// The option passed in may be an Ignore, Transformer, Comparer, Options, or -// a previously filtered Option. +// The option passed in may be an [Ignore], [Transformer], [Comparer], [Options], or +// a previously filtered [Option]. func FilterValues(f interface{}, opt Option) Option { v := reflect.ValueOf(f) if !function.IsType(v.Type(), function.ValueFilter) || v.IsNil() { @@ -192,9 +192,9 @@ func (f valuesFilter) String() string { return fmt.Sprintf("FilterValues(%s, %v)", function.NameOf(f.fnc), f.opt) } -// Ignore is an Option that causes all comparisons to be ignored. -// This value is intended to be combined with FilterPath or FilterValues. -// It is an error to pass an unfiltered Ignore option to Equal. +// Ignore is an [Option] that causes all comparisons to be ignored. +// This value is intended to be combined with [FilterPath] or [FilterValues]. +// It is an error to pass an unfiltered Ignore option to [Equal]. func Ignore() Option { return ignore{} } type ignore struct{ core } @@ -234,6 +234,8 @@ func (validator) apply(s *state, vx, vy reflect.Value) { name = fmt.Sprintf("%q.%v", t.PkgPath(), t.Name()) // e.g., "path/to/package".MyType if _, ok := reflect.New(t).Interface().(error); ok { help = "consider using cmpopts.EquateErrors to compare error values" + } else if t.Comparable() { + help = "consider using cmpopts.EquateComparable to compare comparable Go types" } } else { // Unnamed type with unexported fields. Derive PkgPath from field. @@ -254,7 +256,7 @@ const identRx = `[_\p{L}][_\p{L}\p{N}]*` var identsRx = regexp.MustCompile(`^` + identRx + `(\.` + identRx + `)*$`) -// Transformer returns an Option that applies a transformation function that +// Transformer returns an [Option] that applies a transformation function that // converts values of a certain type into that of another. // // The transformer f must be a function "func(T) R" that converts values of @@ -265,13 +267,14 @@ var identsRx = regexp.MustCompile(`^` + identRx + `(\.` + identRx + `)*$`) // same transform to the output of itself (e.g., in the case where the // input and output types are the same), an implicit filter is added such that // a transformer is applicable only if that exact transformer is not already -// in the tail of the Path since the last non-Transform step. +// in the tail of the [Path] since the last non-[Transform] step. // For situations where the implicit filter is still insufficient, -// consider using cmpopts.AcyclicTransformer, which adds a filter -// to prevent the transformer from being recursively applied upon itself. +// consider using [github.com/google/go-cmp/cmp/cmpopts.AcyclicTransformer], +// which adds a filter to prevent the transformer from +// being recursively applied upon itself. // -// The name is a user provided label that is used as the Transform.Name in the -// transformation PathStep (and eventually shown in the Diff output). +// The name is a user provided label that is used as the [Transform.Name] in the +// transformation [PathStep] (and eventually shown in the [Diff] output). // The name must be a valid identifier or qualified identifier in Go syntax. // If empty, an arbitrary name is used. func Transformer(name string, f interface{}) Option { @@ -329,7 +332,7 @@ func (tr transformer) String() string { return fmt.Sprintf("Transformer(%s, %s)", tr.name, function.NameOf(tr.fnc)) } -// Comparer returns an Option that determines whether two values are equal +// Comparer returns an [Option] that determines whether two values are equal // to each other. // // The comparer f must be a function "func(T, T) bool" and is implicitly @@ -377,35 +380,32 @@ func (cm comparer) String() string { return fmt.Sprintf("Comparer(%s)", function.NameOf(cm.fnc)) } -// Exporter returns an Option that specifies whether Equal is allowed to +// Exporter returns an [Option] that specifies whether [Equal] is allowed to // introspect into the unexported fields of certain struct types. // // Users of this option must understand that comparing on unexported fields // from external packages is not safe since changes in the internal -// implementation of some external package may cause the result of Equal +// implementation of some external package may cause the result of [Equal] // to unexpectedly change. However, it may be valid to use this option on types // defined in an internal package where the semantic meaning of an unexported // field is in the control of the user. // -// In many cases, a custom Comparer should be used instead that defines +// In many cases, a custom [Comparer] should be used instead that defines // equality as a function of the public API of a type rather than the underlying // unexported implementation. // -// For example, the reflect.Type documentation defines equality to be determined +// For example, the [reflect.Type] documentation defines equality to be determined // by the == operator on the interface (essentially performing a shallow pointer -// comparison) and most attempts to compare *regexp.Regexp types are interested +// comparison) and most attempts to compare *[regexp.Regexp] types are interested // in only checking that the regular expression strings are equal. -// Both of these are accomplished using Comparers: +// Both of these are accomplished using [Comparer] options: // // Comparer(func(x, y reflect.Type) bool { return x == y }) // Comparer(func(x, y *regexp.Regexp) bool { return x.String() == y.String() }) // -// In other cases, the cmpopts.IgnoreUnexported option can be used to ignore -// all unexported fields on specified struct types. +// In other cases, the [github.com/google/go-cmp/cmp/cmpopts.IgnoreUnexported] +// option can be used to ignore all unexported fields on specified struct types. func Exporter(f func(reflect.Type) bool) Option { - if !supportExporters { - panic("Exporter is not supported on purego builds") - } return exporter(f) } @@ -415,10 +415,10 @@ func (exporter) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableO panic("not implemented") } -// AllowUnexported returns an Options that allows Equal to forcibly introspect +// AllowUnexported returns an [Option] that allows [Equal] to forcibly introspect // unexported fields of the specified struct types. // -// See Exporter for the proper use of this option. +// See [Exporter] for the proper use of this option. func AllowUnexported(types ...interface{}) Option { m := make(map[reflect.Type]bool) for _, typ := range types { @@ -432,7 +432,7 @@ func AllowUnexported(types ...interface{}) Option { } // Result represents the comparison result for a single node and -// is provided by cmp when calling Report (see Reporter). +// is provided by cmp when calling Report (see [Reporter]). type Result struct { _ [0]func() // Make Result incomparable flags resultFlags @@ -445,7 +445,7 @@ func (r Result) Equal() bool { } // ByIgnore reports whether the node is equal because it was ignored. -// This never reports true if Equal reports false. +// This never reports true if [Result.Equal] reports false. func (r Result) ByIgnore() bool { return r.flags&reportByIgnore != 0 } @@ -455,7 +455,7 @@ func (r Result) ByMethod() bool { return r.flags&reportByMethod != 0 } -// ByFunc reports whether a Comparer function determined equality. +// ByFunc reports whether a [Comparer] function determined equality. func (r Result) ByFunc() bool { return r.flags&reportByFunc != 0 } @@ -478,7 +478,7 @@ const ( reportByCycle ) -// Reporter is an Option that can be passed to Equal. When Equal traverses +// Reporter is an [Option] that can be passed to [Equal]. When [Equal] traverses // the value trees, it calls PushStep as it descends into each node in the // tree and PopStep as it ascend out of the node. The leaves of the tree are // either compared (determined to be equal or not equal) or ignored and reported diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go index a0a58850..c3c14564 100644 --- a/vendor/github.com/google/go-cmp/cmp/path.go +++ b/vendor/github.com/google/go-cmp/cmp/path.go @@ -14,9 +14,9 @@ import ( "github.com/google/go-cmp/cmp/internal/value" ) -// Path is a list of PathSteps describing the sequence of operations to get +// Path is a list of [PathStep] describing the sequence of operations to get // from some root type to the current position in the value tree. -// The first Path element is always an operation-less PathStep that exists +// The first Path element is always an operation-less [PathStep] that exists // simply to identify the initial type. // // When traversing structs with embedded structs, the embedded struct will @@ -29,8 +29,13 @@ type Path []PathStep // a value's tree structure. Users of this package never need to implement // these types as values of this type will be returned by this package. // -// Implementations of this interface are -// StructField, SliceIndex, MapIndex, Indirect, TypeAssertion, and Transform. +// Implementations of this interface: +// - [StructField] +// - [SliceIndex] +// - [MapIndex] +// - [Indirect] +// - [TypeAssertion] +// - [Transform] type PathStep interface { String() string @@ -70,8 +75,9 @@ func (pa *Path) pop() { *pa = (*pa)[:len(*pa)-1] } -// Last returns the last PathStep in the Path. -// If the path is empty, this returns a non-nil PathStep that reports a nil Type. +// Last returns the last [PathStep] in the Path. +// If the path is empty, this returns a non-nil [PathStep] +// that reports a nil [PathStep.Type]. func (pa Path) Last() PathStep { return pa.Index(-1) } @@ -79,7 +85,8 @@ func (pa Path) Last() PathStep { // Index returns the ith step in the Path and supports negative indexing. // A negative index starts counting from the tail of the Path such that -1 // refers to the last step, -2 refers to the second-to-last step, and so on. -// If index is invalid, this returns a non-nil PathStep that reports a nil Type. +// If index is invalid, this returns a non-nil [PathStep] +// that reports a nil [PathStep.Type]. func (pa Path) Index(i int) PathStep { if i < 0 { i = len(pa) + i @@ -168,7 +175,8 @@ func (ps pathStep) String() string { return fmt.Sprintf("{%s}", s) } -// StructField represents a struct field access on a field called Name. +// StructField is a [PathStep] that represents a struct field access +// on a field called [StructField.Name]. type StructField struct{ *structField } type structField struct { pathStep @@ -204,10 +212,11 @@ func (sf StructField) String() string { return fmt.Sprintf(".%s", sf.name) } func (sf StructField) Name() string { return sf.name } // Index is the index of the field in the parent struct type. -// See reflect.Type.Field. +// See [reflect.Type.Field]. func (sf StructField) Index() int { return sf.idx } -// SliceIndex is an index operation on a slice or array at some index Key. +// SliceIndex is a [PathStep] that represents an index operation on +// a slice or array at some index [SliceIndex.Key]. type SliceIndex struct{ *sliceIndex } type sliceIndex struct { pathStep @@ -247,12 +256,12 @@ func (si SliceIndex) Key() int { // all of the indexes to be shifted. If an index is -1, then that // indicates that the element does not exist in the associated slice. // -// Key is guaranteed to return -1 if and only if the indexes returned -// by SplitKeys are not the same. SplitKeys will never return -1 for +// [SliceIndex.Key] is guaranteed to return -1 if and only if the indexes +// returned by SplitKeys are not the same. SplitKeys will never return -1 for // both indexes. func (si SliceIndex) SplitKeys() (ix, iy int) { return si.xkey, si.ykey } -// MapIndex is an index operation on a map at some index Key. +// MapIndex is a [PathStep] that represents an index operation on a map at some index Key. type MapIndex struct{ *mapIndex } type mapIndex struct { pathStep @@ -266,7 +275,7 @@ func (mi MapIndex) String() string { return fmt.Sprintf("[%#v]", // Key is the value of the map key. func (mi MapIndex) Key() reflect.Value { return mi.key } -// Indirect represents pointer indirection on the parent type. +// Indirect is a [PathStep] that represents pointer indirection on the parent type. type Indirect struct{ *indirect } type indirect struct { pathStep @@ -276,7 +285,7 @@ func (in Indirect) Type() reflect.Type { return in.typ } func (in Indirect) Values() (vx, vy reflect.Value) { return in.vx, in.vy } func (in Indirect) String() string { return "*" } -// TypeAssertion represents a type assertion on an interface. +// TypeAssertion is a [PathStep] that represents a type assertion on an interface. type TypeAssertion struct{ *typeAssertion } type typeAssertion struct { pathStep @@ -286,7 +295,8 @@ func (ta TypeAssertion) Type() reflect.Type { return ta.typ } func (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy } func (ta TypeAssertion) String() string { return fmt.Sprintf(".(%v)", value.TypeString(ta.typ, false)) } -// Transform is a transformation from the parent type to the current type. +// Transform is a [PathStep] that represents a transformation +// from the parent type to the current type. type Transform struct{ *transform } type transform struct { pathStep @@ -297,13 +307,13 @@ func (tf Transform) Type() reflect.Type { return tf.typ } func (tf Transform) Values() (vx, vy reflect.Value) { return tf.vx, tf.vy } func (tf Transform) String() string { return fmt.Sprintf("%s()", tf.trans.name) } -// Name is the name of the Transformer. +// Name is the name of the [Transformer]. func (tf Transform) Name() string { return tf.trans.name } // Func is the function pointer to the transformer function. func (tf Transform) Func() reflect.Value { return tf.trans.fnc } -// Option returns the originally constructed Transformer option. +// Option returns the originally constructed [Transformer] option. // The == operator can be used to detect the exact option used. func (tf Transform) Option() Option { return tf.trans } diff --git a/vendor/github.com/google/go-cmp/cmp/report_reflect.go b/vendor/github.com/google/go-cmp/cmp/report_reflect.go index 2ab41fad..e39f4228 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_reflect.go +++ b/vendor/github.com/google/go-cmp/cmp/report_reflect.go @@ -199,7 +199,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, break } sf := t.Field(i) - if supportExporters && !isExported(sf.Name) { + if !isExported(sf.Name) { vv = retrieveUnexportedField(v, sf, true) } s := opts.WithTypeMode(autoType).FormatValue(vv, t.Kind(), ptrs) diff --git a/vendor/github.com/google/uuid/.travis.yml b/vendor/github.com/google/uuid/.travis.yml deleted file mode 100644 index d8156a60..00000000 --- a/vendor/github.com/google/uuid/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - 1.4.3 - - 1.5.3 - - tip - -script: - - go test -v ./... diff --git a/vendor/github.com/google/uuid/CHANGELOG.md b/vendor/github.com/google/uuid/CHANGELOG.md new file mode 100644 index 00000000..7ec5ac7e --- /dev/null +++ b/vendor/github.com/google/uuid/CHANGELOG.md @@ -0,0 +1,41 @@ +# Changelog + +## [1.6.0](https://github.com/google/uuid/compare/v1.5.0...v1.6.0) (2024-01-16) + + +### Features + +* add Max UUID constant ([#149](https://github.com/google/uuid/issues/149)) ([c58770e](https://github.com/google/uuid/commit/c58770eb495f55fe2ced6284f93c5158a62e53e3)) + + +### Bug Fixes + +* fix typo in version 7 uuid documentation ([#153](https://github.com/google/uuid/issues/153)) ([016b199](https://github.com/google/uuid/commit/016b199544692f745ffc8867b914129ecb47ef06)) +* Monotonicity in UUIDv7 ([#150](https://github.com/google/uuid/issues/150)) ([a2b2b32](https://github.com/google/uuid/commit/a2b2b32373ff0b1a312b7fdf6d38a977099698a6)) + +## [1.5.0](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) (2023-12-12) + + +### Features + +* Validate UUID without creating new UUID ([#141](https://github.com/google/uuid/issues/141)) ([9ee7366](https://github.com/google/uuid/commit/9ee7366e66c9ad96bab89139418a713dc584ae29)) + +## [1.4.0](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) (2023-10-26) + + +### Features + +* UUIDs slice type with Strings() convenience method ([#133](https://github.com/google/uuid/issues/133)) ([cd5fbbd](https://github.com/google/uuid/commit/cd5fbbdd02f3e3467ac18940e07e062be1f864b4)) + +### Fixes + +* Clarify that Parse's job is to parse but not necessarily validate strings. (Documents current behavior) + +## [1.3.1](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) (2023-08-18) + + +### Bug Fixes + +* Use .EqualFold() to parse urn prefixed UUIDs ([#118](https://github.com/google/uuid/issues/118)) ([574e687](https://github.com/google/uuid/commit/574e6874943741fb99d41764c705173ada5293f0)) + +## Changelog diff --git a/vendor/github.com/google/uuid/CONTRIBUTING.md b/vendor/github.com/google/uuid/CONTRIBUTING.md index 04fdf09f..a502fdc5 100644 --- a/vendor/github.com/google/uuid/CONTRIBUTING.md +++ b/vendor/github.com/google/uuid/CONTRIBUTING.md @@ -2,6 +2,22 @@ We definitely welcome patches and contribution to this project! +### Tips + +Commits must be formatted according to the [Conventional Commits Specification](https://www.conventionalcommits.org). + +Always try to include a test case! If it is not possible or not necessary, +please explain why in the pull request description. + +### Releasing + +Commits that would precipitate a SemVer change, as described in the Conventional +Commits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action) +to create a release candidate pull request. Once submitted, `release-please` +will create a release. + +For tips on how to work with `release-please`, see its documentation. + ### Legal requirements In order to protect both you and ourselves, you will need to sign the diff --git a/vendor/github.com/google/uuid/README.md b/vendor/github.com/google/uuid/README.md index f765a46f..3e9a6188 100644 --- a/vendor/github.com/google/uuid/README.md +++ b/vendor/github.com/google/uuid/README.md @@ -1,6 +1,6 @@ -# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master) +# uuid The uuid package generates and inspects UUIDs based on -[RFC 4122](http://tools.ietf.org/html/rfc4122) +[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) and DCE 1.1: Authentication and Security Services. This package is based on the github.com/pborman/uuid package (previously named @@ -9,10 +9,12 @@ a UUID is a 16 byte array rather than a byte slice. One loss due to this change is the ability to represent an invalid UUID (vs a NIL UUID). ###### Install -`go get github.com/google/uuid` +```sh +go get github.com/google/uuid +``` ###### Documentation -[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid) +[![Go Reference](https://pkg.go.dev/badge/github.com/google/uuid.svg)](https://pkg.go.dev/github.com/google/uuid) Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here: diff --git a/vendor/github.com/google/uuid/hash.go b/vendor/github.com/google/uuid/hash.go index b404f4be..dc60082d 100644 --- a/vendor/github.com/google/uuid/hash.go +++ b/vendor/github.com/google/uuid/hash.go @@ -17,6 +17,12 @@ var ( NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) Nil UUID // empty UUID, all zeros + + // The Max UUID is special form of UUID that is specified to have all 128 bits set to 1. + Max = UUID{ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + } ) // NewHash returns a new UUID derived from the hash of space concatenated with diff --git a/vendor/github.com/google/uuid/node_js.go b/vendor/github.com/google/uuid/node_js.go index 24b78edc..b2a0bc87 100644 --- a/vendor/github.com/google/uuid/node_js.go +++ b/vendor/github.com/google/uuid/node_js.go @@ -7,6 +7,6 @@ package uuid // getHardwareInterface returns nil values for the JS version of the code. -// This remvoves the "net" dependency, because it is not used in the browser. +// This removes the "net" dependency, because it is not used in the browser. // Using the "net" library inflates the size of the transpiled JS code by 673k bytes. func getHardwareInterface(name string) (string, []byte) { return "", nil } diff --git a/vendor/github.com/google/uuid/time.go b/vendor/github.com/google/uuid/time.go index e6ef06cd..c3511292 100644 --- a/vendor/github.com/google/uuid/time.go +++ b/vendor/github.com/google/uuid/time.go @@ -108,12 +108,23 @@ func setClockSequence(seq int) { } // Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in -// uuid. The time is only defined for version 1 and 2 UUIDs. +// uuid. The time is only defined for version 1, 2, 6 and 7 UUIDs. func (uuid UUID) Time() Time { - time := int64(binary.BigEndian.Uint32(uuid[0:4])) - time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 - time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 - return Time(time) + var t Time + switch uuid.Version() { + case 6: + time := binary.BigEndian.Uint64(uuid[:8]) // Ignore uuid[6] version b0110 + t = Time(time) + case 7: + time := binary.BigEndian.Uint64(uuid[:8]) + t = Time((time>>16)*10000 + g1582ns100) + default: // forward compatible + time := int64(binary.BigEndian.Uint32(uuid[0:4])) + time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 + time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 + t = Time(time) + } + return t } // ClockSequence returns the clock sequence encoded in uuid. diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index a57207ae..5232b486 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -56,11 +56,15 @@ func IsInvalidLengthError(err error) bool { return ok } -// Parse decodes s into a UUID or returns an error. Both the standard UUID -// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the -// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex -// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. +// Parse decodes s into a UUID or returns an error if it cannot be parsed. Both +// the standard UUID forms defined in RFC 4122 +// (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) are decoded. In addition, +// Parse accepts non-standard strings such as the raw hex encoding +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx and 38 byte "Microsoft style" encodings, +// e.g. {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. Only the middle 36 bytes are +// examined in the latter case. Parse should not be used to validate strings as +// it parses non-standard encodings as indicated above. func Parse(s string) (UUID, error) { var uuid UUID switch len(s) { @@ -69,7 +73,7 @@ func Parse(s string) (UUID, error) { // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx case 36 + 9: - if strings.ToLower(s[:9]) != "urn:uuid:" { + if !strings.EqualFold(s[:9], "urn:uuid:") { return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) } s = s[9:] @@ -101,7 +105,8 @@ func Parse(s string) (UUID, error) { 9, 11, 14, 16, 19, 21, - 24, 26, 28, 30, 32, 34} { + 24, 26, 28, 30, 32, 34, + } { v, ok := xtob(s[x], s[x+1]) if !ok { return uuid, errors.New("invalid UUID format") @@ -117,7 +122,7 @@ func ParseBytes(b []byte) (UUID, error) { switch len(b) { case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) { + if !bytes.EqualFold(b[:9], []byte("urn:uuid:")) { return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) } b = b[9:] @@ -145,7 +150,8 @@ func ParseBytes(b []byte) (UUID, error) { 9, 11, 14, 16, 19, 21, - 24, 26, 28, 30, 32, 34} { + 24, 26, 28, 30, 32, 34, + } { v, ok := xtob(b[x], b[x+1]) if !ok { return uuid, errors.New("invalid UUID format") @@ -180,6 +186,59 @@ func Must(uuid UUID, err error) UUID { return uuid } +// Validate returns an error if s is not a properly formatted UUID in one of the following formats: +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} +// It returns an error if the format is invalid, otherwise nil. +func Validate(s string) error { + switch len(s) { + // Standard UUID format + case 36: + + // UUID with "urn:uuid:" prefix + case 36 + 9: + if !strings.EqualFold(s[:9], "urn:uuid:") { + return fmt.Errorf("invalid urn prefix: %q", s[:9]) + } + s = s[9:] + + // UUID enclosed in braces + case 36 + 2: + if s[0] != '{' || s[len(s)-1] != '}' { + return fmt.Errorf("invalid bracketed UUID format") + } + s = s[1 : len(s)-1] + + // UUID without hyphens + case 32: + for i := 0; i < len(s); i += 2 { + _, ok := xtob(s[i], s[i+1]) + if !ok { + return errors.New("invalid UUID format") + } + } + + default: + return invalidLengthError{len(s)} + } + + // Check for standard UUID format + if len(s) == 36 { + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return errors.New("invalid UUID format") + } + for _, x := range []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} { + if _, ok := xtob(s[x], s[x+1]); !ok { + return errors.New("invalid UUID format") + } + } + } + + return nil +} + // String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx // , or "" if uuid is invalid. func (uuid UUID) String() string { @@ -292,3 +351,15 @@ func DisableRandPool() { poolMu.Lock() poolPos = randPoolSize } + +// UUIDs is a slice of UUID types. +type UUIDs []UUID + +// Strings returns a string slice containing the string form of each UUID in uuids. +func (uuids UUIDs) Strings() []string { + var uuidStrs = make([]string, len(uuids)) + for i, uuid := range uuids { + uuidStrs[i] = uuid.String() + } + return uuidStrs +} diff --git a/vendor/github.com/google/uuid/version6.go b/vendor/github.com/google/uuid/version6.go new file mode 100644 index 00000000..339a959a --- /dev/null +++ b/vendor/github.com/google/uuid/version6.go @@ -0,0 +1,56 @@ +// Copyright 2023 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import "encoding/binary" + +// UUID version 6 is a field-compatible version of UUIDv1, reordered for improved DB locality. +// It is expected that UUIDv6 will primarily be used in contexts where there are existing v1 UUIDs. +// Systems that do not involve legacy UUIDv1 SHOULD consider using UUIDv7 instead. +// +// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#uuidv6 +// +// NewV6 returns a Version 6 UUID based on the current NodeID and clock +// sequence, and the current time. If the NodeID has not been set by SetNodeID +// or SetNodeInterface then it will be set automatically. If the NodeID cannot +// be set NewV6 set NodeID is random bits automatically . If clock sequence has not been set by +// SetClockSequence then it will be set automatically. If GetTime fails to +// return the current NewV6 returns Nil and an error. +func NewV6() (UUID, error) { + var uuid UUID + now, seq, err := GetTime() + if err != nil { + return uuid, err + } + + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_high | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_mid | time_low_and_version | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |clk_seq_hi_res | clk_seq_low | node (0-1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | node (2-5) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + binary.BigEndian.PutUint64(uuid[0:], uint64(now)) + binary.BigEndian.PutUint16(uuid[8:], seq) + + uuid[6] = 0x60 | (uuid[6] & 0x0F) + uuid[8] = 0x80 | (uuid[8] & 0x3F) + + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + copy(uuid[10:], nodeID[:]) + nodeMu.Unlock() + + return uuid, nil +} diff --git a/vendor/github.com/google/uuid/version7.go b/vendor/github.com/google/uuid/version7.go new file mode 100644 index 00000000..3167b643 --- /dev/null +++ b/vendor/github.com/google/uuid/version7.go @@ -0,0 +1,104 @@ +// Copyright 2023 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "io" +) + +// UUID version 7 features a time-ordered value field derived from the widely +// implemented and well known Unix Epoch timestamp source, +// the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded. +// As well as improved entropy characteristics over versions 1 or 6. +// +// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#name-uuid-version-7 +// +// Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible. +// +// NewV7 returns a Version 7 UUID based on the current time(Unix Epoch). +// Uses the randomness pool if it was enabled with EnableRandPool. +// On error, NewV7 returns Nil and an error +func NewV7() (UUID, error) { + uuid, err := NewRandom() + if err != nil { + return uuid, err + } + makeV7(uuid[:]) + return uuid, nil +} + +// NewV7FromReader returns a Version 7 UUID based on the current time(Unix Epoch). +// it use NewRandomFromReader fill random bits. +// On error, NewV7FromReader returns Nil and an error. +func NewV7FromReader(r io.Reader) (UUID, error) { + uuid, err := NewRandomFromReader(r) + if err != nil { + return uuid, err + } + + makeV7(uuid[:]) + return uuid, nil +} + +// makeV7 fill 48 bits time (uuid[0] - uuid[5]), set version b0111 (uuid[6]) +// uuid[8] already has the right version number (Variant is 10) +// see function NewV7 and NewV7FromReader +func makeV7(uuid []byte) { + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | ver | rand_a (12 bit seq) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |var| rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + _ = uuid[15] // bounds check + + t, s := getV7Time() + + uuid[0] = byte(t >> 40) + uuid[1] = byte(t >> 32) + uuid[2] = byte(t >> 24) + uuid[3] = byte(t >> 16) + uuid[4] = byte(t >> 8) + uuid[5] = byte(t) + + uuid[6] = 0x70 | (0x0F & byte(s>>8)) + uuid[7] = byte(s) +} + +// lastV7time is the last time we returned stored as: +// +// 52 bits of time in milliseconds since epoch +// 12 bits of (fractional nanoseconds) >> 8 +var lastV7time int64 + +const nanoPerMilli = 1000000 + +// getV7Time returns the time in milliseconds and nanoseconds / 256. +// The returned (milli << 12 + seq) is guarenteed to be greater than +// (milli << 12 + seq) returned by any previous call to getV7Time. +func getV7Time() (milli, seq int64) { + timeMu.Lock() + defer timeMu.Unlock() + + nano := timeNow().UnixNano() + milli = nano / nanoPerMilli + // Sequence number is between 0 and 3906 (nanoPerMilli>>8) + seq = (nano - milli*nanoPerMilli) >> 8 + now := milli<<12 + seq + if now <= lastV7time { + now = lastV7time + 1 + milli = now >> 12 + seq = now & 0xfff + } + lastV7time = now + return milli, seq +} diff --git a/vendor/github.com/hashicorp/go-hclog/README.md b/vendor/github.com/hashicorp/go-hclog/README.md index 21a17c5a..983d44c7 100644 --- a/vendor/github.com/hashicorp/go-hclog/README.md +++ b/vendor/github.com/hashicorp/go-hclog/README.md @@ -140,9 +140,10 @@ log.Printf("[DEBUG] %d", 42) ... [DEBUG] my-app: 42 ``` -Notice that if `appLogger` is initialized with the `INFO` log level _and_ you +Notice that if `appLogger` is initialized with the `INFO` log level, _and_ you specify `InferLevels: true`, you will not see any output here. You must change `appLogger` to `DEBUG` to see output. See the docs for more information. If the log lines start with a timestamp you can use the -`InferLevelsWithTimestamp` option to try and ignore them. +`InferLevelsWithTimestamp` option to try and ignore them. Please note that in order +for `InferLevelsWithTimestamp` to be relevant, `InferLevels` must be set to `true`. diff --git a/vendor/github.com/hashicorp/go-hclog/intlogger.go b/vendor/github.com/hashicorp/go-hclog/intlogger.go index b45064ac..272a710c 100644 --- a/vendor/github.com/hashicorp/go-hclog/intlogger.go +++ b/vendor/github.com/hashicorp/go-hclog/intlogger.go @@ -55,23 +55,38 @@ var ( faintBoldColor = color.New(color.Faint, color.Bold) faintColor = color.New(color.Faint) - faintMultiLinePrefix = faintColor.Sprint(" | ") - faintFieldSeparator = faintColor.Sprint("=") - faintFieldSeparatorWithNewLine = faintColor.Sprint("=\n") + faintMultiLinePrefix string + faintFieldSeparator string + faintFieldSeparatorWithNewLine string ) +func init() { + // Force all the colors to enabled because we do our own detection of color usage. + for _, c := range _levelToColor { + c.EnableColor() + } + + faintBoldColor.EnableColor() + faintColor.EnableColor() + + faintMultiLinePrefix = faintColor.Sprint(" | ") + faintFieldSeparator = faintColor.Sprint("=") + faintFieldSeparatorWithNewLine = faintColor.Sprint("=\n") +} + // Make sure that intLogger is a Logger var _ Logger = &intLogger{} // intLogger is an internal logger implementation. Internal in that it is // defined entirely by this package. type intLogger struct { - json bool - callerOffset int - name string - timeFormat string - timeFn TimeFunction - disableTime bool + json bool + jsonEscapeEnabled bool + callerOffset int + name string + timeFormat string + timeFn TimeFunction + disableTime bool // This is an interface so that it's shared by any derived loggers, since // those derived loggers share the bufio.Writer as well. @@ -79,6 +94,19 @@ type intLogger struct { writer *writer level *int32 + // The value of curEpoch when our level was set + setEpoch uint64 + + // The value of curEpoch the last time we performed the level sync process + ownEpoch uint64 + + // Shared amongst all the loggers created in this hierachy, used to determine + // if the level sync process should be run by comparing it with ownEpoch + curEpoch *uint64 + + // The logger this one was created from. Only set when syncParentLevel is set + parent *intLogger + headerColor ColorOption fieldColor ColorOption @@ -88,6 +116,7 @@ type intLogger struct { // create subloggers with their own level setting independentLevels bool + syncParentLevel bool subloggerHook func(sub Logger) Logger } @@ -129,9 +158,9 @@ func newLogger(opts *LoggerOptions) *intLogger { } var ( - primaryColor ColorOption = ColorOff - headerColor ColorOption = ColorOff - fieldColor ColorOption = ColorOff + primaryColor = ColorOff + headerColor = ColorOff + fieldColor = ColorOff ) switch { case opts.ColorHeaderOnly: @@ -145,6 +174,7 @@ func newLogger(opts *LoggerOptions) *intLogger { l := &intLogger{ json: opts.JSONFormat, + jsonEscapeEnabled: !opts.JSONEscapeDisabled, name: opts.Name, timeFormat: TimeFormat, timeFn: time.Now, @@ -152,8 +182,10 @@ func newLogger(opts *LoggerOptions) *intLogger { mutex: mutex, writer: newWriter(output, primaryColor), level: new(int32), + curEpoch: new(uint64), exclude: opts.Exclude, independentLevels: opts.IndependentLevels, + syncParentLevel: opts.SyncParentLevel, headerColor: headerColor, fieldColor: fieldColor, subloggerHook: opts.SubloggerHook, @@ -194,7 +226,7 @@ const offsetIntLogger = 3 // Log a message and a set of key/value pairs if the given level is at // or more severe that the threshold configured in the Logger. func (l *intLogger) log(name string, level Level, msg string, args ...interface{}) { - if level < Level(atomic.LoadInt32(l.level)) { + if level < l.GetLevel() { return } @@ -597,7 +629,7 @@ func (l *intLogger) logJSON(t time.Time, name string, level Level, msg string, a vals := l.jsonMapEntry(t, name, level, msg) args = append(l.implied, args...) - if args != nil && len(args) > 0 { + if len(args) > 0 { if len(args)%2 != 0 { cs, ok := args[len(args)-1].(CapturedStacktrace) if ok { @@ -637,13 +669,17 @@ func (l *intLogger) logJSON(t time.Time, name string, level Level, msg string, a } } - err := json.NewEncoder(l.writer).Encode(vals) + encoder := json.NewEncoder(l.writer) + encoder.SetEscapeHTML(l.jsonEscapeEnabled) + err := encoder.Encode(vals) if err != nil { if _, ok := err.(*json.UnsupportedTypeError); ok { plainVal := l.jsonMapEntry(t, name, level, msg) plainVal["@warn"] = errJsonUnsupportedTypeMsg - json.NewEncoder(l.writer).Encode(plainVal) + errEncoder := json.NewEncoder(l.writer) + errEncoder.SetEscapeHTML(l.jsonEscapeEnabled) + errEncoder.Encode(plainVal) } } } @@ -718,27 +754,27 @@ func (l *intLogger) Error(msg string, args ...interface{}) { // Indicate that the logger would emit TRACE level logs func (l *intLogger) IsTrace() bool { - return Level(atomic.LoadInt32(l.level)) == Trace + return l.GetLevel() == Trace } // Indicate that the logger would emit DEBUG level logs func (l *intLogger) IsDebug() bool { - return Level(atomic.LoadInt32(l.level)) <= Debug + return l.GetLevel() <= Debug } // Indicate that the logger would emit INFO level logs func (l *intLogger) IsInfo() bool { - return Level(atomic.LoadInt32(l.level)) <= Info + return l.GetLevel() <= Info } // Indicate that the logger would emit WARN level logs func (l *intLogger) IsWarn() bool { - return Level(atomic.LoadInt32(l.level)) <= Warn + return l.GetLevel() <= Warn } // Indicate that the logger would emit ERROR level logs func (l *intLogger) IsError() bool { - return Level(atomic.LoadInt32(l.level)) <= Error + return l.GetLevel() <= Error } const MissingKey = "EXTRA_VALUE_AT_END" @@ -854,12 +890,63 @@ func (l *intLogger) resetOutput(opts *LoggerOptions) error { // Update the logging level on-the-fly. This will affect all subloggers as // well. func (l *intLogger) SetLevel(level Level) { - atomic.StoreInt32(l.level, int32(level)) + if !l.syncParentLevel { + atomic.StoreInt32(l.level, int32(level)) + return + } + + nsl := new(int32) + *nsl = int32(level) + + l.level = nsl + + l.ownEpoch = atomic.AddUint64(l.curEpoch, 1) + l.setEpoch = l.ownEpoch +} + +func (l *intLogger) searchLevelPtr() *int32 { + p := l.parent + + ptr := l.level + + max := l.setEpoch + + for p != nil { + if p.setEpoch > max { + max = p.setEpoch + ptr = p.level + } + + p = p.parent + } + + return ptr } // Returns the current level func (l *intLogger) GetLevel() Level { - return Level(atomic.LoadInt32(l.level)) + // We perform the loads immediately to keep the CPU pipeline busy, which + // effectively makes the second load cost nothing. Once loaded into registers + // the comparison returns the already loaded value. The comparison is almost + // always true, so the branch predictor should hit consistently with it. + var ( + curEpoch = atomic.LoadUint64(l.curEpoch) + level = Level(atomic.LoadInt32(l.level)) + own = l.ownEpoch + ) + + if curEpoch == own { + return level + } + + // Perform the level sync process. We'll avoid doing this next time by seeing the + // epoch as current. + + ptr := l.searchLevelPtr() + l.level = ptr + l.ownEpoch = curEpoch + + return Level(atomic.LoadInt32(ptr)) } // Create a *log.Logger that will send it's data through this Logger. This @@ -912,6 +999,8 @@ func (l *intLogger) copy() *intLogger { if l.independentLevels { sl.level = new(int32) *sl.level = *l.level + } else if l.syncParentLevel { + sl.parent = l } return &sl diff --git a/vendor/github.com/hashicorp/go-hclog/logger.go b/vendor/github.com/hashicorp/go-hclog/logger.go index 947ac0c9..ad17544f 100644 --- a/vendor/github.com/hashicorp/go-hclog/logger.go +++ b/vendor/github.com/hashicorp/go-hclog/logger.go @@ -233,6 +233,7 @@ type StandardLoggerOptions struct { // [DEBUG] and strip it off before reapplying it. // The timestamp detection may result in false positives and incomplete // string outputs. + // InferLevelsWithTimestamp is only relevant if InferLevels is true. InferLevelsWithTimestamp bool // ForceLevel is used to force all output from the standard logger to be at @@ -263,6 +264,9 @@ type LoggerOptions struct { // Control if the output should be in JSON. JSONFormat bool + // Control the escape switch of json.Encoder + JSONEscapeDisabled bool + // Include file and line information in each log line IncludeLocation bool @@ -303,6 +307,24 @@ type LoggerOptions struct { // will not affect the parent or sibling loggers. IndependentLevels bool + // When set, changing the level of a logger effects only it's direct sub-loggers + // rather than all sub-loggers. For example: + // a := logger.Named("a") + // a.SetLevel(Error) + // b := a.Named("b") + // c := a.Named("c") + // b.GetLevel() => Error + // c.GetLevel() => Error + // b.SetLevel(Info) + // a.GetLevel() => Error + // b.GetLevel() => Info + // c.GetLevel() => Error + // a.SetLevel(Warn) + // a.GetLevel() => Warn + // b.GetLevel() => Warn + // c.GetLevel() => Warn + SyncParentLevel bool + // SubloggerHook registers a function that is called when a sublogger via // Named, With, or ResetNamed is created. If defined, the function is passed // the newly created Logger and the returned Logger is returned from the diff --git a/vendor/github.com/hashicorp/go-plugin/CHANGELOG.md b/vendor/github.com/hashicorp/go-plugin/CHANGELOG.md index dbb20c96..3d0379c5 100644 --- a/vendor/github.com/hashicorp/go-plugin/CHANGELOG.md +++ b/vendor/github.com/hashicorp/go-plugin/CHANGELOG.md @@ -1,12 +1,63 @@ +## v1.6.0 + +CHANGES: + +* plugin: Plugins written in other languages can optionally start to advertise whether they support gRPC broker multiplexing. + If the environment variable `PLUGIN_MULTIPLEX_GRPC` is set, it is safe to include a seventh field containing a boolean + value in the `|`-separated protocol negotiation line. + +ENHANCEMENTS: + +* Support muxing gRPC broker connections over a single listener [[GH-288](https://github.com/hashicorp/go-plugin/pull/288)] +* client: Configurable buffer size for reading plugin log lines [[GH-265](https://github.com/hashicorp/go-plugin/pull/265)] +* Use `buf` for proto generation [[GH-286](https://github.com/hashicorp/go-plugin/pull/286)] +* deps: bump golang.org/x/net to v0.17.0 [[GH-285](https://github.com/hashicorp/go-plugin/pull/285)] +* deps: bump golang.org/x/sys to v0.13.0 [[GH-285](https://github.com/hashicorp/go-plugin/pull/285)] +* deps: bump golang.org/x/text to v0.13.0 [[GH-285](https://github.com/hashicorp/go-plugin/pull/285)] + +## v1.5.2 + +ENHANCEMENTS: + +client: New `UnixSocketConfig.TempDir` option allows setting the directory to use when creating plugin-specific Unix socket directories [[GH-282](https://github.com/hashicorp/go-plugin/pull/282)] + +## v1.5.1 + +BUGS: + +* server: `PLUGIN_UNIX_SOCKET_DIR` is consistently used for gRPC broker sockets as well as the initial socket [[GH-277](https://github.com/hashicorp/go-plugin/pull/277)] + +ENHANCEMENTS: + +* client: New `UnixSocketConfig` option in `ClientConfig` to support making the client's Unix sockets group-writable [[GH-277](https://github.com/hashicorp/go-plugin/pull/277)] + +## v1.5.0 + +ENHANCEMENTS: + +* client: New `runner.Runner` interface to support clients providing custom plugin command runner implementations [[GH-270](https://github.com/hashicorp/go-plugin/pull/270)] + * Accessible via new `ClientConfig` field `RunnerFunc`, which is mutually exclusive with `Cmd` and `Reattach` + * Reattaching support via `ReattachConfig` field `ReattachFunc` +* client: New `ClientConfig` field `SkipHostEnv` allows omitting the client process' own environment variables from the plugin command's environment [[GH-270](https://github.com/hashicorp/go-plugin/pull/270)] +* client: Add `ID()` method to `Client` for retrieving the pid or other unique ID of a running plugin [[GH-272](https://github.com/hashicorp/go-plugin/pull/272)] +* server: Support setting the directory to create Unix sockets in with the env var `PLUGIN_UNIX_SOCKET_DIR` [[GH-270](https://github.com/hashicorp/go-plugin/pull/270)] +* server: Support setting group write permission and a custom group name or gid owner with the env var `PLUGIN_UNIX_SOCKET_GROUP` [[GH-270](https://github.com/hashicorp/go-plugin/pull/270)] + +## v1.4.11-rc1 + +ENHANCEMENTS: + +* deps: bump protoreflect to v1.15.1 [[GH-264](https://github.com/hashicorp/go-plugin/pull/264)] + ## v1.4.10 BUG FIXES: -* additional notes: ensure to close files [GH-241](https://github.com/hashicorp/go-plugin/pull/241)] +* additional notes: ensure to close files [[GH-241](https://github.com/hashicorp/go-plugin/pull/241)] ENHANCEMENTS: -* deps: Remove direct dependency on golang.org/x/net [GH-240](https://github.com/hashicorp/go-plugin/pull/240)] +* deps: Remove direct dependency on golang.org/x/net [[GH-240](https://github.com/hashicorp/go-plugin/pull/240)] ## v1.4.9 diff --git a/vendor/github.com/hashicorp/go-plugin/buf.gen.yaml b/vendor/github.com/hashicorp/go-plugin/buf.gen.yaml new file mode 100644 index 00000000..033d0153 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/buf.gen.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +version: v1 +plugins: + - plugin: buf.build/protocolbuffers/go + out: . + opt: + - paths=source_relative + - plugin: buf.build/grpc/go:v1.3.0 + out: . + opt: + - paths=source_relative + - require_unimplemented_servers=false diff --git a/vendor/github.com/hashicorp/go-plugin/buf.yaml b/vendor/github.com/hashicorp/go-plugin/buf.yaml new file mode 100644 index 00000000..3d0da4c7 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/buf.yaml @@ -0,0 +1,7 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +version: v1 +build: + excludes: + - examples/ \ No newline at end of file diff --git a/vendor/github.com/hashicorp/go-plugin/client.go b/vendor/github.com/hashicorp/go-plugin/client.go index a6a9ffa2..73f6b351 100644 --- a/vendor/github.com/hashicorp/go-plugin/client.go +++ b/vendor/github.com/hashicorp/go-plugin/client.go @@ -26,17 +26,12 @@ import ( "time" "github.com/hashicorp/go-hclog" + "github.com/hashicorp/go-plugin/internal/cmdrunner" + "github.com/hashicorp/go-plugin/internal/grpcmux" + "github.com/hashicorp/go-plugin/runner" "google.golang.org/grpc" ) -const unrecognizedRemotePluginMessage = `Unrecognized remote plugin message: %s -This usually means - the plugin was not compiled for this architecture, - the plugin is missing dynamic-link libraries necessary to run, - the plugin is not executable by this process due to file permissions, or - the plugin failed to negotiate the initial go-plugin protocol handshake -%s` - // If this is 1, then we've called CleanupClients. This can be used // by plugin RPC implementations to change error behavior since you // can expected network connection errors at this point. This should be @@ -52,7 +47,7 @@ var managedClientsLock sync.Mutex var ( // ErrProcessNotFound is returned when a client is instantiated to // reattach to an existing process and it isn't found. - ErrProcessNotFound = errors.New("Reattachment process not found") + ErrProcessNotFound = cmdrunner.ErrProcessNotFound // ErrChecksumsDoNotMatch is returned when binary's checksum doesn't match // the one provided in the SecureConfig. @@ -69,8 +64,18 @@ var ( // ErrSecureConfigAndReattach is returned when both Reattach and // SecureConfig are set. ErrSecureConfigAndReattach = errors.New("only one of Reattach or SecureConfig can be set") + + // ErrGRPCBrokerMuxNotSupported is returned when the client requests + // multiplexing over the gRPC broker, but the plugin does not support the + // feature. In most cases, this should be resolvable by updating and + // rebuilding the plugin, or restarting the plugin with + // ClientConfig.GRPCBrokerMultiplex set to false. + ErrGRPCBrokerMuxNotSupported = errors.New("client requested gRPC broker multiplexing but plugin does not support the feature") ) +// defaultPluginLogBufferSize is the default size of the buffer used to read from stderr for plugin log lines. +const defaultPluginLogBufferSize = 64 * 1024 + // Client handles the lifecycle of a plugin application. It launches // plugins, connects to them, dispenses interface implementations, and handles // killing the process. @@ -87,7 +92,7 @@ type Client struct { exited bool l sync.Mutex address net.Addr - process *os.Process + runner runner.AttachedRunner client ClientProtocol protocol Protocol logger hclog.Logger @@ -106,6 +111,11 @@ type Client struct { // processKilled is used for testing only, to flag when the process was // forcefully killed. processKilled bool + + unixSocketCfg UnixSocketConfig + + grpcMuxerOnce sync.Once + grpcMuxer *grpcmux.GRPCClientMuxer } // NegotiatedVersion returns the protocol version negotiated with the server. @@ -114,6 +124,19 @@ func (c *Client) NegotiatedVersion() int { return c.negotiatedVersion } +// ID returns a unique ID for the running plugin. By default this is the process +// ID (pid), but it could take other forms if RunnerFunc was provided. +func (c *Client) ID() string { + c.l.Lock() + defer c.l.Unlock() + + if c.runner != nil { + return c.runner.ID() + } + + return "" +} + // ClientConfig is the configuration used to initialize a new // plugin client. After being used to initialize a plugin client, // that configuration must not be modified again. @@ -141,6 +164,13 @@ type ClientConfig struct { Cmd *exec.Cmd Reattach *ReattachConfig + // RunnerFunc allows consumers to provide their own implementation of + // runner.Runner and control the context within which a plugin is executed. + // The cmd argument will have been copied from the config and populated with + // environment variables that a go-plugin server expects to read such as + // AutoMTLS certs and the magic cookie key. + RunnerFunc func(l hclog.Logger, cmd *exec.Cmd, tmpDir string) (runner.Runner, error) + // SecureConfig is configuration for verifying the integrity of the // executable. It can not be used with Reattach. SecureConfig *SecureConfig @@ -193,6 +223,10 @@ type ClientConfig struct { // it will default to hclog's default logger. Logger hclog.Logger + // PluginLogBufferSize is the buffer size(bytes) to read from stderr for plugin log lines. + // If this is 0, then the default of 64KB is used. + PluginLogBufferSize int + // AutoMTLS has the client and server automatically negotiate mTLS for // transport authentication. This ensures that only the original client will // be allowed to connect to the server, and all other connections will be @@ -220,6 +254,44 @@ type ClientConfig struct { // to create gRPC connections. This only affects plugins using the gRPC // protocol. GRPCDialOptions []grpc.DialOption + + // GRPCBrokerMultiplex turns on multiplexing for the gRPC broker. The gRPC + // broker will multiplex all brokered gRPC servers over the plugin's original + // listener socket instead of making a new listener for each server. The + // go-plugin library currently only includes a Go implementation for the + // server (i.e. plugin) side of gRPC broker multiplexing. + // + // Does not support reattaching. + // + // Multiplexed gRPC streams MUST be established sequentially, i.e. after + // calling AcceptAndServe from one side, wait for the other side to Dial + // before calling AcceptAndServe again. + GRPCBrokerMultiplex bool + + // SkipHostEnv allows plugins to run without inheriting the parent process' + // environment variables. + SkipHostEnv bool + + // UnixSocketConfig configures additional options for any Unix sockets + // that are created. Not normally required. Not supported on Windows. + UnixSocketConfig *UnixSocketConfig +} + +type UnixSocketConfig struct { + // If set, go-plugin will change the owner of any Unix sockets created to + // this group, and set them as group-writable. Can be a name or gid. The + // client process must be a member of this group or chown will fail. + Group string + + // TempDir specifies the base directory to use when creating a plugin-specific + // temporary directory. It is expected to already exist and be writable. If + // not set, defaults to the directory chosen by os.MkdirTemp. + TempDir string + + // The directory to create Unix sockets in. Internally created and managed + // by go-plugin and deleted when the plugin is killed. Will be created + // inside TempDir if specified. + socketDir string } // ReattachConfig is used to configure a client to reattach to an @@ -231,6 +303,11 @@ type ReattachConfig struct { Addr net.Addr Pid int + // ReattachFunc allows consumers to provide their own implementation of + // runner.AttachedRunner and attach to something other than a plain process. + // At least one of Pid or ReattachFunc must be set. + ReattachFunc runner.ReattachFunc + // Test is set to true if this is reattaching to to a plugin in "test mode" // (see ServeConfig.Test). In this mode, client.Kill will NOT kill the // process and instead will rely on the plugin to terminate itself. This @@ -306,11 +383,11 @@ func CleanupClients() { wg.Wait() } -// Creates a new plugin client which manages the lifecycle of an external +// NewClient creates a new plugin client which manages the lifecycle of an external // plugin and gets the address for the RPC connection. // // The client must be cleaned up at some point by calling Kill(). If -// the client is a managed client (created with NewManagedClient) you +// the client is a managed client (created with ClientConfig.Managed) you // can just call CleanupClients at the end of your program and they will // be properly cleaned. func NewClient(config *ClientConfig) (c *Client) { @@ -328,10 +405,10 @@ func NewClient(config *ClientConfig) (c *Client) { } if config.SyncStdout == nil { - config.SyncStdout = ioutil.Discard + config.SyncStdout = io.Discard } if config.SyncStderr == nil { - config.SyncStderr = ioutil.Discard + config.SyncStderr = io.Discard } if config.AllowedProtocols == nil { @@ -346,6 +423,10 @@ func NewClient(config *ClientConfig) (c *Client) { }) } + if config.PluginLogBufferSize == 0 { + config.PluginLogBufferSize = defaultPluginLogBufferSize + } + c = &Client{ config: config, logger: config.Logger, @@ -418,12 +499,13 @@ func (c *Client) killed() bool { func (c *Client) Kill() { // Grab a lock to read some private fields. c.l.Lock() - process := c.process + runner := c.runner addr := c.address + hostSocketDir := c.unixSocketCfg.socketDir c.l.Unlock() - // If there is no process, there is nothing to kill. - if process == nil { + // If there is no runner or ID, there is nothing to kill. + if runner == nil || runner.ID() == "" { return } @@ -431,10 +513,14 @@ func (c *Client) Kill() { // Wait for the all client goroutines to finish. c.clientWaitGroup.Wait() + if hostSocketDir != "" { + os.RemoveAll(hostSocketDir) + } + // Make sure there is no reference to the old process after it has been // killed. c.l.Lock() - c.process = nil + c.runner = nil c.l.Unlock() }() @@ -477,23 +563,15 @@ func (c *Client) Kill() { // If graceful exiting failed, just kill it c.logger.Warn("plugin failed to exit gracefully") - process.Kill() + if err := runner.Kill(context.Background()); err != nil { + c.logger.Debug("error killing plugin", "error", err) + } c.l.Lock() c.processKilled = true c.l.Unlock() } -// peTypes is a list of Portable Executable (PE) machine types from https://learn.microsoft.com/en-us/windows/win32/debug/pe-format -// mapped to GOARCH types. It is not comprehensive, and only includes machine types that Go supports. -var peTypes = map[uint16]string{ - 0x14c: "386", - 0x1c0: "arm", - 0x6264: "loong64", - 0x8664: "amd64", - 0xaa64: "arm64", -} - // Start the underlying subprocess, communicating with it to negotiate // a port for RPC connections, and returning the address to connect via RPC. // @@ -512,16 +590,27 @@ func (c *Client) Start() (addr net.Addr, err error) { // this in a {} for scoping reasons, and hopeful that the escape // analysis will pop the stack here. { - cmdSet := c.config.Cmd != nil - attachSet := c.config.Reattach != nil - secureSet := c.config.SecureConfig != nil - if cmdSet == attachSet { - return nil, fmt.Errorf("Only one of Cmd or Reattach must be set") + var mutuallyExclusiveOptions int + if c.config.Cmd != nil { + mutuallyExclusiveOptions += 1 + } + if c.config.Reattach != nil { + mutuallyExclusiveOptions += 1 + } + if c.config.RunnerFunc != nil { + mutuallyExclusiveOptions += 1 + } + if mutuallyExclusiveOptions != 1 { + return nil, fmt.Errorf("exactly one of Cmd, or Reattach, or RunnerFunc must be set") } - if secureSet && attachSet { + if c.config.SecureConfig != nil && c.config.Reattach != nil { return nil, ErrSecureConfigAndReattach } + + if c.config.GRPCBrokerMultiplex && c.config.Reattach != nil { + return nil, fmt.Errorf("gRPC broker multiplexing is not supported with Reattach config") + } } if c.config.Reattach != nil { @@ -553,20 +642,22 @@ func (c *Client) Start() (addr net.Addr, err error) { fmt.Sprintf("PLUGIN_MAX_PORT=%d", c.config.MaxPort), fmt.Sprintf("PLUGIN_PROTOCOL_VERSIONS=%s", strings.Join(versionStrings, ",")), } + if c.config.GRPCBrokerMultiplex { + env = append(env, fmt.Sprintf("%s=true", envMultiplexGRPC)) + } cmd := c.config.Cmd - cmd.Env = append(cmd.Env, os.Environ()...) - cmd.Env = append(cmd.Env, env...) - cmd.Stdin = os.Stdin - - cmdStdout, err := cmd.StdoutPipe() - if err != nil { - return nil, err + if cmd == nil { + // It's only possible to get here if RunnerFunc is non-nil, but we'll + // still use cmd as a spec to populate metadata for the external + // implementation to consume. + cmd = exec.Command("") } - cmdStderr, err := cmd.StderrPipe() - if err != nil { - return nil, err + if !c.config.SkipHostEnv { + cmd.Env = append(cmd.Env, os.Environ()...) } + cmd.Env = append(cmd.Env, env...) + cmd.Stdin = os.Stdin if c.config.SecureConfig != nil { if ok, err := c.config.SecureConfig.Check(cmd.Path); err != nil { @@ -601,26 +692,62 @@ func (c *Client) Start() (addr net.Addr, err error) { } } - c.logger.Debug("starting plugin", "path", cmd.Path, "args", cmd.Args) - err = cmd.Start() - if err != nil { - return + if c.config.UnixSocketConfig != nil { + c.unixSocketCfg = *c.config.UnixSocketConfig + } + + if c.unixSocketCfg.Group != "" { + cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", EnvUnixSocketGroup, c.unixSocketCfg.Group)) } - // Set the process - c.process = cmd.Process - c.logger.Debug("plugin started", "path", cmd.Path, "pid", c.process.Pid) + var runner runner.Runner + switch { + case c.config.RunnerFunc != nil: + c.unixSocketCfg.socketDir, err = os.MkdirTemp(c.unixSocketCfg.TempDir, "plugin-dir") + if err != nil { + return nil, err + } + // os.MkdirTemp creates folders with 0o700, so if we have a group + // configured we need to make it group-writable. + if c.unixSocketCfg.Group != "" { + err = setGroupWritable(c.unixSocketCfg.socketDir, c.unixSocketCfg.Group, 0o770) + if err != nil { + return nil, err + } + } + cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", EnvUnixSocketDir, c.unixSocketCfg.socketDir)) + c.logger.Trace("created temporary directory for unix sockets", "dir", c.unixSocketCfg.socketDir) + + runner, err = c.config.RunnerFunc(c.logger, cmd, c.unixSocketCfg.socketDir) + if err != nil { + return nil, err + } + default: + runner, err = cmdrunner.NewCmdRunner(c.logger, cmd) + if err != nil { + return nil, err + } + + } + + c.runner = runner + startCtx, startCtxCancel := context.WithTimeout(context.Background(), c.config.StartTimeout) + defer startCtxCancel() + err = runner.Start(startCtx) + if err != nil { + return nil, err + } // Make sure the command is properly cleaned up if there is an error defer func() { - r := recover() + rErr := recover() - if err != nil || r != nil { - cmd.Process.Kill() + if err != nil || rErr != nil { + runner.Kill(context.Background()) } - if r != nil { - panic(r) + if rErr != nil { + panic(rErr) } }() @@ -631,7 +758,7 @@ func (c *Client) Start() (addr net.Addr, err error) { c.clientWaitGroup.Add(1) c.stderrWaitGroup.Add(1) // logStderr calls Done() - go c.logStderr(cmdStderr) + go c.logStderr(runner.Name(), runner.Stderr()) c.clientWaitGroup.Add(1) go func() { @@ -640,29 +767,17 @@ func (c *Client) Start() (addr net.Addr, err error) { defer c.clientWaitGroup.Done() - // get the cmd info early, since the process information will be removed - // in Kill. - pid := c.process.Pid - path := cmd.Path - // wait to finish reading from stderr since the stderr pipe reader // will be closed by the subsequent call to cmd.Wait(). c.stderrWaitGroup.Wait() // Wait for the command to end. - err := cmd.Wait() - - msgArgs := []interface{}{ - "path", path, - "pid", pid, - } + err := runner.Wait(context.Background()) if err != nil { - msgArgs = append(msgArgs, - []interface{}{"error", err.Error()}...) - c.logger.Error("plugin process exited", msgArgs...) + c.logger.Error("plugin process exited", "plugin", runner.Name(), "id", runner.ID(), "error", err.Error()) } else { // Log and make sure to flush the logs right away - c.logger.Info("plugin process exited", msgArgs...) + c.logger.Info("plugin process exited", "plugin", runner.Name(), "id", runner.ID()) } os.Stderr.Sync() @@ -681,10 +796,13 @@ func (c *Client) Start() (addr net.Addr, err error) { defer c.clientWaitGroup.Done() defer close(linesCh) - scanner := bufio.NewScanner(cmdStdout) + scanner := bufio.NewScanner(runner.Stdout()) for scanner.Scan() { linesCh <- scanner.Text() } + if scanner.Err() != nil { + c.logger.Error("error encountered while scanning stdout", "error", scanner.Err()) + } }() // Make sure after we exit we read the lines from stdout forever @@ -704,19 +822,27 @@ func (c *Client) Start() (addr net.Addr, err error) { timeout := time.After(c.config.StartTimeout) // Start looking for the address - c.logger.Debug("waiting for RPC address", "path", cmd.Path) + c.logger.Debug("waiting for RPC address", "plugin", runner.Name()) select { case <-timeout: err = errors.New("timeout while waiting for plugin to start") case <-c.doneCtx.Done(): err = errors.New("plugin exited before we could connect") - case line := <-linesCh: + case line, ok := <-linesCh: // Trim the line and split by "|" in order to get the parts of // the output. line = strings.TrimSpace(line) - parts := strings.SplitN(line, "|", 6) + parts := strings.Split(line, "|") if len(parts) < 4 { - err = fmt.Errorf(unrecognizedRemotePluginMessage, line, additionalNotesAboutCommand(cmd.Path)) + errText := fmt.Sprintf("Unrecognized remote plugin message: %s", line) + if !ok { + errText += "\n" + "Failed to read any lines from plugin's stdout" + } + additionalNotes := runner.Diagnose(context.Background()) + if additionalNotes != "" { + errText += "\n" + additionalNotes + } + err = errors.New(errText) return } @@ -751,13 +877,18 @@ func (c *Client) Start() (addr net.Addr, err error) { c.negotiatedVersion = version c.logger.Debug("using plugin", "version", version) - switch parts[2] { + network, address, err := runner.PluginToHost(parts[2], parts[3]) + if err != nil { + return addr, err + } + + switch network { case "tcp": - addr, err = net.ResolveTCPAddr("tcp", parts[3]) + addr, err = net.ResolveTCPAddr("tcp", address) case "unix": - addr, err = net.ResolveUnixAddr("unix", parts[3]) + addr, err = net.ResolveUnixAddr("unix", address) default: - err = fmt.Errorf("Unknown address type: %s", parts[3]) + err = fmt.Errorf("Unknown address type: %s", address) } // If we have a server type, then record that. We default to net/rpc @@ -789,6 +920,18 @@ func (c *Client) Start() (addr net.Addr, err error) { return nil, fmt.Errorf("error parsing server cert: %s", err) } } + + if c.config.GRPCBrokerMultiplex && c.protocol == ProtocolGRPC { + if len(parts) <= 6 { + return nil, fmt.Errorf("%w; for Go plugins, you will need to update the "+ + "github.com/hashicorp/go-plugin dependency and recompile", ErrGRPCBrokerMuxNotSupported) + } + if muxSupported, err := strconv.ParseBool(parts[6]); err != nil { + return nil, fmt.Errorf("error parsing %q as a boolean for gRPC broker multiplexing support", parts[6]) + } else if !muxSupported { + return nil, ErrGRPCBrokerMuxNotSupported + } + } } c.address = addr @@ -818,39 +961,30 @@ func (c *Client) loadServerCert(cert string) error { } func (c *Client) reattach() (net.Addr, error) { - // Verify the process still exists. If not, then it is an error - p, err := os.FindProcess(c.config.Reattach.Pid) - if err != nil { - // On Unix systems, FindProcess never returns an error. - // On Windows, for non-existent pids it returns: - // os.SyscallError - 'OpenProcess: the paremter is incorrect' - return nil, ErrProcessNotFound + reattachFunc := c.config.Reattach.ReattachFunc + // For backwards compatibility default to cmdrunner.ReattachFunc + if reattachFunc == nil { + reattachFunc = cmdrunner.ReattachFunc(c.config.Reattach.Pid, c.config.Reattach.Addr) } - // Attempt to connect to the addr since on Unix systems FindProcess - // doesn't actually return an error if it can't find the process. - conn, err := net.Dial( - c.config.Reattach.Addr.Network(), - c.config.Reattach.Addr.String()) + r, err := reattachFunc() if err != nil { - p.Kill() - return nil, ErrProcessNotFound + return nil, err } - conn.Close() // Create a context for when we kill c.doneCtx, c.ctxCancel = context.WithCancel(context.Background()) c.clientWaitGroup.Add(1) // Goroutine to mark exit status - go func(pid int) { + go func(r runner.AttachedRunner) { defer c.clientWaitGroup.Done() // ensure the context is cancelled when we're done defer c.ctxCancel() // Wait for the process to die - pidWait(pid) + r.Wait(context.Background()) // Log so we can see it c.logger.Debug("reattached plugin process exited") @@ -859,7 +993,7 @@ func (c *Client) reattach() (net.Addr, error) { c.l.Lock() defer c.l.Unlock() c.exited = true - }(p.Pid) + }(r) // Set the address and protocol c.address = c.config.Reattach.Addr @@ -871,13 +1005,12 @@ func (c *Client) reattach() (net.Addr, error) { if c.config.Reattach.Test { c.negotiatedVersion = c.config.Reattach.ProtocolVersion - } - - // If we're in test mode, we do NOT set the process. This avoids the - // process being killed (the only purpose we have for c.process), since - // in test mode the process is responsible for exiting on its own. - if !c.config.Reattach.Test { - c.process = p + } else { + // If we're in test mode, we do NOT set the runner. This avoids the + // runner being killed (the only purpose we have for setting c.runner + // when reattaching), since in test mode the process is responsible for + // exiting on its own. + c.runner = r } return c.address, nil @@ -916,6 +1049,9 @@ func (c *Client) checkProtoVersion(protoVersion string) (int, PluginSet, error) // // If this returns nil then the process hasn't been started yet. Please // call Start or Client before calling this. +// +// Clients who specified a RunnerFunc will need to populate their own +// ReattachFunc in the returned ReattachConfig before it can be used. func (c *Client) ReattachConfig() *ReattachConfig { c.l.Lock() defer c.l.Unlock() @@ -933,11 +1069,16 @@ func (c *Client) ReattachConfig() *ReattachConfig { return c.config.Reattach } - return &ReattachConfig{ + reattach := &ReattachConfig{ Protocol: c.protocol, Addr: c.address, - Pid: c.config.Cmd.Process.Pid, } + + if c.config.Cmd != nil && c.config.Cmd.Process != nil { + reattach.Pid = c.config.Cmd.Process.Pid + } + + return reattach } // Protocol returns the protocol of server on the remote end. This will @@ -973,11 +1114,24 @@ func netAddrDialer(addr net.Addr) func(string, time.Duration) (net.Conn, error) // dialer is compatible with grpc.WithDialer and creates the connection // to the plugin. func (c *Client) dialer(_ string, timeout time.Duration) (net.Conn, error) { - conn, err := netAddrDialer(c.address)("", timeout) + muxer, err := c.getGRPCMuxer(c.address) if err != nil { return nil, err } + var conn net.Conn + if muxer.Enabled() { + conn, err = muxer.Dial() + if err != nil { + return nil, err + } + } else { + conn, err = netAddrDialer(c.address)("", timeout) + if err != nil { + return nil, err + } + } + // If we have a TLS config we wrap our connection. We only do this // for net/rpc since gRPC uses its own mechanism for TLS. if c.protocol == ProtocolNetRPC && c.config.TLSConfig != nil { @@ -987,14 +1141,28 @@ func (c *Client) dialer(_ string, timeout time.Duration) (net.Conn, error) { return conn, nil } -var stdErrBufferSize = 64 * 1024 +func (c *Client) getGRPCMuxer(addr net.Addr) (*grpcmux.GRPCClientMuxer, error) { + if c.protocol != ProtocolGRPC || !c.config.GRPCBrokerMultiplex { + return nil, nil + } + + var err error + c.grpcMuxerOnce.Do(func() { + c.grpcMuxer, err = grpcmux.NewGRPCClientMuxer(c.logger, addr) + }) + if err != nil { + return nil, err + } + + return c.grpcMuxer, nil +} -func (c *Client) logStderr(r io.Reader) { +func (c *Client) logStderr(name string, r io.Reader) { defer c.clientWaitGroup.Done() defer c.stderrWaitGroup.Done() - l := c.logger.Named(filepath.Base(c.config.Cmd.Path)) + l := c.logger.Named(filepath.Base(name)) - reader := bufio.NewReaderSize(r, stdErrBufferSize) + reader := bufio.NewReaderSize(r, c.config.PluginLogBufferSize) // continuation indicates the previous line was a prefix continuation := false diff --git a/vendor/github.com/hashicorp/go-plugin/constants.go b/vendor/github.com/hashicorp/go-plugin/constants.go new file mode 100644 index 00000000..e7f5bbe5 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/constants.go @@ -0,0 +1,16 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugin + +const ( + // EnvUnixSocketDir specifies the directory that _plugins_ should create unix + // sockets in. Does not affect client behavior. + EnvUnixSocketDir = "PLUGIN_UNIX_SOCKET_DIR" + + // EnvUnixSocketGroup specifies the owning, writable group to set for Unix + // sockets created by _plugins_. Does not affect client behavior. + EnvUnixSocketGroup = "PLUGIN_UNIX_SOCKET_GROUP" + + envMultiplexGRPC = "PLUGIN_MULTIPLEX_GRPC" +) diff --git a/vendor/github.com/hashicorp/go-plugin/grpc_broker.go b/vendor/github.com/hashicorp/go-plugin/grpc_broker.go index 9bf56776..5b17e37f 100644 --- a/vendor/github.com/hashicorp/go-plugin/grpc_broker.go +++ b/vendor/github.com/hashicorp/go-plugin/grpc_broker.go @@ -14,7 +14,9 @@ import ( "sync/atomic" "time" + "github.com/hashicorp/go-plugin/internal/grpcmux" "github.com/hashicorp/go-plugin/internal/plugin" + "github.com/hashicorp/go-plugin/runner" "github.com/oklog/run" "google.golang.org/grpc" @@ -39,6 +41,8 @@ type sendErr struct { // connection information to/from the plugin. Implements GRPCBrokerServer and // streamer interfaces. type gRPCBrokerServer struct { + plugin.UnimplementedGRPCBrokerServer + // send is used to send connection info to the gRPC stream. send chan *sendErr @@ -262,25 +266,41 @@ func (s *gRPCBrokerClientImpl) Close() { type GRPCBroker struct { nextId uint32 streamer streamer - streams map[uint32]*gRPCBrokerPending tls *tls.Config doneCh chan struct{} o sync.Once + clientStreams map[uint32]*gRPCBrokerPending + serverStreams map[uint32]*gRPCBrokerPending + + unixSocketCfg UnixSocketConfig + addrTranslator runner.AddrTranslator + + dialMutex sync.Mutex + + muxer grpcmux.GRPCMuxer + sync.Mutex } type gRPCBrokerPending struct { ch chan *plugin.ConnInfo doneCh chan struct{} + once sync.Once } -func newGRPCBroker(s streamer, tls *tls.Config) *GRPCBroker { +func newGRPCBroker(s streamer, tls *tls.Config, unixSocketCfg UnixSocketConfig, addrTranslator runner.AddrTranslator, muxer grpcmux.GRPCMuxer) *GRPCBroker { return &GRPCBroker{ streamer: s, - streams: make(map[uint32]*gRPCBrokerPending), tls: tls, doneCh: make(chan struct{}), + + clientStreams: make(map[uint32]*gRPCBrokerPending), + serverStreams: make(map[uint32]*gRPCBrokerPending), + muxer: muxer, + + unixSocketCfg: unixSocketCfg, + addrTranslator: addrTranslator, } } @@ -288,15 +308,59 @@ func newGRPCBroker(s streamer, tls *tls.Config) *GRPCBroker { // // This should not be called multiple times with the same ID at one time. func (b *GRPCBroker) Accept(id uint32) (net.Listener, error) { - listener, err := serverListener() + if b.muxer.Enabled() { + p := b.getServerStream(id) + go func() { + err := b.listenForKnocks(id) + if err != nil { + log.Printf("[ERR]: error listening for knocks, id: %d, error: %s", id, err) + } + }() + + ln, err := b.muxer.Listener(id, p.doneCh) + if err != nil { + return nil, err + } + + ln = &rmListener{ + Listener: ln, + close: func() error { + // We could have multiple listeners on the same ID, so use sync.Once + // for closing doneCh to ensure we don't get a panic. + p.once.Do(func() { + close(p.doneCh) + }) + + b.Lock() + defer b.Unlock() + + // No longer need to listen for knocks once the listener is closed. + delete(b.serverStreams, id) + + return nil + }, + } + + return ln, nil + } + + listener, err := serverListener(b.unixSocketCfg) if err != nil { return nil, err } + advertiseNet := listener.Addr().Network() + advertiseAddr := listener.Addr().String() + if b.addrTranslator != nil { + advertiseNet, advertiseAddr, err = b.addrTranslator.HostToPlugin(advertiseNet, advertiseAddr) + if err != nil { + return nil, err + } + } err = b.streamer.Send(&plugin.ConnInfo{ ServiceId: id, - Network: listener.Addr().Network(), - Address: listener.Addr().String(), + Network: advertiseNet, + Address: advertiseAddr, }) if err != nil { return nil, err @@ -312,20 +376,20 @@ func (b *GRPCBroker) Accept(id uint32) (net.Listener, error) { // connection is opened every call, these calls should be used sparingly. // Multiple gRPC server implementations can be registered to a single // AcceptAndServe call. -func (b *GRPCBroker) AcceptAndServe(id uint32, s func([]grpc.ServerOption) *grpc.Server) { - listener, err := b.Accept(id) +func (b *GRPCBroker) AcceptAndServe(id uint32, newGRPCServer func([]grpc.ServerOption) *grpc.Server) { + ln, err := b.Accept(id) if err != nil { log.Printf("[ERR] plugin: plugin acceptAndServe error: %s", err) return } - defer listener.Close() + defer ln.Close() var opts []grpc.ServerOption if b.tls != nil { opts = []grpc.ServerOption{grpc.Creds(credentials.NewTLS(b.tls))} } - server := s(opts) + server := newGRPCServer(opts) // Here we use a run group to close this goroutine if the server is shutdown // or the broker is shutdown. @@ -333,7 +397,7 @@ func (b *GRPCBroker) AcceptAndServe(id uint32, s func([]grpc.ServerOption) *grpc { // Serve on the listener, if shutting down call GracefulStop. g.Add(func() error { - return server.Serve(listener) + return server.Serve(ln) }, func(err error) { server.GracefulStop() }) @@ -366,12 +430,108 @@ func (b *GRPCBroker) Close() error { return nil } +func (b *GRPCBroker) listenForKnocks(id uint32) error { + p := b.getServerStream(id) + for { + select { + case msg := <-p.ch: + // Shouldn't be possible. + if msg.ServiceId != id { + return fmt.Errorf("knock received with wrong service ID; expected %d but got %d", id, msg.ServiceId) + } + + // Also shouldn't be possible. + if msg.Knock == nil || !msg.Knock.Knock || msg.Knock.Ack { + return fmt.Errorf("knock received for service ID %d with incorrect values; knock=%+v", id, msg.Knock) + } + + // Successful knock, open the door for the given ID. + var ackError string + err := b.muxer.AcceptKnock(id) + if err != nil { + ackError = err.Error() + } + + // Send back an acknowledgement to allow the client to start dialling. + err = b.streamer.Send(&plugin.ConnInfo{ + ServiceId: id, + Knock: &plugin.ConnInfo_Knock{ + Knock: true, + Ack: true, + Error: ackError, + }, + }) + if err != nil { + return fmt.Errorf("error sending back knock acknowledgement: %w", err) + } + case <-p.doneCh: + return nil + } + } +} + +func (b *GRPCBroker) knock(id uint32) error { + // Send a knock. + err := b.streamer.Send(&plugin.ConnInfo{ + ServiceId: id, + Knock: &plugin.ConnInfo_Knock{ + Knock: true, + }, + }) + if err != nil { + return err + } + + // Wait for the ack. + p := b.getClientStream(id) + select { + case msg := <-p.ch: + if msg.ServiceId != id { + return fmt.Errorf("handshake failed for multiplexing on id %d; got response for %d", id, msg.ServiceId) + } + if msg.Knock == nil || !msg.Knock.Knock || !msg.Knock.Ack { + return fmt.Errorf("handshake failed for multiplexing on id %d; expected knock and ack, but got %+v", id, msg.Knock) + } + if msg.Knock.Error != "" { + return fmt.Errorf("failed to knock for id %d: %s", id, msg.Knock.Error) + } + case <-time.After(5 * time.Second): + return fmt.Errorf("timeout waiting for multiplexing knock handshake on id %d", id) + } + + return nil +} + +func (b *GRPCBroker) muxDial(id uint32) func(string, time.Duration) (net.Conn, error) { + return func(string, time.Duration) (net.Conn, error) { + b.dialMutex.Lock() + defer b.dialMutex.Unlock() + + // Tell the other side the listener ID it should give the next stream to. + err := b.knock(id) + if err != nil { + return nil, fmt.Errorf("failed to knock before dialling client: %w", err) + } + + conn, err := b.muxer.Dial() + if err != nil { + return nil, err + } + + return conn, nil + } +} + // Dial opens a connection by ID. func (b *GRPCBroker) Dial(id uint32) (conn *grpc.ClientConn, err error) { + if b.muxer.Enabled() { + return dialGRPCConn(b.tls, b.muxDial(id)) + } + var c *plugin.ConnInfo // Open the stream - p := b.getStream(id) + p := b.getClientStream(id) select { case c = <-p.ch: close(p.doneCh) @@ -379,12 +539,20 @@ func (b *GRPCBroker) Dial(id uint32) (conn *grpc.ClientConn, err error) { return nil, fmt.Errorf("timeout waiting for connection info") } + network, address := c.Network, c.Address + if b.addrTranslator != nil { + network, address, err = b.addrTranslator.PluginToHost(network, address) + if err != nil { + return nil, err + } + } + var addr net.Addr - switch c.Network { + switch network { case "tcp": - addr, err = net.ResolveTCPAddr("tcp", c.Address) + addr, err = net.ResolveTCPAddr("tcp", address) case "unix": - addr, err = net.ResolveUnixAddr("unix", c.Address) + addr, err = net.ResolveUnixAddr("unix", address) default: err = fmt.Errorf("Unknown address type: %s", c.Address) } @@ -411,37 +579,63 @@ func (m *GRPCBroker) NextId() uint32 { // the plugin host/client. func (m *GRPCBroker) Run() { for { - stream, err := m.streamer.Recv() + msg, err := m.streamer.Recv() if err != nil { // Once we receive an error, just exit break } // Initialize the waiter - p := m.getStream(stream.ServiceId) + var p *gRPCBrokerPending + if msg.Knock != nil && msg.Knock.Knock && !msg.Knock.Ack { + p = m.getServerStream(msg.ServiceId) + // The server side doesn't close the channel immediately as it needs + // to continuously listen for knocks. + } else { + p = m.getClientStream(msg.ServiceId) + go m.timeoutWait(msg.ServiceId, p) + } select { - case p.ch <- stream: + case p.ch <- msg: default: } + } +} + +// getClientStream is a buffer to receive new connection info and knock acks +// by stream ID. +func (m *GRPCBroker) getClientStream(id uint32) *gRPCBrokerPending { + m.Lock() + defer m.Unlock() + + p, ok := m.clientStreams[id] + if ok { + return p + } - go m.timeoutWait(stream.ServiceId, p) + m.clientStreams[id] = &gRPCBrokerPending{ + ch: make(chan *plugin.ConnInfo, 1), + doneCh: make(chan struct{}), } + return m.clientStreams[id] } -func (m *GRPCBroker) getStream(id uint32) *gRPCBrokerPending { +// getServerStream is a buffer to receive knocks to a multiplexed stream ID +// that its side is listening on. Not used unless multiplexing is enabled. +func (m *GRPCBroker) getServerStream(id uint32) *gRPCBrokerPending { m.Lock() defer m.Unlock() - p, ok := m.streams[id] + p, ok := m.serverStreams[id] if ok { return p } - m.streams[id] = &gRPCBrokerPending{ + m.serverStreams[id] = &gRPCBrokerPending{ ch: make(chan *plugin.ConnInfo, 1), doneCh: make(chan struct{}), } - return m.streams[id] + return m.serverStreams[id] } func (m *GRPCBroker) timeoutWait(id uint32, p *gRPCBrokerPending) { @@ -456,5 +650,5 @@ func (m *GRPCBroker) timeoutWait(id uint32, p *gRPCBrokerPending) { defer m.Unlock() // Delete the stream so no one else can grab it - delete(m.streams, id) + delete(m.clientStreams, id) } diff --git a/vendor/github.com/hashicorp/go-plugin/grpc_client.go b/vendor/github.com/hashicorp/go-plugin/grpc_client.go index 6454d426..627649d8 100644 --- a/vendor/github.com/hashicorp/go-plugin/grpc_client.go +++ b/vendor/github.com/hashicorp/go-plugin/grpc_client.go @@ -61,9 +61,14 @@ func newGRPCClient(doneCtx context.Context, c *Client) (*GRPCClient, error) { return nil, err } + muxer, err := c.getGRPCMuxer(c.address) + if err != nil { + return nil, err + } + // Start the broker. brokerGRPCClient := newGRPCBrokerClient(conn) - broker := newGRPCBroker(brokerGRPCClient, c.config.TLSConfig) + broker := newGRPCBroker(brokerGRPCClient, c.config.TLSConfig, c.unixSocketCfg, c.runner, muxer) go broker.Run() go brokerGRPCClient.StartStream() diff --git a/vendor/github.com/hashicorp/go-plugin/grpc_server.go b/vendor/github.com/hashicorp/go-plugin/grpc_server.go index 7203a2cf..a5f40c7f 100644 --- a/vendor/github.com/hashicorp/go-plugin/grpc_server.go +++ b/vendor/github.com/hashicorp/go-plugin/grpc_server.go @@ -12,6 +12,7 @@ import ( "net" hclog "github.com/hashicorp/go-hclog" + "github.com/hashicorp/go-plugin/internal/grpcmux" "github.com/hashicorp/go-plugin/internal/plugin" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -61,6 +62,8 @@ type GRPCServer struct { stdioServer *grpcStdioServer logger hclog.Logger + + muxer *grpcmux.GRPCServerMuxer } // ServerProtocol impl. @@ -84,7 +87,7 @@ func (s *GRPCServer) Init() error { // Register the broker service brokerServer := newGRPCBrokerServer() plugin.RegisterGRPCBrokerServer(s.server, brokerServer) - s.broker = newGRPCBroker(brokerServer, s.TLS) + s.broker = newGRPCBroker(brokerServer, s.TLS, unixSocketConfigFromEnv(), nil, s.muxer) go s.broker.Run() // Register the controller diff --git a/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/addr_translator.go b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/addr_translator.go new file mode 100644 index 00000000..1854d2dd --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/addr_translator.go @@ -0,0 +1,16 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package cmdrunner + +// addrTranslator implements stateless identity functions, as the host and plugin +// run in the same context wrt Unix and network addresses. +type addrTranslator struct{} + +func (*addrTranslator) PluginToHost(pluginNet, pluginAddr string) (string, string, error) { + return pluginNet, pluginAddr, nil +} + +func (*addrTranslator) HostToPlugin(hostNet, hostAddr string) (string, string, error) { + return hostNet, hostAddr, nil +} diff --git a/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/cmd_reattach.go b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/cmd_reattach.go new file mode 100644 index 00000000..dce1a86a --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/cmd_reattach.go @@ -0,0 +1,63 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package cmdrunner + +import ( + "context" + "fmt" + "net" + "os" + + "github.com/hashicorp/go-plugin/runner" +) + +// ReattachFunc returns a function that allows reattaching to a plugin running +// as a plain process. The process may or may not be a child process. +func ReattachFunc(pid int, addr net.Addr) runner.ReattachFunc { + return func() (runner.AttachedRunner, error) { + p, err := os.FindProcess(pid) + if err != nil { + // On Unix systems, FindProcess never returns an error. + // On Windows, for non-existent pids it returns: + // os.SyscallError - 'OpenProcess: the paremter is incorrect' + return nil, ErrProcessNotFound + } + + // Attempt to connect to the addr since on Unix systems FindProcess + // doesn't actually return an error if it can't find the process. + conn, err := net.Dial(addr.Network(), addr.String()) + if err != nil { + p.Kill() + return nil, ErrProcessNotFound + } + conn.Close() + + return &CmdAttachedRunner{ + pid: pid, + process: p, + }, nil + } +} + +// CmdAttachedRunner is mostly a subset of CmdRunner, except the Wait function +// does not assume the process is a child of the host process, and so uses a +// different implementation to wait on the process. +type CmdAttachedRunner struct { + pid int + process *os.Process + + addrTranslator +} + +func (c *CmdAttachedRunner) Wait(_ context.Context) error { + return pidWait(c.pid) +} + +func (c *CmdAttachedRunner) Kill(_ context.Context) error { + return c.process.Kill() +} + +func (c *CmdAttachedRunner) ID() string { + return fmt.Sprintf("%d", c.pid) +} diff --git a/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/cmd_runner.go b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/cmd_runner.go new file mode 100644 index 00000000..b26fea92 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/cmd_runner.go @@ -0,0 +1,129 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package cmdrunner + +import ( + "context" + "errors" + "fmt" + "io" + "os" + "os/exec" + + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/go-plugin/runner" +) + +var ( + _ runner.Runner = (*CmdRunner)(nil) + + // ErrProcessNotFound is returned when a client is instantiated to + // reattach to an existing process and it isn't found. + ErrProcessNotFound = errors.New("Reattachment process not found") +) + +const unrecognizedRemotePluginMessage = `This usually means + the plugin was not compiled for this architecture, + the plugin is missing dynamic-link libraries necessary to run, + the plugin is not executable by this process due to file permissions, or + the plugin failed to negotiate the initial go-plugin protocol handshake +%s` + +// CmdRunner implements the runner.Runner interface. It mostly just passes through +// to exec.Cmd methods. +type CmdRunner struct { + logger hclog.Logger + cmd *exec.Cmd + + stdout io.ReadCloser + stderr io.ReadCloser + + // Cmd info is persisted early, since the process information will be removed + // after Kill is called. + path string + pid int + + addrTranslator +} + +// NewCmdRunner returns an implementation of runner.Runner for running a plugin +// as a subprocess. It must be passed a cmd that hasn't yet been started. +func NewCmdRunner(logger hclog.Logger, cmd *exec.Cmd) (*CmdRunner, error) { + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, err + } + + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, err + } + + return &CmdRunner{ + logger: logger, + cmd: cmd, + stdout: stdout, + stderr: stderr, + path: cmd.Path, + }, nil +} + +func (c *CmdRunner) Start(_ context.Context) error { + c.logger.Debug("starting plugin", "path", c.cmd.Path, "args", c.cmd.Args) + err := c.cmd.Start() + if err != nil { + return err + } + + c.pid = c.cmd.Process.Pid + c.logger.Debug("plugin started", "path", c.path, "pid", c.pid) + return nil +} + +func (c *CmdRunner) Wait(_ context.Context) error { + return c.cmd.Wait() +} + +func (c *CmdRunner) Kill(_ context.Context) error { + if c.cmd.Process != nil { + err := c.cmd.Process.Kill() + // Swallow ErrProcessDone, we support calling Kill multiple times. + if !errors.Is(err, os.ErrProcessDone) { + return err + } + return nil + } + + return nil +} + +func (c *CmdRunner) Stdout() io.ReadCloser { + return c.stdout +} + +func (c *CmdRunner) Stderr() io.ReadCloser { + return c.stderr +} + +func (c *CmdRunner) Name() string { + return c.path +} + +func (c *CmdRunner) ID() string { + return fmt.Sprintf("%d", c.pid) +} + +// peTypes is a list of Portable Executable (PE) machine types from https://learn.microsoft.com/en-us/windows/win32/debug/pe-format +// mapped to GOARCH types. It is not comprehensive, and only includes machine types that Go supports. +var peTypes = map[uint16]string{ + 0x14c: "386", + 0x1c0: "arm", + 0x6264: "loong64", + 0x8664: "amd64", + 0xaa64: "arm64", +} + +func (c *CmdRunner) Diagnose(_ context.Context) string { + return fmt.Sprintf(unrecognizedRemotePluginMessage, additionalNotesAboutCommand(c.cmd.Path)) +} diff --git a/vendor/github.com/hashicorp/go-plugin/notes_unix.go b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/notes_unix.go similarity index 99% rename from vendor/github.com/hashicorp/go-plugin/notes_unix.go rename to vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/notes_unix.go index 97345575..ce04cfeb 100644 --- a/vendor/github.com/hashicorp/go-plugin/notes_unix.go +++ b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/notes_unix.go @@ -4,7 +4,7 @@ //go:build !windows // +build !windows -package plugin +package cmdrunner import ( "debug/elf" diff --git a/vendor/github.com/hashicorp/go-plugin/notes_windows.go b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/notes_windows.go similarity index 98% rename from vendor/github.com/hashicorp/go-plugin/notes_windows.go rename to vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/notes_windows.go index 7afcaf3f..39c51dd1 100644 --- a/vendor/github.com/hashicorp/go-plugin/notes_windows.go +++ b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/notes_windows.go @@ -4,7 +4,7 @@ //go:build windows // +build windows -package plugin +package cmdrunner import ( "debug/elf" diff --git a/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/process.go b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/process.go new file mode 100644 index 00000000..6c34dc77 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/process.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package cmdrunner + +import "time" + +// pidAlive checks whether a pid is alive. +func pidAlive(pid int) bool { + return _pidAlive(pid) +} + +// pidWait blocks for a process to exit. +func pidWait(pid int) error { + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + + for range ticker.C { + if !pidAlive(pid) { + break + } + } + + return nil +} diff --git a/vendor/github.com/hashicorp/go-plugin/process_posix.go b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/process_posix.go similarity index 95% rename from vendor/github.com/hashicorp/go-plugin/process_posix.go rename to vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/process_posix.go index b73a3607..bf3fc5b6 100644 --- a/vendor/github.com/hashicorp/go-plugin/process_posix.go +++ b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/process_posix.go @@ -4,7 +4,7 @@ //go:build !windows // +build !windows -package plugin +package cmdrunner import ( "os" diff --git a/vendor/github.com/hashicorp/go-plugin/process_windows.go b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/process_windows.go similarity index 97% rename from vendor/github.com/hashicorp/go-plugin/process_windows.go rename to vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/process_windows.go index ffa9b9e0..6c39df28 100644 --- a/vendor/github.com/hashicorp/go-plugin/process_windows.go +++ b/vendor/github.com/hashicorp/go-plugin/internal/cmdrunner/process_windows.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package plugin +package cmdrunner import ( "syscall" diff --git a/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/blocked_client_listener.go b/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/blocked_client_listener.go new file mode 100644 index 00000000..e8a3a152 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/blocked_client_listener.go @@ -0,0 +1,51 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package grpcmux + +import ( + "io" + "net" + + "github.com/hashicorp/yamux" +) + +var _ net.Listener = (*blockedClientListener)(nil) + +// blockedClientListener accepts connections for a specific gRPC broker stream +// ID on the client (host) side of the connection. +type blockedClientListener struct { + session *yamux.Session + waitCh chan struct{} + doneCh <-chan struct{} +} + +func newBlockedClientListener(session *yamux.Session, doneCh <-chan struct{}) *blockedClientListener { + return &blockedClientListener{ + waitCh: make(chan struct{}, 1), + doneCh: doneCh, + session: session, + } +} + +func (b *blockedClientListener) Accept() (net.Conn, error) { + select { + case <-b.waitCh: + return b.session.Accept() + case <-b.doneCh: + return nil, io.EOF + } +} + +func (b *blockedClientListener) Addr() net.Addr { + return b.session.Addr() +} + +func (b *blockedClientListener) Close() error { + // We don't close the session, the client muxer is responsible for that. + return nil +} + +func (b *blockedClientListener) unblock() { + b.waitCh <- struct{}{} +} diff --git a/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/blocked_server_listener.go b/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/blocked_server_listener.go new file mode 100644 index 00000000..0edb2c05 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/blocked_server_listener.go @@ -0,0 +1,49 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package grpcmux + +import ( + "io" + "net" +) + +var _ net.Listener = (*blockedServerListener)(nil) + +// blockedServerListener accepts connections for a specific gRPC broker stream +// ID on the server (plugin) side of the connection. +type blockedServerListener struct { + addr net.Addr + acceptCh chan acceptResult + doneCh <-chan struct{} +} + +type acceptResult struct { + conn net.Conn + err error +} + +func newBlockedServerListener(addr net.Addr, doneCh <-chan struct{}) *blockedServerListener { + return &blockedServerListener{ + addr: addr, + acceptCh: make(chan acceptResult), + doneCh: doneCh, + } +} + +func (b *blockedServerListener) Accept() (net.Conn, error) { + select { + case accept := <-b.acceptCh: + return accept.conn, accept.err + case <-b.doneCh: + return nil, io.EOF + } +} + +func (b *blockedServerListener) Addr() net.Addr { + return b.addr +} + +func (b *blockedServerListener) Close() error { + return nil +} diff --git a/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_client_muxer.go b/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_client_muxer.go new file mode 100644 index 00000000..b203ba46 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_client_muxer.go @@ -0,0 +1,105 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package grpcmux + +import ( + "fmt" + "net" + "sync" + + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/yamux" +) + +var _ GRPCMuxer = (*GRPCClientMuxer)(nil) + +// GRPCClientMuxer implements the client (host) side of the gRPC broker's +// GRPCMuxer interface for multiplexing multiple gRPC broker connections over +// a single net.Conn. +// +// The client dials the initial net.Conn eagerly, and creates a yamux.Session +// as the implementation for multiplexing any additional connections. +// +// Each net.Listener returned from Listener will block until the client receives +// a knock that matches its gRPC broker stream ID. There is no default listener +// on the client, as it is a client for the gRPC broker's control services. (See +// GRPCServerMuxer for more details). +type GRPCClientMuxer struct { + logger hclog.Logger + session *yamux.Session + + acceptMutex sync.Mutex + acceptListeners map[uint32]*blockedClientListener +} + +func NewGRPCClientMuxer(logger hclog.Logger, addr net.Addr) (*GRPCClientMuxer, error) { + // Eagerly establish the underlying connection as early as possible. + logger.Debug("making new client mux initial connection", "addr", addr) + conn, err := net.Dial(addr.Network(), addr.String()) + if err != nil { + return nil, err + } + if tcpConn, ok := conn.(*net.TCPConn); ok { + // Make sure to set keep alive so that the connection doesn't die + _ = tcpConn.SetKeepAlive(true) + } + + cfg := yamux.DefaultConfig() + cfg.Logger = logger.Named("yamux").StandardLogger(&hclog.StandardLoggerOptions{ + InferLevels: true, + }) + cfg.LogOutput = nil + sess, err := yamux.Client(conn, cfg) + if err != nil { + return nil, err + } + + logger.Debug("client muxer connected", "addr", addr) + m := &GRPCClientMuxer{ + logger: logger, + session: sess, + acceptListeners: make(map[uint32]*blockedClientListener), + } + + return m, nil +} + +func (m *GRPCClientMuxer) Enabled() bool { + return m != nil +} + +func (m *GRPCClientMuxer) Listener(id uint32, doneCh <-chan struct{}) (net.Listener, error) { + ln := newBlockedClientListener(m.session, doneCh) + + m.acceptMutex.Lock() + m.acceptListeners[id] = ln + m.acceptMutex.Unlock() + + return ln, nil +} + +func (m *GRPCClientMuxer) AcceptKnock(id uint32) error { + m.acceptMutex.Lock() + defer m.acceptMutex.Unlock() + + ln, ok := m.acceptListeners[id] + if !ok { + return fmt.Errorf("no listener for id %d", id) + } + ln.unblock() + return nil +} + +func (m *GRPCClientMuxer) Dial() (net.Conn, error) { + stream, err := m.session.Open() + if err != nil { + return nil, fmt.Errorf("error dialling new client stream: %w", err) + } + + return stream, nil +} + +func (m *GRPCClientMuxer) Close() error { + return m.session.Close() +} diff --git a/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_muxer.go b/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_muxer.go new file mode 100644 index 00000000..c52aaf55 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_muxer.go @@ -0,0 +1,41 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package grpcmux + +import ( + "net" +) + +// GRPCMuxer enables multiple implementations of net.Listener to accept +// connections over a single "main" multiplexed net.Conn, and dial multiple +// client connections over the same multiplexed net.Conn. +// +// The first multiplexed connection is used to serve the gRPC broker's own +// control services: plugin.GRPCBroker, plugin.GRPCController, plugin.GRPCStdio. +// +// Clients must "knock" before dialling, to tell the server side that the +// next net.Conn should be accepted onto a specific stream ID. The knock is a +// bidirectional streaming message on the plugin.GRPCBroker service. +type GRPCMuxer interface { + // Enabled determines whether multiplexing should be used. It saves users + // of the interface from having to compare an interface with nil, which + // is a bit awkward to do correctly. + Enabled() bool + + // Listener returns a multiplexed listener that will wait until AcceptKnock + // is called with a matching ID before its Accept function returns. + Listener(id uint32, doneCh <-chan struct{}) (net.Listener, error) + + // AcceptKnock unblocks the listener with the matching ID, and returns an + // error if it hasn't been created yet. + AcceptKnock(id uint32) error + + // Dial makes a new multiplexed client connection. To dial a specific ID, + // a knock must be sent first. + Dial() (net.Conn, error) + + // Close closes connections and releases any resources associated with the + // muxer. + Close() error +} diff --git a/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_server_muxer.go b/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_server_muxer.go new file mode 100644 index 00000000..27696ee7 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/grpcmux/grpc_server_muxer.go @@ -0,0 +1,190 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package grpcmux + +import ( + "errors" + "fmt" + "net" + "sync" + "time" + + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/yamux" +) + +var _ GRPCMuxer = (*GRPCServerMuxer)(nil) +var _ net.Listener = (*GRPCServerMuxer)(nil) + +// GRPCServerMuxer implements the server (plugin) side of the gRPC broker's +// GRPCMuxer interface for multiplexing multiple gRPC broker connections over +// a single net.Conn. +// +// The server side needs a listener to serve the gRPC broker's control services, +// which includes the service we will receive knocks on. That means we always +// accept the first connection onto a "default" main listener, and if we accept +// any further connections without receiving a knock first, they are also given +// to the default listener. +// +// When creating additional multiplexed listeners for specific stream IDs, we +// can't control the order in which gRPC servers will call Accept() on each +// listener, but we do need to control which gRPC server accepts which connection. +// As such, each multiplexed listener blocks waiting on a channel. It will be +// unblocked when a knock is received for the matching stream ID. +type GRPCServerMuxer struct { + addr net.Addr + logger hclog.Logger + + sessionErrCh chan error + sess *yamux.Session + + knockCh chan uint32 + + acceptMutex sync.Mutex + acceptChannels map[uint32]chan acceptResult +} + +func NewGRPCServerMuxer(logger hclog.Logger, ln net.Listener) *GRPCServerMuxer { + m := &GRPCServerMuxer{ + addr: ln.Addr(), + logger: logger, + + sessionErrCh: make(chan error), + + knockCh: make(chan uint32, 1), + acceptChannels: make(map[uint32]chan acceptResult), + } + + go m.acceptSession(ln) + + return m +} + +// acceptSessionAndMuxAccept is responsible for establishing the yamux session, +// and then kicking off the acceptLoop function. +func (m *GRPCServerMuxer) acceptSession(ln net.Listener) { + defer close(m.sessionErrCh) + + m.logger.Debug("accepting initial connection", "addr", m.addr) + conn, err := ln.Accept() + if err != nil { + m.sessionErrCh <- err + return + } + + m.logger.Debug("initial server connection accepted", "addr", m.addr) + cfg := yamux.DefaultConfig() + cfg.Logger = m.logger.Named("yamux").StandardLogger(&hclog.StandardLoggerOptions{ + InferLevels: true, + }) + cfg.LogOutput = nil + m.sess, err = yamux.Server(conn, cfg) + if err != nil { + m.sessionErrCh <- err + return + } +} + +func (m *GRPCServerMuxer) session() (*yamux.Session, error) { + select { + case err := <-m.sessionErrCh: + if err != nil { + return nil, err + } + case <-time.After(5 * time.Second): + return nil, errors.New("timed out waiting for connection to be established") + } + + // Should never happen. + if m.sess == nil { + return nil, errors.New("no connection established and no error received") + } + + return m.sess, nil +} + +// Accept accepts all incoming connections and routes them to the correct +// stream ID based on the most recent knock received. +func (m *GRPCServerMuxer) Accept() (net.Conn, error) { + session, err := m.session() + if err != nil { + return nil, fmt.Errorf("error establishing yamux session: %w", err) + } + + for { + conn, acceptErr := session.Accept() + + select { + case id := <-m.knockCh: + m.acceptMutex.Lock() + acceptCh, ok := m.acceptChannels[id] + m.acceptMutex.Unlock() + + if !ok { + if conn != nil { + _ = conn.Close() + } + return nil, fmt.Errorf("received knock on ID %d that doesn't have a listener", id) + } + m.logger.Debug("sending conn to brokered listener", "id", id) + acceptCh <- acceptResult{ + conn: conn, + err: acceptErr, + } + default: + m.logger.Debug("sending conn to default listener") + return conn, acceptErr + } + } +} + +func (m *GRPCServerMuxer) Addr() net.Addr { + return m.addr +} + +func (m *GRPCServerMuxer) Close() error { + session, err := m.session() + if err != nil { + return err + } + + return session.Close() +} + +func (m *GRPCServerMuxer) Enabled() bool { + return m != nil +} + +func (m *GRPCServerMuxer) Listener(id uint32, doneCh <-chan struct{}) (net.Listener, error) { + sess, err := m.session() + if err != nil { + return nil, err + } + + ln := newBlockedServerListener(sess.Addr(), doneCh) + m.acceptMutex.Lock() + m.acceptChannels[id] = ln.acceptCh + m.acceptMutex.Unlock() + + return ln, nil +} + +func (m *GRPCServerMuxer) Dial() (net.Conn, error) { + sess, err := m.session() + if err != nil { + return nil, err + } + + stream, err := sess.OpenStream() + if err != nil { + return nil, fmt.Errorf("error dialling new server stream: %w", err) + } + + return stream, nil +} + +func (m *GRPCServerMuxer) AcceptKnock(id uint32) error { + m.knockCh <- id + return nil +} diff --git a/vendor/github.com/hashicorp/go-plugin/internal/plugin/gen.go b/vendor/github.com/hashicorp/go-plugin/internal/plugin/gen.go deleted file mode 100644 index a3b5fb12..00000000 --- a/vendor/github.com/hashicorp/go-plugin/internal/plugin/gen.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -//go:generate protoc -I ./ ./grpc_broker.proto ./grpc_controller.proto ./grpc_stdio.proto --go_out=plugins=grpc:. - -package plugin diff --git a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker.pb.go b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker.pb.go index 303b63e4..acc6dc9c 100644 --- a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker.pb.go +++ b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker.pb.go @@ -1,203 +1,264 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + // Code generated by protoc-gen-go. DO NOT EDIT. -// source: grpc_broker.proto +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: internal/plugin/grpc_broker.proto package plugin -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - import ( - context "context" - grpc "google.golang.org/grpc" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type ConnInfo struct { - ServiceId uint32 `protobuf:"varint,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"` - Network string `protobuf:"bytes,2,opt,name=network,proto3" json:"network,omitempty"` - Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServiceId uint32 `protobuf:"varint,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"` + Network string `protobuf:"bytes,2,opt,name=network,proto3" json:"network,omitempty"` + Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` + Knock *ConnInfo_Knock `protobuf:"bytes,4,opt,name=knock,proto3" json:"knock,omitempty"` } -func (m *ConnInfo) Reset() { *m = ConnInfo{} } -func (m *ConnInfo) String() string { return proto.CompactTextString(m) } -func (*ConnInfo) ProtoMessage() {} -func (*ConnInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_grpc_broker_3322b07398605250, []int{0} -} -func (m *ConnInfo) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ConnInfo.Unmarshal(m, b) -} -func (m *ConnInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ConnInfo.Marshal(b, m, deterministic) -} -func (dst *ConnInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConnInfo.Merge(dst, src) +func (x *ConnInfo) Reset() { + *x = ConnInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_plugin_grpc_broker_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *ConnInfo) XXX_Size() int { - return xxx_messageInfo_ConnInfo.Size(m) + +func (x *ConnInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *ConnInfo) XXX_DiscardUnknown() { - xxx_messageInfo_ConnInfo.DiscardUnknown(m) + +func (*ConnInfo) ProtoMessage() {} + +func (x *ConnInfo) ProtoReflect() protoreflect.Message { + mi := &file_internal_plugin_grpc_broker_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_ConnInfo proto.InternalMessageInfo +// Deprecated: Use ConnInfo.ProtoReflect.Descriptor instead. +func (*ConnInfo) Descriptor() ([]byte, []int) { + return file_internal_plugin_grpc_broker_proto_rawDescGZIP(), []int{0} +} -func (m *ConnInfo) GetServiceId() uint32 { - if m != nil { - return m.ServiceId +func (x *ConnInfo) GetServiceId() uint32 { + if x != nil { + return x.ServiceId } return 0 } -func (m *ConnInfo) GetNetwork() string { - if m != nil { - return m.Network +func (x *ConnInfo) GetNetwork() string { + if x != nil { + return x.Network } return "" } -func (m *ConnInfo) GetAddress() string { - if m != nil { - return m.Address +func (x *ConnInfo) GetAddress() string { + if x != nil { + return x.Address } return "" } -func init() { - proto.RegisterType((*ConnInfo)(nil), "plugin.ConnInfo") +func (x *ConnInfo) GetKnock() *ConnInfo_Knock { + if x != nil { + return x.Knock + } + return nil } -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn +type ConnInfo_Knock struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// GRPCBrokerClient is the client API for GRPCBroker service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type GRPCBrokerClient interface { - StartStream(ctx context.Context, opts ...grpc.CallOption) (GRPCBroker_StartStreamClient, error) + Knock bool `protobuf:"varint,1,opt,name=knock,proto3" json:"knock,omitempty"` + Ack bool `protobuf:"varint,2,opt,name=ack,proto3" json:"ack,omitempty"` + Error string `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"` } -type gRPCBrokerClient struct { - cc *grpc.ClientConn +func (x *ConnInfo_Knock) Reset() { + *x = ConnInfo_Knock{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_plugin_grpc_broker_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func NewGRPCBrokerClient(cc *grpc.ClientConn) GRPCBrokerClient { - return &gRPCBrokerClient{cc} +func (x *ConnInfo_Knock) String() string { + return protoimpl.X.MessageStringOf(x) } -func (c *gRPCBrokerClient) StartStream(ctx context.Context, opts ...grpc.CallOption) (GRPCBroker_StartStreamClient, error) { - stream, err := c.cc.NewStream(ctx, &_GRPCBroker_serviceDesc.Streams[0], "/plugin.GRPCBroker/StartStream", opts...) - if err != nil { - return nil, err - } - x := &gRPCBrokerStartStreamClient{stream} - return x, nil -} +func (*ConnInfo_Knock) ProtoMessage() {} -type GRPCBroker_StartStreamClient interface { - Send(*ConnInfo) error - Recv() (*ConnInfo, error) - grpc.ClientStream +func (x *ConnInfo_Knock) ProtoReflect() protoreflect.Message { + mi := &file_internal_plugin_grpc_broker_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -type gRPCBrokerStartStreamClient struct { - grpc.ClientStream +// Deprecated: Use ConnInfo_Knock.ProtoReflect.Descriptor instead. +func (*ConnInfo_Knock) Descriptor() ([]byte, []int) { + return file_internal_plugin_grpc_broker_proto_rawDescGZIP(), []int{0, 0} } -func (x *gRPCBrokerStartStreamClient) Send(m *ConnInfo) error { - return x.ClientStream.SendMsg(m) +func (x *ConnInfo_Knock) GetKnock() bool { + if x != nil { + return x.Knock + } + return false } -func (x *gRPCBrokerStartStreamClient) Recv() (*ConnInfo, error) { - m := new(ConnInfo) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err +func (x *ConnInfo_Knock) GetAck() bool { + if x != nil { + return x.Ack } - return m, nil + return false } -// GRPCBrokerServer is the server API for GRPCBroker service. -type GRPCBrokerServer interface { - StartStream(GRPCBroker_StartStreamServer) error +func (x *ConnInfo_Knock) GetError() string { + if x != nil { + return x.Error + } + return "" } -func RegisterGRPCBrokerServer(s *grpc.Server, srv GRPCBrokerServer) { - s.RegisterService(&_GRPCBroker_serviceDesc, srv) +var File_internal_plugin_grpc_broker_proto protoreflect.FileDescriptor + +var file_internal_plugin_grpc_broker_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x22, 0xd2, 0x01, 0x0a, 0x08, + 0x43, 0x6f, 0x6e, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x6b, + 0x6e, 0x6f, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4b, 0x6e, 0x6f, + 0x63, 0x6b, 0x52, 0x05, 0x6b, 0x6e, 0x6f, 0x63, 0x6b, 0x1a, 0x45, 0x0a, 0x05, 0x4b, 0x6e, 0x6f, + 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x6b, 0x6e, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x05, 0x6b, 0x6e, 0x6f, 0x63, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x6b, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x32, 0x43, 0x0a, 0x0a, 0x47, 0x52, 0x50, 0x43, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x12, 0x35, + 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x10, 0x2e, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x1a, + 0x10, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x49, 0x6e, 0x66, + 0x6f, 0x28, 0x01, 0x30, 0x01, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } -func _GRPCBroker_StartStream_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(GRPCBrokerServer).StartStream(&gRPCBrokerStartStreamServer{stream}) -} +var ( + file_internal_plugin_grpc_broker_proto_rawDescOnce sync.Once + file_internal_plugin_grpc_broker_proto_rawDescData = file_internal_plugin_grpc_broker_proto_rawDesc +) -type GRPCBroker_StartStreamServer interface { - Send(*ConnInfo) error - Recv() (*ConnInfo, error) - grpc.ServerStream +func file_internal_plugin_grpc_broker_proto_rawDescGZIP() []byte { + file_internal_plugin_grpc_broker_proto_rawDescOnce.Do(func() { + file_internal_plugin_grpc_broker_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_plugin_grpc_broker_proto_rawDescData) + }) + return file_internal_plugin_grpc_broker_proto_rawDescData } -type gRPCBrokerStartStreamServer struct { - grpc.ServerStream +var file_internal_plugin_grpc_broker_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_internal_plugin_grpc_broker_proto_goTypes = []interface{}{ + (*ConnInfo)(nil), // 0: plugin.ConnInfo + (*ConnInfo_Knock)(nil), // 1: plugin.ConnInfo.Knock } - -func (x *gRPCBrokerStartStreamServer) Send(m *ConnInfo) error { - return x.ServerStream.SendMsg(m) +var file_internal_plugin_grpc_broker_proto_depIdxs = []int32{ + 1, // 0: plugin.ConnInfo.knock:type_name -> plugin.ConnInfo.Knock + 0, // 1: plugin.GRPCBroker.StartStream:input_type -> plugin.ConnInfo + 0, // 2: plugin.GRPCBroker.StartStream:output_type -> plugin.ConnInfo + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } -func (x *gRPCBrokerStartStreamServer) Recv() (*ConnInfo, error) { - m := new(ConnInfo) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err +func init() { file_internal_plugin_grpc_broker_proto_init() } +func file_internal_plugin_grpc_broker_proto_init() { + if File_internal_plugin_grpc_broker_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_internal_plugin_grpc_broker_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConnInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_plugin_grpc_broker_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConnInfo_Knock); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } - return m, nil -} - -var _GRPCBroker_serviceDesc = grpc.ServiceDesc{ - ServiceName: "plugin.GRPCBroker", - HandlerType: (*GRPCBrokerServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "StartStream", - Handler: _GRPCBroker_StartStream_Handler, - ServerStreams: true, - ClientStreams: true, + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_internal_plugin_grpc_broker_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, }, - }, - Metadata: "grpc_broker.proto", -} - -func init() { proto.RegisterFile("grpc_broker.proto", fileDescriptor_grpc_broker_3322b07398605250) } - -var fileDescriptor_grpc_broker_3322b07398605250 = []byte{ - // 175 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4c, 0x2f, 0x2a, 0x48, - 0x8e, 0x4f, 0x2a, 0xca, 0xcf, 0x4e, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2b, - 0xc8, 0x29, 0x4d, 0xcf, 0xcc, 0x53, 0x8a, 0xe5, 0xe2, 0x70, 0xce, 0xcf, 0xcb, 0xf3, 0xcc, 0x4b, - 0xcb, 0x17, 0x92, 0xe5, 0xe2, 0x2a, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0x8d, 0xcf, 0x4c, 0x91, - 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0d, 0xe2, 0x84, 0x8a, 0x78, 0xa6, 0x08, 0x49, 0x70, 0xb1, 0xe7, - 0xa5, 0x96, 0x94, 0xe7, 0x17, 0x65, 0x4b, 0x30, 0x29, 0x30, 0x6a, 0x70, 0x06, 0xc1, 0xb8, 0x20, - 0x99, 0xc4, 0x94, 0x94, 0xa2, 0xd4, 0xe2, 0x62, 0x09, 0x66, 0x88, 0x0c, 0x94, 0x6b, 0xe4, 0xcc, - 0xc5, 0xe5, 0x1e, 0x14, 0xe0, 0xec, 0x04, 0xb6, 0x5a, 0xc8, 0x94, 0x8b, 0x3b, 0xb8, 0x24, 0xb1, - 0xa8, 0x24, 0xb8, 0xa4, 0x28, 0x35, 0x31, 0x57, 0x48, 0x40, 0x0f, 0xe2, 0x08, 0x3d, 0x98, 0x0b, - 0xa4, 0x30, 0x44, 0x34, 0x18, 0x0d, 0x18, 0x9d, 0x38, 0xa2, 0xa0, 0xae, 0x4d, 0x62, 0x03, 0x3b, - 0xde, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x10, 0x15, 0x39, 0x47, 0xd1, 0x00, 0x00, 0x00, + GoTypes: file_internal_plugin_grpc_broker_proto_goTypes, + DependencyIndexes: file_internal_plugin_grpc_broker_proto_depIdxs, + MessageInfos: file_internal_plugin_grpc_broker_proto_msgTypes, + }.Build() + File_internal_plugin_grpc_broker_proto = out.File + file_internal_plugin_grpc_broker_proto_rawDesc = nil + file_internal_plugin_grpc_broker_proto_goTypes = nil + file_internal_plugin_grpc_broker_proto_depIdxs = nil } diff --git a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker.proto b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker.proto index 038423de..c92cd645 100644 --- a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker.proto +++ b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker.proto @@ -3,12 +3,18 @@ syntax = "proto3"; package plugin; -option go_package = "plugin"; +option go_package = "./plugin"; message ConnInfo { uint32 service_id = 1; string network = 2; string address = 3; + message Knock { + bool knock = 1; + bool ack = 2; + string error = 3; + } + Knock knock = 4; } service GRPCBroker { diff --git a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker_grpc.pb.go b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker_grpc.pb.go new file mode 100644 index 00000000..1b0f8070 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_broker_grpc.pb.go @@ -0,0 +1,142 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: internal/plugin/grpc_broker.proto + +package plugin + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + GRPCBroker_StartStream_FullMethodName = "/plugin.GRPCBroker/StartStream" +) + +// GRPCBrokerClient is the client API for GRPCBroker service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type GRPCBrokerClient interface { + StartStream(ctx context.Context, opts ...grpc.CallOption) (GRPCBroker_StartStreamClient, error) +} + +type gRPCBrokerClient struct { + cc grpc.ClientConnInterface +} + +func NewGRPCBrokerClient(cc grpc.ClientConnInterface) GRPCBrokerClient { + return &gRPCBrokerClient{cc} +} + +func (c *gRPCBrokerClient) StartStream(ctx context.Context, opts ...grpc.CallOption) (GRPCBroker_StartStreamClient, error) { + stream, err := c.cc.NewStream(ctx, &GRPCBroker_ServiceDesc.Streams[0], GRPCBroker_StartStream_FullMethodName, opts...) + if err != nil { + return nil, err + } + x := &gRPCBrokerStartStreamClient{stream} + return x, nil +} + +type GRPCBroker_StartStreamClient interface { + Send(*ConnInfo) error + Recv() (*ConnInfo, error) + grpc.ClientStream +} + +type gRPCBrokerStartStreamClient struct { + grpc.ClientStream +} + +func (x *gRPCBrokerStartStreamClient) Send(m *ConnInfo) error { + return x.ClientStream.SendMsg(m) +} + +func (x *gRPCBrokerStartStreamClient) Recv() (*ConnInfo, error) { + m := new(ConnInfo) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// GRPCBrokerServer is the server API for GRPCBroker service. +// All implementations should embed UnimplementedGRPCBrokerServer +// for forward compatibility +type GRPCBrokerServer interface { + StartStream(GRPCBroker_StartStreamServer) error +} + +// UnimplementedGRPCBrokerServer should be embedded to have forward compatible implementations. +type UnimplementedGRPCBrokerServer struct { +} + +func (UnimplementedGRPCBrokerServer) StartStream(GRPCBroker_StartStreamServer) error { + return status.Errorf(codes.Unimplemented, "method StartStream not implemented") +} + +// UnsafeGRPCBrokerServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to GRPCBrokerServer will +// result in compilation errors. +type UnsafeGRPCBrokerServer interface { + mustEmbedUnimplementedGRPCBrokerServer() +} + +func RegisterGRPCBrokerServer(s grpc.ServiceRegistrar, srv GRPCBrokerServer) { + s.RegisterService(&GRPCBroker_ServiceDesc, srv) +} + +func _GRPCBroker_StartStream_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(GRPCBrokerServer).StartStream(&gRPCBrokerStartStreamServer{stream}) +} + +type GRPCBroker_StartStreamServer interface { + Send(*ConnInfo) error + Recv() (*ConnInfo, error) + grpc.ServerStream +} + +type gRPCBrokerStartStreamServer struct { + grpc.ServerStream +} + +func (x *gRPCBrokerStartStreamServer) Send(m *ConnInfo) error { + return x.ServerStream.SendMsg(m) +} + +func (x *gRPCBrokerStartStreamServer) Recv() (*ConnInfo, error) { + m := new(ConnInfo) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// GRPCBroker_ServiceDesc is the grpc.ServiceDesc for GRPCBroker service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var GRPCBroker_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "plugin.GRPCBroker", + HandlerType: (*GRPCBrokerServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "StartStream", + Handler: _GRPCBroker_StartStream_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "internal/plugin/grpc_broker.proto", +} diff --git a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller.pb.go b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller.pb.go index 982fca0a..8ca48e0d 100644 --- a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller.pb.go +++ b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller.pb.go @@ -1,145 +1,141 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + // Code generated by protoc-gen-go. DO NOT EDIT. -// source: grpc_controller.proto +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: internal/plugin/grpc_controller.proto package plugin -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - import ( - context "context" - grpc "google.golang.org/grpc" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type Empty struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *Empty) Reset() { *m = Empty{} } -func (m *Empty) String() string { return proto.CompactTextString(m) } -func (*Empty) ProtoMessage() {} -func (*Empty) Descriptor() ([]byte, []int) { - return fileDescriptor_grpc_controller_08f8296ef6d80436, []int{0} -} -func (m *Empty) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Empty.Unmarshal(m, b) -} -func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Empty.Marshal(b, m, deterministic) -} -func (dst *Empty) XXX_Merge(src proto.Message) { - xxx_messageInfo_Empty.Merge(dst, src) -} -func (m *Empty) XXX_Size() int { - return xxx_messageInfo_Empty.Size(m) -} -func (m *Empty) XXX_DiscardUnknown() { - xxx_messageInfo_Empty.DiscardUnknown(m) +func (x *Empty) Reset() { + *x = Empty{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_plugin_grpc_controller_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -var xxx_messageInfo_Empty proto.InternalMessageInfo - -func init() { - proto.RegisterType((*Empty)(nil), "plugin.Empty") +func (x *Empty) String() string { + return protoimpl.X.MessageStringOf(x) } -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 +func (*Empty) ProtoMessage() {} -// GRPCControllerClient is the client API for GRPCController service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type GRPCControllerClient interface { - Shutdown(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) +func (x *Empty) ProtoReflect() protoreflect.Message { + mi := &file_internal_plugin_grpc_controller_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -type gRPCControllerClient struct { - cc *grpc.ClientConn +// Deprecated: Use Empty.ProtoReflect.Descriptor instead. +func (*Empty) Descriptor() ([]byte, []int) { + return file_internal_plugin_grpc_controller_proto_rawDescGZIP(), []int{0} } -func NewGRPCControllerClient(cc *grpc.ClientConn) GRPCControllerClient { - return &gRPCControllerClient{cc} -} +var File_internal_plugin_grpc_controller_proto protoreflect.FileDescriptor -func (c *gRPCControllerClient) Shutdown(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/plugin.GRPCController/Shutdown", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +var file_internal_plugin_grpc_controller_proto_rawDesc = []byte{ + 0x0a, 0x25, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x22, + 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x32, 0x3a, 0x0a, 0x0e, 0x47, 0x52, 0x50, 0x43, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x08, 0x53, 0x68, + 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x0d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } -// GRPCControllerServer is the server API for GRPCController service. -type GRPCControllerServer interface { - Shutdown(context.Context, *Empty) (*Empty, error) +var ( + file_internal_plugin_grpc_controller_proto_rawDescOnce sync.Once + file_internal_plugin_grpc_controller_proto_rawDescData = file_internal_plugin_grpc_controller_proto_rawDesc +) + +func file_internal_plugin_grpc_controller_proto_rawDescGZIP() []byte { + file_internal_plugin_grpc_controller_proto_rawDescOnce.Do(func() { + file_internal_plugin_grpc_controller_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_plugin_grpc_controller_proto_rawDescData) + }) + return file_internal_plugin_grpc_controller_proto_rawDescData } -func RegisterGRPCControllerServer(s *grpc.Server, srv GRPCControllerServer) { - s.RegisterService(&_GRPCController_serviceDesc, srv) +var file_internal_plugin_grpc_controller_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_internal_plugin_grpc_controller_proto_goTypes = []interface{}{ + (*Empty)(nil), // 0: plugin.Empty +} +var file_internal_plugin_grpc_controller_proto_depIdxs = []int32{ + 0, // 0: plugin.GRPCController.Shutdown:input_type -> plugin.Empty + 0, // 1: plugin.GRPCController.Shutdown:output_type -> plugin.Empty + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } -func _GRPCController_Shutdown_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GRPCControllerServer).Shutdown(ctx, in) +func init() { file_internal_plugin_grpc_controller_proto_init() } +func file_internal_plugin_grpc_controller_proto_init() { + if File_internal_plugin_grpc_controller_proto != nil { + return } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/plugin.GRPCController/Shutdown", + if !protoimpl.UnsafeEnabled { + file_internal_plugin_grpc_controller_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Empty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(GRPCControllerServer).Shutdown(ctx, req.(*Empty)) - } - return interceptor(ctx, in, info, handler) -} - -var _GRPCController_serviceDesc = grpc.ServiceDesc{ - ServiceName: "plugin.GRPCController", - HandlerType: (*GRPCControllerServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Shutdown", - Handler: _GRPCController_Shutdown_Handler, + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_internal_plugin_grpc_controller_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "grpc_controller.proto", -} - -func init() { - proto.RegisterFile("grpc_controller.proto", fileDescriptor_grpc_controller_08f8296ef6d80436) -} - -var fileDescriptor_grpc_controller_08f8296ef6d80436 = []byte{ - // 108 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4d, 0x2f, 0x2a, 0x48, - 0x8e, 0x4f, 0xce, 0xcf, 0x2b, 0x29, 0xca, 0xcf, 0xc9, 0x49, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, - 0xc9, 0x17, 0x62, 0x2b, 0xc8, 0x29, 0x4d, 0xcf, 0xcc, 0x53, 0x62, 0xe7, 0x62, 0x75, 0xcd, 0x2d, - 0x28, 0xa9, 0x34, 0xb2, 0xe2, 0xe2, 0x73, 0x0f, 0x0a, 0x70, 0x76, 0x86, 0x2b, 0x14, 0xd2, 0xe0, - 0xe2, 0x08, 0xce, 0x28, 0x2d, 0x49, 0xc9, 0x2f, 0xcf, 0x13, 0xe2, 0xd5, 0x83, 0xa8, 0xd7, 0x03, - 0x2b, 0x96, 0x42, 0xe5, 0x3a, 0x71, 0x44, 0x41, 0x8d, 0x4b, 0x62, 0x03, 0x9b, 0x6e, 0x0c, 0x08, - 0x00, 0x00, 0xff, 0xff, 0xab, 0x7c, 0x27, 0xe5, 0x76, 0x00, 0x00, 0x00, + GoTypes: file_internal_plugin_grpc_controller_proto_goTypes, + DependencyIndexes: file_internal_plugin_grpc_controller_proto_depIdxs, + MessageInfos: file_internal_plugin_grpc_controller_proto_msgTypes, + }.Build() + File_internal_plugin_grpc_controller_proto = out.File + file_internal_plugin_grpc_controller_proto_rawDesc = nil + file_internal_plugin_grpc_controller_proto_goTypes = nil + file_internal_plugin_grpc_controller_proto_depIdxs = nil } diff --git a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller.proto b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller.proto index 3157eb88..2755fa63 100644 --- a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller.proto +++ b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller.proto @@ -3,7 +3,7 @@ syntax = "proto3"; package plugin; -option go_package = "plugin"; +option go_package = "./plugin"; message Empty { } diff --git a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller_grpc.pb.go b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller_grpc.pb.go new file mode 100644 index 00000000..427611aa --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_controller_grpc.pb.go @@ -0,0 +1,110 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: internal/plugin/grpc_controller.proto + +package plugin + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + GRPCController_Shutdown_FullMethodName = "/plugin.GRPCController/Shutdown" +) + +// GRPCControllerClient is the client API for GRPCController service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type GRPCControllerClient interface { + Shutdown(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) +} + +type gRPCControllerClient struct { + cc grpc.ClientConnInterface +} + +func NewGRPCControllerClient(cc grpc.ClientConnInterface) GRPCControllerClient { + return &gRPCControllerClient{cc} +} + +func (c *gRPCControllerClient) Shutdown(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, GRPCController_Shutdown_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// GRPCControllerServer is the server API for GRPCController service. +// All implementations should embed UnimplementedGRPCControllerServer +// for forward compatibility +type GRPCControllerServer interface { + Shutdown(context.Context, *Empty) (*Empty, error) +} + +// UnimplementedGRPCControllerServer should be embedded to have forward compatible implementations. +type UnimplementedGRPCControllerServer struct { +} + +func (UnimplementedGRPCControllerServer) Shutdown(context.Context, *Empty) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Shutdown not implemented") +} + +// UnsafeGRPCControllerServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to GRPCControllerServer will +// result in compilation errors. +type UnsafeGRPCControllerServer interface { + mustEmbedUnimplementedGRPCControllerServer() +} + +func RegisterGRPCControllerServer(s grpc.ServiceRegistrar, srv GRPCControllerServer) { + s.RegisterService(&GRPCController_ServiceDesc, srv) +} + +func _GRPCController_Shutdown_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GRPCControllerServer).Shutdown(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GRPCController_Shutdown_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GRPCControllerServer).Shutdown(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +// GRPCController_ServiceDesc is the grpc.ServiceDesc for GRPCController service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var GRPCController_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "plugin.GRPCController", + HandlerType: (*GRPCControllerServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Shutdown", + Handler: _GRPCController_Shutdown_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "internal/plugin/grpc_controller.proto", +} diff --git a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio.pb.go b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio.pb.go index bdef71b8..139cbb4a 100644 --- a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio.pb.go +++ b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio.pb.go @@ -1,28 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + // Code generated by protoc-gen-go. DO NOT EDIT. -// source: grpc_stdio.proto +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: internal/plugin/grpc_stdio.proto package plugin -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import empty "github.com/golang/protobuf/ptypes/empty" - import ( - context "context" - grpc "google.golang.org/grpc" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type StdioData_Channel int32 @@ -32,202 +32,194 @@ const ( StdioData_STDERR StdioData_Channel = 2 ) -var StdioData_Channel_name = map[int32]string{ - 0: "INVALID", - 1: "STDOUT", - 2: "STDERR", -} -var StdioData_Channel_value = map[string]int32{ - "INVALID": 0, - "STDOUT": 1, - "STDERR": 2, -} - -func (x StdioData_Channel) String() string { - return proto.EnumName(StdioData_Channel_name, int32(x)) -} -func (StdioData_Channel) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_grpc_stdio_db2934322ca63bd5, []int{0, 0} -} +// Enum value maps for StdioData_Channel. +var ( + StdioData_Channel_name = map[int32]string{ + 0: "INVALID", + 1: "STDOUT", + 2: "STDERR", + } + StdioData_Channel_value = map[string]int32{ + "INVALID": 0, + "STDOUT": 1, + "STDERR": 2, + } +) -// StdioData is a single chunk of stdout or stderr data that is streamed -// from GRPCStdio. -type StdioData struct { - Channel StdioData_Channel `protobuf:"varint,1,opt,name=channel,proto3,enum=plugin.StdioData_Channel" json:"channel,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +func (x StdioData_Channel) Enum() *StdioData_Channel { + p := new(StdioData_Channel) + *p = x + return p } -func (m *StdioData) Reset() { *m = StdioData{} } -func (m *StdioData) String() string { return proto.CompactTextString(m) } -func (*StdioData) ProtoMessage() {} -func (*StdioData) Descriptor() ([]byte, []int) { - return fileDescriptor_grpc_stdio_db2934322ca63bd5, []int{0} -} -func (m *StdioData) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_StdioData.Unmarshal(m, b) -} -func (m *StdioData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_StdioData.Marshal(b, m, deterministic) -} -func (dst *StdioData) XXX_Merge(src proto.Message) { - xxx_messageInfo_StdioData.Merge(dst, src) -} -func (m *StdioData) XXX_Size() int { - return xxx_messageInfo_StdioData.Size(m) -} -func (m *StdioData) XXX_DiscardUnknown() { - xxx_messageInfo_StdioData.DiscardUnknown(m) +func (x StdioData_Channel) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -var xxx_messageInfo_StdioData proto.InternalMessageInfo - -func (m *StdioData) GetChannel() StdioData_Channel { - if m != nil { - return m.Channel - } - return StdioData_INVALID +func (StdioData_Channel) Descriptor() protoreflect.EnumDescriptor { + return file_internal_plugin_grpc_stdio_proto_enumTypes[0].Descriptor() } -func (m *StdioData) GetData() []byte { - if m != nil { - return m.Data - } - return nil +func (StdioData_Channel) Type() protoreflect.EnumType { + return &file_internal_plugin_grpc_stdio_proto_enumTypes[0] } -func init() { - proto.RegisterType((*StdioData)(nil), "plugin.StdioData") - proto.RegisterEnum("plugin.StdioData_Channel", StdioData_Channel_name, StdioData_Channel_value) +func (x StdioData_Channel) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// GRPCStdioClient is the client API for GRPCStdio service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type GRPCStdioClient interface { - // StreamStdio returns a stream that contains all the stdout/stderr. - // This RPC endpoint must only be called ONCE. Once stdio data is consumed - // it is not sent again. - // - // Callers should connect early to prevent blocking on the plugin process. - StreamStdio(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (GRPCStdio_StreamStdioClient, error) +// Deprecated: Use StdioData_Channel.Descriptor instead. +func (StdioData_Channel) EnumDescriptor() ([]byte, []int) { + return file_internal_plugin_grpc_stdio_proto_rawDescGZIP(), []int{0, 0} } -type gRPCStdioClient struct { - cc *grpc.ClientConn -} +// StdioData is a single chunk of stdout or stderr data that is streamed +// from GRPCStdio. +type StdioData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func NewGRPCStdioClient(cc *grpc.ClientConn) GRPCStdioClient { - return &gRPCStdioClient{cc} + Channel StdioData_Channel `protobuf:"varint,1,opt,name=channel,proto3,enum=plugin.StdioData_Channel" json:"channel,omitempty"` + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` } -func (c *gRPCStdioClient) StreamStdio(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (GRPCStdio_StreamStdioClient, error) { - stream, err := c.cc.NewStream(ctx, &_GRPCStdio_serviceDesc.Streams[0], "/plugin.GRPCStdio/StreamStdio", opts...) - if err != nil { - return nil, err - } - x := &gRPCStdioStreamStdioClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err +func (x *StdioData) Reset() { + *x = StdioData{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_plugin_grpc_stdio_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return x, nil } -type GRPCStdio_StreamStdioClient interface { - Recv() (*StdioData, error) - grpc.ClientStream +func (x *StdioData) String() string { + return protoimpl.X.MessageStringOf(x) } -type gRPCStdioStreamStdioClient struct { - grpc.ClientStream -} +func (*StdioData) ProtoMessage() {} -func (x *gRPCStdioStreamStdioClient) Recv() (*StdioData, error) { - m := new(StdioData) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err +func (x *StdioData) ProtoReflect() protoreflect.Message { + mi := &file_internal_plugin_grpc_stdio_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return m, nil -} - -// GRPCStdioServer is the server API for GRPCStdio service. -type GRPCStdioServer interface { - // StreamStdio returns a stream that contains all the stdout/stderr. - // This RPC endpoint must only be called ONCE. Once stdio data is consumed - // it is not sent again. - // - // Callers should connect early to prevent blocking on the plugin process. - StreamStdio(*empty.Empty, GRPCStdio_StreamStdioServer) error + return mi.MessageOf(x) } -func RegisterGRPCStdioServer(s *grpc.Server, srv GRPCStdioServer) { - s.RegisterService(&_GRPCStdio_serviceDesc, srv) +// Deprecated: Use StdioData.ProtoReflect.Descriptor instead. +func (*StdioData) Descriptor() ([]byte, []int) { + return file_internal_plugin_grpc_stdio_proto_rawDescGZIP(), []int{0} } -func _GRPCStdio_StreamStdio_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(empty.Empty) - if err := stream.RecvMsg(m); err != nil { - return err +func (x *StdioData) GetChannel() StdioData_Channel { + if x != nil { + return x.Channel } - return srv.(GRPCStdioServer).StreamStdio(m, &gRPCStdioStreamStdioServer{stream}) -} - -type GRPCStdio_StreamStdioServer interface { - Send(*StdioData) error - grpc.ServerStream + return StdioData_INVALID } -type gRPCStdioStreamStdioServer struct { - grpc.ServerStream +func (x *StdioData) GetData() []byte { + if x != nil { + return x.Data + } + return nil } -func (x *gRPCStdioStreamStdioServer) Send(m *StdioData) error { - return x.ServerStream.SendMsg(m) -} +var File_internal_plugin_grpc_stdio_proto protoreflect.FileDescriptor + +var file_internal_plugin_grpc_stdio_proto_rawDesc = []byte{ + 0x0a, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x74, 0x64, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, 0x01, 0x0a, 0x09, 0x53, 0x74, 0x64, 0x69, + 0x6f, 0x44, 0x61, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, + 0x53, 0x74, 0x64, 0x69, 0x6f, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, + 0x6c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x2e, + 0x0a, 0x07, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x44, 0x4f, 0x55, 0x54, + 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x10, 0x02, 0x32, 0x47, + 0x0a, 0x09, 0x47, 0x52, 0x50, 0x43, 0x53, 0x74, 0x64, 0x69, 0x6f, 0x12, 0x3a, 0x0a, 0x0b, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x64, 0x69, 0x6f, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, 0x74, 0x64, 0x69, + 0x6f, 0x44, 0x61, 0x74, 0x61, 0x30, 0x01, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_internal_plugin_grpc_stdio_proto_rawDescOnce sync.Once + file_internal_plugin_grpc_stdio_proto_rawDescData = file_internal_plugin_grpc_stdio_proto_rawDesc +) -var _GRPCStdio_serviceDesc = grpc.ServiceDesc{ - ServiceName: "plugin.GRPCStdio", - HandlerType: (*GRPCStdioServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "StreamStdio", - Handler: _GRPCStdio_StreamStdio_Handler, - ServerStreams: true, +func file_internal_plugin_grpc_stdio_proto_rawDescGZIP() []byte { + file_internal_plugin_grpc_stdio_proto_rawDescOnce.Do(func() { + file_internal_plugin_grpc_stdio_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_plugin_grpc_stdio_proto_rawDescData) + }) + return file_internal_plugin_grpc_stdio_proto_rawDescData +} + +var file_internal_plugin_grpc_stdio_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_internal_plugin_grpc_stdio_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_internal_plugin_grpc_stdio_proto_goTypes = []interface{}{ + (StdioData_Channel)(0), // 0: plugin.StdioData.Channel + (*StdioData)(nil), // 1: plugin.StdioData + (*emptypb.Empty)(nil), // 2: google.protobuf.Empty +} +var file_internal_plugin_grpc_stdio_proto_depIdxs = []int32{ + 0, // 0: plugin.StdioData.channel:type_name -> plugin.StdioData.Channel + 2, // 1: plugin.GRPCStdio.StreamStdio:input_type -> google.protobuf.Empty + 1, // 2: plugin.GRPCStdio.StreamStdio:output_type -> plugin.StdioData + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_internal_plugin_grpc_stdio_proto_init() } +func file_internal_plugin_grpc_stdio_proto_init() { + if File_internal_plugin_grpc_stdio_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_internal_plugin_grpc_stdio_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StdioData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_internal_plugin_grpc_stdio_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, }, - }, - Metadata: "grpc_stdio.proto", -} - -func init() { proto.RegisterFile("grpc_stdio.proto", fileDescriptor_grpc_stdio_db2934322ca63bd5) } - -var fileDescriptor_grpc_stdio_db2934322ca63bd5 = []byte{ - // 221 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x48, 0x2f, 0x2a, 0x48, - 0x8e, 0x2f, 0x2e, 0x49, 0xc9, 0xcc, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2b, 0xc8, - 0x29, 0x4d, 0xcf, 0xcc, 0x93, 0x92, 0x4e, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x07, 0x8b, 0x26, - 0x95, 0xa6, 0xe9, 0xa7, 0xe6, 0x16, 0x94, 0x54, 0x42, 0x14, 0x29, 0xb5, 0x30, 0x72, 0x71, 0x06, - 0x83, 0x34, 0xb9, 0x24, 0x96, 0x24, 0x0a, 0x19, 0x73, 0xb1, 0x27, 0x67, 0x24, 0xe6, 0xe5, 0xa5, - 0xe6, 0x48, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x19, 0x49, 0xea, 0x41, 0x0c, 0xd1, 0x83, 0xab, 0xd1, - 0x73, 0x86, 0x28, 0x08, 0x82, 0xa9, 0x14, 0x12, 0xe2, 0x62, 0x49, 0x49, 0x2c, 0x49, 0x94, 0x60, - 0x52, 0x60, 0xd4, 0xe0, 0x09, 0x02, 0xb3, 0x95, 0xf4, 0xb8, 0xd8, 0xa1, 0xea, 0x84, 0xb8, 0xb9, - 0xd8, 0x3d, 0xfd, 0xc2, 0x1c, 0x7d, 0x3c, 0x5d, 0x04, 0x18, 0x84, 0xb8, 0xb8, 0xd8, 0x82, 0x43, - 0x5c, 0xfc, 0x43, 0x43, 0x04, 0x18, 0xa1, 0x6c, 0xd7, 0xa0, 0x20, 0x01, 0x26, 0x23, 0x77, 0x2e, - 0x4e, 0xf7, 0xa0, 0x00, 0x67, 0xb0, 0x2d, 0x42, 0x56, 0x5c, 0xdc, 0xc1, 0x25, 0x45, 0xa9, 0x89, - 0xb9, 0x10, 0xae, 0x98, 0x1e, 0xc4, 0x03, 0x7a, 0x30, 0x0f, 0xe8, 0xb9, 0x82, 0x3c, 0x20, 0x25, - 0x88, 0xe1, 0x36, 0x03, 0x46, 0x27, 0x8e, 0x28, 0xa8, 0xb7, 0x93, 0xd8, 0xc0, 0xca, 0x8d, 0x01, - 0x01, 0x00, 0x00, 0xff, 0xff, 0x5d, 0xbb, 0xe0, 0x69, 0x19, 0x01, 0x00, 0x00, + GoTypes: file_internal_plugin_grpc_stdio_proto_goTypes, + DependencyIndexes: file_internal_plugin_grpc_stdio_proto_depIdxs, + EnumInfos: file_internal_plugin_grpc_stdio_proto_enumTypes, + MessageInfos: file_internal_plugin_grpc_stdio_proto_msgTypes, + }.Build() + File_internal_plugin_grpc_stdio_proto = out.File + file_internal_plugin_grpc_stdio_proto_rawDesc = nil + file_internal_plugin_grpc_stdio_proto_goTypes = nil + file_internal_plugin_grpc_stdio_proto_depIdxs = nil } diff --git a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio.proto b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio.proto index 1c0d1d05..f48ac76c 100644 --- a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio.proto +++ b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio.proto @@ -3,7 +3,7 @@ syntax = "proto3"; package plugin; -option go_package = "plugin"; +option go_package = "./plugin"; import "google/protobuf/empty.proto"; diff --git a/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio_grpc.pb.go b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio_grpc.pb.go new file mode 100644 index 00000000..f82b1503 --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/internal/plugin/grpc_stdio_grpc.pb.go @@ -0,0 +1,148 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: internal/plugin/grpc_stdio.proto + +package plugin + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + GRPCStdio_StreamStdio_FullMethodName = "/plugin.GRPCStdio/StreamStdio" +) + +// GRPCStdioClient is the client API for GRPCStdio service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type GRPCStdioClient interface { + // StreamStdio returns a stream that contains all the stdout/stderr. + // This RPC endpoint must only be called ONCE. Once stdio data is consumed + // it is not sent again. + // + // Callers should connect early to prevent blocking on the plugin process. + StreamStdio(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (GRPCStdio_StreamStdioClient, error) +} + +type gRPCStdioClient struct { + cc grpc.ClientConnInterface +} + +func NewGRPCStdioClient(cc grpc.ClientConnInterface) GRPCStdioClient { + return &gRPCStdioClient{cc} +} + +func (c *gRPCStdioClient) StreamStdio(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (GRPCStdio_StreamStdioClient, error) { + stream, err := c.cc.NewStream(ctx, &GRPCStdio_ServiceDesc.Streams[0], GRPCStdio_StreamStdio_FullMethodName, opts...) + if err != nil { + return nil, err + } + x := &gRPCStdioStreamStdioClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type GRPCStdio_StreamStdioClient interface { + Recv() (*StdioData, error) + grpc.ClientStream +} + +type gRPCStdioStreamStdioClient struct { + grpc.ClientStream +} + +func (x *gRPCStdioStreamStdioClient) Recv() (*StdioData, error) { + m := new(StdioData) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// GRPCStdioServer is the server API for GRPCStdio service. +// All implementations should embed UnimplementedGRPCStdioServer +// for forward compatibility +type GRPCStdioServer interface { + // StreamStdio returns a stream that contains all the stdout/stderr. + // This RPC endpoint must only be called ONCE. Once stdio data is consumed + // it is not sent again. + // + // Callers should connect early to prevent blocking on the plugin process. + StreamStdio(*emptypb.Empty, GRPCStdio_StreamStdioServer) error +} + +// UnimplementedGRPCStdioServer should be embedded to have forward compatible implementations. +type UnimplementedGRPCStdioServer struct { +} + +func (UnimplementedGRPCStdioServer) StreamStdio(*emptypb.Empty, GRPCStdio_StreamStdioServer) error { + return status.Errorf(codes.Unimplemented, "method StreamStdio not implemented") +} + +// UnsafeGRPCStdioServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to GRPCStdioServer will +// result in compilation errors. +type UnsafeGRPCStdioServer interface { + mustEmbedUnimplementedGRPCStdioServer() +} + +func RegisterGRPCStdioServer(s grpc.ServiceRegistrar, srv GRPCStdioServer) { + s.RegisterService(&GRPCStdio_ServiceDesc, srv) +} + +func _GRPCStdio_StreamStdio_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(emptypb.Empty) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(GRPCStdioServer).StreamStdio(m, &gRPCStdioStreamStdioServer{stream}) +} + +type GRPCStdio_StreamStdioServer interface { + Send(*StdioData) error + grpc.ServerStream +} + +type gRPCStdioStreamStdioServer struct { + grpc.ServerStream +} + +func (x *gRPCStdioStreamStdioServer) Send(m *StdioData) error { + return x.ServerStream.SendMsg(m) +} + +// GRPCStdio_ServiceDesc is the grpc.ServiceDesc for GRPCStdio service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var GRPCStdio_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "plugin.GRPCStdio", + HandlerType: (*GRPCStdioServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "StreamStdio", + Handler: _GRPCStdio_StreamStdio_Handler, + ServerStreams: true, + }, + }, + Metadata: "internal/plugin/grpc_stdio.proto", +} diff --git a/vendor/github.com/hashicorp/go-plugin/process.go b/vendor/github.com/hashicorp/go-plugin/process.go index 68b028c6..b8844636 100644 --- a/vendor/github.com/hashicorp/go-plugin/process.go +++ b/vendor/github.com/hashicorp/go-plugin/process.go @@ -2,26 +2,3 @@ // SPDX-License-Identifier: MPL-2.0 package plugin - -import ( - "time" -) - -// pidAlive checks whether a pid is alive. -func pidAlive(pid int) bool { - return _pidAlive(pid) -} - -// pidWait blocks for a process to exit. -func pidWait(pid int) error { - ticker := time.NewTicker(1 * time.Second) - defer ticker.Stop() - - for range ticker.C { - if !pidAlive(pid) { - break - } - } - - return nil -} diff --git a/vendor/github.com/hashicorp/go-plugin/runner/runner.go b/vendor/github.com/hashicorp/go-plugin/runner/runner.go new file mode 100644 index 00000000..e638ae5f --- /dev/null +++ b/vendor/github.com/hashicorp/go-plugin/runner/runner.go @@ -0,0 +1,72 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package runner + +import ( + "context" + "io" +) + +// Runner defines the interface required by go-plugin to manage the lifecycle of +// of a plugin and attempt to negotiate a connection with it. Note that this +// is orthogonal to the protocol and transport used, which is negotiated over stdout. +type Runner interface { + // Start should start the plugin and ensure any work required for servicing + // other interface methods is done. If the context is cancelled, it should + // only abort any attempts to _start_ the plugin. Waiting and shutdown are + // handled separately. + Start(ctx context.Context) error + + // Diagnose makes a best-effort attempt to return any debug information that + // might help users understand why a plugin failed to start and negotiate a + // connection. + Diagnose(ctx context.Context) string + + // Stdout is used to negotiate the go-plugin protocol. + Stdout() io.ReadCloser + + // Stderr is used for forwarding plugin logs to the host process logger. + Stderr() io.ReadCloser + + // Name is a human-friendly name for the plugin, such as the path to the + // executable. It does not have to be unique. + Name() string + + AttachedRunner +} + +// AttachedRunner defines a limited subset of Runner's interface to represent the +// reduced responsibility for plugin lifecycle when attaching to an already running +// plugin. +type AttachedRunner interface { + // Wait should wait until the plugin stops running, whether in response to + // an out of band signal or in response to calling Kill(). + Wait(ctx context.Context) error + + // Kill should stop the plugin and perform any cleanup required. + Kill(ctx context.Context) error + + // ID is a unique identifier to represent the running plugin. e.g. pid or + // container ID. + ID() string + + AddrTranslator +} + +// AddrTranslator translates addresses between the execution context of the host +// process and the plugin. For example, if the plugin is in a container, the file +// path for a Unix socket may be different between the host and the container. +// +// It is only intended to be used by the host process. +type AddrTranslator interface { + // Called before connecting on any addresses received back from the plugin. + PluginToHost(pluginNet, pluginAddr string) (hostNet string, hostAddr string, err error) + + // Called on any host process addresses before they are sent to the plugin. + HostToPlugin(hostNet, hostAddr string) (pluginNet string, pluginAddr string, err error) +} + +// ReattachFunc can be passed to a client's reattach config to reattach to an +// already running plugin instead of starting it ourselves. +type ReattachFunc func() (AttachedRunner, error) diff --git a/vendor/github.com/hashicorp/go-plugin/server.go b/vendor/github.com/hashicorp/go-plugin/server.go index 3f4a017d..e741bc7f 100644 --- a/vendor/github.com/hashicorp/go-plugin/server.go +++ b/vendor/github.com/hashicorp/go-plugin/server.go @@ -11,16 +11,17 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "os" "os/signal" + "os/user" "runtime" "sort" "strconv" "strings" hclog "github.com/hashicorp/go-hclog" + "github.com/hashicorp/go-plugin/internal/grpcmux" "google.golang.org/grpc" ) @@ -134,6 +135,13 @@ type ServeTestConfig struct { SyncStdio bool } +func unixSocketConfigFromEnv() UnixSocketConfig { + return UnixSocketConfig{ + Group: os.Getenv(EnvUnixSocketGroup), + socketDir: os.Getenv(EnvUnixSocketDir), + } +} + // protocolVersion determines the protocol version and plugin set to be used by // the server. In the event that there is no suitable version, the last version // in the config is returned leaving the client to report the incompatibility. @@ -273,7 +281,7 @@ func Serve(opts *ServeConfig) { } // Register a listener so we can accept a connection - listener, err := serverListener() + listener, err := serverListener(unixSocketConfigFromEnv()) if err != nil { logger.Error("plugin init error", "error", err) return @@ -380,6 +388,12 @@ func Serve(opts *ServeConfig) { } case ProtocolGRPC: + var muxer *grpcmux.GRPCServerMuxer + if multiplex, _ := strconv.ParseBool(os.Getenv(envMultiplexGRPC)); multiplex { + muxer = grpcmux.NewGRPCServerMuxer(logger, listener) + listener = muxer + } + // Create the gRPC server server = &GRPCServer{ Plugins: pluginSet, @@ -389,6 +403,7 @@ func Serve(opts *ServeConfig) { Stderr: stderr_r, DoneCh: doneCh, logger: logger, + muxer: muxer, } default: @@ -407,13 +422,27 @@ func Serve(opts *ServeConfig) { // bring it up. In test mode, we don't do this because clients will // attach via a reattach config. if opts.Test == nil { - fmt.Printf("%d|%d|%s|%s|%s|%s\n", + const grpcBrokerMultiplexingSupported = true + protocolLine := fmt.Sprintf("%d|%d|%s|%s|%s|%s", CoreProtocolVersion, protoVersion, listener.Addr().Network(), listener.Addr().String(), protoType, serverCert) + + // Old clients will error with new plugins if we blindly append the + // seventh segment for gRPC broker multiplexing support, because old + // client code uses strings.SplitN(line, "|", 6), which means a seventh + // segment will get appended to the sixth segment as "sixthpart|true". + // + // If the environment variable is set, we assume the client is new enough + // to handle a seventh segment, as it should now use + // strings.Split(line, "|") and always handle each segment individually. + if os.Getenv(envMultiplexGRPC) != "" { + protocolLine += fmt.Sprintf("|%v", grpcBrokerMultiplexingSupported) + } + fmt.Printf("%s\n", protocolLine) os.Stdout.Sync() } else if ch := opts.Test.ReattachConfigCh; ch != nil { // Send back the reattach config that can be used. This isn't @@ -496,12 +525,12 @@ func Serve(opts *ServeConfig) { } } -func serverListener() (net.Listener, error) { +func serverListener(unixSocketCfg UnixSocketConfig) (net.Listener, error) { if runtime.GOOS == "windows" { return serverListener_tcp() } - return serverListener_unix() + return serverListener_unix(unixSocketCfg) } func serverListener_tcp() (net.Listener, error) { @@ -546,8 +575,8 @@ func serverListener_tcp() (net.Listener, error) { return nil, errors.New("Couldn't bind plugin TCP listener") } -func serverListener_unix() (net.Listener, error) { - tf, err := ioutil.TempFile("", "plugin") +func serverListener_unix(unixSocketCfg UnixSocketConfig) (net.Listener, error) { + tf, err := os.CreateTemp(unixSocketCfg.socketDir, "plugin") if err != nil { return nil, err } @@ -567,20 +596,62 @@ func serverListener_unix() (net.Listener, error) { return nil, err } + // By default, unix sockets are only writable by the owner. Set up a custom + // group owner and group write permissions if configured. + if unixSocketCfg.Group != "" { + err = setGroupWritable(path, unixSocketCfg.Group, 0o660) + if err != nil { + return nil, err + } + } + // Wrap the listener in rmListener so that the Unix domain socket file // is removed on close. - return &rmListener{ - Listener: l, - Path: path, - }, nil + return newDeleteFileListener(l, path), nil +} + +func setGroupWritable(path, groupString string, mode os.FileMode) error { + groupID, err := strconv.Atoi(groupString) + if err != nil { + group, err := user.LookupGroup(groupString) + if err != nil { + return fmt.Errorf("failed to find gid from %q: %w", groupString, err) + } + groupID, err = strconv.Atoi(group.Gid) + if err != nil { + return fmt.Errorf("failed to parse %q group's gid as an integer: %w", groupString, err) + } + } + + err = os.Chown(path, -1, groupID) + if err != nil { + return err + } + + err = os.Chmod(path, mode) + if err != nil { + return err + } + + return nil } // rmListener is an implementation of net.Listener that forwards most -// calls to the listener but also removes a file as part of the close. We -// use this to cleanup the unix domain socket on close. +// calls to the listener but also calls an additional close function. We +// use this to cleanup the unix domain socket on close, as well as clean +// up multiplexed listeners. type rmListener struct { net.Listener - Path string + close func() error +} + +func newDeleteFileListener(ln net.Listener, path string) *rmListener { + return &rmListener{ + Listener: ln, + close: func() error { + return os.Remove(path) + }, + } } func (l *rmListener) Close() error { @@ -590,5 +661,5 @@ func (l *rmListener) Close() error { } // Remove the file - return os.Remove(l.Path) + return l.close() } diff --git a/vendor/github.com/hashicorp/go-plugin/testing.go b/vendor/github.com/hashicorp/go-plugin/testing.go index ffe6fa46..a8735dfc 100644 --- a/vendor/github.com/hashicorp/go-plugin/testing.go +++ b/vendor/github.com/hashicorp/go-plugin/testing.go @@ -11,7 +11,7 @@ import ( "net/rpc" hclog "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-plugin/internal/plugin" + "github.com/hashicorp/go-plugin/internal/grpcmux" "github.com/mitchellh/go-testing-interface" "google.golang.org/grpc" ) @@ -135,49 +135,51 @@ func TestGRPCConn(t testing.T, register func(*grpc.Server)) (*grpc.ClientConn, * // TestPluginGRPCConn returns a plugin gRPC client and server that are connected // together and configured. This is used to test gRPC connections. -func TestPluginGRPCConn(t testing.T, ps map[string]Plugin) (*GRPCClient, *GRPCServer) { +func TestPluginGRPCConn(t testing.T, multiplex bool, ps map[string]Plugin) (*GRPCClient, *GRPCServer) { // Create a listener - l, err := net.Listen("tcp", "127.0.0.1:0") + ln, err := serverListener(UnixSocketConfig{}) if err != nil { - t.Fatalf("err: %s", err) + t.Fatal(err) } + logger := hclog.New(&hclog.LoggerOptions{ + Level: hclog.Debug, + }) + // Start up the server + var muxer *grpcmux.GRPCServerMuxer + if multiplex { + muxer = grpcmux.NewGRPCServerMuxer(logger, ln) + ln = muxer + } server := &GRPCServer{ Plugins: ps, DoneCh: make(chan struct{}), Server: DefaultGRPCServer, Stdout: new(bytes.Buffer), Stderr: new(bytes.Buffer), - logger: hclog.Default(), + logger: logger, + muxer: muxer, } if err := server.Init(); err != nil { t.Fatalf("err: %s", err) } - go server.Serve(l) - - // Connect to the server - conn, err := grpc.Dial( - l.Addr().String(), - grpc.WithBlock(), - grpc.WithInsecure()) - if err != nil { - t.Fatalf("err: %s", err) + go server.Serve(ln) + + client := &Client{ + address: ln.Addr(), + protocol: ProtocolGRPC, + config: &ClientConfig{ + Plugins: ps, + GRPCBrokerMultiplex: multiplex, + }, + logger: logger, } - brokerGRPCClient := newGRPCBrokerClient(conn) - broker := newGRPCBroker(brokerGRPCClient, nil) - go broker.Run() - go brokerGRPCClient.StartStream() - - // Create the client - client := &GRPCClient{ - Conn: conn, - Plugins: ps, - broker: broker, - doneCtx: context.Background(), - controller: plugin.NewGRPCControllerClient(conn), + grpcClient, err := newGRPCClient(context.Background(), client) + if err != nil { + t.Fatal(err) } - return client, server + return grpcClient, server } diff --git a/vendor/github.com/hashicorp/hc-install/.go-version b/vendor/github.com/hashicorp/hc-install/.go-version index 5fb5a6b4..ce2dd535 100644 --- a/vendor/github.com/hashicorp/hc-install/.go-version +++ b/vendor/github.com/hashicorp/hc-install/.go-version @@ -1 +1 @@ -1.20 +1.21.5 diff --git a/vendor/github.com/hashicorp/hc-install/README.md b/vendor/github.com/hashicorp/hc-install/README.md index d3012d75..6e78b5a6 100644 --- a/vendor/github.com/hashicorp/hc-install/README.md +++ b/vendor/github.com/hashicorp/hc-install/README.md @@ -41,15 +41,16 @@ Each comes with different trade-offs described below. - `releases.{LatestVersion,ExactVersion}` - Downloads, verifies & installs any known product from `releases.hashicorp.com` - **Pros:** - Fast and reliable way of obtaining any pre-built version of any product + - Allows installation of enterprise versions - **Cons:** - - Installation may consume some bandwith, disk space and a little time + - Installation may consume some bandwidth, disk space and a little time - Potentially less stable builds (see `checkpoint` below) - `checkpoint.LatestVersion` - Downloads, verifies & installs any known product available in HashiCorp Checkpoint - **Pros:** - Checkpoint typically contains only product versions considered stable - **Cons:** - - Installation may consume some bandwith, disk space and a little time - - Currently doesn't allow installation of a old versions (see `releases` above) + - Installation may consume some bandwidth, disk space and a little time + - Currently doesn't allow installation of old versions or enterprise versions (see `releases` above) - `build.GitRevision` - Clones raw source code and builds the product from it - **Pros:** - Useful for catching bugs and incompatibilities as early as possible (prior to product release). diff --git a/vendor/github.com/hashicorp/hc-install/checkpoint/latest_version.go b/vendor/github.com/hashicorp/hc-install/checkpoint/latest_version.go index 23c6891e..2cd5379f 100644 --- a/vendor/github.com/hashicorp/hc-install/checkpoint/latest_version.go +++ b/vendor/github.com/hashicorp/hc-install/checkpoint/latest_version.go @@ -126,7 +126,7 @@ func (lv *LatestVersion) Install(ctx context.Context) (string, error) { if lv.ArmoredPublicKey != "" { d.ArmoredPublicKey = lv.ArmoredPublicKey } - zipFilePath, err := d.DownloadAndUnpack(ctx, pv, dstDir) + zipFilePath, err := d.DownloadAndUnpack(ctx, pv, dstDir, "") if zipFilePath != "" { lv.pathsToRemove = append(lv.pathsToRemove, zipFilePath) } diff --git a/vendor/github.com/hashicorp/hc-install/internal/build/install_go_version.go b/vendor/github.com/hashicorp/hc-install/internal/build/install_go_version.go index 385509a0..9dc070d7 100644 --- a/vendor/github.com/hashicorp/hc-install/internal/build/install_go_version.go +++ b/vendor/github.com/hashicorp/hc-install/internal/build/install_go_version.go @@ -13,14 +13,21 @@ import ( "github.com/hashicorp/go-version" ) +var v1_21 = version.Must(version.NewVersion("1.21")) + // installGoVersion installs given version of Go using Go // according to https://golang.org/doc/manage-install func (gb *GoBuild) installGoVersion(ctx context.Context, v *version.Version) (Go, error) { - versionString := v.Core().String() + goVersion := v.String() - // trim 0 patch versions as that's how Go does it :shrug: - shortVersion := strings.TrimSuffix(versionString, ".0") - pkgURL := fmt.Sprintf("golang.org/dl/go%s", shortVersion) + // trim 0 patch versions as that's how Go does it + // for versions prior to 1.21 + // See https://github.com/golang/go/issues/62136 + if v.LessThan(v1_21) { + versionString := v.Core().String() + goVersion = strings.TrimSuffix(versionString, ".0") + } + pkgURL := fmt.Sprintf("golang.org/dl/go%s", goVersion) gb.log().Printf("go getting %q", pkgURL) cmd := exec.CommandContext(ctx, "go", "get", pkgURL) @@ -36,7 +43,7 @@ func (gb *GoBuild) installGoVersion(ctx context.Context, v *version.Version) (Go return Go{}, fmt.Errorf("unable to install Go %s: %w\n%s", v, err, out) } - cmdName := fmt.Sprintf("go%s", shortVersion) + cmdName := fmt.Sprintf("go%s", goVersion) gb.log().Printf("downloading go %q", v) cmd = exec.CommandContext(ctx, cmdName, "download") diff --git a/vendor/github.com/hashicorp/hc-install/internal/releasesjson/downloader.go b/vendor/github.com/hashicorp/hc-install/internal/releasesjson/downloader.go index c5d71b38..146c1cf0 100644 --- a/vendor/github.com/hashicorp/hc-install/internal/releasesjson/downloader.go +++ b/vendor/github.com/hashicorp/hc-install/internal/releasesjson/downloader.go @@ -29,7 +29,7 @@ type Downloader struct { BaseURL string } -func (d *Downloader) DownloadAndUnpack(ctx context.Context, pv *ProductVersion, dstDir string) (zipFilePath string, err error) { +func (d *Downloader) DownloadAndUnpack(ctx context.Context, pv *ProductVersion, binDir string, licenseDir string) (zipFilePath string, err error) { if len(pv.Builds) == 0 { return "", fmt.Errorf("no builds found for %s %s", pv.Name, pv.Version) } @@ -166,6 +166,12 @@ func (d *Downloader) DownloadAndUnpack(ctx context.Context, pv *ProductVersion, return pkgFilePath, err } + // Determine the appropriate destination file path + dstDir := binDir + if isLicenseFile(f.Name) && licenseDir != "" { + dstDir = licenseDir + } + d.Logger.Printf("unpacking %s to %s", f.Name, dstDir) dstPath := filepath.Join(dstDir, f.Name) dstFile, err := os.Create(dstPath) @@ -200,3 +206,19 @@ func contentTypeIsZip(contentType string) bool { } return false } + +// Enterprise products have a few additional license files +// that need to be extracted to a separate directory +var licenseFiles = []string{ + "EULA.txt", + "TermsOfEvaluation.txt", +} + +func isLicenseFile(filename string) bool { + for _, lf := range licenseFiles { + if lf == filename { + return true + } + } + return false +} diff --git a/vendor/github.com/hashicorp/hc-install/internal/releasesjson/releases.go b/vendor/github.com/hashicorp/hc-install/internal/releasesjson/releases.go index acbb6761..755019f2 100644 --- a/vendor/github.com/hashicorp/hc-install/internal/releasesjson/releases.go +++ b/vendor/github.com/hashicorp/hc-install/internal/releasesjson/releases.go @@ -115,13 +115,6 @@ func (r *Releases) ListProductVersions(ctx context.Context, productName string) continue } - if ok, _ := versionIsSupported(v); !ok { - // Remove (currently unsupported) enterprise - // version and any other "custom" build - delete(p.Versions, rawVersion) - continue - } - p.Versions[rawVersion].Version = v } @@ -129,10 +122,6 @@ func (r *Releases) ListProductVersions(ctx context.Context, productName string) } func (r *Releases) GetProductVersion(ctx context.Context, product string, version *version.Version) (*ProductVersion, error) { - if ok, err := versionIsSupported(version); !ok { - return nil, fmt.Errorf("%s: %w", product, err) - } - client := httpclient.NewHTTPClient() indexURL := fmt.Sprintf("%s/%s/%s/index.json", @@ -178,12 +167,3 @@ func (r *Releases) GetProductVersion(ctx context.Context, product string, versio return pv, nil } - -func versionIsSupported(v *version.Version) (bool, error) { - isSupported := v.Metadata() == "" - if !isSupported { - return false, fmt.Errorf("cannot obtain %s (enterprise versions are not supported)", - v.String()) - } - return true, nil -} diff --git a/vendor/github.com/hashicorp/hc-install/product/nomad.go b/vendor/github.com/hashicorp/hc-install/product/nomad.go new file mode 100644 index 00000000..b675d9a1 --- /dev/null +++ b/vendor/github.com/hashicorp/hc-install/product/nomad.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package product + +import ( + "context" + "fmt" + "os/exec" + "regexp" + "runtime" + "strings" + + "github.com/hashicorp/go-version" + "github.com/hashicorp/hc-install/internal/build" +) + +var nomadVersionOutputRe = regexp.MustCompile(`Nomad ` + simpleVersionRe) + +var Nomad = Product{ + Name: "nomad", + BinaryName: func() string { + if runtime.GOOS == "windows" { + return "nomad.exe" + } + return "nomad" + }, + GetVersion: func(ctx context.Context, path string) (*version.Version, error) { + cmd := exec.CommandContext(ctx, path, "version") + + out, err := cmd.Output() + if err != nil { + return nil, err + } + + stdout := strings.TrimSpace(string(out)) + + submatches := nomadVersionOutputRe.FindStringSubmatch(stdout) + if len(submatches) != 2 { + return nil, fmt.Errorf("unexpected number of version matches %d for %s", len(submatches), stdout) + } + v, err := version.NewVersion(submatches[1]) + if err != nil { + return nil, fmt.Errorf("unable to parse version %q: %w", submatches[1], err) + } + + return v, err + }, + BuildInstructions: &BuildInstructions{ + GitRepoURL: "https://github.com/hashicorp/nomad.git", + PreCloneCheck: &build.GoIsInstalled{}, + Build: &build.GoBuild{DetectVendoring: true}, + }, +} diff --git a/vendor/github.com/hashicorp/hc-install/releases/enterprise.go b/vendor/github.com/hashicorp/hc-install/releases/enterprise.go new file mode 100644 index 00000000..179d40d1 --- /dev/null +++ b/vendor/github.com/hashicorp/hc-install/releases/enterprise.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package releases + +import "fmt" + +type EnterpriseOptions struct { + // LicenseDir represents directory path where to install license files (required) + LicenseDir string + + // Meta represents optional version metadata (e.g. hsm, fips1402) + Meta string +} + +func enterpriseVersionMetadata(eo *EnterpriseOptions) string { + if eo == nil { + return "" + } + + metadata := "ent" + if eo.Meta != "" { + metadata += "." + eo.Meta + } + return metadata +} + +func validateEnterpriseOptions(eo *EnterpriseOptions) error { + if eo == nil { + return nil + } + + if eo.LicenseDir == "" { + return fmt.Errorf("LicenseDir must be provided when requesting enterprise versions") + } + + return nil +} diff --git a/vendor/github.com/hashicorp/hc-install/releases/exact_version.go b/vendor/github.com/hashicorp/hc-install/releases/exact_version.go index 03111230..e42f4d23 100644 --- a/vendor/github.com/hashicorp/hc-install/releases/exact_version.go +++ b/vendor/github.com/hashicorp/hc-install/releases/exact_version.go @@ -28,6 +28,9 @@ type ExactVersion struct { InstallDir string Timeout time.Duration + // Enterprise indicates installation of enterprise version (leave nil for Community editions) + Enterprise *EnterpriseOptions + SkipChecksumVerification bool // ArmoredPublicKey is a public PGP key in ASCII/armor format to use @@ -67,6 +70,10 @@ func (ev *ExactVersion) Validate() error { return fmt.Errorf("unknown version") } + if err := validateEnterpriseOptions(ev.Enterprise); err != nil { + return err + } + return nil } @@ -100,7 +107,11 @@ func (ev *ExactVersion) Install(ctx context.Context) (string, error) { rels.BaseURL = ev.apiBaseURL } rels.SetLogger(ev.log()) - pv, err := rels.GetProductVersion(ctx, ev.Product.Name, ev.Version) + installVersion := ev.Version + if ev.Enterprise != nil { + installVersion = versionWithMetadata(installVersion, enterpriseVersionMetadata(ev.Enterprise)) + } + pv, err := rels.GetProductVersion(ctx, ev.Product.Name, installVersion) if err != nil { return "", err } @@ -118,7 +129,11 @@ func (ev *ExactVersion) Install(ctx context.Context) (string, error) { d.BaseURL = ev.apiBaseURL } - zipFilePath, err := d.DownloadAndUnpack(ctx, pv, dstDir) + licenseDir := "" + if ev.Enterprise != nil { + licenseDir = ev.Enterprise.LicenseDir + } + zipFilePath, err := d.DownloadAndUnpack(ctx, pv, dstDir, licenseDir) if zipFilePath != "" { ev.pathsToRemove = append(ev.pathsToRemove, zipFilePath) } @@ -151,3 +166,21 @@ func (ev *ExactVersion) Remove(ctx context.Context) error { return nil } + +// versionWithMetadata returns a new version by combining the given version with the given metadata +func versionWithMetadata(v *version.Version, metadata string) *version.Version { + if v == nil { + return nil + } + + if metadata == "" { + return v + } + + v2, err := version.NewVersion(fmt.Sprintf("%s+%s", v.Core(), metadata)) + if err != nil { + return nil + } + + return v2 +} diff --git a/vendor/github.com/hashicorp/hc-install/releases/latest_version.go b/vendor/github.com/hashicorp/hc-install/releases/latest_version.go index 0dc1ffa4..9893b223 100644 --- a/vendor/github.com/hashicorp/hc-install/releases/latest_version.go +++ b/vendor/github.com/hashicorp/hc-install/releases/latest_version.go @@ -28,6 +28,9 @@ type LatestVersion struct { Timeout time.Duration IncludePrereleases bool + // Enterprise indicates installation of enterprise version (leave nil for Community editions) + Enterprise *EnterpriseOptions + SkipChecksumVerification bool // ArmoredPublicKey is a public PGP key in ASCII/armor format to use @@ -63,6 +66,10 @@ func (lv *LatestVersion) Validate() error { return fmt.Errorf("invalid binary name: %q", lv.Product.BinaryName()) } + if err := validateEnterpriseOptions(lv.Enterprise); err != nil { + return err + } + return nil } @@ -122,7 +129,11 @@ func (lv *LatestVersion) Install(ctx context.Context) (string, error) { if lv.apiBaseURL != "" { d.BaseURL = lv.apiBaseURL } - zipFilePath, err := d.DownloadAndUnpack(ctx, versionToInstall, dstDir) + licenseDir := "" + if lv.Enterprise != nil { + licenseDir = lv.Enterprise.LicenseDir + } + zipFilePath, err := d.DownloadAndUnpack(ctx, versionToInstall, dstDir, licenseDir) if zipFilePath != "" { lv.pathsToRemove = append(lv.pathsToRemove, zipFilePath) } @@ -156,6 +167,7 @@ func (lv *LatestVersion) Remove(ctx context.Context) error { } func (lv *LatestVersion) findLatestMatchingVersion(pvs rjson.ProductVersionsMap, vc version.Constraints) (*rjson.ProductVersion, bool) { + expectedMetadata := enterpriseVersionMetadata(lv.Enterprise) versions := make(version.Collection, 0) for _, pv := range pvs.AsSlice() { if !lv.IncludePrereleases && pv.Version.Prerelease() != "" { @@ -163,7 +175,13 @@ func (lv *LatestVersion) findLatestMatchingVersion(pvs rjson.ProductVersionsMap, continue } - versions = append(versions, pv.Version) + if pv.Version.Metadata() != expectedMetadata { + continue + } + + if vc.Check(pv.Version) { + versions = append(versions, pv.Version) + } } if len(versions) == 0 { diff --git a/vendor/github.com/hashicorp/hc-install/releases/versions.go b/vendor/github.com/hashicorp/hc-install/releases/versions.go index 9084c91b..49b1af78 100644 --- a/vendor/github.com/hashicorp/hc-install/releases/versions.go +++ b/vendor/github.com/hashicorp/hc-install/releases/versions.go @@ -21,6 +21,7 @@ import ( type Versions struct { Product product.Product Constraints version.Constraints + Enterprise *EnterpriseOptions // require enterprise version if set (leave nil for OSS) ListTimeout time.Duration @@ -45,6 +46,10 @@ func (v *Versions) List(ctx context.Context) ([]src.Source, error) { return nil, fmt.Errorf("invalid product name: %q", v.Product.Name) } + if err := validateEnterpriseOptions(v.Enterprise); err != nil { + return nil, err + } + timeout := defaultListTimeout if v.ListTimeout > 0 { timeout = v.ListTimeout @@ -61,6 +66,8 @@ func (v *Versions) List(ctx context.Context) ([]src.Source, error) { versions := pvs.AsSlice() sort.Stable(versions) + expectedMetadata := enterpriseVersionMetadata(v.Enterprise) + installables := make([]src.Source, 0) for _, pv := range versions { if !v.Constraints.Check(pv.Version) { @@ -68,6 +75,11 @@ func (v *Versions) List(ctx context.Context) ([]src.Source, error) { continue } + if pv.Version.Metadata() != expectedMetadata { + // skip version which doesn't match required metadata for enterprise or OSS versions + continue + } + ev := &ExactVersion{ Product: v.Product, Version: pv.Version, @@ -78,6 +90,13 @@ func (v *Versions) List(ctx context.Context) ([]src.Source, error) { SkipChecksumVerification: v.Install.SkipChecksumVerification, } + if v.Enterprise != nil { + ev.Enterprise = &EnterpriseOptions{ + Meta: v.Enterprise.Meta, + LicenseDir: v.Enterprise.LicenseDir, + } + } + installables = append(installables, ev) } diff --git a/vendor/github.com/hashicorp/hc-install/version/VERSION b/vendor/github.com/hashicorp/hc-install/version/VERSION index cb0c939a..844f6a91 100644 --- a/vendor/github.com/hashicorp/hc-install/version/VERSION +++ b/vendor/github.com/hashicorp/hc-install/version/VERSION @@ -1 +1 @@ -0.5.2 +0.6.3 diff --git a/vendor/github.com/hashicorp/hcl/v2/CHANGELOG.md b/vendor/github.com/hashicorp/hcl/v2/CHANGELOG.md index 82175271..2eebedbc 100644 --- a/vendor/github.com/hashicorp/hcl/v2/CHANGELOG.md +++ b/vendor/github.com/hashicorp/hcl/v2/CHANGELOG.md @@ -1,5 +1,61 @@ # HCL Changelog +## v2.20.1 (March 26, 2024) + +### Bugs Fixed + +* Return `ExprSyntaxError` when an invalid namespaced function is encountered during parsing ([#668](https://github.com/hashicorp/hcl/pull/668)) + +### Internal + +* Standardize on only two value dumping/diffing libraries ([#669](https://github.com/hashicorp/hcl/pull/669)) + +## v2.20.0 (February 29, 2024) + +### Enhancements + +* Support for namespaced functions ([#639](https://github.com/hashicorp/hcl/pull/639)) + +### Bugs Fixed + +* ext/dynblock: if `iterator` is invalid return this error instead of consequential errors ([#656](https://github.com/hashicorp/hcl/pull/656)) + +## v2.19.0 (October 16, 2023) + +### Enhancements + +* ext/dynblock: `dynblock.Expand` now supports an optional hook for calling applications to check and potentially veto (by returning error diagnostics) particular `for_each` values. The behavior is unchanged for callers that don't set the new option. ([#634](https://github.com/hashicorp/hcl/pull/634)) + +### Bugs Fixed + +* hclsyntax: Further fixes for treatment of "marked" values in the conditional expression, and better tracking of refined values into the conditional expression results, building on the fixes from v2.18.1. ([#633](https://github.com/hashicorp/hcl/pull/633)) + +## v2.18.1 (October 5, 2023) + +### Bugs Fixed + +* hclsyntax: Conditional expressions will no longer panic when one or both of their results are "marked", as is the case for situations like how HashiCorp Terraform tracks its concept of "sensitive values". ([#630](https://github.com/hashicorp/hcl/pull/630)) + +## v2.18.0 (August 30, 2023) + +### Enhancements + +* HCL now uses the tables from Unicode 15 when performing string normalization and character segmentation. HCL was previously using the Unicode 13 tables. + + For calling applications where consistent Unicode support is important, consider also upgrading to Go 1.21 at the same time as adopting HCL v2.18.0 so that the standard library unicode tables (used for case folding, etc) will also be from Unicode 15. + +## v2.17.1 (August 30, 2023) + +### Enhancements + +* hclsyntax: When evaluating string templates that have a long known constant prefix, HCL will truncate the known prefix to avoid creating excessively-large refinements. String prefix refinements are intended primarily for relatively-short fixed prefixes, such as `https://` at the start of a URL known to use that scheme. ([#617](https://github.com/hashicorp/hcl/pull/617)) +* ext/tryfunc: The "try" and "can" functions now handle unknown values slightly more precisely, and so can return known values in more situations when given expressions referring to unknown symbols. ([#622](https://github.com/hashicorp/hcl/pull/622)) + +### Bugs Fixed + +* ext/typeexpr: Will no longer try to refine unknown values of unknown type when dealing with a user-specified type constraint containing the `any` keyword, avoiding an incorrect panic at runtime. ([#625](https://github.com/hashicorp/hcl/pull/625)) +* ext/typeexpr: Now correctly handles attempts to declare the same object type attribute multiple times by returning an error. Previously this could potentially panic by creating an incoherent internal state. ([#624](https://github.com/hashicorp/hcl/pull/624)) + ## v2.17.0 (May 31, 2023) ### Enhancements @@ -7,7 +63,7 @@ * HCL now uses a newer version of the upstream `cty` library which has improved treatment of unknown values: it can now track additional optional information that reduces the range of an unknown value, which allows some operations against unknown values to return known or partially-known results. ([#590](https://github.com/hashicorp/hcl/pull/590)) **Note:** This change effectively passes on [`cty`'s notion of backward compatibility](https://github.com/zclconf/go-cty/blob/main/COMPATIBILITY.md) whereby unknown values can become "more known" in later releases. In particular, if your caller is using `cty.Value.RawEquals` in its tests against the results of operations with unknown values then you may see those tests begin failing after upgrading, due to the values now being more "refined". - + If so, you should review the refinements with consideration to [the `cty` refinements docs](https://github.com/zclconf/go-cty/blob/7dcbae46a6f247e983efb1fa774d2bb68781a333/docs/refinements.md) and update your expected results to match only if the reported refinements seem correct for the given situation. The `RawEquals` method is intended only for making exact value comparisons in test cases, so main application code should not use it; use `Equals` instead for real logic, which will take refinements into account automatically. ## v2.16.2 (March 9, 2023) @@ -137,7 +193,7 @@ * hclsyntax: Mark objects with keys that are sensitive. ([#440](https://github.com/hashicorp/hcl/pull/440)) ## v2.8.1 (December 17, 2020) - + ### Bugs Fixed * hclsyntax: Fix panic when expanding marked function arguments. ([#429](https://github.com/hashicorp/hcl/pull/429)) diff --git a/vendor/github.com/hashicorp/hcl/v2/Makefile b/vendor/github.com/hashicorp/hcl/v2/Makefile new file mode 100644 index 00000000..675178e7 --- /dev/null +++ b/vendor/github.com/hashicorp/hcl/v2/Makefile @@ -0,0 +1,18 @@ +fmtcheck: + "$(CURDIR)/scripts/gofmtcheck.sh" + +fmtfix: + gofmt -w ./ + +vetcheck: + go vet ./... + +copyrightcheck: + go run github.com/hashicorp/copywrite@latest headers --plan + +copyrightfix: + go run github.com/hashicorp/copywrite@latest headers + +check: copyrightcheck vetcheck fmtcheck + +fix: copyrightfix fmtfix diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression.go index 5df423fe..81597399 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression.go @@ -6,6 +6,7 @@ package hclsyntax import ( "fmt" "sort" + "strings" "sync" "github.com/hashicorp/hcl/v2" @@ -251,6 +252,76 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti } } + extraUnknown := &functionCallUnknown{ + name: e.Name, + } + + // For historical reasons, we represent namespaced function names + // as strings with :: separating the names. If this was an attempt + // to call a namespaced function then we'll try to distinguish + // between an invalid namespace or an invalid name within a valid + // namespace in order to give the user better feedback about what + // is wrong. + // + // The parser guarantees that a function name will always + // be a series of valid identifiers separated by "::" with no + // other content, so we can be relatively unforgiving in our processing + // here. + if sepIdx := strings.LastIndex(e.Name, "::"); sepIdx != -1 { + namespace := e.Name[:sepIdx+2] + name := e.Name[sepIdx+2:] + + avail := make([]string, 0, len(ctx.Functions)) + for availName := range ctx.Functions { + if strings.HasPrefix(availName, namespace) { + avail = append(avail, availName) + } + } + + extraUnknown.name = name + extraUnknown.namespace = namespace + + if len(avail) == 0 { + // TODO: Maybe use nameSuggestion for the other available + // namespaces? But that'd require us to go scan the function + // table again, so we'll wait to see if it's really warranted. + // For now, we're assuming people are more likely to misremember + // the function names than the namespaces, because in many + // applications there will be relatively few namespaces compared + // to the number of distinct functions. + return cty.DynamicVal, hcl.Diagnostics{ + { + Severity: hcl.DiagError, + Summary: "Call to unknown function", + Detail: fmt.Sprintf("There are no functions in namespace %q.", namespace), + Subject: &e.NameRange, + Context: e.Range().Ptr(), + Expression: e, + EvalContext: ctx, + Extra: extraUnknown, + }, + } + } else { + suggestion := nameSuggestion(name, avail) + if suggestion != "" { + suggestion = fmt.Sprintf(" Did you mean %s%s?", namespace, suggestion) + } + + return cty.DynamicVal, hcl.Diagnostics{ + { + Severity: hcl.DiagError, + Summary: "Call to unknown function", + Detail: fmt.Sprintf("There is no function named %q in namespace %s.%s", name, namespace, suggestion), + Subject: &e.NameRange, + Context: e.Range().Ptr(), + Expression: e, + EvalContext: ctx, + Extra: extraUnknown, + }, + } + } + } + avail := make([]string, 0, len(ctx.Functions)) for name := range ctx.Functions { avail = append(avail, name) @@ -269,6 +340,7 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti Context: e.Range().Ptr(), Expression: e, EvalContext: ctx, + Extra: extraUnknown, }, } } @@ -616,6 +688,27 @@ func (e *functionCallDiagExtra) FunctionCallError() error { return e.functionCallError } +// FunctionCallUnknownDiagExtra is an interface implemented by a value in the Extra +// field of some diagnostics to indicate when the error was caused by a call to +// an unknown function. +type FunctionCallUnknownDiagExtra interface { + CalledFunctionName() string + CalledFunctionNamespace() string +} + +type functionCallUnknown struct { + name string + namespace string +} + +func (e *functionCallUnknown) CalledFunctionName() string { + return e.name +} + +func (e *functionCallUnknown) CalledFunctionNamespace() string { + return e.namespace +} + type ConditionalExpr struct { Condition Expression TrueResult Expression @@ -696,60 +789,95 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic return cty.UnknownVal(resultType), diags } if !condResult.IsKnown() { + // we use the unmarked values throughout the unknown branch + _, condResultMarks := condResult.Unmark() + trueResult, trueResultMarks := trueResult.Unmark() + falseResult, falseResultMarks := falseResult.Unmark() + + // use a value to merge marks + _, resMarks := cty.DynamicVal.WithMarks(condResultMarks, trueResultMarks, falseResultMarks).Unmark() + + trueRange := trueResult.Range() + falseRange := falseResult.Range() + + // if both branches are known to be null, then the result must still be null + if trueResult.IsNull() && falseResult.IsNull() { + return cty.NullVal(resultType).WithMarks(resMarks), diags + } + // We might be able to offer a refined range for the result based on // the two possible outcomes. if trueResult.Type() == cty.Number && falseResult.Type() == cty.Number { - // This case deals with the common case of (predicate ? 1 : 0) and - // significantly decreases the range of the result in that case. - if !(trueResult.IsNull() || falseResult.IsNull()) { - if gt := trueResult.GreaterThan(falseResult); gt.IsKnown() { - b := cty.UnknownVal(cty.Number).Refine() - if gt.True() { - b = b. - NumberRangeLowerBound(falseResult, true). - NumberRangeUpperBound(trueResult, true) - } else { - b = b. - NumberRangeLowerBound(trueResult, true). - NumberRangeUpperBound(falseResult, true) - } - b = b.NotNull() // If neither of the results is null then the result can't be either - return b.NewValue().WithSameMarks(condResult).WithSameMarks(trueResult).WithSameMarks(falseResult), diags + ref := cty.UnknownVal(cty.Number).Refine() + if trueRange.DefinitelyNotNull() && falseRange.DefinitelyNotNull() { + ref = ref.NotNull() + } + + falseLo, falseLoInc := falseRange.NumberLowerBound() + falseHi, falseHiInc := falseRange.NumberUpperBound() + trueLo, trueLoInc := trueRange.NumberLowerBound() + trueHi, trueHiInc := trueRange.NumberUpperBound() + + if falseLo.IsKnown() && trueLo.IsKnown() { + lo, loInc := falseLo, falseLoInc + switch { + case trueLo.LessThan(falseLo).True(): + lo, loInc = trueLo, trueLoInc + case trueLo.Equals(falseLo).True(): + loInc = trueLoInc || falseLoInc + } + + ref = ref.NumberRangeLowerBound(lo, loInc) + } + + if falseHi.IsKnown() && trueHi.IsKnown() { + hi, hiInc := falseHi, falseHiInc + switch { + case trueHi.GreaterThan(falseHi).True(): + hi, hiInc = trueHi, trueHiInc + case trueHi.Equals(falseHi).True(): + hiInc = trueHiInc || falseHiInc } + ref = ref.NumberRangeUpperBound(hi, hiInc) } + + return ref.NewValue().WithMarks(resMarks), diags } + if trueResult.Type().IsCollectionType() && falseResult.Type().IsCollectionType() { if trueResult.Type().Equals(falseResult.Type()) { - if !(trueResult.IsNull() || falseResult.IsNull()) { - trueLen := trueResult.Length() - falseLen := falseResult.Length() - if gt := trueLen.GreaterThan(falseLen); gt.IsKnown() { - b := cty.UnknownVal(resultType).Refine() - trueLen, _ := trueLen.AsBigFloat().Int64() - falseLen, _ := falseLen.AsBigFloat().Int64() - if gt.True() { - b = b. - CollectionLengthLowerBound(int(falseLen)). - CollectionLengthUpperBound(int(trueLen)) - } else { - b = b. - CollectionLengthLowerBound(int(trueLen)). - CollectionLengthUpperBound(int(falseLen)) - } - b = b.NotNull() // If neither of the results is null then the result can't be either - return b.NewValue().WithSameMarks(condResult).WithSameMarks(trueResult).WithSameMarks(falseResult), diags - } + ref := cty.UnknownVal(resultType).Refine() + if trueRange.DefinitelyNotNull() && falseRange.DefinitelyNotNull() { + ref = ref.NotNull() + } + + falseLo := falseRange.LengthLowerBound() + falseHi := falseRange.LengthUpperBound() + trueLo := trueRange.LengthLowerBound() + trueHi := trueRange.LengthUpperBound() + + lo := falseLo + if trueLo < falseLo { + lo = trueLo + } + + hi := falseHi + if trueHi > falseHi { + hi = trueHi } + + ref = ref.CollectionLengthLowerBound(lo).CollectionLengthUpperBound(hi) + return ref.NewValue().WithMarks(resMarks), diags } } - trueRng := trueResult.Range() - falseRng := falseResult.Range() + ret := cty.UnknownVal(resultType) - if trueRng.DefinitelyNotNull() && falseRng.DefinitelyNotNull() { + if trueRange.DefinitelyNotNull() && falseRange.DefinitelyNotNull() { ret = ret.RefineNotNull() } - return ret.WithSameMarks(condResult).WithSameMarks(trueResult).WithSameMarks(falseResult), diags + return ret.WithMarks(resMarks), diags } + condResult, err := convert.Convert(condResult, cty.Bool) if err != nil { diags = append(diags, &hcl.Diagnostic{ @@ -1240,9 +1368,9 @@ func (e *ObjectConsKeyExpr) UnwrapExpression() Expression { // ForExpr represents iteration constructs: // -// tuple = [for i, v in list: upper(v) if i > 2] -// object = {for k, v in map: k => upper(v)} -// object_of_tuples = {for v in list: v.key: v...} +// tuple = [for i, v in list: upper(v) if i > 2] +// object = {for k, v in map: k => upper(v)} +// object_of_tuples = {for v in list: v.key: v...} type ForExpr struct { KeyVar string // empty if ignoring the key ValVar string @@ -1738,7 +1866,8 @@ func (e *SplatExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { if ty.IsListType() && sourceVal.Type().IsCollectionType() { // We can refine the length of an unknown list result based on // the source collection's own length. - sourceRng := sourceVal.Range() + sv, _ := sourceVal.Unmark() + sourceRng := sv.Range() ret = ret.Refine(). CollectionLengthLowerBound(sourceRng.LengthLowerBound()). CollectionLengthUpperBound(sourceRng.LengthUpperBound()). @@ -1884,3 +2013,27 @@ func (e *AnonSymbolExpr) Range() hcl.Range { func (e *AnonSymbolExpr) StartRange() hcl.Range { return e.SrcRange } + +// ExprSyntaxError is a placeholder for an invalid expression that could not +// be parsed due to syntax errors. +type ExprSyntaxError struct { + Placeholder cty.Value + ParseDiags hcl.Diagnostics + SrcRange hcl.Range +} + +func (e *ExprSyntaxError) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { + return e.Placeholder, e.ParseDiags +} + +func (e *ExprSyntaxError) walkChildNodes(w internalWalkFunc) { + // ExprSyntaxError is a leaf node in the tree +} + +func (e *ExprSyntaxError) Range() hcl.Range { + return e.SrcRange +} + +func (e *ExprSyntaxError) StartRange() hcl.Range { + return e.SrcRange +} diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_template.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_template.go index f175fc5f..a0dc7c22 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_template.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_template.go @@ -94,7 +94,16 @@ func (e *TemplateExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) ret = cty.UnknownVal(cty.String) if !diags.HasErrors() { // Invalid input means our partial result buffer is suspect if knownPrefix := buf.String(); knownPrefix != "" { - ret = ret.Refine().StringPrefix(knownPrefix).NewValue() + byteLen := len(knownPrefix) + // Impose a reasonable upper limit to avoid producing too long a prefix. + // The 128 B is about 10% of the safety limits in cty's msgpack decoder. + // @see https://github.com/zclconf/go-cty/blob/v1.13.2/cty/msgpack/unknown.go#L170-L175 + // + // This operation is safe because StringPrefix removes incomplete trailing grapheme clusters. + if byteLen > 128 { // arbitrarily-decided threshold + byteLen = 128 + } + ret = ret.Refine().StringPrefix(knownPrefix[:byteLen]).NewValue() } } } else { diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_vars.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_vars.go index ce5a5cb7..6c3e472c 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_vars.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_vars.go @@ -3,7 +3,7 @@ package hclsyntax -// Generated by expression_vars_get.go. DO NOT EDIT. +// Generated by expression_vars_gen.go. DO NOT EDIT. // Run 'go generate' on this package to update the set of functions here. import ( @@ -22,6 +22,10 @@ func (e *ConditionalExpr) Variables() []hcl.Traversal { return Variables(e) } +func (e *ExprSyntaxError) Variables() []hcl.Traversal { + return Variables(e) +} + func (e *ForExpr) Variables() []hcl.Traversal { return Variables(e) } diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/generate.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/generate.go index 383ec6b8..66486074 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/generate.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/generate.go @@ -9,4 +9,4 @@ package hclsyntax //go:generate gofmt -w scan_tokens.go //go:generate ragel -Z scan_string_lit.rl //go:generate gofmt -w scan_string_lit.go -//go:generate stringer -type TokenType -output token_type_string.go +//go:generate go run golang.org/x/tools/cmd/stringer -type TokenType -output token_type_string.go diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser.go index 6ed88e63..ce96ae35 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser.go @@ -9,7 +9,7 @@ import ( "strconv" "unicode/utf8" - "github.com/apparentlymart/go-textseg/v13/textseg" + "github.com/apparentlymart/go-textseg/v15/textseg" "github.com/hashicorp/hcl/v2" "github.com/zclconf/go-cty/cty" ) @@ -999,7 +999,7 @@ func (p *parser) parseExpressionTerm() (Expression, hcl.Diagnostics) { case TokenIdent: tok := p.Read() // eat identifier token - if p.Peek().Type == TokenOParen { + if p.Peek().Type == TokenOParen || p.Peek().Type == TokenDoubleColon { return p.finishParsingFunctionCall(tok) } @@ -1145,16 +1145,76 @@ func (p *parser) numberLitValue(tok Token) (cty.Value, hcl.Diagnostics) { // finishParsingFunctionCall parses a function call assuming that the function // name was already read, and so the peeker should be pointing at the opening -// parenthesis after the name. +// parenthesis after the name, or at the double-colon after the initial +// function scope name. func (p *parser) finishParsingFunctionCall(name Token) (Expression, hcl.Diagnostics) { + var diags hcl.Diagnostics + openTok := p.Read() - if openTok.Type != TokenOParen { + if openTok.Type != TokenOParen && openTok.Type != TokenDoubleColon { // should never happen if callers behave - panic("finishParsingFunctionCall called with non-parenthesis as next token") + panic("finishParsingFunctionCall called with unsupported next token") + } + + nameStr := string(name.Bytes) + nameEndPos := name.Range.End + for openTok.Type == TokenDoubleColon { + nextName := p.Read() + if nextName.Type != TokenIdent { + diag := hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Missing function name", + Detail: "Function scope resolution symbol :: must be followed by a function name in this scope.", + Subject: &nextName.Range, + Context: hcl.RangeBetween(name.Range, nextName.Range).Ptr(), + } + diags = append(diags, &diag) + p.recoverOver(TokenOParen) + return &ExprSyntaxError{ + ParseDiags: hcl.Diagnostics{&diag}, + Placeholder: cty.DynamicVal, + SrcRange: hcl.RangeBetween(name.Range, nextName.Range), + }, diags + } + + // Initial versions of HCLv2 didn't support function namespaces, and + // so for backward compatibility we just treat namespaced functions + // as weird names with "::" separators in them, saved as a string + // to keep the API unchanged. FunctionCallExpr also has some special + // handling of names containing :: when referring to a function that + // doesn't exist in EvalContext, to return better error messages + // when namespaces are used incorrectly. + nameStr = nameStr + "::" + string(nextName.Bytes) + nameEndPos = nextName.Range.End + + openTok = p.Read() + } + + nameRange := hcl.Range{ + Filename: name.Range.Filename, + Start: name.Range.Start, + End: nameEndPos, + } + + if openTok.Type != TokenOParen { + diag := hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Missing open parenthesis", + Detail: "Function selector must be followed by an open parenthesis to begin the function call.", + Subject: &openTok.Range, + Context: hcl.RangeBetween(name.Range, openTok.Range).Ptr(), + } + + diags = append(diags, &diag) + p.recoverOver(TokenOParen) + return &ExprSyntaxError{ + ParseDiags: hcl.Diagnostics{&diag}, + Placeholder: cty.DynamicVal, + SrcRange: hcl.RangeBetween(name.Range, openTok.Range), + }, diags } var args []Expression - var diags hcl.Diagnostics var expandFinal bool var closeTok Token @@ -1218,7 +1278,7 @@ Token: diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Unterminated function call", - Detail: "There is no closing parenthesis for this function call before the end of the file. This may be caused by incorrect parethesis nesting elsewhere in this file.", + Detail: "There is no closing parenthesis for this function call before the end of the file. This may be caused by incorrect parenthesis nesting elsewhere in this file.", Subject: hcl.RangeBetween(name.Range, openTok.Range).Ptr(), }) default: @@ -1245,12 +1305,12 @@ Token: p.PopIncludeNewlines() return &FunctionCallExpr{ - Name: string(name.Bytes), + Name: nameStr, Args: args, ExpandFinal: expandFinal, - NameRange: name.Range, + NameRange: nameRange, OpenParenRange: openTok.Range, CloseParenRange: closeTok.Range, }, diags diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser_template.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser_template.go index 3ac68298..19e98806 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser_template.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser_template.go @@ -8,7 +8,7 @@ import ( "strings" "unicode" - "github.com/apparentlymart/go-textseg/v13/textseg" + "github.com/apparentlymart/go-textseg/v15/textseg" "github.com/hashicorp/hcl/v2" "github.com/zclconf/go-cty/cty" ) diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_string_lit.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_string_lit.go index 5d60ff5a..6b44d992 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_string_lit.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_string_lit.go @@ -1,13 +1,12 @@ +//line scan_string_lit.rl:1 // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -//line scan_string_lit.rl:1 - package hclsyntax // This file is generated from scan_string_lit.rl. DO NOT EDIT. -//line scan_string_lit.go:9 +//line scan_string_lit.go:11 var _hclstrtok_actions []byte = []byte{ 0, 1, 0, 1, 1, 2, 1, 0, } @@ -117,12 +116,12 @@ const hclstrtok_error int = 0 const hclstrtok_en_quoted int = 10 const hclstrtok_en_unquoted int = 4 -//line scan_string_lit.rl:10 +//line scan_string_lit.rl:12 func scanStringLit(data []byte, quoted bool) [][]byte { var ret [][]byte -//line scan_string_lit.rl:61 +//line scan_string_lit.rl:63 // Ragel state p := 0 // "Pointer" into data @@ -147,11 +146,11 @@ func scanStringLit(data []byte, quoted bool) [][]byte { ret = append(ret, data[ts:te]) }*/ -//line scan_string_lit.go:154 +//line scan_string_lit.go:156 { } -//line scan_string_lit.go:158 +//line scan_string_lit.go:160 { var _klen int var _trans int @@ -232,7 +231,7 @@ func scanStringLit(data []byte, quoted bool) [][]byte { _acts++ switch _hclstrtok_actions[_acts-1] { case 0: -//line scan_string_lit.rl:40 +//line scan_string_lit.rl:42 // If te is behind p then we've skipped over some literal // characters which we must now return. @@ -242,12 +241,12 @@ func scanStringLit(data []byte, quoted bool) [][]byte { ts = p case 1: -//line scan_string_lit.rl:48 +//line scan_string_lit.rl:50 te = p ret = append(ret, data[ts:te]) -//line scan_string_lit.go:253 +//line scan_string_lit.go:255 } } @@ -270,12 +269,12 @@ func scanStringLit(data []byte, quoted bool) [][]byte { __acts++ switch _hclstrtok_actions[__acts-1] { case 1: -//line scan_string_lit.rl:48 +//line scan_string_lit.rl:50 te = p ret = append(ret, data[ts:te]) -//line scan_string_lit.go:278 +//line scan_string_lit.go:280 } } } @@ -285,7 +284,7 @@ func scanStringLit(data []byte, quoted bool) [][]byte { } } -//line scan_string_lit.rl:89 +//line scan_string_lit.rl:91 if te < p { // Collect any leftover literal characters at the end of the input diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_string_lit.rl b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_string_lit.rl index f8ac1175..21d2c8bc 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_string_lit.rl +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_string_lit.rl @@ -1,3 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 package hclsyntax diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_tokens.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_tokens.go index 1bbbb927..3ed8455f 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_tokens.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_tokens.go @@ -1,8 +1,7 @@ +//line scan_tokens.rl:1 // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -//line scan_tokens.rl:1 - package hclsyntax import ( @@ -13,7 +12,7 @@ import ( // This file is generated from scan_tokens.rl. DO NOT EDIT. -//line scan_tokens.go:15 +//line scan_tokens.go:17 var _hcltok_actions []byte = []byte{ 0, 1, 0, 1, 1, 1, 3, 1, 4, 1, 7, 1, 8, 1, 9, 1, 10, @@ -33,13 +32,13 @@ var _hcltok_actions []byte = []byte{ 1, 71, 1, 72, 1, 73, 1, 74, 1, 75, 1, 76, 1, 77, 1, 78, 1, 79, 1, 80, 1, 81, 1, 82, - 1, 83, 1, 84, 1, 85, 2, 0, - 14, 2, 0, 25, 2, 0, 29, 2, - 0, 37, 2, 0, 41, 2, 1, 2, - 2, 4, 5, 2, 4, 6, 2, 4, - 21, 2, 4, 22, 2, 4, 33, 2, - 4, 34, 2, 4, 45, 2, 4, 46, - 2, 4, 54, 2, 4, 55, + 1, 83, 1, 84, 1, 85, 1, 86, + 2, 0, 14, 2, 0, 25, 2, 0, + 29, 2, 0, 37, 2, 0, 41, 2, + 1, 2, 2, 4, 5, 2, 4, 6, + 2, 4, 21, 2, 4, 22, 2, 4, + 33, 2, 4, 34, 2, 4, 45, 2, + 4, 46, 2, 4, 54, 2, 4, 55, } var _hcltok_key_offsets []int16 = []int16{ @@ -225,22 +224,22 @@ var _hcltok_key_offsets []int16 = []int16{ 9153, 9171, 9172, 9182, 9183, 9192, 9200, 9202, 9205, 9207, 9209, 9211, 9216, 9229, 9233, 9248, 9277, 9288, 9290, 9294, 9298, 9303, 9307, 9309, - 9316, 9320, 9328, 9332, 9407, 9409, 9410, 9411, - 9412, 9413, 9414, 9416, 9421, 9423, 9425, 9426, - 9470, 9471, 9472, 9474, 9479, 9483, 9483, 9485, - 9487, 9498, 9508, 9516, 9517, 9519, 9520, 9524, - 9528, 9538, 9542, 9549, 9560, 9567, 9571, 9577, - 9588, 9620, 9669, 9684, 9699, 9704, 9706, 9711, - 9743, 9751, 9753, 9775, 9797, 9799, 9815, 9831, - 9833, 9835, 9835, 9836, 9837, 9838, 9840, 9841, - 9853, 9855, 9857, 9859, 9873, 9887, 9889, 9892, - 9895, 9897, 9898, 9899, 9901, 9903, 9905, 9919, - 9933, 9935, 9938, 9941, 9943, 9944, 9945, 9947, - 9949, 9951, 10000, 10044, 10046, 10051, 10055, 10055, - 10057, 10059, 10070, 10080, 10088, 10089, 10091, 10092, - 10096, 10100, 10110, 10114, 10121, 10132, 10139, 10143, - 10149, 10160, 10192, 10241, 10256, 10271, 10276, 10278, - 10283, 10315, 10323, 10325, 10347, 10369, + 9316, 9320, 9328, 9332, 9408, 9410, 9411, 9412, + 9413, 9414, 9415, 9417, 9422, 9423, 9425, 9427, + 9428, 9472, 9473, 9474, 9476, 9481, 9485, 9485, + 9487, 9489, 9500, 9510, 9518, 9519, 9521, 9522, + 9526, 9530, 9540, 9544, 9551, 9562, 9569, 9573, + 9579, 9590, 9622, 9671, 9686, 9701, 9706, 9708, + 9713, 9745, 9753, 9755, 9777, 9799, 9801, 9817, + 9833, 9835, 9837, 9837, 9838, 9839, 9840, 9842, + 9843, 9855, 9857, 9859, 9861, 9875, 9889, 9891, + 9894, 9897, 9899, 9900, 9901, 9903, 9905, 9907, + 9921, 9935, 9937, 9940, 9943, 9945, 9946, 9947, + 9949, 9951, 9953, 10002, 10046, 10048, 10053, 10057, + 10057, 10059, 10061, 10072, 10082, 10090, 10091, 10093, + 10094, 10098, 10102, 10112, 10116, 10123, 10134, 10141, + 10145, 10151, 10162, 10194, 10243, 10258, 10273, 10278, + 10280, 10285, 10317, 10325, 10327, 10349, 10371, } var _hcltok_trans_keys []byte = []byte{ @@ -263,7 +262,7 @@ var _hcltok_trans_keys []byte = []byte{ 233, 234, 237, 239, 240, 243, 48, 57, 65, 90, 97, 122, 196, 218, 229, 236, 10, 170, 181, 183, 186, 128, 150, 152, - 182, 184, 255, 192, 255, 128, 255, 173, + 182, 184, 255, 192, 255, 0, 127, 173, 130, 133, 146, 159, 165, 171, 175, 255, 181, 190, 184, 185, 192, 255, 140, 134, 138, 142, 161, 163, 255, 182, 130, 136, @@ -572,7 +571,7 @@ var _hcltok_trans_keys []byte = []byte{ 150, 153, 131, 140, 255, 160, 163, 164, 165, 184, 185, 186, 161, 162, 133, 255, 170, 181, 183, 186, 128, 150, 152, 182, - 184, 255, 192, 255, 128, 255, 173, 130, + 184, 255, 192, 255, 0, 127, 173, 130, 133, 146, 159, 165, 171, 175, 255, 181, 190, 184, 185, 192, 255, 140, 134, 138, 142, 161, 163, 255, 182, 130, 136, 137, @@ -1411,136 +1410,136 @@ var _hcltok_trans_keys []byte = []byte{ 187, 191, 192, 255, 162, 191, 192, 255, 160, 168, 128, 159, 161, 167, 169, 191, 158, 191, 192, 255, 9, 10, 13, 32, - 33, 34, 35, 38, 46, 47, 60, 61, - 62, 64, 92, 95, 123, 124, 125, 126, - 127, 194, 195, 198, 199, 203, 204, 205, - 206, 207, 210, 212, 213, 214, 215, 216, - 217, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 233, 234, 237, 238, 239, - 240, 0, 36, 37, 45, 48, 57, 58, - 63, 65, 90, 91, 96, 97, 122, 192, - 193, 196, 218, 229, 236, 241, 247, 9, - 32, 10, 61, 10, 38, 46, 42, 47, - 46, 69, 101, 48, 57, 60, 61, 61, - 62, 61, 45, 95, 194, 195, 198, 199, - 203, 204, 205, 206, 207, 210, 212, 213, - 214, 215, 216, 217, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 233, 234, - 237, 239, 240, 243, 48, 57, 65, 90, - 97, 122, 196, 218, 229, 236, 124, 125, - 128, 191, 170, 181, 186, 128, 191, 151, - 183, 128, 255, 192, 255, 0, 127, 173, - 130, 133, 146, 159, 165, 171, 175, 191, - 192, 255, 181, 190, 128, 175, 176, 183, - 184, 185, 186, 191, 134, 139, 141, 162, - 128, 135, 136, 255, 182, 130, 137, 176, - 151, 152, 154, 160, 136, 191, 192, 255, - 128, 143, 144, 170, 171, 175, 176, 178, - 179, 191, 128, 159, 160, 191, 176, 128, - 138, 139, 173, 174, 255, 148, 150, 164, - 167, 173, 176, 185, 189, 190, 192, 255, - 144, 128, 145, 146, 175, 176, 191, 128, - 140, 141, 255, 166, 176, 178, 191, 192, - 255, 186, 128, 137, 138, 170, 171, 179, - 180, 181, 182, 191, 160, 161, 162, 164, - 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 128, 191, 128, 129, 130, 131, - 137, 138, 139, 140, 141, 142, 143, 144, - 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 182, 183, 184, 188, - 189, 190, 191, 132, 187, 129, 130, 132, - 133, 134, 176, 177, 178, 179, 180, 181, - 182, 183, 128, 191, 128, 129, 130, 131, - 132, 133, 134, 135, 144, 136, 143, 145, - 191, 192, 255, 182, 183, 184, 128, 191, - 128, 191, 191, 128, 190, 192, 255, 128, - 146, 147, 148, 152, 153, 154, 155, 156, - 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 129, 191, 192, 255, 158, - 159, 128, 157, 160, 191, 192, 255, 128, - 191, 164, 169, 171, 172, 173, 174, 175, - 180, 181, 182, 183, 184, 185, 187, 188, - 189, 190, 191, 128, 163, 165, 186, 144, - 145, 146, 147, 148, 150, 151, 152, 155, - 157, 158, 160, 170, 171, 172, 175, 128, - 159, 161, 169, 173, 191, 128, 191, 10, - 13, 34, 36, 37, 92, 128, 191, 192, - 223, 224, 239, 240, 247, 248, 255, 10, - 13, 34, 92, 36, 37, 128, 191, 192, - 223, 224, 239, 240, 247, 248, 255, 10, - 13, 36, 123, 123, 126, 126, 37, 123, - 126, 10, 13, 128, 191, 192, 223, 224, - 239, 240, 247, 248, 255, 128, 191, 128, + 33, 34, 35, 38, 46, 47, 58, 60, + 61, 62, 64, 92, 95, 123, 124, 125, + 126, 127, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 233, 234, 237, 238, + 239, 240, 0, 36, 37, 45, 48, 57, + 59, 63, 65, 90, 91, 96, 97, 122, + 192, 193, 196, 218, 229, 236, 241, 247, + 9, 32, 10, 61, 10, 38, 46, 42, + 47, 46, 69, 101, 48, 57, 58, 60, + 61, 61, 62, 61, 45, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, + 233, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 196, 218, 229, 236, + 124, 125, 128, 191, 170, 181, 186, 128, + 191, 151, 183, 128, 255, 192, 255, 0, + 127, 173, 130, 133, 146, 159, 165, 171, + 175, 191, 192, 255, 181, 190, 128, 175, + 176, 183, 184, 185, 186, 191, 134, 139, + 141, 162, 128, 135, 136, 255, 182, 130, + 137, 176, 151, 152, 154, 160, 136, 191, + 192, 255, 128, 143, 144, 170, 171, 175, + 176, 178, 179, 191, 128, 159, 160, 191, + 176, 128, 138, 139, 173, 174, 255, 148, + 150, 164, 167, 173, 176, 185, 189, 190, + 192, 255, 144, 128, 145, 146, 175, 176, + 191, 128, 140, 141, 255, 166, 176, 178, + 191, 192, 255, 186, 128, 137, 138, 170, + 171, 179, 180, 181, 182, 191, 160, 161, + 162, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 128, 191, 128, 129, + 130, 131, 137, 138, 139, 140, 141, 142, + 143, 144, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 182, 183, + 184, 188, 189, 190, 191, 132, 187, 129, + 130, 132, 133, 134, 176, 177, 178, 179, + 180, 181, 182, 183, 128, 191, 128, 129, + 130, 131, 132, 133, 134, 135, 144, 136, + 143, 145, 191, 192, 255, 182, 183, 184, + 128, 191, 128, 191, 191, 128, 190, 192, + 255, 128, 146, 147, 148, 152, 153, 154, + 155, 156, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 129, 191, 192, + 255, 158, 159, 128, 157, 160, 191, 192, + 255, 128, 191, 164, 169, 171, 172, 173, + 174, 175, 180, 181, 182, 183, 184, 185, + 187, 188, 189, 190, 191, 128, 163, 165, + 186, 144, 145, 146, 147, 148, 150, 151, + 152, 155, 157, 158, 160, 170, 171, 172, + 175, 128, 159, 161, 169, 173, 191, 128, + 191, 10, 13, 34, 36, 37, 92, 128, + 191, 192, 223, 224, 239, 240, 247, 248, + 255, 10, 13, 34, 92, 36, 37, 128, + 191, 192, 223, 224, 239, 240, 247, 248, + 255, 10, 13, 36, 123, 123, 126, 126, + 37, 123, 126, 10, 13, 128, 191, 192, + 223, 224, 239, 240, 247, 248, 255, 128, + 191, 128, 191, 128, 191, 10, 13, 36, + 37, 128, 191, 192, 223, 224, 239, 240, + 247, 248, 255, 10, 13, 36, 37, 128, + 191, 192, 223, 224, 239, 240, 247, 248, + 255, 10, 13, 10, 13, 123, 10, 13, + 126, 10, 13, 126, 126, 128, 191, 128, 191, 128, 191, 10, 13, 36, 37, 128, 191, 192, 223, 224, 239, 240, 247, 248, 255, 10, 13, 36, 37, 128, 191, 192, 223, 224, 239, 240, 247, 248, 255, 10, 13, 10, 13, 123, 10, 13, 126, 10, 13, 126, 126, 128, 191, 128, 191, 128, - 191, 10, 13, 36, 37, 128, 191, 192, - 223, 224, 239, 240, 247, 248, 255, 10, - 13, 36, 37, 128, 191, 192, 223, 224, - 239, 240, 247, 248, 255, 10, 13, 10, - 13, 123, 10, 13, 126, 10, 13, 126, - 126, 128, 191, 128, 191, 128, 191, 95, - 194, 195, 198, 199, 203, 204, 205, 206, - 207, 210, 212, 213, 214, 215, 216, 217, - 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 233, 234, 237, 238, 239, 240, - 65, 90, 97, 122, 128, 191, 192, 193, - 196, 218, 229, 236, 241, 247, 248, 255, - 45, 95, 194, 195, 198, 199, 203, 204, + 191, 95, 194, 195, 198, 199, 203, 204, 205, 206, 207, 210, 212, 213, 214, 215, 216, 217, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 233, 234, 237, 239, - 240, 243, 48, 57, 65, 90, 97, 122, - 196, 218, 229, 236, 128, 191, 170, 181, - 186, 128, 191, 151, 183, 128, 255, 192, - 255, 0, 127, 173, 130, 133, 146, 159, - 165, 171, 175, 191, 192, 255, 181, 190, - 128, 175, 176, 183, 184, 185, 186, 191, - 134, 139, 141, 162, 128, 135, 136, 255, - 182, 130, 137, 176, 151, 152, 154, 160, - 136, 191, 192, 255, 128, 143, 144, 170, - 171, 175, 176, 178, 179, 191, 128, 159, - 160, 191, 176, 128, 138, 139, 173, 174, - 255, 148, 150, 164, 167, 173, 176, 185, - 189, 190, 192, 255, 144, 128, 145, 146, - 175, 176, 191, 128, 140, 141, 255, 166, - 176, 178, 191, 192, 255, 186, 128, 137, - 138, 170, 171, 179, 180, 181, 182, 191, - 160, 161, 162, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 128, 191, - 128, 129, 130, 131, 137, 138, 139, 140, - 141, 142, 143, 144, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, - 182, 183, 184, 188, 189, 190, 191, 132, - 187, 129, 130, 132, 133, 134, 176, 177, - 178, 179, 180, 181, 182, 183, 128, 191, - 128, 129, 130, 131, 132, 133, 134, 135, - 144, 136, 143, 145, 191, 192, 255, 182, - 183, 184, 128, 191, 128, 191, 191, 128, - 190, 192, 255, 128, 146, 147, 148, 152, - 153, 154, 155, 156, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 129, - 191, 192, 255, 158, 159, 128, 157, 160, - 191, 192, 255, 128, 191, 164, 169, 171, - 172, 173, 174, 175, 180, 181, 182, 183, - 184, 185, 187, 188, 189, 190, 191, 128, - 163, 165, 186, 144, 145, 146, 147, 148, - 150, 151, 152, 155, 157, 158, 160, 170, - 171, 172, 175, 128, 159, 161, 169, 173, - 191, 128, 191, + 225, 226, 227, 228, 233, 234, 237, 238, + 239, 240, 65, 90, 97, 122, 128, 191, + 192, 193, 196, 218, 229, 236, 241, 247, + 248, 255, 45, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 233, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 196, 218, 229, 236, 128, 191, + 170, 181, 186, 128, 191, 151, 183, 128, + 255, 192, 255, 0, 127, 173, 130, 133, + 146, 159, 165, 171, 175, 191, 192, 255, + 181, 190, 128, 175, 176, 183, 184, 185, + 186, 191, 134, 139, 141, 162, 128, 135, + 136, 255, 182, 130, 137, 176, 151, 152, + 154, 160, 136, 191, 192, 255, 128, 143, + 144, 170, 171, 175, 176, 178, 179, 191, + 128, 159, 160, 191, 176, 128, 138, 139, + 173, 174, 255, 148, 150, 164, 167, 173, + 176, 185, 189, 190, 192, 255, 144, 128, + 145, 146, 175, 176, 191, 128, 140, 141, + 255, 166, 176, 178, 191, 192, 255, 186, + 128, 137, 138, 170, 171, 179, 180, 181, + 182, 191, 160, 161, 162, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, + 128, 191, 128, 129, 130, 131, 137, 138, + 139, 140, 141, 142, 143, 144, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 182, 183, 184, 188, 189, 190, + 191, 132, 187, 129, 130, 132, 133, 134, + 176, 177, 178, 179, 180, 181, 182, 183, + 128, 191, 128, 129, 130, 131, 132, 133, + 134, 135, 144, 136, 143, 145, 191, 192, + 255, 182, 183, 184, 128, 191, 128, 191, + 191, 128, 190, 192, 255, 128, 146, 147, + 148, 152, 153, 154, 155, 156, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 129, 191, 192, 255, 158, 159, 128, + 157, 160, 191, 192, 255, 128, 191, 164, + 169, 171, 172, 173, 174, 175, 180, 181, + 182, 183, 184, 185, 187, 188, 189, 190, + 191, 128, 163, 165, 186, 144, 145, 146, + 147, 148, 150, 151, 152, 155, 157, 158, + 160, 170, 171, 172, 175, 128, 159, 161, + 169, 173, 191, 128, 191, } var _hcltok_single_lengths []byte = []byte{ @@ -1726,22 +1725,22 @@ var _hcltok_single_lengths []byte = []byte{ 12, 1, 4, 1, 5, 2, 0, 3, 2, 2, 2, 1, 7, 0, 7, 17, 3, 0, 2, 0, 3, 0, 0, 1, - 0, 2, 0, 53, 2, 1, 1, 1, - 1, 1, 2, 3, 2, 2, 1, 34, - 1, 1, 0, 3, 2, 0, 0, 0, - 1, 2, 4, 1, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 1, - 30, 47, 13, 9, 3, 0, 1, 28, - 2, 0, 18, 16, 0, 6, 4, 2, - 2, 0, 1, 1, 1, 2, 1, 2, - 0, 0, 0, 4, 2, 2, 3, 3, - 2, 1, 1, 0, 0, 0, 4, 2, - 2, 3, 3, 2, 1, 1, 0, 0, - 0, 33, 34, 0, 3, 2, 0, 0, + 0, 2, 0, 54, 2, 1, 1, 1, + 1, 1, 2, 3, 1, 2, 2, 1, + 34, 1, 1, 0, 3, 2, 0, 0, 0, 1, 2, 4, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 30, 47, 13, 9, 3, 0, 1, - 28, 2, 0, 18, 16, 0, + 28, 2, 0, 18, 16, 0, 6, 4, + 2, 2, 0, 1, 1, 1, 2, 1, + 2, 0, 0, 0, 4, 2, 2, 3, + 3, 2, 1, 1, 0, 0, 0, 4, + 2, 2, 3, 3, 2, 1, 1, 0, + 0, 0, 33, 34, 0, 3, 2, 0, + 0, 0, 1, 2, 4, 1, 0, 1, + 0, 0, 0, 0, 1, 1, 1, 0, + 0, 1, 30, 47, 13, 9, 3, 0, + 1, 28, 2, 0, 18, 16, 0, } var _hcltok_range_lengths []byte = []byte{ @@ -1928,21 +1927,21 @@ var _hcltok_range_lengths []byte = []byte{ 0, 0, 0, 2, 3, 2, 4, 6, 4, 1, 1, 2, 1, 2, 1, 3, 2, 3, 2, 11, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 5, - 0, 0, 1, 1, 1, 0, 1, 1, - 5, 4, 2, 0, 1, 0, 2, 2, - 5, 2, 3, 5, 3, 2, 3, 5, - 1, 1, 1, 3, 1, 1, 2, 2, - 3, 1, 2, 3, 1, 5, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 5, - 1, 1, 1, 5, 6, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 5, 6, - 0, 0, 0, 0, 0, 0, 1, 1, - 1, 8, 5, 1, 1, 1, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 0, + 5, 0, 0, 1, 1, 1, 0, 1, 1, 5, 4, 2, 0, 1, 0, 2, 2, 5, 2, 3, 5, 3, 2, 3, 5, 1, 1, 1, 3, 1, 1, 2, - 2, 3, 1, 2, 3, 1, + 2, 3, 1, 2, 3, 1, 5, 6, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 1, 1, 1, 5, 6, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 5, + 6, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 8, 5, 1, 1, 1, 0, + 1, 1, 5, 4, 2, 0, 1, 0, + 2, 2, 5, 2, 3, 5, 3, 2, + 3, 5, 1, 1, 1, 3, 1, 1, + 2, 2, 3, 1, 2, 3, 1, } var _hcltok_index_offsets []int16 = []int16{ @@ -2128,22 +2127,22 @@ var _hcltok_index_offsets []int16 = []int16{ 7187, 7203, 7205, 7213, 7215, 7223, 7229, 7231, 7235, 7238, 7241, 7244, 7248, 7259, 7262, 7274, 7298, 7306, 7308, 7312, 7315, 7320, 7323, 7325, - 7330, 7333, 7339, 7342, 7407, 7410, 7412, 7414, - 7416, 7418, 7420, 7423, 7428, 7431, 7434, 7436, - 7476, 7478, 7480, 7482, 7487, 7491, 7492, 7494, - 7496, 7503, 7510, 7517, 7519, 7521, 7523, 7526, - 7529, 7535, 7538, 7543, 7550, 7555, 7558, 7562, - 7569, 7601, 7650, 7665, 7678, 7683, 7685, 7689, - 7720, 7726, 7728, 7749, 7769, 7771, 7783, 7794, - 7797, 7800, 7801, 7803, 7805, 7807, 7810, 7812, - 7820, 7822, 7824, 7826, 7836, 7845, 7848, 7852, - 7856, 7859, 7861, 7863, 7865, 7867, 7869, 7879, - 7888, 7891, 7895, 7899, 7902, 7904, 7906, 7908, - 7910, 7912, 7954, 7994, 7996, 8001, 8005, 8006, - 8008, 8010, 8017, 8024, 8031, 8033, 8035, 8037, - 8040, 8043, 8049, 8052, 8057, 8064, 8069, 8072, - 8076, 8083, 8115, 8164, 8179, 8192, 8197, 8199, - 8203, 8234, 8240, 8242, 8263, 8283, + 7330, 7333, 7339, 7342, 7408, 7411, 7413, 7415, + 7417, 7419, 7421, 7424, 7429, 7431, 7434, 7437, + 7439, 7479, 7481, 7483, 7485, 7490, 7494, 7495, + 7497, 7499, 7506, 7513, 7520, 7522, 7524, 7526, + 7529, 7532, 7538, 7541, 7546, 7553, 7558, 7561, + 7565, 7572, 7604, 7653, 7668, 7681, 7686, 7688, + 7692, 7723, 7729, 7731, 7752, 7772, 7774, 7786, + 7797, 7800, 7803, 7804, 7806, 7808, 7810, 7813, + 7815, 7823, 7825, 7827, 7829, 7839, 7848, 7851, + 7855, 7859, 7862, 7864, 7866, 7868, 7870, 7872, + 7882, 7891, 7894, 7898, 7902, 7905, 7907, 7909, + 7911, 7913, 7915, 7957, 7997, 7999, 8004, 8008, + 8009, 8011, 8013, 8020, 8027, 8034, 8036, 8038, + 8040, 8043, 8046, 8052, 8055, 8060, 8067, 8072, + 8075, 8079, 8086, 8118, 8167, 8182, 8195, 8200, + 8202, 8206, 8237, 8243, 8245, 8266, 8286, } var _hcltok_indicies []int16 = []int16{ @@ -2165,7 +2164,7 @@ var _hcltok_indicies []int16 = []int16{ 61, 62, 37, 39, 63, 41, 64, 65, 66, 11, 11, 11, 14, 38, 0, 44, 0, 11, 11, 11, 11, 0, 11, 11, - 11, 0, 11, 0, 11, 11, 0, 0, + 11, 0, 11, 0, 11, 0, 11, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 11, 11, 11, 11, 11, 0, 0, 11, 0, 0, 11, 0, 11, 0, 0, @@ -2418,7 +2417,7 @@ var _hcltok_indicies []int16 = []int16{ 11, 16, 417, 16, 265, 300, 301, 302, 14, 0, 0, 11, 419, 419, 419, 419, 418, 419, 419, 419, 418, 419, 418, 419, - 419, 418, 418, 418, 418, 418, 418, 419, + 418, 419, 418, 418, 418, 418, 418, 419, 418, 418, 418, 418, 419, 419, 419, 419, 419, 418, 418, 419, 418, 418, 419, 418, 419, 418, 418, 419, 418, 418, 418, 419, @@ -3066,123 +3065,123 @@ var _hcltok_indicies []int16 = []int16{ 1045, 801, 1046, 1045, 795, 1050, 1141, 1047, 1059, 1047, 1045, 1046, 1045, 795, 1142, 1143, 1144, 1142, 1145, 1146, 1147, 1149, 1150, 1151, - 1152, 1153, 1154, 670, 670, 419, 1155, 1156, - 1157, 1158, 670, 1161, 1162, 1164, 1165, 1166, - 1160, 1167, 1168, 1169, 1170, 1171, 1172, 1173, + 1152, 1153, 1154, 1155, 670, 670, 419, 1156, + 1157, 1158, 1159, 670, 1162, 1163, 1165, 1166, + 1167, 1161, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, - 1182, 1183, 1184, 1185, 1186, 1188, 1189, 1190, - 1191, 1192, 1193, 670, 1148, 7, 1148, 419, - 1148, 419, 1160, 1163, 1187, 1194, 1159, 1142, - 1142, 1195, 1143, 1196, 1198, 1197, 4, 1147, - 1200, 1197, 1201, 1197, 2, 1147, 1197, 6, - 8, 8, 7, 1202, 1203, 1204, 1197, 1205, - 1206, 1197, 1207, 1197, 419, 419, 1209, 1210, - 489, 470, 1211, 470, 1212, 1213, 1214, 1215, - 1216, 1217, 1218, 1219, 1220, 1221, 1222, 544, - 1223, 520, 1224, 1225, 1226, 1227, 1228, 1229, - 1230, 1231, 1232, 1233, 1234, 1235, 419, 419, - 419, 425, 565, 1208, 1236, 1197, 1237, 1197, - 670, 1238, 419, 419, 419, 670, 1238, 670, - 670, 419, 1238, 419, 1238, 419, 1238, 419, - 670, 670, 670, 670, 670, 1238, 419, 670, - 670, 670, 419, 670, 419, 1238, 419, 670, - 670, 670, 670, 419, 1238, 670, 419, 670, - 419, 670, 419, 670, 670, 419, 670, 1238, - 419, 670, 419, 670, 419, 670, 1238, 670, - 419, 1238, 670, 419, 670, 419, 1238, 670, - 670, 670, 670, 670, 1238, 419, 419, 670, - 419, 670, 1238, 670, 419, 1238, 670, 670, - 1238, 419, 419, 670, 419, 670, 419, 670, - 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, - 1246, 1247, 1248, 1249, 715, 1250, 1251, 1252, - 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, - 1261, 1260, 1262, 1263, 1264, 1265, 1266, 671, - 1238, 1267, 1268, 1269, 1270, 1271, 1272, 1273, - 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, - 1282, 1283, 1284, 1285, 725, 1286, 1287, 1288, - 692, 1289, 1290, 1291, 1292, 1293, 1294, 671, - 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, - 674, 1303, 671, 674, 1304, 1305, 1306, 1307, - 683, 1238, 1308, 1309, 1310, 1311, 703, 1312, - 1313, 683, 1314, 1315, 1316, 1317, 1318, 671, - 1238, 1319, 1278, 1320, 1321, 1322, 683, 1323, - 1324, 674, 671, 683, 425, 1238, 1288, 671, - 674, 683, 425, 683, 425, 1325, 683, 1238, - 425, 674, 1326, 1327, 674, 1328, 1329, 681, - 1330, 1331, 1332, 1333, 1334, 1284, 1335, 1336, - 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, - 1345, 1346, 1303, 1347, 674, 683, 425, 1238, - 1348, 1349, 683, 671, 1238, 425, 671, 1238, - 674, 1350, 731, 1351, 1352, 1353, 1354, 1355, - 1356, 1357, 1358, 671, 1359, 1360, 1361, 1362, - 1363, 1364, 671, 683, 1238, 1366, 1367, 1368, - 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, - 1372, 1378, 1379, 1380, 1381, 1365, 1377, 1365, - 1238, 1365, 1238, 1382, 1382, 1383, 1384, 1385, - 1386, 1387, 1388, 1389, 1390, 1387, 767, 1391, - 1391, 1391, 1392, 1391, 1391, 768, 769, 770, - 1391, 767, 1382, 1382, 1393, 1396, 1397, 1395, - 1398, 1399, 1398, 1400, 1391, 1402, 1401, 1396, - 1403, 1395, 1405, 1404, 1394, 1394, 1394, 768, - 769, 770, 1394, 767, 767, 1406, 773, 1406, - 1407, 1406, 775, 1408, 1409, 1410, 1411, 1412, - 1413, 1414, 1411, 776, 775, 1408, 1415, 1415, - 777, 779, 1416, 1415, 776, 1418, 1419, 1417, - 1418, 1419, 1420, 1417, 775, 1408, 1421, 1415, - 775, 1408, 1415, 1423, 1422, 1425, 1424, 776, - 1426, 777, 1426, 779, 1426, 785, 1427, 1428, - 1429, 1430, 1431, 1432, 1433, 1430, 786, 785, - 1427, 1434, 1434, 787, 789, 1435, 1434, 786, - 1437, 1438, 1436, 1437, 1438, 1439, 1436, 785, - 1427, 1440, 1434, 785, 1427, 1434, 1442, 1441, - 1444, 1443, 786, 1445, 787, 1445, 789, 1445, - 795, 1448, 1449, 1451, 1452, 1453, 1447, 1454, - 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, - 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, - 1471, 1472, 1473, 1475, 1476, 1477, 1478, 1479, - 1480, 795, 795, 1446, 1447, 1450, 1474, 1481, - 1446, 1046, 795, 795, 1483, 1484, 865, 846, - 1485, 846, 1486, 1487, 1488, 1489, 1490, 1491, - 1492, 1493, 1494, 1495, 1496, 920, 1497, 896, - 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, - 1506, 1507, 1508, 1509, 795, 795, 795, 801, - 941, 1482, 1046, 1510, 795, 795, 795, 1046, - 1510, 1046, 1046, 795, 1510, 795, 1510, 795, - 1510, 795, 1046, 1046, 1046, 1046, 1046, 1510, - 795, 1046, 1046, 1046, 795, 1046, 795, 1510, - 795, 1046, 1046, 1046, 1046, 795, 1510, 1046, - 795, 1046, 795, 1046, 795, 1046, 1046, 795, - 1046, 1510, 795, 1046, 795, 1046, 795, 1046, - 1510, 1046, 795, 1510, 1046, 795, 1046, 795, - 1510, 1046, 1046, 1046, 1046, 1046, 1510, 795, - 795, 1046, 795, 1046, 1510, 1046, 795, 1510, - 1046, 1046, 1510, 795, 795, 1046, 795, 1046, - 795, 1046, 1510, 1511, 1512, 1513, 1514, 1515, - 1516, 1517, 1518, 1519, 1520, 1521, 1091, 1522, - 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, - 1531, 1532, 1533, 1532, 1534, 1535, 1536, 1537, - 1538, 1047, 1510, 1539, 1540, 1541, 1542, 1543, - 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, - 1552, 1553, 1554, 1555, 1556, 1557, 1101, 1558, - 1559, 1560, 1068, 1561, 1562, 1563, 1564, 1565, - 1566, 1047, 1567, 1568, 1569, 1570, 1571, 1572, - 1573, 1574, 1050, 1575, 1047, 1050, 1576, 1577, - 1578, 1579, 1059, 1510, 1580, 1581, 1582, 1583, - 1079, 1584, 1585, 1059, 1586, 1587, 1588, 1589, - 1590, 1047, 1510, 1591, 1550, 1592, 1593, 1594, - 1059, 1595, 1596, 1050, 1047, 1059, 801, 1510, - 1560, 1047, 1050, 1059, 801, 1059, 801, 1597, - 1059, 1510, 801, 1050, 1598, 1599, 1050, 1600, - 1601, 1057, 1602, 1603, 1604, 1605, 1606, 1556, - 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, - 1615, 1616, 1617, 1618, 1575, 1619, 1050, 1059, - 801, 1510, 1620, 1621, 1059, 1047, 1510, 801, - 1047, 1510, 1050, 1622, 1107, 1623, 1624, 1625, - 1626, 1627, 1628, 1629, 1630, 1047, 1631, 1632, - 1633, 1634, 1635, 1636, 1047, 1059, 1510, 1638, - 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, - 1647, 1648, 1644, 1650, 1651, 1652, 1653, 1637, - 1649, 1637, 1510, 1637, 1510, + 1182, 1183, 1184, 1185, 1186, 1187, 1189, 1190, + 1191, 1192, 1193, 1194, 670, 1148, 7, 1148, + 419, 1148, 419, 1161, 1164, 1188, 1195, 1160, + 1142, 1142, 1196, 1143, 1197, 1199, 1198, 4, + 1147, 1201, 1198, 1202, 1198, 2, 1147, 1198, + 6, 8, 8, 7, 1203, 1204, 1198, 1205, + 1206, 1198, 1207, 1208, 1198, 1209, 1198, 419, + 419, 1211, 1212, 489, 470, 1213, 470, 1214, + 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 544, 1225, 520, 1226, 1227, 1228, + 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, + 1237, 419, 419, 419, 425, 565, 1210, 1238, + 1198, 1239, 1198, 670, 1240, 419, 419, 419, + 670, 1240, 670, 670, 419, 1240, 419, 1240, + 419, 1240, 419, 670, 670, 670, 670, 670, + 1240, 419, 670, 670, 670, 419, 670, 419, + 1240, 419, 670, 670, 670, 670, 419, 1240, + 670, 419, 670, 419, 670, 419, 670, 670, + 419, 670, 1240, 419, 670, 419, 670, 419, + 670, 1240, 670, 419, 1240, 670, 419, 670, + 419, 1240, 670, 670, 670, 670, 670, 1240, + 419, 419, 670, 419, 670, 1240, 670, 419, + 1240, 670, 670, 1240, 419, 419, 670, 419, + 670, 419, 670, 1240, 1241, 1242, 1243, 1244, + 1245, 1246, 1247, 1248, 1249, 1250, 1251, 715, + 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, + 1260, 1261, 1262, 1263, 1262, 1264, 1265, 1266, + 1267, 1268, 671, 1240, 1269, 1270, 1271, 1272, + 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, + 1281, 1282, 1283, 1284, 1285, 1286, 1287, 725, + 1288, 1289, 1290, 692, 1291, 1292, 1293, 1294, + 1295, 1296, 671, 1297, 1298, 1299, 1300, 1301, + 1302, 1303, 1304, 674, 1305, 671, 674, 1306, + 1307, 1308, 1309, 683, 1240, 1310, 1311, 1312, + 1313, 703, 1314, 1315, 683, 1316, 1317, 1318, + 1319, 1320, 671, 1240, 1321, 1280, 1322, 1323, + 1324, 683, 1325, 1326, 674, 671, 683, 425, + 1240, 1290, 671, 674, 683, 425, 683, 425, + 1327, 683, 1240, 425, 674, 1328, 1329, 674, + 1330, 1331, 681, 1332, 1333, 1334, 1335, 1336, + 1286, 1337, 1338, 1339, 1340, 1341, 1342, 1343, + 1344, 1345, 1346, 1347, 1348, 1305, 1349, 674, + 683, 425, 1240, 1350, 1351, 683, 671, 1240, + 425, 671, 1240, 674, 1352, 731, 1353, 1354, + 1355, 1356, 1357, 1358, 1359, 1360, 671, 1361, + 1362, 1363, 1364, 1365, 1366, 671, 683, 1240, + 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, + 1376, 1377, 1378, 1374, 1380, 1381, 1382, 1383, + 1367, 1379, 1367, 1240, 1367, 1240, 1384, 1384, + 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, + 1389, 767, 1393, 1393, 1393, 1394, 1393, 1393, + 768, 769, 770, 1393, 767, 1384, 1384, 1395, + 1398, 1399, 1397, 1400, 1401, 1400, 1402, 1393, + 1404, 1403, 1398, 1405, 1397, 1407, 1406, 1396, + 1396, 1396, 768, 769, 770, 1396, 767, 767, + 1408, 773, 1408, 1409, 1408, 775, 1410, 1411, + 1412, 1413, 1414, 1415, 1416, 1413, 776, 775, + 1410, 1417, 1417, 777, 779, 1418, 1417, 776, + 1420, 1421, 1419, 1420, 1421, 1422, 1419, 775, + 1410, 1423, 1417, 775, 1410, 1417, 1425, 1424, + 1427, 1426, 776, 1428, 777, 1428, 779, 1428, + 785, 1429, 1430, 1431, 1432, 1433, 1434, 1435, + 1432, 786, 785, 1429, 1436, 1436, 787, 789, + 1437, 1436, 786, 1439, 1440, 1438, 1439, 1440, + 1441, 1438, 785, 1429, 1442, 1436, 785, 1429, + 1436, 1444, 1443, 1446, 1445, 786, 1447, 787, + 1447, 789, 1447, 795, 1450, 1451, 1453, 1454, + 1455, 1449, 1456, 1457, 1458, 1459, 1460, 1461, + 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, + 1470, 1471, 1472, 1473, 1474, 1475, 1477, 1478, + 1479, 1480, 1481, 1482, 795, 795, 1448, 1449, + 1452, 1476, 1483, 1448, 1046, 795, 795, 1485, + 1486, 865, 846, 1487, 846, 1488, 1489, 1490, + 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, + 920, 1499, 896, 1500, 1501, 1502, 1503, 1504, + 1505, 1506, 1507, 1508, 1509, 1510, 1511, 795, + 795, 795, 801, 941, 1484, 1046, 1512, 795, + 795, 795, 1046, 1512, 1046, 1046, 795, 1512, + 795, 1512, 795, 1512, 795, 1046, 1046, 1046, + 1046, 1046, 1512, 795, 1046, 1046, 1046, 795, + 1046, 795, 1512, 795, 1046, 1046, 1046, 1046, + 795, 1512, 1046, 795, 1046, 795, 1046, 795, + 1046, 1046, 795, 1046, 1512, 795, 1046, 795, + 1046, 795, 1046, 1512, 1046, 795, 1512, 1046, + 795, 1046, 795, 1512, 1046, 1046, 1046, 1046, + 1046, 1512, 795, 795, 1046, 795, 1046, 1512, + 1046, 795, 1512, 1046, 1046, 1512, 795, 795, + 1046, 795, 1046, 795, 1046, 1512, 1513, 1514, + 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, + 1523, 1091, 1524, 1525, 1526, 1527, 1528, 1529, + 1530, 1531, 1532, 1533, 1534, 1535, 1534, 1536, + 1537, 1538, 1539, 1540, 1047, 1512, 1541, 1542, + 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, + 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, + 1559, 1101, 1560, 1561, 1562, 1068, 1563, 1564, + 1565, 1566, 1567, 1568, 1047, 1569, 1570, 1571, + 1572, 1573, 1574, 1575, 1576, 1050, 1577, 1047, + 1050, 1578, 1579, 1580, 1581, 1059, 1512, 1582, + 1583, 1584, 1585, 1079, 1586, 1587, 1059, 1588, + 1589, 1590, 1591, 1592, 1047, 1512, 1593, 1552, + 1594, 1595, 1596, 1059, 1597, 1598, 1050, 1047, + 1059, 801, 1512, 1562, 1047, 1050, 1059, 801, + 1059, 801, 1599, 1059, 1512, 801, 1050, 1600, + 1601, 1050, 1602, 1603, 1057, 1604, 1605, 1606, + 1607, 1608, 1558, 1609, 1610, 1611, 1612, 1613, + 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1577, + 1621, 1050, 1059, 801, 1512, 1622, 1623, 1059, + 1047, 1512, 801, 1047, 1512, 1050, 1624, 1107, + 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, + 1047, 1633, 1634, 1635, 1636, 1637, 1638, 1047, + 1059, 1512, 1640, 1641, 1642, 1643, 1644, 1645, + 1646, 1647, 1648, 1649, 1650, 1646, 1652, 1653, + 1654, 1655, 1639, 1651, 1639, 1512, 1639, 1512, } var _hcltok_trans_targs []int16 = []int16{ @@ -3238,7 +3237,7 @@ var _hcltok_trans_targs []int16 = []int16{ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 405, 406, 407, 408, 410, - 412, 414, 1459, 1471, 1459, 437, 438, 439, + 412, 414, 1459, 1472, 1459, 437, 438, 439, 440, 417, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, @@ -3281,11 +3280,11 @@ var _hcltok_trans_targs []int16 = []int16{ 888, 889, 890, 891, 892, 895, 896, 898, 899, 900, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 914, 915, 916, - 917, 920, 922, 923, 925, 927, 1509, 1510, - 929, 930, 931, 1509, 1509, 932, 1523, 1523, - 1524, 935, 1523, 936, 1525, 1526, 1529, 1530, - 1534, 1534, 1535, 941, 1534, 942, 1536, 1537, - 1540, 1541, 1545, 1546, 1545, 968, 969, 970, + 917, 920, 922, 923, 925, 927, 1510, 1511, + 929, 930, 931, 1510, 1510, 932, 1524, 1524, + 1525, 935, 1524, 936, 1526, 1527, 1530, 1531, + 1535, 1535, 1536, 941, 1535, 942, 1537, 1538, + 1541, 1542, 1546, 1547, 1546, 968, 969, 970, 971, 948, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, @@ -3316,7 +3315,7 @@ var _hcltok_trans_targs []int16 = []int16{ 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1204, 1205, 1206, 1207, 1208, 1209, 1211, - 1213, 1215, 1217, 1219, 1220, 1545, 1545, 1221, + 1213, 1215, 1217, 1219, 1220, 1546, 1546, 1221, 1358, 1359, 1290, 1360, 1361, 1362, 1363, 1364, 1365, 1319, 1366, 1255, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1275, 1375, 1376, 1377, @@ -3330,78 +3329,78 @@ var _hcltok_trans_targs []int16 = []int16{ 1439, 1440, 1441, 1442, 1443, 1445, 1446, 1447, 1448, 1451, 1453, 1454, 1456, 1458, 1460, 1459, 1461, 1462, 1459, 1463, 1459, 1464, 1465, 1466, - 1468, 1469, 1470, 1459, 1472, 1459, 1473, 1459, - 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, + 1468, 1469, 1470, 1471, 1459, 1473, 1459, 1474, + 1459, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, - 1506, 1507, 1508, 1459, 1459, 1459, 1459, 1459, - 1459, 1, 1459, 7, 1459, 1459, 1459, 1459, - 1459, 415, 416, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 433, - 435, 436, 468, 509, 524, 531, 533, 535, - 555, 558, 574, 687, 1459, 1459, 1459, 691, - 692, 693, 694, 695, 696, 697, 698, 699, - 700, 701, 703, 704, 705, 706, 707, 708, - 709, 710, 711, 712, 713, 714, 715, 716, - 717, 718, 719, 720, 721, 722, 723, 725, - 726, 727, 728, 729, 730, 731, 732, 733, - 734, 735, 736, 737, 738, 739, 741, 742, - 743, 745, 746, 747, 748, 749, 750, 751, - 752, 753, 754, 755, 756, 757, 758, 760, - 761, 762, 763, 764, 765, 766, 767, 768, - 770, 771, 772, 773, 774, 775, 776, 777, - 778, 779, 780, 781, 782, 783, 784, 785, - 786, 787, 789, 790, 791, 792, 793, 794, - 795, 796, 797, 798, 799, 800, 801, 802, - 803, 804, 805, 806, 807, 808, 809, 811, - 812, 813, 814, 815, 816, 817, 818, 819, - 820, 821, 822, 823, 824, 825, 826, 855, - 880, 883, 884, 886, 893, 894, 897, 901, - 913, 918, 919, 921, 924, 926, 1511, 1509, - 1512, 1517, 1519, 1509, 1520, 1521, 1522, 1509, - 928, 1509, 1509, 1513, 1514, 1516, 1509, 1515, - 1509, 1509, 1509, 1518, 1509, 1509, 1509, 933, - 934, 938, 939, 1523, 1531, 1532, 1533, 1523, - 937, 1523, 1523, 934, 1527, 1528, 1523, 1523, - 1523, 1523, 1523, 940, 944, 945, 1534, 1542, - 1543, 1544, 1534, 943, 1534, 1534, 940, 1538, - 1539, 1534, 1534, 1534, 1534, 1534, 1545, 1547, - 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, - 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, - 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, - 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, - 1580, 1581, 1545, 946, 947, 951, 952, 953, - 954, 955, 956, 957, 958, 959, 960, 961, - 962, 964, 966, 967, 999, 1040, 1055, 1062, - 1064, 1066, 1086, 1089, 1105, 1218, 1545, 1222, - 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, - 1231, 1232, 1234, 1235, 1236, 1237, 1238, 1239, - 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, - 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1256, - 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, - 1265, 1266, 1267, 1268, 1269, 1270, 1272, 1273, - 1274, 1276, 1277, 1278, 1279, 1280, 1281, 1282, - 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1291, - 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, - 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, - 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, - 1317, 1318, 1320, 1321, 1322, 1323, 1324, 1325, - 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, - 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1342, - 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, - 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1386, - 1411, 1414, 1415, 1417, 1424, 1425, 1428, 1432, - 1444, 1449, 1450, 1452, 1455, 1457, + 1506, 1507, 1508, 1509, 1459, 1459, 1459, 1459, + 1459, 1459, 1, 1459, 1459, 7, 1459, 1459, + 1459, 1459, 1459, 415, 416, 420, 421, 422, + 423, 424, 425, 426, 427, 428, 429, 430, + 431, 433, 435, 436, 468, 509, 524, 531, + 533, 535, 555, 558, 574, 687, 1459, 1459, + 1459, 691, 692, 693, 694, 695, 696, 697, + 698, 699, 700, 701, 703, 704, 705, 706, + 707, 708, 709, 710, 711, 712, 713, 714, + 715, 716, 717, 718, 719, 720, 721, 722, + 723, 725, 726, 727, 728, 729, 730, 731, + 732, 733, 734, 735, 736, 737, 738, 739, + 741, 742, 743, 745, 746, 747, 748, 749, + 750, 751, 752, 753, 754, 755, 756, 757, + 758, 760, 761, 762, 763, 764, 765, 766, + 767, 768, 770, 771, 772, 773, 774, 775, + 776, 777, 778, 779, 780, 781, 782, 783, + 784, 785, 786, 787, 789, 790, 791, 792, + 793, 794, 795, 796, 797, 798, 799, 800, + 801, 802, 803, 804, 805, 806, 807, 808, + 809, 811, 812, 813, 814, 815, 816, 817, + 818, 819, 820, 821, 822, 823, 824, 825, + 826, 855, 880, 883, 884, 886, 893, 894, + 897, 901, 913, 918, 919, 921, 924, 926, + 1512, 1510, 1513, 1518, 1520, 1510, 1521, 1522, + 1523, 1510, 928, 1510, 1510, 1514, 1515, 1517, + 1510, 1516, 1510, 1510, 1510, 1519, 1510, 1510, + 1510, 933, 934, 938, 939, 1524, 1532, 1533, + 1534, 1524, 937, 1524, 1524, 934, 1528, 1529, + 1524, 1524, 1524, 1524, 1524, 940, 944, 945, + 1535, 1543, 1544, 1545, 1535, 943, 1535, 1535, + 940, 1539, 1540, 1535, 1535, 1535, 1535, 1535, + 1546, 1548, 1549, 1550, 1551, 1552, 1553, 1554, + 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, + 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, + 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, + 1579, 1580, 1581, 1582, 1546, 946, 947, 951, + 952, 953, 954, 955, 956, 957, 958, 959, + 960, 961, 962, 964, 966, 967, 999, 1040, + 1055, 1062, 1064, 1066, 1086, 1089, 1105, 1218, + 1546, 1222, 1223, 1224, 1225, 1226, 1227, 1228, + 1229, 1230, 1231, 1232, 1234, 1235, 1236, 1237, + 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, + 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1256, 1257, 1258, 1259, 1260, 1261, 1262, + 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, + 1272, 1273, 1274, 1276, 1277, 1278, 1279, 1280, + 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, + 1289, 1291, 1292, 1293, 1294, 1295, 1296, 1297, + 1298, 1299, 1301, 1302, 1303, 1304, 1305, 1306, + 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, + 1315, 1316, 1317, 1318, 1320, 1321, 1322, 1323, + 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, + 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, + 1340, 1342, 1343, 1344, 1345, 1346, 1347, 1348, + 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, + 1357, 1386, 1411, 1414, 1415, 1417, 1424, 1425, + 1428, 1432, 1444, 1449, 1450, 1452, 1455, 1457, } var _hcltok_trans_actions []byte = []byte{ - 145, 107, 0, 0, 91, 141, 0, 7, + 147, 109, 0, 0, 91, 143, 0, 7, 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, - 0, 0, 0, 0, 121, 0, 0, 0, + 0, 0, 0, 0, 123, 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, @@ -3448,7 +3447,7 @@ var _hcltok_trans_actions []byte = []byte{ 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, 143, 193, 149, 0, 0, 0, + 0, 0, 145, 195, 151, 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, @@ -3479,7 +3478,7 @@ var _hcltok_trans_actions []byte = []byte{ 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, 147, 125, 0, + 0, 0, 0, 0, 0, 149, 127, 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, @@ -3491,11 +3490,11 @@ var _hcltok_trans_actions []byte = []byte{ 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, 31, 169, + 0, 0, 0, 0, 0, 0, 31, 171, 0, 0, 0, 35, 33, 0, 55, 41, - 175, 0, 53, 0, 175, 175, 0, 0, - 75, 61, 181, 0, 73, 0, 181, 181, - 0, 0, 85, 187, 89, 0, 0, 0, + 177, 0, 53, 0, 177, 177, 0, 0, + 75, 61, 183, 0, 73, 0, 183, 183, + 0, 0, 85, 189, 89, 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, @@ -3539,18 +3538,19 @@ var _hcltok_trans_actions []byte = []byte{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, - 0, 0, 119, 0, 111, 0, 7, 7, - 7, 0, 0, 113, 0, 115, 0, 123, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 121, 0, 113, 0, 7, 7, + 0, 7, 0, 0, 115, 0, 117, 0, + 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 7, 7, - 7, 196, 196, 196, 196, 196, 196, 7, - 7, 196, 7, 127, 139, 135, 97, 133, - 103, 0, 129, 0, 101, 95, 109, 99, - 131, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, + 7, 7, 198, 198, 198, 198, 198, 198, + 7, 7, 198, 7, 129, 141, 137, 97, + 135, 103, 0, 131, 107, 0, 101, 95, + 111, 99, 133, 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, 105, 117, 137, 0, + 0, 0, 0, 0, 0, 0, 105, 119, + 139, 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, @@ -3568,23 +3568,23 @@ var _hcltok_trans_actions []byte = []byte{ 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, 13, - 0, 0, 172, 17, 0, 7, 7, 23, - 0, 25, 27, 0, 0, 0, 151, 0, - 15, 19, 9, 0, 21, 11, 29, 0, - 0, 0, 0, 43, 0, 178, 178, 49, - 0, 157, 154, 1, 175, 175, 45, 37, - 47, 39, 51, 0, 0, 0, 63, 0, - 184, 184, 69, 0, 163, 160, 1, 181, - 181, 65, 57, 67, 59, 71, 77, 0, + 0, 13, 0, 0, 174, 17, 0, 7, + 7, 23, 0, 25, 27, 0, 0, 0, + 153, 0, 15, 19, 9, 0, 21, 11, + 29, 0, 0, 0, 0, 43, 0, 180, + 180, 49, 0, 159, 156, 1, 177, 177, + 45, 37, 47, 39, 51, 0, 0, 0, + 63, 0, 186, 186, 69, 0, 165, 162, + 1, 183, 183, 65, 57, 67, 59, 71, + 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, + 7, 7, 192, 192, 192, 192, 192, 192, + 7, 7, 192, 7, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 7, 7, - 190, 190, 190, 190, 190, 190, 7, 7, - 190, 7, 81, 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, 83, 0, + 83, 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, @@ -3602,7 +3602,6 @@ var _hcltok_trans_actions []byte = []byte{ 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, } var _hcltok_to_state_actions []byte = []byte{ @@ -3794,16 +3793,16 @@ var _hcltok_to_state_actions []byte = []byte{ 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, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 166, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 166, 0, + 0, 0, 0, 0, 168, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, } var _hcltok_from_state_actions []byte = []byte{ @@ -3995,16 +3994,16 @@ var _hcltok_from_state_actions []byte = []byte{ 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, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, } var _hcltok_eof_trans []int16 = []int16{ @@ -4190,35 +4189,35 @@ var _hcltok_eof_trans []int16 = []int16{ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - 1046, 1046, 1046, 0, 1196, 1197, 1198, 1200, - 1198, 1198, 1198, 1203, 1198, 1198, 1198, 1209, - 1198, 1198, 1239, 1239, 1239, 1239, 1239, 1239, - 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, - 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, - 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, - 1239, 1239, 1239, 1239, 1239, 0, 1392, 1394, - 1395, 1399, 1399, 1392, 1402, 1395, 1405, 1395, - 1407, 1407, 1407, 0, 1416, 1418, 1418, 1416, - 1416, 1423, 1425, 1427, 1427, 1427, 0, 1435, - 1437, 1437, 1435, 1435, 1442, 1444, 1446, 1446, - 1446, 0, 1483, 1511, 1511, 1511, 1511, 1511, - 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, - 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, - 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, - 1511, 1511, 1511, 1511, 1511, 1511, + 1046, 1046, 1046, 0, 1197, 1198, 1199, 1201, + 1199, 1199, 1199, 1204, 1199, 1199, 1199, 1199, + 1211, 1199, 1199, 1241, 1241, 1241, 1241, 1241, + 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, + 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, + 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, + 1241, 1241, 1241, 1241, 1241, 1241, 0, 1394, + 1396, 1397, 1401, 1401, 1394, 1404, 1397, 1407, + 1397, 1409, 1409, 1409, 0, 1418, 1420, 1420, + 1418, 1418, 1425, 1427, 1429, 1429, 1429, 0, + 1437, 1439, 1439, 1437, 1437, 1444, 1446, 1448, + 1448, 1448, 0, 1485, 1513, 1513, 1513, 1513, + 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, + 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, + 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, + 1513, 1513, 1513, 1513, 1513, 1513, 1513, } const hcltok_start int = 1459 const hcltok_first_final int = 1459 const hcltok_error int = 0 -const hcltok_en_stringTemplate int = 1509 -const hcltok_en_heredocTemplate int = 1523 -const hcltok_en_bareTemplate int = 1534 -const hcltok_en_identOnly int = 1545 +const hcltok_en_stringTemplate int = 1510 +const hcltok_en_heredocTemplate int = 1524 +const hcltok_en_bareTemplate int = 1535 +const hcltok_en_identOnly int = 1546 const hcltok_en_main int = 1459 -//line scan_tokens.rl:16 +//line scan_tokens.rl:18 func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []Token { stripData := stripUTF8BOM(data) @@ -4232,7 +4231,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To StartByte: start.Byte, } -//line scan_tokens.rl:305 +//line scan_tokens.rl:317 // Ragel state p := 0 // "Pointer" into data @@ -4260,7 +4259,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To var retBraces []int // stack of brace levels that cause us to use fret var heredocs []heredocInProgress // stack of heredocs we're currently processing -//line scan_tokens.rl:340 +//line scan_tokens.rl:352 // Make Go compiler happy _ = ts @@ -4280,7 +4279,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To f.emitToken(TokenType(b[0]), ts, te) } -//line scan_tokens.go:4289 +//line scan_tokens.go:4292 { top = 0 ts = 0 @@ -4288,7 +4287,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To act = 0 } -//line scan_tokens.go:4297 +//line scan_tokens.go:4300 { var _klen int var _trans int @@ -4312,7 +4311,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To //line NONE:1 ts = p -//line scan_tokens.go:4320 +//line scan_tokens.go:4323 } } @@ -4384,7 +4383,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To _acts++ switch _hcltok_actions[_acts-1] { case 0: -//line scan_tokens.rl:224 +//line scan_tokens.rl:235 p-- case 4: @@ -4392,13 +4391,13 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To te = p + 1 case 5: -//line scan_tokens.rl:248 +//line scan_tokens.rl:259 act = 4 case 6: -//line scan_tokens.rl:250 +//line scan_tokens.rl:261 act = 6 case 7: -//line scan_tokens.rl:160 +//line scan_tokens.rl:171 te = p + 1 { token(TokenTemplateInterp) @@ -4416,7 +4415,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 8: -//line scan_tokens.rl:170 +//line scan_tokens.rl:181 te = p + 1 { token(TokenTemplateControl) @@ -4434,7 +4433,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 9: -//line scan_tokens.rl:84 +//line scan_tokens.rl:95 te = p + 1 { token(TokenCQuote) @@ -4447,19 +4446,19 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } case 10: -//line scan_tokens.rl:248 +//line scan_tokens.rl:259 te = p + 1 { token(TokenQuotedLit) } case 11: -//line scan_tokens.rl:251 +//line scan_tokens.rl:262 te = p + 1 { token(TokenBadUTF8) } case 12: -//line scan_tokens.rl:160 +//line scan_tokens.rl:171 te = p p-- { @@ -4478,7 +4477,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 13: -//line scan_tokens.rl:170 +//line scan_tokens.rl:181 te = p p-- { @@ -4497,41 +4496,41 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 14: -//line scan_tokens.rl:248 +//line scan_tokens.rl:259 te = p p-- { token(TokenQuotedLit) } case 15: -//line scan_tokens.rl:249 +//line scan_tokens.rl:260 te = p p-- { token(TokenQuotedNewline) } case 16: -//line scan_tokens.rl:250 +//line scan_tokens.rl:261 te = p p-- { token(TokenInvalid) } case 17: -//line scan_tokens.rl:251 +//line scan_tokens.rl:262 te = p p-- { token(TokenBadUTF8) } case 18: -//line scan_tokens.rl:248 +//line scan_tokens.rl:259 p = (te) - 1 { token(TokenQuotedLit) } case 19: -//line scan_tokens.rl:251 +//line scan_tokens.rl:262 p = (te) - 1 { token(TokenBadUTF8) @@ -4552,13 +4551,13 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } case 21: -//line scan_tokens.rl:148 +//line scan_tokens.rl:159 act = 11 case 22: -//line scan_tokens.rl:259 +//line scan_tokens.rl:270 act = 12 case 23: -//line scan_tokens.rl:160 +//line scan_tokens.rl:171 te = p + 1 { token(TokenTemplateInterp) @@ -4576,7 +4575,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 24: -//line scan_tokens.rl:170 +//line scan_tokens.rl:181 te = p + 1 { token(TokenTemplateControl) @@ -4594,7 +4593,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 25: -//line scan_tokens.rl:111 +//line scan_tokens.rl:122 te = p + 1 { // This action is called specificially when a heredoc literal @@ -4639,13 +4638,13 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To token(TokenStringLit) } case 26: -//line scan_tokens.rl:259 +//line scan_tokens.rl:270 te = p + 1 { token(TokenBadUTF8) } case 27: -//line scan_tokens.rl:160 +//line scan_tokens.rl:171 te = p p-- { @@ -4664,7 +4663,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 28: -//line scan_tokens.rl:170 +//line scan_tokens.rl:181 te = p p-- { @@ -4683,7 +4682,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 29: -//line scan_tokens.rl:148 +//line scan_tokens.rl:159 te = p p-- { @@ -4694,14 +4693,14 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To token(TokenStringLit) } case 30: -//line scan_tokens.rl:259 +//line scan_tokens.rl:270 te = p p-- { token(TokenBadUTF8) } case 31: -//line scan_tokens.rl:148 +//line scan_tokens.rl:159 p = (te) - 1 { // This action is called when a heredoc literal _doesn't_ end @@ -4736,13 +4735,13 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } case 33: -//line scan_tokens.rl:156 +//line scan_tokens.rl:167 act = 15 case 34: -//line scan_tokens.rl:266 +//line scan_tokens.rl:277 act = 16 case 35: -//line scan_tokens.rl:160 +//line scan_tokens.rl:171 te = p + 1 { token(TokenTemplateInterp) @@ -4760,7 +4759,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 36: -//line scan_tokens.rl:170 +//line scan_tokens.rl:181 te = p + 1 { token(TokenTemplateControl) @@ -4778,19 +4777,19 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 37: -//line scan_tokens.rl:156 +//line scan_tokens.rl:167 te = p + 1 { token(TokenStringLit) } case 38: -//line scan_tokens.rl:266 +//line scan_tokens.rl:277 te = p + 1 { token(TokenBadUTF8) } case 39: -//line scan_tokens.rl:160 +//line scan_tokens.rl:171 te = p p-- { @@ -4809,7 +4808,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 40: -//line scan_tokens.rl:170 +//line scan_tokens.rl:181 te = p p-- { @@ -4828,21 +4827,21 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } case 41: -//line scan_tokens.rl:156 +//line scan_tokens.rl:167 te = p p-- { token(TokenStringLit) } case 42: -//line scan_tokens.rl:266 +//line scan_tokens.rl:277 te = p p-- { token(TokenBadUTF8) } case 43: -//line scan_tokens.rl:156 +//line scan_tokens.rl:167 p = (te) - 1 { token(TokenStringLit) @@ -4869,45 +4868,45 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } case 45: -//line scan_tokens.rl:270 +//line scan_tokens.rl:281 act = 17 case 46: -//line scan_tokens.rl:271 +//line scan_tokens.rl:282 act = 18 case 47: -//line scan_tokens.rl:271 +//line scan_tokens.rl:282 te = p + 1 { token(TokenBadUTF8) } case 48: -//line scan_tokens.rl:272 +//line scan_tokens.rl:283 te = p + 1 { token(TokenInvalid) } case 49: -//line scan_tokens.rl:270 +//line scan_tokens.rl:281 te = p p-- { token(TokenIdent) } case 50: -//line scan_tokens.rl:271 +//line scan_tokens.rl:282 te = p p-- { token(TokenBadUTF8) } case 51: -//line scan_tokens.rl:270 +//line scan_tokens.rl:281 p = (te) - 1 { token(TokenIdent) } case 52: -//line scan_tokens.rl:271 +//line scan_tokens.rl:282 p = (te) - 1 { token(TokenBadUTF8) @@ -4928,86 +4927,92 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } case 54: -//line scan_tokens.rl:278 +//line scan_tokens.rl:289 act = 22 case 55: -//line scan_tokens.rl:301 - act = 39 +//line scan_tokens.rl:313 + act = 40 case 56: -//line scan_tokens.rl:280 +//line scan_tokens.rl:291 te = p + 1 { token(TokenComment) } case 57: -//line scan_tokens.rl:281 +//line scan_tokens.rl:292 te = p + 1 { token(TokenNewline) } case 58: -//line scan_tokens.rl:283 +//line scan_tokens.rl:294 te = p + 1 { token(TokenEqualOp) } case 59: -//line scan_tokens.rl:284 +//line scan_tokens.rl:295 te = p + 1 { token(TokenNotEqual) } case 60: -//line scan_tokens.rl:285 +//line scan_tokens.rl:296 te = p + 1 { token(TokenGreaterThanEq) } case 61: -//line scan_tokens.rl:286 +//line scan_tokens.rl:297 te = p + 1 { token(TokenLessThanEq) } case 62: -//line scan_tokens.rl:287 +//line scan_tokens.rl:298 te = p + 1 { token(TokenAnd) } case 63: -//line scan_tokens.rl:288 +//line scan_tokens.rl:299 te = p + 1 { token(TokenOr) } case 64: -//line scan_tokens.rl:289 +//line scan_tokens.rl:300 te = p + 1 { - token(TokenEllipsis) + token(TokenDoubleColon) } case 65: -//line scan_tokens.rl:290 +//line scan_tokens.rl:301 te = p + 1 { - token(TokenFatArrow) + token(TokenEllipsis) } case 66: -//line scan_tokens.rl:291 +//line scan_tokens.rl:302 te = p + 1 { - selfToken() + token(TokenFatArrow) } case 67: -//line scan_tokens.rl:180 +//line scan_tokens.rl:303 + te = p + 1 + { + selfToken() + } + case 68: +//line scan_tokens.rl:191 te = p + 1 { token(TokenOBrace) braces++ } - case 68: -//line scan_tokens.rl:185 + case 69: +//line scan_tokens.rl:196 te = p + 1 { if len(retBraces) > 0 && retBraces[len(retBraces)-1] == braces { @@ -5026,8 +5031,8 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To braces-- } } - case 69: -//line scan_tokens.rl:197 + case 70: +//line scan_tokens.rl:208 te = p + 1 { // Only consume from the retBraces stack and return if we are at @@ -5055,8 +5060,8 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To braces-- } } - case 70: -//line scan_tokens.rl:79 + case 71: +//line scan_tokens.rl:90 te = p + 1 { token(TokenOQuote) @@ -5064,12 +5069,12 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To stack = append(stack, 0) stack[top] = cs top++ - cs = 1509 + cs = 1510 goto _again } } - case 71: -//line scan_tokens.rl:89 + case 72: +//line scan_tokens.rl:100 te = p + 1 { token(TokenOHeredoc) @@ -5094,94 +5099,94 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To stack = append(stack, 0) stack[top] = cs top++ - cs = 1523 + cs = 1524 goto _again } } - case 72: -//line scan_tokens.rl:301 + case 73: +//line scan_tokens.rl:313 te = p + 1 { token(TokenBadUTF8) } - case 73: -//line scan_tokens.rl:302 + case 74: +//line scan_tokens.rl:314 te = p + 1 { token(TokenInvalid) } - case 74: -//line scan_tokens.rl:276 + case 75: +//line scan_tokens.rl:287 te = p p-- - case 75: -//line scan_tokens.rl:277 + case 76: +//line scan_tokens.rl:288 te = p p-- { token(TokenNumberLit) } - case 76: -//line scan_tokens.rl:278 + case 77: +//line scan_tokens.rl:289 te = p p-- { token(TokenIdent) } - case 77: -//line scan_tokens.rl:280 + case 78: +//line scan_tokens.rl:291 te = p p-- { token(TokenComment) } - case 78: -//line scan_tokens.rl:291 + case 79: +//line scan_tokens.rl:303 te = p p-- { selfToken() } - case 79: -//line scan_tokens.rl:301 + case 80: +//line scan_tokens.rl:313 te = p p-- { token(TokenBadUTF8) } - case 80: -//line scan_tokens.rl:302 + case 81: +//line scan_tokens.rl:314 te = p p-- { token(TokenInvalid) } - case 81: -//line scan_tokens.rl:277 + case 82: +//line scan_tokens.rl:288 p = (te) - 1 { token(TokenNumberLit) } - case 82: -//line scan_tokens.rl:278 + case 83: +//line scan_tokens.rl:289 p = (te) - 1 { token(TokenIdent) } - case 83: -//line scan_tokens.rl:291 + case 84: +//line scan_tokens.rl:303 p = (te) - 1 { selfToken() } - case 84: -//line scan_tokens.rl:301 + case 85: +//line scan_tokens.rl:313 p = (te) - 1 { token(TokenBadUTF8) } - case 85: + case 86: //line NONE:1 switch act { case 22: @@ -5189,14 +5194,14 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To p = (te) - 1 token(TokenIdent) } - case 39: + case 40: { p = (te) - 1 token(TokenBadUTF8) } } -//line scan_tokens.go:5055 +//line scan_tokens.go:5062 } } @@ -5215,7 +5220,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To //line NONE:1 act = 0 -//line scan_tokens.go:5073 +//line scan_tokens.go:5080 } } @@ -5241,7 +5246,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To } } -//line scan_tokens.rl:363 +//line scan_tokens.rl:375 // If we fall out here without being in a final state then we've // encountered something that the scanner can't match, which we'll diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_tokens.rl b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_tokens.rl index 942ad92b..66bb4714 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_tokens.rl +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/scan_tokens.rl @@ -1,3 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 package hclsyntax @@ -53,6 +55,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To LogicalAnd = "&&"; LogicalOr = "||"; + DoubleColon = "::"; Ellipsis = "..."; FatArrow = "=>"; @@ -294,6 +297,7 @@ func scanTokens(data []byte, filename string, start hcl.Pos, mode scanMode) []To LessThanEqual => { token(TokenLessThanEq); }; LogicalAnd => { token(TokenAnd); }; LogicalOr => { token(TokenOr); }; + DoubleColon => { token(TokenDoubleColon); }; Ellipsis => { token(TokenEllipsis); }; FatArrow => { token(TokenFatArrow); }; SelfToken => { selfToken() }; diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/spec.md b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/spec.md index 6d31e352..88925410 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/spec.md +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/spec.md @@ -668,7 +668,7 @@ a == b equal a != b not equal ``` -Two values are equal if the are of identical types and their values are +Two values are equal if they are of identical types and their values are equal as defined in the HCL syntax-agnostic information model. The equality operators are commutative and opposite, such that `(a == b) == !(a != b)` and `(a == b) == (b == a)` for all values `a` and `b`. diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/token.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/token.go index a14b3940..47648b8f 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/token.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/token.go @@ -7,7 +7,7 @@ import ( "bytes" "fmt" - "github.com/apparentlymart/go-textseg/v13/textseg" + "github.com/apparentlymart/go-textseg/v15/textseg" "github.com/hashicorp/hcl/v2" ) @@ -63,8 +63,9 @@ const ( TokenDot TokenType = '.' TokenComma TokenType = ',' - TokenEllipsis TokenType = '…' - TokenFatArrow TokenType = '⇒' + TokenDoubleColon TokenType = '⸬' + TokenEllipsis TokenType = '…' + TokenFatArrow TokenType = '⇒' TokenQuestion TokenType = '?' TokenColon TokenType = ':' diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/token_type_string.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/token_type_string.go index c23c4f0b..1453389c 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/token_type_string.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/token_type_string.go @@ -1,11 +1,11 @@ -// Code generated by "stringer -type TokenType -output token_type_string.go"; DO NOT EDIT. +// Code generated by "stringer -type TokenType -output token_type_string.go token_type.go"; DO NOT EDIT. package hclsyntax import "strconv" func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. + // An "invalid array index" compiler error signifies that the constant values (55) have changed. // Re-run the stringer command to generate them again. var x [1]struct{} _ = x[TokenOBrace-123] @@ -35,6 +35,7 @@ func _() { _ = x[TokenBang-33] _ = x[TokenDot-46] _ = x[TokenComma-44] + _ = x[TokenDoubleColon-11820] _ = x[TokenEllipsis-8230] _ = x[TokenFatArrow-8658] _ = x[TokenQuestion-63] @@ -64,7 +65,7 @@ func _() { _ = x[TokenNil-0] } -const _TokenType_name = "TokenNilTokenNewlineTokenBangTokenPercentTokenBitwiseAndTokenApostropheTokenOParenTokenCParenTokenStarTokenPlusTokenCommaTokenMinusTokenDotTokenSlashTokenColonTokenSemicolonTokenLessThanTokenEqualTokenGreaterThanTokenQuestionTokenCommentTokenOHeredocTokenIdentTokenNumberLitTokenQuotedLitTokenStringLitTokenOBrackTokenCBrackTokenBitwiseXorTokenBacktickTokenCHeredocTokenOBraceTokenBitwiseOrTokenCBraceTokenBitwiseNotTokenOQuoteTokenCQuoteTokenTemplateControlTokenEllipsisTokenFatArrowTokenTemplateSeqEndTokenAndTokenOrTokenTemplateInterpTokenEqualOpTokenNotEqualTokenLessThanEqTokenGreaterThanEqTokenEOFTokenTabsTokenQuotedNewlineTokenStarStarTokenInvalidTokenBadUTF8" +const _TokenType_name = "TokenNilTokenNewlineTokenBangTokenPercentTokenBitwiseAndTokenApostropheTokenOParenTokenCParenTokenStarTokenPlusTokenCommaTokenMinusTokenDotTokenSlashTokenColonTokenSemicolonTokenLessThanTokenEqualTokenGreaterThanTokenQuestionTokenCommentTokenOHeredocTokenIdentTokenNumberLitTokenQuotedLitTokenStringLitTokenOBrackTokenCBrackTokenBitwiseXorTokenBacktickTokenCHeredocTokenOBraceTokenBitwiseOrTokenCBraceTokenBitwiseNotTokenOQuoteTokenCQuoteTokenTemplateControlTokenEllipsisTokenFatArrowTokenTemplateSeqEndTokenAndTokenOrTokenTemplateInterpTokenEqualOpTokenNotEqualTokenLessThanEqTokenGreaterThanEqTokenEOFTokenTabsTokenQuotedNewlineTokenStarStarTokenDoubleColonTokenInvalidTokenBadUTF8" var _TokenType_map = map[TokenType]string{ 0: _TokenType_name[0:8], @@ -119,8 +120,9 @@ var _TokenType_map = map[TokenType]string{ 9225: _TokenType_name[603:612], 9252: _TokenType_name[612:630], 10138: _TokenType_name[630:643], - 65533: _TokenType_name[643:655], - 128169: _TokenType_name[655:667], + 11820: _TokenType_name[643:659], + 65533: _TokenType_name[659:671], + 128169: _TokenType_name[671:683], } func (i TokenType) String() string { diff --git a/vendor/github.com/hashicorp/hcl/v2/pos_scanner.go b/vendor/github.com/hashicorp/hcl/v2/pos_scanner.go index cff55392..2232f374 100644 --- a/vendor/github.com/hashicorp/hcl/v2/pos_scanner.go +++ b/vendor/github.com/hashicorp/hcl/v2/pos_scanner.go @@ -7,7 +7,7 @@ import ( "bufio" "bytes" - "github.com/apparentlymart/go-textseg/v13/textseg" + "github.com/apparentlymart/go-textseg/v15/textseg" ) // RangeScanner is a helper that will scan over a buffer using a bufio.SplitFunc diff --git a/vendor/github.com/hashicorp/hcl/v2/tools.go b/vendor/github.com/hashicorp/hcl/v2/tools.go new file mode 100644 index 00000000..e8c42ad1 --- /dev/null +++ b/vendor/github.com/hashicorp/hcl/v2/tools.go @@ -0,0 +1,11 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:build tools +// +build tools + +package hcl + +import ( + _ "golang.org/x/tools/cmd/stringer" +) diff --git a/vendor/github.com/hashicorp/terraform-exec/internal/version/version.go b/vendor/github.com/hashicorp/terraform-exec/internal/version/version.go index bf1a046c..90b66889 100644 --- a/vendor/github.com/hashicorp/terraform-exec/internal/version/version.go +++ b/vendor/github.com/hashicorp/terraform-exec/internal/version/version.go @@ -1,6 +1,9 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package version -const version = "0.18.1" +const version = "0.20.0" // ModuleVersion returns the current version of the github.com/hashicorp/terraform-exec Go module. // This is a function to allow for future possible enhancement using debug.BuildInfo. diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/apply.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/apply.go index 6dfdb976..2c5a6d07 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/apply.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/apply.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( @@ -10,6 +13,7 @@ import ( type applyConfig struct { backup string + destroy bool dirOrPlan string lock bool @@ -18,6 +22,7 @@ type applyConfig struct { parallelism int reattachInfo ReattachInfo refresh bool + refreshOnly bool replaceAddrs []string state string stateOut string @@ -29,6 +34,7 @@ type applyConfig struct { } var defaultApplyOptions = applyConfig{ + destroy: false, lock: true, parallelism: 10, refresh: true, @@ -75,6 +81,10 @@ func (opt *RefreshOption) configureApply(conf *applyConfig) { conf.refresh = opt.refresh } +func (opt *RefreshOnlyOption) configureApply(conf *applyConfig) { + conf.refreshOnly = opt.refreshOnly +} + func (opt *ReplaceOption) configureApply(conf *applyConfig) { conf.replaceAddrs = append(conf.replaceAddrs, opt.address) } @@ -91,6 +101,10 @@ func (opt *ReattachOption) configureApply(conf *applyConfig) { conf.reattachInfo = opt.info } +func (opt *DestroyFlagOption) configureApply(conf *applyConfig) { + conf.destroy = opt.destroy +} + // Apply represents the terraform apply subcommand. func (tf *Terraform) Apply(ctx context.Context, opts ...ApplyOption) error { cmd, err := tf.applyCmd(ctx, opts...) @@ -178,6 +192,17 @@ func (tf *Terraform) buildApplyArgs(ctx context.Context, c applyConfig) ([]strin args = append(args, "-parallelism="+fmt.Sprint(c.parallelism)) args = append(args, "-refresh="+strconv.FormatBool(c.refresh)) + if c.refreshOnly { + err := tf.compatible(ctx, tf0_15_4, nil) + if err != nil { + return nil, fmt.Errorf("refresh-only option was introduced in Terraform 0.15.4: %w", err) + } + if !c.refresh { + return nil, fmt.Errorf("you cannot use refresh=false in refresh-only planning mode") + } + args = append(args, "-refresh-only") + } + // string slice opts: split into separate args if c.replaceAddrs != nil { err := tf.compatible(ctx, tf0_15_2, nil) @@ -188,6 +213,14 @@ func (tf *Terraform) buildApplyArgs(ctx context.Context, c applyConfig) ([]strin args = append(args, "-replace="+addr) } } + if c.destroy { + err := tf.compatible(ctx, tf0_15_2, nil) + if err != nil { + return nil, fmt.Errorf("-destroy option was introduced in Terraform 0.15.2: %w", err) + } + args = append(args, "-destroy") + } + if c.targets != nil { for _, ta := range c.targets { args = append(args, "-target="+ta) diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd.go index 56393a00..5e160324 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( @@ -166,7 +169,7 @@ func (tf *Terraform) buildEnv(mergeEnv map[string]string) []string { env[automationEnvVar] = "1" // force usage of workspace methods for switching - env[workspaceEnvVar] = "" + delete(env, workspaceEnvVar) if tf.disablePluginTLS { env[disablePluginTLSEnvVar] = "1" diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd_default.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd_default.go index 79dacc93..3af11c81 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd_default.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd_default.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + //go:build !linux // +build !linux diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd_linux.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd_linux.go index 440fafe8..0565372c 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd_linux.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd_linux.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/destroy.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/destroy.go index 189db7e4..dbef8b37 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/destroy.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/destroy.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/doc.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/doc.go index 0e82bbd9..288476f5 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/doc.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/doc.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + // Package tfexec exposes functionality for constructing and running Terraform // CLI commands. Structured return values use the data types defined in the // github.com/hashicorp/terraform-json package. diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/errors.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/errors.go index 3bbb431c..c6645e8b 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/errors.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/errors.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/fmt.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/fmt.go index 2234c79f..09794923 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/fmt.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/fmt.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/force_unlock.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/force_unlock.go index de95f547..7d74a12f 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/force_unlock.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/force_unlock.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/get.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/get.go index 5bac9b19..8a1363b5 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/get.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/get.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/graph.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/graph.go index 73396280..0f8b0eee 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/graph.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/graph.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( @@ -57,7 +60,7 @@ func (tf *Terraform) graphCmd(ctx context.Context, opts ...GraphOption) (*exec.C args := []string{"graph"} if c.plan != "" { - // plan was a positional arguement prior to Terraform 0.15.0. Ensure proper use by checking version. + // plan was a positional argument prior to Terraform 0.15.0. Ensure proper use by checking version. if err := tf.compatible(ctx, tf0_15_0, nil); err == nil { args = append(args, "-plan="+c.plan) } else { diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/import.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/import.go index e243d728..67275dfa 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/import.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/import.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/init.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/init.go index 8fd36677..c292fdc0 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/init.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/init.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/metadata_functions.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/metadata_functions.go index 4577e062..0e642b2d 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/metadata_functions.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/metadata_functions.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/options.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/options.go index ad3cc65c..d783027a 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/options.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/options.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( @@ -240,6 +243,15 @@ func GraphPlan(file string) *GraphPlanOption { return &GraphPlanOption{file} } +type UseJSONNumberOption struct { + useJSONNumber bool +} + +// JSONNumber determines how numerical values are handled during JSON decoding. +func JSONNumber(useJSONNumber bool) *UseJSONNumberOption { + return &UseJSONNumberOption{useJSONNumber} +} + type PlatformOption struct { platform string } @@ -324,6 +336,14 @@ func Refresh(refresh bool) *RefreshOption { return &RefreshOption{refresh} } +type RefreshOnlyOption struct { + refreshOnly bool +} + +func RefreshOnly(refreshOnly bool) *RefreshOnlyOption { + return &RefreshOnlyOption{refreshOnly} +} + type ReplaceOption struct { address string } @@ -362,6 +382,15 @@ func Target(resource string) *TargetOption { return &TargetOption{resource} } +type TestsDirectoryOption struct { + testsDirectory string +} + +// TestsDirectory represents the -tests-directory option (path to tests files) +func TestsDirectory(testsDirectory string) *TestsDirectoryOption { + return &TestsDirectoryOption{testsDirectory} +} + type GraphTypeOption struct { graphType string } diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/output.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/output.go index b16b8b72..b1185e8a 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/output.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/output.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/plan.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/plan.go index 5ea31552..946ce8d0 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/plan.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/plan.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( @@ -17,6 +20,7 @@ type planConfig struct { parallelism int reattachInfo ReattachInfo refresh bool + refreshOnly bool replaceAddrs []string state string targets []string @@ -65,6 +69,10 @@ func (opt *RefreshOption) configurePlan(conf *planConfig) { conf.refresh = opt.refresh } +func (opt *RefreshOnlyOption) configurePlan(conf *planConfig) { + conf.refreshOnly = opt.refreshOnly +} + func (opt *ReplaceOption) configurePlan(conf *planConfig) { conf.replaceAddrs = append(conf.replaceAddrs, opt.address) } @@ -199,6 +207,17 @@ func (tf *Terraform) buildPlanArgs(ctx context.Context, c planConfig) ([]string, args = append(args, "-parallelism="+fmt.Sprint(c.parallelism)) args = append(args, "-refresh="+strconv.FormatBool(c.refresh)) + if c.refreshOnly { + err := tf.compatible(ctx, tf0_15_4, nil) + if err != nil { + return nil, fmt.Errorf("refresh-only option was introduced in Terraform 0.15.4: %w", err) + } + if !c.refresh { + return nil, fmt.Errorf("you cannot use refresh=false in refresh-only planning mode") + } + args = append(args, "-refresh-only") + } + // unary flags: pass if true if c.replaceAddrs != nil { err := tf.compatible(ctx, tf0_15_2, nil) diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/providers_lock.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/providers_lock.go index b3a20216..ef5d995b 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/providers_lock.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/providers_lock.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/providers_schema.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/providers_schema.go index 52efc5db..995dd156 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/providers_schema.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/providers_schema.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/refresh.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/refresh.go index 4bdd8960..16733889 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/refresh.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/refresh.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/show.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/show.go index 61e660ac..5854af1d 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/show.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/show.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( @@ -11,6 +14,7 @@ import ( type showConfig struct { reattachInfo ReattachInfo + jsonNumber *UseJSONNumberOption } var defaultShowOptions = showConfig{} @@ -23,6 +27,10 @@ func (opt *ReattachOption) configureShow(conf *showConfig) { conf.reattachInfo = opt.info } +func (opt *UseJSONNumberOption) configureShow(conf *showConfig) { + conf.jsonNumber = opt +} + // Show reads the default state path and outputs the state. // To read a state or plan file, ShowState or ShowPlan must be used instead. func (tf *Terraform) Show(ctx context.Context, opts ...ShowOption) (*tfjson.State, error) { @@ -50,6 +58,11 @@ func (tf *Terraform) Show(ctx context.Context, opts ...ShowOption) (*tfjson.Stat var ret tfjson.State ret.UseJSONNumber(true) + + if c.jsonNumber != nil { + ret.UseJSONNumber(c.jsonNumber.useJSONNumber) + } + err = tf.runTerraformCmdJSON(ctx, showCmd, &ret) if err != nil { return nil, err @@ -93,6 +106,11 @@ func (tf *Terraform) ShowStateFile(ctx context.Context, statePath string, opts . var ret tfjson.State ret.UseJSONNumber(true) + + if c.jsonNumber != nil { + ret.UseJSONNumber(c.jsonNumber.useJSONNumber) + } + err = tf.runTerraformCmdJSON(ctx, showCmd, &ret) if err != nil { return nil, err @@ -135,6 +153,11 @@ func (tf *Terraform) ShowPlanFile(ctx context.Context, planPath string, opts ... showCmd := tf.showCmd(ctx, true, mergeEnv, planPath) var ret tfjson.Plan + + if c.jsonNumber != nil { + ret.UseJSONNumber(c.jsonNumber.useJSONNumber) + } + err = tf.runTerraformCmdJSON(ctx, showCmd, &ret) if err != nil { return nil, err diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/state_mv.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/state_mv.go index fc7eecf8..ca92e522 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/state_mv.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/state_mv.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/state_pull.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/state_pull.go index 11b6b9c7..9fa6e5db 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/state_pull.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/state_pull.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/state_push.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/state_push.go index 14e55a2e..a0873e96 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/state_push.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/state_push.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/state_rm.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/state_rm.go index 0c5dd666..2db18cb7 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/state_rm.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/state_rm.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/taint.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/taint.go index cd69df30..b6ac955c 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/taint.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/taint.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/terraform.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/terraform.go index 10d7d9ad..628b733d 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/terraform.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/terraform.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/test.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/test.go new file mode 100644 index 00000000..5e0bb635 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/test.go @@ -0,0 +1,66 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfexec + +import ( + "context" + "fmt" + "io" + "os/exec" +) + +type testConfig struct { + testsDirectory string +} + +var defaultTestOptions = testConfig{} + +type TestOption interface { + configureTest(*testConfig) +} + +func (opt *TestsDirectoryOption) configureTest(conf *testConfig) { + conf.testsDirectory = opt.testsDirectory +} + +// Test represents the terraform test -json subcommand. +// +// The given io.Writer, if specified, will receive +// [machine-readable](https://developer.hashicorp.com/terraform/internals/machine-readable-ui) +// JSON from Terraform including test results. +func (tf *Terraform) Test(ctx context.Context, w io.Writer, opts ...TestOption) error { + err := tf.compatible(ctx, tf1_6_0, nil) + + if err != nil { + return fmt.Errorf("terraform test was added in 1.6.0: %w", err) + } + + tf.SetStdout(w) + + testCmd := tf.testCmd(ctx) + + err = tf.runTerraformCmd(ctx, testCmd) + + if err != nil { + return err + } + + return nil +} + +func (tf *Terraform) testCmd(ctx context.Context, opts ...TestOption) *exec.Cmd { + c := defaultTestOptions + + for _, o := range opts { + o.configureTest(&c) + } + + args := []string{"test", "-json"} + + if c.testsDirectory != "" { + args = append(args, "-tests-directory="+c.testsDirectory) + } + + return tf.buildTerraformCmd(ctx, nil, args...) +} diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/untaint.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/untaint.go index bda12727..5f0bf350 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/untaint.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/untaint.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/upgrade012.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/upgrade012.go index e55237a7..34a2c87d 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/upgrade012.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/upgrade012.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/upgrade013.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/upgrade013.go index f1f444e2..98dc4590 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/upgrade013.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/upgrade013.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/validate.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/validate.go index 320011df..d995d375 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/validate.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/validate.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/version.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/version.go index a2e97368..4ba4f6ea 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/version.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/version.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( @@ -26,8 +29,10 @@ var ( tf0_15_0 = version.Must(version.NewVersion("0.15.0")) tf0_15_2 = version.Must(version.NewVersion("0.15.2")) tf0_15_3 = version.Must(version.NewVersion("0.15.3")) + tf0_15_4 = version.Must(version.NewVersion("0.15.4")) tf1_1_0 = version.Must(version.NewVersion("1.1.0")) tf1_4_0 = version.Must(version.NewVersion("1.4.0")) + tf1_6_0 = version.Must(version.NewVersion("1.6.0")) ) // Version returns structured output from the terraform version command including both the Terraform CLI version diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_delete.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_delete.go index 52677207..f2a17e65 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_delete.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_delete.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_list.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_list.go index 33c0d779..1b4bec37 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_list.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_list.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_new.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_new.go index 2e05ffdb..921a1187 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_new.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_new.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_select.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_select.go index 5a51330f..da88472a 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_select.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_select.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import "context" diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_show.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_show.go index 7d5a267f..840eff9a 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_show.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/workspace_show.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package tfexec import ( diff --git a/vendor/github.com/hashicorp/terraform-json/README.md b/vendor/github.com/hashicorp/terraform-json/README.md index 4a9cd94a..462c1a81 100644 --- a/vendor/github.com/hashicorp/terraform-json/README.md +++ b/vendor/github.com/hashicorp/terraform-json/README.md @@ -15,7 +15,39 @@ This repository also serves as de facto documentation for the formats produced by these commands. For more details, see the [GoDoc](https://godoc.org/github.com/hashicorp/terraform-json). -## Why a Separate Repository? +## Should I use this library? + +This library was built for a few specific applications, and is not intended for +general purpose use. + +The Terraform core team **recommends against** using `terraform-json` if your +application has any of the following requirements: + +* **Forward-compatibility**: each version of this library represents a specific + snapshot of the [Terraform JSON output format](https://developer.hashicorp.com/terraform/internals/json-format), + and it often slightly lags behind Terraform itself. The library supports + [the 1.x compatibility promises](https://developer.hashicorp.com/terraform/language/v1-compatibility-promises) + but you will need to upgrade the version promptly to use new additions. If you + require full compatibility with future Terraform versions, we recommend + implementing your own custom decoders for the parts of the JSON format you need. +* **Writing JSON output**: the structures in this library are not guaranteed to emit + JSON data which is semantically equivalent to Terraform itself. If your application + must robustly write JSON data to be consumed by systems which expect Terraform's + format to be supported, you should implement your own custom encoders. +* **Filtering or round-tripping**: the Terraform JSON formats are designed to be + forwards compatible, and permit new attributes to be added which may safely be + ignored by earlier versions of consumers. This library **drops unknown attributes**, + which means it is unsuitable for any application which intends to filter data + or read-modify-write data which will be consumed downstream. Any application doing + this will silently drop new data from new versions. For this application, you should + implement a custom decoder and encoder which preserves any unknown attributes + through a round-trip. + +When is `terraform-json` suitable? We recommend using it for applications which +decode the core stable data types and use it directly, and don't attempt to emit +JSON to be consumed by applications which expect the Terraform format. + +## Why a separate repository? To reduce dependencies on any of Terraform core's internals, we've made a design decision to make any helpers or libraries that work with the external JSON data diff --git a/vendor/github.com/hashicorp/terraform-json/metadata.go b/vendor/github.com/hashicorp/terraform-json/metadata.go index eb525776..8ac111ad 100644 --- a/vendor/github.com/hashicorp/terraform-json/metadata.go +++ b/vendor/github.com/hashicorp/terraform-json/metadata.go @@ -77,6 +77,14 @@ type FunctionSignature struct { // of the function Description string `json:"description,omitempty"` + // Summary is an optional shortened description of the function + Summary string `json:"summary,omitempty"` + + // DeprecationMessage is an optional message that indicates that the + // function should be considered deprecated and what actions should be + // performed by the practitioner to handle the deprecation. + DeprecationMessage string `json:"deprecation_message,omitempty"` + // ReturnType is the ctyjson representation of the function's // return types based on supplying all parameters using // dynamic types. Functions can have dynamic return types. diff --git a/vendor/github.com/hashicorp/terraform-json/plan.go b/vendor/github.com/hashicorp/terraform-json/plan.go index de529acc..38ea778e 100644 --- a/vendor/github.com/hashicorp/terraform-json/plan.go +++ b/vendor/github.com/hashicorp/terraform-json/plan.go @@ -4,6 +4,7 @@ package tfjson import ( + "bytes" "encoding/json" "errors" "fmt" @@ -29,6 +30,12 @@ const ( // Plan represents the entire contents of an output Terraform plan. type Plan struct { + // useJSONNumber opts into the behavior of calling + // json.Decoder.UseNumber prior to decoding the plan, which turns + // numbers into json.Numbers instead of float64s. Set it using + // Plan.UseJSONNumber. + useJSONNumber bool + // The version of the plan format. This should always match the // PlanFormatVersion constant in this package, or else an unmarshal // will be unstable. @@ -85,6 +92,14 @@ type ResourceAttribute struct { Attribute []json.RawMessage `json:"attribute"` } +// UseJSONNumber controls whether the Plan will be decoded using the +// json.Number behavior or the float64 behavior. When b is true, the Plan will +// represent numbers in PlanOutputs as json.Numbers. When b is false, the +// Plan will represent numbers in PlanOutputs as float64s. +func (p *Plan) UseJSONNumber(b bool) { + p.useJSONNumber = b +} + // Validate checks to ensure that the plan is present, and the // version matches the version supported by this library. func (p *Plan) Validate() error { @@ -127,7 +142,11 @@ func (p *Plan) UnmarshalJSON(b []byte) error { type rawPlan Plan var plan rawPlan - err := json.Unmarshal(b, &plan) + dec := json.NewDecoder(bytes.NewReader(b)) + if p.useJSONNumber { + dec.UseNumber() + } + err := dec.Decode(&plan) if err != nil { return err } @@ -144,6 +163,10 @@ type ResourceChange struct { // The absolute resource address. Address string `json:"address,omitempty"` + // The absolute address that this resource instance had + // at the conclusion of a previous plan. + PreviousAddress string `json:"previous_address,omitempty"` + // The module portion of the above address. Omitted if the instance // is in the root module. ModuleAddress string `json:"module_address,omitempty"` @@ -223,6 +246,15 @@ type Change struct { // might change in the future. However, not all Importing changes will // contain generated config. GeneratedConfig string `json:"generated_config,omitempty"` + + // ReplacePaths contains a set of paths that point to attributes/elements + // that are causing the overall resource to be replaced rather than simply + // updated. + // + // This field is always a slice of indexes, where an index in this context + // is either an integer pointing to a child of a set/list, or a string + // pointing to the child of a map, object, or block. + ReplacePaths []interface{} `json:"replace_paths,omitempty"` } // Importing is a nested object for the resource import metadata. diff --git a/vendor/github.com/hashicorp/terraform-json/schemas.go b/vendor/github.com/hashicorp/terraform-json/schemas.go index 64f87d84..a2918ef4 100644 --- a/vendor/github.com/hashicorp/terraform-json/schemas.go +++ b/vendor/github.com/hashicorp/terraform-json/schemas.go @@ -86,6 +86,9 @@ type ProviderSchema struct { // The schemas for any data sources in this provider. DataSourceSchemas map[string]*Schema `json:"data_source_schemas,omitempty"` + + // The definitions for any functions in this provider. + Functions map[string]*FunctionSignature `json:"functions,omitempty"` } // Schema is the JSON representation of a particular schema diff --git a/vendor/github.com/hashicorp/terraform-json/state.go b/vendor/github.com/hashicorp/terraform-json/state.go index 0f2a9996..e5336329 100644 --- a/vendor/github.com/hashicorp/terraform-json/state.go +++ b/vendor/github.com/hashicorp/terraform-json/state.go @@ -38,7 +38,7 @@ type State struct { // Checks contains the results of any conditional checks when Values was // last updated. - Checks *CheckResultStatic `json:"checks,omitempty"` + Checks []CheckResultStatic `json:"checks,omitempty"` } // UseJSONNumber controls whether the State will be decoded using the diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/internal/logging/keys.go b/vendor/github.com/hashicorp/terraform-plugin-go/internal/logging/keys.go index 0b2b9d2f..7ad91271 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/internal/logging/keys.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/internal/logging/keys.go @@ -29,6 +29,15 @@ const ( // Underlying error string KeyError = "error" + // Argument position of the function error. + KeyFunctionErrorArgument = "function_error_argument" + + // Boolean indicating presence of function error + KeyFunctionErrorExists = "function_error_exists" + + // Message of the function error. + KeyFunctionErrorText = "function_error_text" + // Duration in milliseconds for the RPC request KeyRequestDurationMs = "tf_req_duration_ms" @@ -53,4 +62,10 @@ const ( // The protocol version being used, as a string, such as "6" KeyProtocolVersion = "tf_proto_version" + + // Whether the GetProviderSchemaOptional server capability is enabled + KeyServerCapabilityGetProviderSchemaOptional = "tf_server_capability_get_provider_schema_optional" + + // Whether the PlanDestroy server capability is enabled + KeyServerCapabilityPlanDestroy = "tf_server_capability_plan_destroy" ) diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/data_source.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/data_source.go index c84e8076..f76df341 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/data_source.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/data_source.go @@ -7,6 +7,13 @@ import ( "context" ) +// DataSourceMetadata describes metadata for a data resource in the GetMetadata +// RPC. +type DataSourceMetadata struct { + // TypeName is the name of the data resource. + TypeName string +} + // DataSourceServer is an interface containing the methods a data source // implementation needs to fill. type DataSourceServer interface { diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/function.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/function.go new file mode 100644 index 00000000..ef1e363a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/function.go @@ -0,0 +1,141 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfprotov5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Function describes the definition of a function. Result must be defined. +type Function struct { + // Parameters is the ordered list of positional function parameters. + Parameters []*FunctionParameter + + // VariadicParameter is an optional final parameter which accepts zero or + // more argument values, in which Terraform will send an ordered list of the + // parameter type. + VariadicParameter *FunctionParameter + + // Return is the function result. + Return *FunctionReturn + + // Summary is the shortened human-readable documentation for the function. + Summary string + + // Description is the longer human-readable documentation for the function. + Description string + + // DescriptionKind indicates the formatting and encoding that the + // Description field is using. + DescriptionKind StringKind + + // DeprecationMessage is the human-readable documentation if the function + // is deprecated. This message should be practitioner oriented to explain + // how their configuration should be updated. + DeprecationMessage string +} + +// FunctionMetadata describes metadata for a function in the GetMetadata RPC. +type FunctionMetadata struct { + // Name is the name of the function. + Name string +} + +// FunctionParameter describes the definition of a function parameter. Type must +// be defined. +type FunctionParameter struct { + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the provider. When disabled, Terraform returns an error if the + // argument value is null. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that any unknown argument value + // (recursively checked for collections) can be passed to the provider. When + // disabled and an unknown value is present, Terraform skips the function + // call entirely and returns an unknown value result from the function. + AllowUnknownValues bool + + // Description is the human-readable documentation for the parameter. + Description string + + // DescriptionKind indicates the formatting and encoding that the + // Description field is using. + DescriptionKind StringKind + + // Name is the human-readable display name for the parameter. Parameters + // are by definition positional and this name is only used in documentation. + Name string + + // Type indicates the type of data the parameter expects. + Type tftypes.Type +} + +// FunctionReturn describes the definition of a function result. Type must be +// defined. +type FunctionReturn struct { + // Type indicates the type of return data. + Type tftypes.Type +} + +// FunctionServer is an interface containing the methods a function +// implementation needs to fill. +type FunctionServer interface { + // CallFunction is called when Terraform wants to execute the logic of a + // function referenced in the configuration. + CallFunction(context.Context, *CallFunctionRequest) (*CallFunctionResponse, error) + + // GetFunctions is called when Terraform wants to lookup which functions a + // provider supports when not calling GetProviderSchema. + GetFunctions(context.Context, *GetFunctionsRequest) (*GetFunctionsResponse, error) +} + +// CallFunctionRequest is the request Terraform sends when it wants to execute +// the logic of function referenced in the configuration. +type CallFunctionRequest struct { + // Name is the function name being called. + Name string + + // Arguments is the configuration value of each argument the practitioner + // supplied for the function call. The ordering and value of each element + // matches the function parameters and their associated type. If the + // function definition includes a final variadic parameter, its value is an + // ordered list of the variadic parameter type. + Arguments []*DynamicValue +} + +// CallFunctionResponse is the response from the provider with the result of +// executing the logic of the function. +type CallFunctionResponse struct { + // Error reports errors related to the execution of the + // function logic. Returning a nil error indicates a successful response + // with no errors presented to practitioners. + Error *FunctionError + + // Result is the return value from the called function, matching the result + // type in the function definition. + Result *DynamicValue +} + +// GetFunctionsRequest is the request Terraform sends when it wants to lookup +// which functions a provider supports when not calling GetProviderSchema. +type GetFunctionsRequest struct{} + +// GetFunctionsResponse is the response from the provider about the implemented +// functions. +type GetFunctionsResponse struct { + // Diagnostics report errors or warnings related to the provider + // implementation. Returning an empty slice indicates a successful response + // with no warnings or errors presented to practitioners. + Diagnostics []*Diagnostic + + // Functions is a map of function names to their definition. + // + // Unlike data resources and managed resources, the name should NOT be + // prefixed with the provider name and an underscore. Configuration + // references to functions use a separate namespacing syntax that already + // includes the provider name. + Functions map[string]*Function +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/function_error.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/function_error.go new file mode 100644 index 00000000..558335f9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/function_error.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfprotov5 + +// FunctionError is used to convey information back to the user running Terraform. +type FunctionError struct { + // Text is the description of the error. + Text string + + // FunctionArgument is the positional function argument for aligning + // configuration source. + FunctionArgument *int64 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/attribute_path.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/attribute_path.go deleted file mode 100644 index 182479ec..00000000 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/attribute_path.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package fromproto - -import ( - "errors" - - "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -var ErrUnknownAttributePathStepType = errors.New("unknown type of AttributePath_Step") - -func AttributePath(in *tfplugin5.AttributePath) (*tftypes.AttributePath, error) { - steps, err := AttributePathSteps(in.Steps) - if err != nil { - return nil, err - } - return tftypes.NewAttributePathWithSteps(steps), nil -} - -func AttributePaths(in []*tfplugin5.AttributePath) ([]*tftypes.AttributePath, error) { - resp := make([]*tftypes.AttributePath, 0, len(in)) - for _, a := range in { - if a == nil { - resp = append(resp, nil) - continue - } - attr, err := AttributePath(a) - if err != nil { - return resp, err - } - resp = append(resp, attr) - } - return resp, nil -} - -func AttributePathStep(step *tfplugin5.AttributePath_Step) (tftypes.AttributePathStep, error) { - selector := step.GetSelector() - if v, ok := selector.(*tfplugin5.AttributePath_Step_AttributeName); ok { - return tftypes.AttributeName(v.AttributeName), nil - } - if v, ok := selector.(*tfplugin5.AttributePath_Step_ElementKeyString); ok { - return tftypes.ElementKeyString(v.ElementKeyString), nil - } - if v, ok := selector.(*tfplugin5.AttributePath_Step_ElementKeyInt); ok { - return tftypes.ElementKeyInt(v.ElementKeyInt), nil - } - return nil, ErrUnknownAttributePathStepType -} - -func AttributePathSteps(in []*tfplugin5.AttributePath_Step) ([]tftypes.AttributePathStep, error) { - resp := make([]tftypes.AttributePathStep, 0, len(in)) - for _, step := range in { - if step == nil { - continue - } - s, err := AttributePathStep(step) - if err != nil { - return resp, err - } - resp = append(resp, s) - } - return resp, nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/data_source.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/data_source.go index ae2957e4..3b831e7d 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/data_source.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/data_source.go @@ -8,49 +8,29 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" ) -func ValidateDataSourceConfigRequest(in *tfplugin5.ValidateDataSourceConfig_Request) (*tfprotov5.ValidateDataSourceConfigRequest, error) { +func ValidateDataSourceConfigRequest(in *tfplugin5.ValidateDataSourceConfig_Request) *tfprotov5.ValidateDataSourceConfigRequest { + if in == nil { + return nil + } + resp := &tfprotov5.ValidateDataSourceConfigRequest{ + Config: DynamicValue(in.Config), TypeName: in.TypeName, } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - return resp, nil + + return resp } -func ValidateDataSourceConfigResponse(in *tfplugin5.ValidateDataSourceConfig_Response) (*tfprotov5.ValidateDataSourceConfigResponse, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func ReadDataSourceRequest(in *tfplugin5.ReadDataSource_Request) *tfprotov5.ReadDataSourceRequest { + if in == nil { + return nil } - return &tfprotov5.ValidateDataSourceConfigResponse{ - Diagnostics: diags, - }, nil -} -func ReadDataSourceRequest(in *tfplugin5.ReadDataSource_Request) (*tfprotov5.ReadDataSourceRequest, error) { resp := &tfprotov5.ReadDataSourceRequest{ - TypeName: in.TypeName, + Config: DynamicValue(in.Config), + ProviderMeta: DynamicValue(in.ProviderMeta), + TypeName: in.TypeName, } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) - } - return resp, nil -} -func ReadDataSourceResponse(in *tfplugin5.ReadDataSource_Response) (*tfprotov5.ReadDataSourceResponse, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err - } - resp := &tfprotov5.ReadDataSourceResponse{ - Diagnostics: diags, - } - if in.State != nil { - resp.State = DynamicValue(in.State) - } - return resp, nil + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/diagnostic.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/diagnostic.go deleted file mode 100644 index 1dc41687..00000000 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/diagnostic.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package fromproto - -import ( - "github.com/hashicorp/terraform-plugin-go/tfprotov5" - "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" -) - -func Diagnostic(in *tfplugin5.Diagnostic) (*tfprotov5.Diagnostic, error) { - diag := &tfprotov5.Diagnostic{ - Severity: DiagnosticSeverity(in.Severity), - Summary: in.Summary, - Detail: in.Detail, - } - if in.Attribute != nil { - attr, err := AttributePath(in.Attribute) - if err != nil { - return diag, err - } - diag.Attribute = attr - } - return diag, nil -} - -func DiagnosticSeverity(in tfplugin5.Diagnostic_Severity) tfprotov5.DiagnosticSeverity { - return tfprotov5.DiagnosticSeverity(in) -} - -func Diagnostics(in []*tfplugin5.Diagnostic) ([]*tfprotov5.Diagnostic, error) { - diagnostics := make([]*tfprotov5.Diagnostic, 0, len(in)) - for _, diag := range in { - if diag == nil { - diagnostics = append(diagnostics, nil) - continue - } - d, err := Diagnostic(diag) - if err != nil { - return diagnostics, err - } - diagnostics = append(diagnostics, d) - } - return diagnostics, nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/doc.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/doc.go new file mode 100644 index 00000000..01a7012d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package fromproto converts Protocol Buffers generated tfplugin5 types into +// terraform-plugin-go tfprotov5 types. +package fromproto diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/types.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/dynamic_value.go similarity index 81% rename from vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/types.go rename to vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/dynamic_value.go index f99ff2b7..af332bfd 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/types.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/dynamic_value.go @@ -9,8 +9,14 @@ import ( ) func DynamicValue(in *tfplugin5.DynamicValue) *tfprotov5.DynamicValue { - return &tfprotov5.DynamicValue{ + if in == nil { + return nil + } + + resp := &tfprotov5.DynamicValue{ MsgPack: in.Msgpack, JSON: in.Json, } + + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/function.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/function.go new file mode 100644 index 00000000..0abd61de --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/function.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto + +import ( + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" +) + +func CallFunctionRequest(in *tfplugin5.CallFunction_Request) *tfprotov5.CallFunctionRequest { + if in == nil { + return nil + } + + resp := &tfprotov5.CallFunctionRequest{ + Arguments: make([]*tfprotov5.DynamicValue, 0, len(in.Arguments)), + Name: in.Name, + } + + for _, argument := range in.Arguments { + resp.Arguments = append(resp.Arguments, DynamicValue(argument)) + } + + return resp +} + +func GetFunctionsRequest(in *tfplugin5.GetFunctions_Request) *tfprotov5.GetFunctionsRequest { + if in == nil { + return nil + } + + resp := &tfprotov5.GetFunctionsRequest{} + + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/provider.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/provider.go index 3442814b..6f8cd7d9 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/provider.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/provider.go @@ -8,105 +8,57 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" ) -func GetProviderSchemaRequest(in *tfplugin5.GetProviderSchema_Request) (*tfprotov5.GetProviderSchemaRequest, error) { - return &tfprotov5.GetProviderSchemaRequest{}, nil -} - -func GetProviderSchemaResponse(in *tfplugin5.GetProviderSchema_Response) (*tfprotov5.GetProviderSchemaResponse, error) { - var resp tfprotov5.GetProviderSchemaResponse - if in.Provider != nil { - schema, err := Schema(in.Provider) - if err != nil { - return &resp, err - } - resp.Provider = schema - } - if in.ProviderMeta != nil { - schema, err := Schema(in.ProviderMeta) - if err != nil { - return &resp, err - } - resp.ProviderMeta = schema - } - resp.ResourceSchemas = make(map[string]*tfprotov5.Schema, len(in.ResourceSchemas)) - for k, v := range in.ResourceSchemas { - if v == nil { - resp.ResourceSchemas[k] = nil - continue - } - schema, err := Schema(v) - if err != nil { - return &resp, err - } - resp.ResourceSchemas[k] = schema - } - resp.DataSourceSchemas = make(map[string]*tfprotov5.Schema, len(in.DataSourceSchemas)) - for k, v := range in.DataSourceSchemas { - if v == nil { - resp.DataSourceSchemas[k] = nil - continue - } - schema, err := Schema(v) - if err != nil { - return &resp, err - } - resp.DataSourceSchemas[k] = schema +func GetMetadataRequest(in *tfplugin5.GetMetadata_Request) *tfprotov5.GetMetadataRequest { + if in == nil { + return nil } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return &resp, err - } - resp.Diagnostics = diags - return &resp, nil + + resp := &tfprotov5.GetMetadataRequest{} + + return resp } -func PrepareProviderConfigRequest(in *tfplugin5.PrepareProviderConfig_Request) (*tfprotov5.PrepareProviderConfigRequest, error) { - var resp tfprotov5.PrepareProviderConfigRequest - if in.Config != nil { - resp.Config = DynamicValue(in.Config) +func GetProviderSchemaRequest(in *tfplugin5.GetProviderSchema_Request) *tfprotov5.GetProviderSchemaRequest { + if in == nil { + return nil } - return &resp, nil + + resp := &tfprotov5.GetProviderSchemaRequest{} + + return resp } -func PrepareProviderConfigResponse(in *tfplugin5.PrepareProviderConfig_Response) (*tfprotov5.PrepareProviderConfigResponse, error) { - var resp tfprotov5.PrepareProviderConfigResponse - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func PrepareProviderConfigRequest(in *tfplugin5.PrepareProviderConfig_Request) *tfprotov5.PrepareProviderConfigRequest { + if in == nil { + return nil } - resp.Diagnostics = diags - if in.PreparedConfig != nil { - resp.PreparedConfig = DynamicValue(in.PreparedConfig) + + resp := &tfprotov5.PrepareProviderConfigRequest{ + Config: DynamicValue(in.Config), } - return &resp, nil + + return resp } -func ConfigureProviderRequest(in *tfplugin5.Configure_Request) (*tfprotov5.ConfigureProviderRequest, error) { +func ConfigureProviderRequest(in *tfplugin5.Configure_Request) *tfprotov5.ConfigureProviderRequest { + if in == nil { + return nil + } + resp := &tfprotov5.ConfigureProviderRequest{ + Config: DynamicValue(in.Config), TerraformVersion: in.TerraformVersion, } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - return resp, nil + + return resp } -func ConfigureProviderResponse(in *tfplugin5.Configure_Response) (*tfprotov5.ConfigureProviderResponse, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func StopProviderRequest(in *tfplugin5.Stop_Request) *tfprotov5.StopProviderRequest { + if in == nil { + return nil } - return &tfprotov5.ConfigureProviderResponse{ - Diagnostics: diags, - }, nil -} -func StopProviderRequest(in *tfplugin5.Stop_Request) (*tfprotov5.StopProviderRequest, error) { - return &tfprotov5.StopProviderRequest{}, nil -} + resp := &tfprotov5.StopProviderRequest{} -func StopProviderResponse(in *tfplugin5.Stop_Response) (*tfprotov5.StopProviderResponse, error) { - return &tfprotov5.StopProviderResponse{ - Error: in.Error, - }, nil + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/state.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/raw_state.go similarity index 81% rename from vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/state.go rename to vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/raw_state.go index 910f0c73..c31b7e64 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/state.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/raw_state.go @@ -9,8 +9,14 @@ import ( ) func RawState(in *tfplugin5.RawState) *tfprotov5.RawState { - return &tfprotov5.RawState{ + if in == nil { + return nil + } + + resp := &tfprotov5.RawState{ JSON: in.Json, Flatmap: in.Flatmap, } + + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/resource.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/resource.go index 9133bb91..c7e8d72e 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/resource.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/resource.go @@ -4,208 +4,112 @@ package fromproto import ( - "fmt" - "github.com/hashicorp/terraform-plugin-go/tfprotov5" "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" ) -func ValidateResourceTypeConfigRequest(in *tfplugin5.ValidateResourceTypeConfig_Request) (*tfprotov5.ValidateResourceTypeConfigRequest, error) { +func ValidateResourceTypeConfigRequest(in *tfplugin5.ValidateResourceTypeConfig_Request) *tfprotov5.ValidateResourceTypeConfigRequest { + if in == nil { + return nil + } + resp := &tfprotov5.ValidateResourceTypeConfigRequest{ + Config: DynamicValue(in.Config), TypeName: in.TypeName, } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - return resp, nil + + return resp } -func ValidateResourceTypeConfigResponse(in *tfplugin5.ValidateResourceTypeConfig_Response) (*tfprotov5.ValidateResourceTypeConfigResponse, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func UpgradeResourceStateRequest(in *tfplugin5.UpgradeResourceState_Request) *tfprotov5.UpgradeResourceStateRequest { + if in == nil { + return nil } - return &tfprotov5.ValidateResourceTypeConfigResponse{ - Diagnostics: diags, - }, nil -} -func UpgradeResourceStateRequest(in *tfplugin5.UpgradeResourceState_Request) (*tfprotov5.UpgradeResourceStateRequest, error) { resp := &tfprotov5.UpgradeResourceStateRequest{ + RawState: RawState(in.RawState), TypeName: in.TypeName, Version: in.Version, } - if in.RawState != nil { - resp.RawState = RawState(in.RawState) - } - return resp, nil + + return resp } -func UpgradeResourceStateResponse(in *tfplugin5.UpgradeResourceState_Response) (*tfprotov5.UpgradeResourceStateResponse, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err - } - resp := &tfprotov5.UpgradeResourceStateResponse{ - Diagnostics: diags, +func ReadResourceRequest(in *tfplugin5.ReadResource_Request) *tfprotov5.ReadResourceRequest { + if in == nil { + return nil } - if in.UpgradedState != nil { - resp.UpgradedState = DynamicValue(in.UpgradedState) - } - return resp, nil -} -func ReadResourceRequest(in *tfplugin5.ReadResource_Request) (*tfprotov5.ReadResourceRequest, error) { resp := &tfprotov5.ReadResourceRequest{ - TypeName: in.TypeName, - Private: in.Private, - } - if in.CurrentState != nil { - resp.CurrentState = DynamicValue(in.CurrentState) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) + CurrentState: DynamicValue(in.CurrentState), + Private: in.Private, + ProviderMeta: DynamicValue(in.ProviderMeta), + TypeName: in.TypeName, } - return resp, nil + + return resp } -func ReadResourceResponse(in *tfplugin5.ReadResource_Response) (*tfprotov5.ReadResourceResponse, error) { - resp := &tfprotov5.ReadResourceResponse{ - Private: in.Private, - } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err - } - resp.Diagnostics = diags - if in.NewState != nil { - resp.NewState = DynamicValue(in.NewState) +func PlanResourceChangeRequest(in *tfplugin5.PlanResourceChange_Request) *tfprotov5.PlanResourceChangeRequest { + if in == nil { + return nil } - return resp, nil -} -func PlanResourceChangeRequest(in *tfplugin5.PlanResourceChange_Request) (*tfprotov5.PlanResourceChangeRequest, error) { resp := &tfprotov5.PlanResourceChangeRequest{ - TypeName: in.TypeName, - PriorPrivate: in.PriorPrivate, - } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - if in.PriorState != nil { - resp.PriorState = DynamicValue(in.PriorState) - } - if in.ProposedNewState != nil { - resp.ProposedNewState = DynamicValue(in.ProposedNewState) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) + Config: DynamicValue(in.Config), + PriorPrivate: in.PriorPrivate, + PriorState: DynamicValue(in.PriorState), + ProposedNewState: DynamicValue(in.ProposedNewState), + ProviderMeta: DynamicValue(in.ProviderMeta), + TypeName: in.TypeName, } - return resp, nil + + return resp } -func PlanResourceChangeResponse(in *tfplugin5.PlanResourceChange_Response) (*tfprotov5.PlanResourceChangeResponse, error) { - resp := &tfprotov5.PlanResourceChangeResponse{ - PlannedPrivate: in.PlannedPrivate, - UnsafeToUseLegacyTypeSystem: in.LegacyTypeSystem, - } - attributePaths, err := AttributePaths(in.RequiresReplace) - if err != nil { - return resp, err - } - resp.RequiresReplace = attributePaths - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err +func ApplyResourceChangeRequest(in *tfplugin5.ApplyResourceChange_Request) *tfprotov5.ApplyResourceChangeRequest { + if in == nil { + return nil } - resp.Diagnostics = diags - if in.PlannedState != nil { - resp.PlannedState = DynamicValue(in.PlannedState) - } - return resp, nil -} -func ApplyResourceChangeRequest(in *tfplugin5.ApplyResourceChange_Request) (*tfprotov5.ApplyResourceChangeRequest, error) { resp := &tfprotov5.ApplyResourceChangeRequest{ - TypeName: in.TypeName, + Config: DynamicValue(in.Config), PlannedPrivate: in.PlannedPrivate, + PlannedState: DynamicValue(in.PlannedState), + PriorState: DynamicValue(in.PriorState), + ProviderMeta: DynamicValue(in.ProviderMeta), + TypeName: in.TypeName, } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - if in.PriorState != nil { - resp.PriorState = DynamicValue(in.PriorState) - } - if in.PlannedState != nil { - resp.PlannedState = DynamicValue(in.PlannedState) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) - } - return resp, nil + + return resp } -func ApplyResourceChangeResponse(in *tfplugin5.ApplyResourceChange_Response) (*tfprotov5.ApplyResourceChangeResponse, error) { - resp := &tfprotov5.ApplyResourceChangeResponse{ - Private: in.Private, - UnsafeToUseLegacyTypeSystem: in.LegacyTypeSystem, +func ImportResourceStateRequest(in *tfplugin5.ImportResourceState_Request) *tfprotov5.ImportResourceStateRequest { + if in == nil { + return nil } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err - } - resp.Diagnostics = diags - if in.NewState != nil { - resp.NewState = DynamicValue(in.NewState) - } - return resp, nil -} -func ImportResourceStateRequest(in *tfplugin5.ImportResourceState_Request) (*tfprotov5.ImportResourceStateRequest, error) { - return &tfprotov5.ImportResourceStateRequest{ + resp := &tfprotov5.ImportResourceStateRequest{ TypeName: in.TypeName, ID: in.Id, - }, nil -} - -func ImportResourceStateResponse(in *tfplugin5.ImportResourceState_Response) (*tfprotov5.ImportResourceStateResponse, error) { - imported, err := ImportedResources(in.ImportedResources) - if err != nil { - return nil, err - } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err } - return &tfprotov5.ImportResourceStateResponse{ - ImportedResources: imported, - Diagnostics: diags, - }, nil + + return resp } -func ImportedResource(in *tfplugin5.ImportResourceState_ImportedResource) (*tfprotov5.ImportedResource, error) { - resp := &tfprotov5.ImportedResource{ - TypeName: in.TypeName, - Private: in.Private, - } - if in.State != nil { - resp.State = DynamicValue(in.State) +func MoveResourceStateRequest(in *tfplugin5.MoveResourceState_Request) *tfprotov5.MoveResourceStateRequest { + if in == nil { + return nil } - return resp, nil -} -func ImportedResources(in []*tfplugin5.ImportResourceState_ImportedResource) ([]*tfprotov5.ImportedResource, error) { - resp := make([]*tfprotov5.ImportedResource, 0, len(in)) - for pos, i := range in { - if i == nil { - resp = append(resp, nil) - continue - } - r, err := ImportedResource(i) - if err != nil { - return resp, fmt.Errorf("Error converting imported resource %d/%d: %w", pos+1, len(in), err) - } - resp = append(resp, r) + resp := &tfprotov5.MoveResourceStateRequest{ + SourcePrivate: in.SourcePrivate, + SourceProviderAddress: in.SourceProviderAddress, + SourceSchemaVersion: in.SourceSchemaVersion, + SourceState: RawState(in.SourceState), + SourceTypeName: in.SourceTypeName, + TargetTypeName: in.TargetTypeName, } - return resp, nil + + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/schema.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/schema.go deleted file mode 100644 index 35828c31..00000000 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/schema.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package fromproto - -import ( - "fmt" - - "github.com/hashicorp/terraform-plugin-go/tfprotov5" - "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -func Schema(in *tfplugin5.Schema) (*tfprotov5.Schema, error) { - var resp tfprotov5.Schema - resp.Version = in.Version - if in.Block != nil { - block, err := SchemaBlock(in.Block) - if err != nil { - return &resp, err - } - resp.Block = block - } - return &resp, nil -} - -func SchemaBlock(in *tfplugin5.Schema_Block) (*tfprotov5.SchemaBlock, error) { - resp := &tfprotov5.SchemaBlock{ - Version: in.Version, - Description: in.Description, - DescriptionKind: StringKind(in.DescriptionKind), - Deprecated: in.Deprecated, - } - attrs, err := SchemaAttributes(in.Attributes) - if err != nil { - return resp, err - } - resp.Attributes = attrs - blocks, err := SchemaNestedBlocks(in.BlockTypes) - if err != nil { - return resp, err - } - resp.BlockTypes = blocks - return resp, nil -} - -func SchemaAttribute(in *tfplugin5.Schema_Attribute) (*tfprotov5.SchemaAttribute, error) { - resp := &tfprotov5.SchemaAttribute{ - Name: in.Name, - Description: in.Description, - Required: in.Required, - Optional: in.Optional, - Computed: in.Computed, - Sensitive: in.Sensitive, - DescriptionKind: StringKind(in.DescriptionKind), - Deprecated: in.Deprecated, - } - typ, err := tftypes.ParseJSONType(in.Type) //nolint:staticcheck - if err != nil { - return resp, err - } - resp.Type = typ - return resp, nil -} - -func SchemaAttributes(in []*tfplugin5.Schema_Attribute) ([]*tfprotov5.SchemaAttribute, error) { - resp := make([]*tfprotov5.SchemaAttribute, 0, len(in)) - for pos, a := range in { - if a == nil { - resp = append(resp, nil) - continue - } - attr, err := SchemaAttribute(a) - if err != nil { - return resp, fmt.Errorf("error converting schema attribute %d: %w", pos, err) - } - resp = append(resp, attr) - } - return resp, nil -} - -func SchemaNestedBlock(in *tfplugin5.Schema_NestedBlock) (*tfprotov5.SchemaNestedBlock, error) { - resp := &tfprotov5.SchemaNestedBlock{ - TypeName: in.TypeName, - Nesting: SchemaNestedBlockNestingMode(in.Nesting), - MinItems: in.MinItems, - MaxItems: in.MaxItems, - } - if in.Block != nil { - block, err := SchemaBlock(in.Block) - if err != nil { - return resp, err - } - resp.Block = block - } - return resp, nil -} - -func SchemaNestedBlocks(in []*tfplugin5.Schema_NestedBlock) ([]*tfprotov5.SchemaNestedBlock, error) { - resp := make([]*tfprotov5.SchemaNestedBlock, 0, len(in)) - for pos, b := range in { - if b == nil { - resp = append(resp, nil) - continue - } - block, err := SchemaNestedBlock(b) - if err != nil { - return resp, fmt.Errorf("error converting nested block %d: %w", pos, err) - } - resp = append(resp, block) - } - return resp, nil -} - -func SchemaNestedBlockNestingMode(in tfplugin5.Schema_NestedBlock_NestingMode) tfprotov5.SchemaNestedBlockNestingMode { - return tfprotov5.SchemaNestedBlockNestingMode(in) -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/string_kind.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/string_kind.go deleted file mode 100644 index b2b47248..00000000 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto/string_kind.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package fromproto - -import ( - "github.com/hashicorp/terraform-plugin-go/tfprotov5" - "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" -) - -func StringKind(in tfplugin5.StringKind) tfprotov5.StringKind { - return tfprotov5.StringKind(in) -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/funcerr/doc.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/funcerr/doc.go new file mode 100644 index 00000000..9b9f61f0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/funcerr/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package funcerr contains function error helpers. These implementations are +// intentionally outside the public API. +package funcerr diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/funcerr/function_error.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/funcerr/function_error.go new file mode 100644 index 00000000..60428b44 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/funcerr/function_error.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package funcerr + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/internal/logging" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// FunctionError is a single FunctionError. +type FunctionError tfprotov5.FunctionError + +// HasError returns true if the FunctionError is not empty. +func (e *FunctionError) HasError() bool { + if e == nil { + return false + } + + return e.Text != "" || e.FunctionArgument != nil +} + +// Log will log the function error: +func (e *FunctionError) Log(ctx context.Context) { + if e == nil { + return + } + + if !e.HasError() { + return + } + + switch { + case e.FunctionArgument != nil && e.Text != "": + logging.ProtocolError(ctx, "Response contains function error", map[string]interface{}{ + logging.KeyFunctionErrorText: e.Text, + logging.KeyFunctionErrorArgument: *e.FunctionArgument, + }) + case e.FunctionArgument != nil: + logging.ProtocolError(ctx, "Response contains function error", map[string]interface{}{ + logging.KeyFunctionErrorArgument: *e.FunctionArgument, + }) + case e.Text != "": + logging.ProtocolError(ctx, "Response contains function error", map[string]interface{}{ + logging.KeyFunctionErrorText: e.Text, + }) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tf5serverlogging/downstream_request.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tf5serverlogging/downstream_request.go index efa4d9b5..8c442fef 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tf5serverlogging/downstream_request.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tf5serverlogging/downstream_request.go @@ -8,7 +8,9 @@ import ( "time" "github.com/hashicorp/terraform-plugin-go/internal/logging" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/diag" + "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/funcerr" ) // DownstreamRequest sets a request duration start time context key and @@ -40,3 +42,23 @@ func DownstreamResponse(ctx context.Context, diagnostics diag.Diagnostics) { logging.ProtocolTrace(ctx, "Received downstream response", responseFields) diagnostics.Log(ctx) } + +// DownstreamResponseWithError generates the following logging: +// +// - TRACE "Received downstream response" log with request duration and +// whether a function error is present +// - Log with function error details +func DownstreamResponseWithError(ctx context.Context, funcErr *tfprotov5.FunctionError) { + fe := (*funcerr.FunctionError)(funcErr) + + responseFields := map[string]interface{}{ + logging.KeyFunctionErrorExists: fe.HasError(), + } + + if requestStart, ok := ctx.Value(ContextKeyDownstreamRequestStartTime{}).(time.Time); ok { + responseFields[logging.KeyRequestDurationMs] = time.Since(requestStart).Milliseconds() + } + + logging.ProtocolTrace(ctx, "Received downstream response", responseFields) + fe.Log(ctx) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tf5serverlogging/server_capabilities.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tf5serverlogging/server_capabilities.go new file mode 100644 index 00000000..d0f86c84 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tf5serverlogging/server_capabilities.go @@ -0,0 +1,26 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tf5serverlogging + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/internal/logging" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ServerCapabilities generates a TRACE "Announced server capabilities" log. +func ServerCapabilities(ctx context.Context, capabilities *tfprotov5.ServerCapabilities) { + responseFields := map[string]interface{}{ + logging.KeyServerCapabilityGetProviderSchemaOptional: false, + logging.KeyServerCapabilityPlanDestroy: false, + } + + if capabilities != nil { + responseFields[logging.KeyServerCapabilityGetProviderSchemaOptional] = capabilities.GetProviderSchemaOptional + responseFields[logging.KeyServerCapabilityPlanDestroy] = capabilities.PlanDestroy + } + + logging.ProtocolTrace(ctx, "Announced server capabilities", responseFields) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5.pb.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5.pb.go index 00a8e625..e10c839b 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5.pb.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5.pb.go @@ -1,9 +1,9 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -// Terraform Plugin RPC protocol version 5.3 +// Terraform Plugin RPC protocol version 5.5 // -// This file defines version 5.3 of the RPC protocol. To implement a plugin +// This file defines version 5.5 of the RPC protocol. To implement a plugin // against this protocol, copy this definition into your own codebase and // use protoc to generate stubs for your target language. // @@ -22,8 +22,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v4.23.2 +// protoc-gen-go v1.33.0 +// protoc v4.25.1 // source: tfplugin5.proto package tfplugin5 @@ -192,7 +192,7 @@ func (x Schema_NestedBlock_NestingMode) Number() protoreflect.EnumNumber { // Deprecated: Use Schema_NestedBlock_NestingMode.Descriptor instead. func (Schema_NestedBlock_NestingMode) EnumDescriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{5, 2, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{6, 2, 0} } // DynamicValue is an opaque encoding of terraform data, with the field name @@ -323,6 +323,63 @@ func (x *Diagnostic) GetAttribute() *AttributePath { return nil } +type FunctionError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` + // The optional function_argument records the index position of the + // argument which caused the error. + FunctionArgument *int64 `protobuf:"varint,2,opt,name=function_argument,json=functionArgument,proto3,oneof" json:"function_argument,omitempty"` +} + +func (x *FunctionError) Reset() { + *x = FunctionError{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FunctionError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FunctionError) ProtoMessage() {} + +func (x *FunctionError) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FunctionError.ProtoReflect.Descriptor instead. +func (*FunctionError) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{2} +} + +func (x *FunctionError) GetText() string { + if x != nil { + return x.Text + } + return "" +} + +func (x *FunctionError) GetFunctionArgument() int64 { + if x != nil && x.FunctionArgument != nil { + return *x.FunctionArgument + } + return 0 +} + type AttributePath struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -334,7 +391,7 @@ type AttributePath struct { func (x *AttributePath) Reset() { *x = AttributePath{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[2] + mi := &file_tfplugin5_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -347,7 +404,7 @@ func (x *AttributePath) String() string { func (*AttributePath) ProtoMessage() {} func (x *AttributePath) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[2] + mi := &file_tfplugin5_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -360,7 +417,7 @@ func (x *AttributePath) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributePath.ProtoReflect.Descriptor instead. func (*AttributePath) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{2} + return file_tfplugin5_proto_rawDescGZIP(), []int{3} } func (x *AttributePath) GetSteps() []*AttributePath_Step { @@ -379,7 +436,7 @@ type Stop struct { func (x *Stop) Reset() { *x = Stop{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[3] + mi := &file_tfplugin5_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -392,7 +449,7 @@ func (x *Stop) String() string { func (*Stop) ProtoMessage() {} func (x *Stop) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[3] + mi := &file_tfplugin5_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -405,7 +462,7 @@ func (x *Stop) ProtoReflect() protoreflect.Message { // Deprecated: Use Stop.ProtoReflect.Descriptor instead. func (*Stop) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{3} + return file_tfplugin5_proto_rawDescGZIP(), []int{4} } // RawState holds the stored state for a resource to be upgraded by the @@ -423,7 +480,7 @@ type RawState struct { func (x *RawState) Reset() { *x = RawState{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[4] + mi := &file_tfplugin5_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -436,7 +493,7 @@ func (x *RawState) String() string { func (*RawState) ProtoMessage() {} func (x *RawState) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[4] + mi := &file_tfplugin5_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -449,7 +506,7 @@ func (x *RawState) ProtoReflect() protoreflect.Message { // Deprecated: Use RawState.ProtoReflect.Descriptor instead. func (*RawState) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{4} + return file_tfplugin5_proto_rawDescGZIP(), []int{5} } func (x *RawState) GetJson() []byte { @@ -483,7 +540,7 @@ type Schema struct { func (x *Schema) Reset() { *x = Schema{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[5] + mi := &file_tfplugin5_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -496,7 +553,7 @@ func (x *Schema) String() string { func (*Schema) ProtoMessage() {} func (x *Schema) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[5] + mi := &file_tfplugin5_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -509,7 +566,7 @@ func (x *Schema) ProtoReflect() protoreflect.Message { // Deprecated: Use Schema.ProtoReflect.Descriptor instead. func (*Schema) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{5} + return file_tfplugin5_proto_rawDescGZIP(), []int{6} } func (x *Schema) GetVersion() int64 { @@ -526,6 +583,224 @@ func (x *Schema) GetBlock() *Schema_Block { return nil } +// ServerCapabilities allows providers to communicate extra information +// regarding supported protocol features. This is used to indicate +// availability of certain forward-compatible changes which may be optional +// in a major protocol version, but cannot be tested for directly. +type ServerCapabilities struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The plan_destroy capability signals that a provider expects a call + // to PlanResourceChange when a resource is going to be destroyed. + PlanDestroy bool `protobuf:"varint,1,opt,name=plan_destroy,json=planDestroy,proto3" json:"plan_destroy,omitempty"` + // The get_provider_schema_optional capability indicates that this + // provider does not require calling GetProviderSchema to operate + // normally, and the caller can used a cached copy of the provider's + // schema. + GetProviderSchemaOptional bool `protobuf:"varint,2,opt,name=get_provider_schema_optional,json=getProviderSchemaOptional,proto3" json:"get_provider_schema_optional,omitempty"` + // The move_resource_state capability signals that a provider supports the + // MoveResourceState RPC. + MoveResourceState bool `protobuf:"varint,3,opt,name=move_resource_state,json=moveResourceState,proto3" json:"move_resource_state,omitempty"` +} + +func (x *ServerCapabilities) Reset() { + *x = ServerCapabilities{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerCapabilities) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerCapabilities) ProtoMessage() {} + +func (x *ServerCapabilities) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerCapabilities.ProtoReflect.Descriptor instead. +func (*ServerCapabilities) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{7} +} + +func (x *ServerCapabilities) GetPlanDestroy() bool { + if x != nil { + return x.PlanDestroy + } + return false +} + +func (x *ServerCapabilities) GetGetProviderSchemaOptional() bool { + if x != nil { + return x.GetProviderSchemaOptional + } + return false +} + +func (x *ServerCapabilities) GetMoveResourceState() bool { + if x != nil { + return x.MoveResourceState + } + return false +} + +type Function struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // parameters is the ordered list of positional function parameters. + Parameters []*Function_Parameter `protobuf:"bytes,1,rep,name=parameters,proto3" json:"parameters,omitempty"` + // variadic_parameter is an optional final parameter which accepts + // zero or more argument values, in which Terraform will send an + // ordered list of the parameter type. + VariadicParameter *Function_Parameter `protobuf:"bytes,2,opt,name=variadic_parameter,json=variadicParameter,proto3" json:"variadic_parameter,omitempty"` + // return is the function result. + Return *Function_Return `protobuf:"bytes,3,opt,name=return,proto3" json:"return,omitempty"` + // summary is the human-readable shortened documentation for the function. + Summary string `protobuf:"bytes,4,opt,name=summary,proto3" json:"summary,omitempty"` + // description is human-readable documentation for the function. + Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` + // description_kind is the formatting of the description. + DescriptionKind StringKind `protobuf:"varint,6,opt,name=description_kind,json=descriptionKind,proto3,enum=tfplugin5.StringKind" json:"description_kind,omitempty"` + // deprecation_message is human-readable documentation if the + // function is deprecated. + DeprecationMessage string `protobuf:"bytes,7,opt,name=deprecation_message,json=deprecationMessage,proto3" json:"deprecation_message,omitempty"` +} + +func (x *Function) Reset() { + *x = Function{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Function) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Function) ProtoMessage() {} + +func (x *Function) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Function.ProtoReflect.Descriptor instead. +func (*Function) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{8} +} + +func (x *Function) GetParameters() []*Function_Parameter { + if x != nil { + return x.Parameters + } + return nil +} + +func (x *Function) GetVariadicParameter() *Function_Parameter { + if x != nil { + return x.VariadicParameter + } + return nil +} + +func (x *Function) GetReturn() *Function_Return { + if x != nil { + return x.Return + } + return nil +} + +func (x *Function) GetSummary() string { + if x != nil { + return x.Summary + } + return "" +} + +func (x *Function) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Function) GetDescriptionKind() StringKind { + if x != nil { + return x.DescriptionKind + } + return StringKind_PLAIN +} + +func (x *Function) GetDeprecationMessage() string { + if x != nil { + return x.DeprecationMessage + } + return "" +} + +type GetMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetMetadata) Reset() { + *x = GetMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMetadata) ProtoMessage() {} + +func (x *GetMetadata) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadata.ProtoReflect.Descriptor instead. +func (*GetMetadata) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{9} +} + type GetProviderSchema struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -535,7 +810,7 @@ type GetProviderSchema struct { func (x *GetProviderSchema) Reset() { *x = GetProviderSchema{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[6] + mi := &file_tfplugin5_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -548,7 +823,7 @@ func (x *GetProviderSchema) String() string { func (*GetProviderSchema) ProtoMessage() {} func (x *GetProviderSchema) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[6] + mi := &file_tfplugin5_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -561,7 +836,7 @@ func (x *GetProviderSchema) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProviderSchema.ProtoReflect.Descriptor instead. func (*GetProviderSchema) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{6} + return file_tfplugin5_proto_rawDescGZIP(), []int{10} } type PrepareProviderConfig struct { @@ -573,7 +848,7 @@ type PrepareProviderConfig struct { func (x *PrepareProviderConfig) Reset() { *x = PrepareProviderConfig{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[7] + mi := &file_tfplugin5_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -586,7 +861,7 @@ func (x *PrepareProviderConfig) String() string { func (*PrepareProviderConfig) ProtoMessage() {} func (x *PrepareProviderConfig) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[7] + mi := &file_tfplugin5_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -599,7 +874,7 @@ func (x *PrepareProviderConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use PrepareProviderConfig.ProtoReflect.Descriptor instead. func (*PrepareProviderConfig) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{7} + return file_tfplugin5_proto_rawDescGZIP(), []int{11} } type UpgradeResourceState struct { @@ -611,7 +886,7 @@ type UpgradeResourceState struct { func (x *UpgradeResourceState) Reset() { *x = UpgradeResourceState{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[8] + mi := &file_tfplugin5_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -624,7 +899,7 @@ func (x *UpgradeResourceState) String() string { func (*UpgradeResourceState) ProtoMessage() {} func (x *UpgradeResourceState) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[8] + mi := &file_tfplugin5_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -637,7 +912,7 @@ func (x *UpgradeResourceState) ProtoReflect() protoreflect.Message { // Deprecated: Use UpgradeResourceState.ProtoReflect.Descriptor instead. func (*UpgradeResourceState) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{8} + return file_tfplugin5_proto_rawDescGZIP(), []int{12} } type ValidateResourceTypeConfig struct { @@ -649,7 +924,7 @@ type ValidateResourceTypeConfig struct { func (x *ValidateResourceTypeConfig) Reset() { *x = ValidateResourceTypeConfig{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[9] + mi := &file_tfplugin5_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -662,7 +937,7 @@ func (x *ValidateResourceTypeConfig) String() string { func (*ValidateResourceTypeConfig) ProtoMessage() {} func (x *ValidateResourceTypeConfig) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[9] + mi := &file_tfplugin5_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -675,7 +950,7 @@ func (x *ValidateResourceTypeConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateResourceTypeConfig.ProtoReflect.Descriptor instead. func (*ValidateResourceTypeConfig) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{9} + return file_tfplugin5_proto_rawDescGZIP(), []int{13} } type ValidateDataSourceConfig struct { @@ -687,7 +962,7 @@ type ValidateDataSourceConfig struct { func (x *ValidateDataSourceConfig) Reset() { *x = ValidateDataSourceConfig{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[10] + mi := &file_tfplugin5_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -700,7 +975,7 @@ func (x *ValidateDataSourceConfig) String() string { func (*ValidateDataSourceConfig) ProtoMessage() {} func (x *ValidateDataSourceConfig) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[10] + mi := &file_tfplugin5_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -713,7 +988,7 @@ func (x *ValidateDataSourceConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateDataSourceConfig.ProtoReflect.Descriptor instead. func (*ValidateDataSourceConfig) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{10} + return file_tfplugin5_proto_rawDescGZIP(), []int{14} } type Configure struct { @@ -725,7 +1000,7 @@ type Configure struct { func (x *Configure) Reset() { *x = Configure{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[11] + mi := &file_tfplugin5_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -738,7 +1013,7 @@ func (x *Configure) String() string { func (*Configure) ProtoMessage() {} func (x *Configure) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[11] + mi := &file_tfplugin5_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -751,7 +1026,7 @@ func (x *Configure) ProtoReflect() protoreflect.Message { // Deprecated: Use Configure.ProtoReflect.Descriptor instead. func (*Configure) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{11} + return file_tfplugin5_proto_rawDescGZIP(), []int{15} } type ReadResource struct { @@ -763,7 +1038,7 @@ type ReadResource struct { func (x *ReadResource) Reset() { *x = ReadResource{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[12] + mi := &file_tfplugin5_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -776,7 +1051,7 @@ func (x *ReadResource) String() string { func (*ReadResource) ProtoMessage() {} func (x *ReadResource) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[12] + mi := &file_tfplugin5_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -789,7 +1064,7 @@ func (x *ReadResource) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadResource.ProtoReflect.Descriptor instead. func (*ReadResource) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{12} + return file_tfplugin5_proto_rawDescGZIP(), []int{16} } type PlanResourceChange struct { @@ -801,7 +1076,7 @@ type PlanResourceChange struct { func (x *PlanResourceChange) Reset() { *x = PlanResourceChange{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[13] + mi := &file_tfplugin5_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -814,7 +1089,7 @@ func (x *PlanResourceChange) String() string { func (*PlanResourceChange) ProtoMessage() {} func (x *PlanResourceChange) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[13] + mi := &file_tfplugin5_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -827,7 +1102,7 @@ func (x *PlanResourceChange) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanResourceChange.ProtoReflect.Descriptor instead. func (*PlanResourceChange) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{13} + return file_tfplugin5_proto_rawDescGZIP(), []int{17} } type ApplyResourceChange struct { @@ -839,7 +1114,7 @@ type ApplyResourceChange struct { func (x *ApplyResourceChange) Reset() { *x = ApplyResourceChange{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[14] + mi := &file_tfplugin5_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -852,7 +1127,7 @@ func (x *ApplyResourceChange) String() string { func (*ApplyResourceChange) ProtoMessage() {} func (x *ApplyResourceChange) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[14] + mi := &file_tfplugin5_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -865,7 +1140,7 @@ func (x *ApplyResourceChange) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyResourceChange.ProtoReflect.Descriptor instead. func (*ApplyResourceChange) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{14} + return file_tfplugin5_proto_rawDescGZIP(), []int{18} } type ImportResourceState struct { @@ -877,7 +1152,7 @@ type ImportResourceState struct { func (x *ImportResourceState) Reset() { *x = ImportResourceState{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[15] + mi := &file_tfplugin5_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -890,7 +1165,7 @@ func (x *ImportResourceState) String() string { func (*ImportResourceState) ProtoMessage() {} func (x *ImportResourceState) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[15] + mi := &file_tfplugin5_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -903,7 +1178,45 @@ func (x *ImportResourceState) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportResourceState.ProtoReflect.Descriptor instead. func (*ImportResourceState) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{15} + return file_tfplugin5_proto_rawDescGZIP(), []int{19} +} + +type MoveResourceState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MoveResourceState) Reset() { + *x = MoveResourceState{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MoveResourceState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MoveResourceState) ProtoMessage() {} + +func (x *MoveResourceState) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MoveResourceState.ProtoReflect.Descriptor instead. +func (*MoveResourceState) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{20} } type ReadDataSource struct { @@ -915,7 +1228,7 @@ type ReadDataSource struct { func (x *ReadDataSource) Reset() { *x = ReadDataSource{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[16] + mi := &file_tfplugin5_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -928,7 +1241,7 @@ func (x *ReadDataSource) String() string { func (*ReadDataSource) ProtoMessage() {} func (x *ReadDataSource) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[16] + mi := &file_tfplugin5_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -941,7 +1254,7 @@ func (x *ReadDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadDataSource.ProtoReflect.Descriptor instead. func (*ReadDataSource) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{16} + return file_tfplugin5_proto_rawDescGZIP(), []int{21} } type GetProvisionerSchema struct { @@ -953,7 +1266,7 @@ type GetProvisionerSchema struct { func (x *GetProvisionerSchema) Reset() { *x = GetProvisionerSchema{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[17] + mi := &file_tfplugin5_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -966,7 +1279,7 @@ func (x *GetProvisionerSchema) String() string { func (*GetProvisionerSchema) ProtoMessage() {} func (x *GetProvisionerSchema) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[17] + mi := &file_tfplugin5_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -979,7 +1292,7 @@ func (x *GetProvisionerSchema) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProvisionerSchema.ProtoReflect.Descriptor instead. func (*GetProvisionerSchema) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{17} + return file_tfplugin5_proto_rawDescGZIP(), []int{22} } type ValidateProvisionerConfig struct { @@ -991,7 +1304,7 @@ type ValidateProvisionerConfig struct { func (x *ValidateProvisionerConfig) Reset() { *x = ValidateProvisionerConfig{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[18] + mi := &file_tfplugin5_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1004,7 +1317,7 @@ func (x *ValidateProvisionerConfig) String() string { func (*ValidateProvisionerConfig) ProtoMessage() {} func (x *ValidateProvisionerConfig) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[18] + mi := &file_tfplugin5_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1017,7 +1330,7 @@ func (x *ValidateProvisionerConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateProvisionerConfig.ProtoReflect.Descriptor instead. func (*ValidateProvisionerConfig) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{18} + return file_tfplugin5_proto_rawDescGZIP(), []int{23} } type ProvisionResource struct { @@ -1029,7 +1342,7 @@ type ProvisionResource struct { func (x *ProvisionResource) Reset() { *x = ProvisionResource{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[19] + mi := &file_tfplugin5_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1042,7 +1355,7 @@ func (x *ProvisionResource) String() string { func (*ProvisionResource) ProtoMessage() {} func (x *ProvisionResource) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[19] + mi := &file_tfplugin5_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1055,7 +1368,83 @@ func (x *ProvisionResource) ProtoReflect() protoreflect.Message { // Deprecated: Use ProvisionResource.ProtoReflect.Descriptor instead. func (*ProvisionResource) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{19} + return file_tfplugin5_proto_rawDescGZIP(), []int{24} +} + +type GetFunctions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetFunctions) Reset() { + *x = GetFunctions{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFunctions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFunctions) ProtoMessage() {} + +func (x *GetFunctions) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFunctions.ProtoReflect.Descriptor instead. +func (*GetFunctions) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{25} +} + +type CallFunction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *CallFunction) Reset() { + *x = CallFunction{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CallFunction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CallFunction) ProtoMessage() {} + +func (x *CallFunction) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CallFunction.ProtoReflect.Descriptor instead. +func (*CallFunction) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{26} } type AttributePath_Step struct { @@ -1074,7 +1463,7 @@ type AttributePath_Step struct { func (x *AttributePath_Step) Reset() { *x = AttributePath_Step{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[20] + mi := &file_tfplugin5_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1087,7 +1476,7 @@ func (x *AttributePath_Step) String() string { func (*AttributePath_Step) ProtoMessage() {} func (x *AttributePath_Step) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[20] + mi := &file_tfplugin5_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1100,7 +1489,7 @@ func (x *AttributePath_Step) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributePath_Step.ProtoReflect.Descriptor instead. func (*AttributePath_Step) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{2, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{3, 0} } func (m *AttributePath_Step) GetSelector() isAttributePath_Step_Selector { @@ -1166,7 +1555,7 @@ type Stop_Request struct { func (x *Stop_Request) Reset() { *x = Stop_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[21] + mi := &file_tfplugin5_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1179,7 +1568,7 @@ func (x *Stop_Request) String() string { func (*Stop_Request) ProtoMessage() {} func (x *Stop_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[21] + mi := &file_tfplugin5_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1192,7 +1581,7 @@ func (x *Stop_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use Stop_Request.ProtoReflect.Descriptor instead. func (*Stop_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{3, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{4, 0} } type Stop_Response struct { @@ -1206,7 +1595,7 @@ type Stop_Response struct { func (x *Stop_Response) Reset() { *x = Stop_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[22] + mi := &file_tfplugin5_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1219,7 +1608,7 @@ func (x *Stop_Response) String() string { func (*Stop_Response) ProtoMessage() {} func (x *Stop_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[22] + mi := &file_tfplugin5_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1232,7 +1621,7 @@ func (x *Stop_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Stop_Response.ProtoReflect.Descriptor instead. func (*Stop_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{3, 1} + return file_tfplugin5_proto_rawDescGZIP(), []int{4, 1} } func (x *Stop_Response) GetError() string { @@ -1258,7 +1647,7 @@ type Schema_Block struct { func (x *Schema_Block) Reset() { *x = Schema_Block{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[24] + mi := &file_tfplugin5_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1271,7 +1660,7 @@ func (x *Schema_Block) String() string { func (*Schema_Block) ProtoMessage() {} func (x *Schema_Block) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[24] + mi := &file_tfplugin5_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1284,7 +1673,7 @@ func (x *Schema_Block) ProtoReflect() protoreflect.Message { // Deprecated: Use Schema_Block.ProtoReflect.Descriptor instead. func (*Schema_Block) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{5, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{6, 0} } func (x *Schema_Block) GetVersion() int64 { @@ -1348,7 +1737,7 @@ type Schema_Attribute struct { func (x *Schema_Attribute) Reset() { *x = Schema_Attribute{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[25] + mi := &file_tfplugin5_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1361,7 +1750,7 @@ func (x *Schema_Attribute) String() string { func (*Schema_Attribute) ProtoMessage() {} func (x *Schema_Attribute) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[25] + mi := &file_tfplugin5_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1374,7 +1763,7 @@ func (x *Schema_Attribute) ProtoReflect() protoreflect.Message { // Deprecated: Use Schema_Attribute.ProtoReflect.Descriptor instead. func (*Schema_Attribute) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{5, 1} + return file_tfplugin5_proto_rawDescGZIP(), []int{6, 1} } func (x *Schema_Attribute) GetName() string { @@ -1455,7 +1844,7 @@ type Schema_NestedBlock struct { func (x *Schema_NestedBlock) Reset() { *x = Schema_NestedBlock{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[26] + mi := &file_tfplugin5_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1468,7 +1857,7 @@ func (x *Schema_NestedBlock) String() string { func (*Schema_NestedBlock) ProtoMessage() {} func (x *Schema_NestedBlock) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[26] + mi := &file_tfplugin5_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1481,7 +1870,7 @@ func (x *Schema_NestedBlock) ProtoReflect() protoreflect.Message { // Deprecated: Use Schema_NestedBlock.ProtoReflect.Descriptor instead. func (*Schema_NestedBlock) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{5, 2} + return file_tfplugin5_proto_rawDescGZIP(), []int{6, 2} } func (x *Schema_NestedBlock) GetTypeName() string { @@ -1519,74 +1908,47 @@ func (x *Schema_NestedBlock) GetMaxItems() int64 { return 0 } -type GetProviderSchema_Request struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *GetProviderSchema_Request) Reset() { - *x = GetProviderSchema_Request{} - if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetProviderSchema_Request) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetProviderSchema_Request) ProtoMessage() {} - -func (x *GetProviderSchema_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[27] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetProviderSchema_Request.ProtoReflect.Descriptor instead. -func (*GetProviderSchema_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{6, 0} -} - -type GetProviderSchema_Response struct { +type Function_Parameter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Provider *Schema `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` - ResourceSchemas map[string]*Schema `protobuf:"bytes,2,rep,name=resource_schemas,json=resourceSchemas,proto3" json:"resource_schemas,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - DataSourceSchemas map[string]*Schema `protobuf:"bytes,3,rep,name=data_source_schemas,json=dataSourceSchemas,proto3" json:"data_source_schemas,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - Diagnostics []*Diagnostic `protobuf:"bytes,4,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` - ProviderMeta *Schema `protobuf:"bytes,5,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` - ServerCapabilities *GetProviderSchema_ServerCapabilities `protobuf:"bytes,6,opt,name=server_capabilities,json=serverCapabilities,proto3" json:"server_capabilities,omitempty"` -} - -func (x *GetProviderSchema_Response) Reset() { - *x = GetProviderSchema_Response{} + // name is the human-readable display name for the parameter. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // type is the type constraint for the parameter. + Type []byte `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + // allow_null_value when enabled denotes that a null argument value can + // be passed to the provider. When disabled, Terraform returns an error + // if the argument value is null. + AllowNullValue bool `protobuf:"varint,3,opt,name=allow_null_value,json=allowNullValue,proto3" json:"allow_null_value,omitempty"` + // allow_unknown_values when enabled denotes that only wholly known + // argument values will be passed to the provider. When disabled, + // Terraform skips the function call entirely and assumes an unknown + // value result from the function. + AllowUnknownValues bool `protobuf:"varint,4,opt,name=allow_unknown_values,json=allowUnknownValues,proto3" json:"allow_unknown_values,omitempty"` + // description is human-readable documentation for the parameter. + Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` + // description_kind is the formatting of the description. + DescriptionKind StringKind `protobuf:"varint,6,opt,name=description_kind,json=descriptionKind,proto3,enum=tfplugin5.StringKind" json:"description_kind,omitempty"` +} + +func (x *Function_Parameter) Reset() { + *x = Function_Parameter{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[28] + mi := &file_tfplugin5_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetProviderSchema_Response) String() string { +func (x *Function_Parameter) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetProviderSchema_Response) ProtoMessage() {} +func (*Function_Parameter) ProtoMessage() {} -func (x *GetProviderSchema_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[28] +func (x *Function_Parameter) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1597,84 +1959,79 @@ func (x *GetProviderSchema_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetProviderSchema_Response.ProtoReflect.Descriptor instead. -func (*GetProviderSchema_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{6, 1} +// Deprecated: Use Function_Parameter.ProtoReflect.Descriptor instead. +func (*Function_Parameter) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{8, 0} } -func (x *GetProviderSchema_Response) GetProvider() *Schema { +func (x *Function_Parameter) GetName() string { if x != nil { - return x.Provider + return x.Name } - return nil + return "" } -func (x *GetProviderSchema_Response) GetResourceSchemas() map[string]*Schema { +func (x *Function_Parameter) GetType() []byte { if x != nil { - return x.ResourceSchemas + return x.Type } return nil } -func (x *GetProviderSchema_Response) GetDataSourceSchemas() map[string]*Schema { +func (x *Function_Parameter) GetAllowNullValue() bool { if x != nil { - return x.DataSourceSchemas + return x.AllowNullValue } - return nil + return false } -func (x *GetProviderSchema_Response) GetDiagnostics() []*Diagnostic { +func (x *Function_Parameter) GetAllowUnknownValues() bool { if x != nil { - return x.Diagnostics + return x.AllowUnknownValues } - return nil + return false } -func (x *GetProviderSchema_Response) GetProviderMeta() *Schema { +func (x *Function_Parameter) GetDescription() string { if x != nil { - return x.ProviderMeta + return x.Description } - return nil + return "" } -func (x *GetProviderSchema_Response) GetServerCapabilities() *GetProviderSchema_ServerCapabilities { +func (x *Function_Parameter) GetDescriptionKind() StringKind { if x != nil { - return x.ServerCapabilities + return x.DescriptionKind } - return nil + return StringKind_PLAIN } -// ServerCapabilities allows providers to communicate extra information -// regarding supported protocol features. This is used to indicate -// availability of certain forward-compatible changes which may be optional -// in a major protocol version, but cannot be tested for directly. -type GetProviderSchema_ServerCapabilities struct { +type Function_Return struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The plan_destroy capability signals that a provider expects a call - // to PlanResourceChange when a resource is going to be destroyed. - PlanDestroy bool `protobuf:"varint,1,opt,name=plan_destroy,json=planDestroy,proto3" json:"plan_destroy,omitempty"` + // type is the type constraint for the function result. + Type []byte `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` } -func (x *GetProviderSchema_ServerCapabilities) Reset() { - *x = GetProviderSchema_ServerCapabilities{} +func (x *Function_Return) Reset() { + *x = Function_Return{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[29] + mi := &file_tfplugin5_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetProviderSchema_ServerCapabilities) String() string { +func (x *Function_Return) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetProviderSchema_ServerCapabilities) ProtoMessage() {} +func (*Function_Return) ProtoMessage() {} -func (x *GetProviderSchema_ServerCapabilities) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[29] +func (x *Function_Return) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1685,43 +2042,437 @@ func (x *GetProviderSchema_ServerCapabilities) ProtoReflect() protoreflect.Messa return mi.MessageOf(x) } -// Deprecated: Use GetProviderSchema_ServerCapabilities.ProtoReflect.Descriptor instead. -func (*GetProviderSchema_ServerCapabilities) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{6, 2} +// Deprecated: Use Function_Return.ProtoReflect.Descriptor instead. +func (*Function_Return) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{8, 1} } -func (x *GetProviderSchema_ServerCapabilities) GetPlanDestroy() bool { +func (x *Function_Return) GetType() []byte { if x != nil { - return x.PlanDestroy + return x.Type } - return false + return nil } -type PrepareProviderConfig_Request struct { +type GetMetadata_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - Config *DynamicValue `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` } -func (x *PrepareProviderConfig_Request) Reset() { - *x = PrepareProviderConfig_Request{} +func (x *GetMetadata_Request) Reset() { + *x = GetMetadata_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[32] + mi := &file_tfplugin5_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *PrepareProviderConfig_Request) String() string { +func (x *GetMetadata_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PrepareProviderConfig_Request) ProtoMessage() {} +func (*GetMetadata_Request) ProtoMessage() {} -func (x *PrepareProviderConfig_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[32] +func (x *GetMetadata_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadata_Request.ProtoReflect.Descriptor instead. +func (*GetMetadata_Request) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{9, 0} +} + +type GetMetadata_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServerCapabilities *ServerCapabilities `protobuf:"bytes,1,opt,name=server_capabilities,json=serverCapabilities,proto3" json:"server_capabilities,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + DataSources []*GetMetadata_DataSourceMetadata `protobuf:"bytes,3,rep,name=data_sources,json=dataSources,proto3" json:"data_sources,omitempty"` + Resources []*GetMetadata_ResourceMetadata `protobuf:"bytes,4,rep,name=resources,proto3" json:"resources,omitempty"` + // functions returns metadata for any functions. + Functions []*GetMetadata_FunctionMetadata `protobuf:"bytes,5,rep,name=functions,proto3" json:"functions,omitempty"` +} + +func (x *GetMetadata_Response) Reset() { + *x = GetMetadata_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMetadata_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMetadata_Response) ProtoMessage() {} + +func (x *GetMetadata_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadata_Response.ProtoReflect.Descriptor instead. +func (*GetMetadata_Response) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{9, 1} +} + +func (x *GetMetadata_Response) GetServerCapabilities() *ServerCapabilities { + if x != nil { + return x.ServerCapabilities + } + return nil +} + +func (x *GetMetadata_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +func (x *GetMetadata_Response) GetDataSources() []*GetMetadata_DataSourceMetadata { + if x != nil { + return x.DataSources + } + return nil +} + +func (x *GetMetadata_Response) GetResources() []*GetMetadata_ResourceMetadata { + if x != nil { + return x.Resources + } + return nil +} + +func (x *GetMetadata_Response) GetFunctions() []*GetMetadata_FunctionMetadata { + if x != nil { + return x.Functions + } + return nil +} + +type GetMetadata_FunctionMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the function name. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *GetMetadata_FunctionMetadata) Reset() { + *x = GetMetadata_FunctionMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMetadata_FunctionMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMetadata_FunctionMetadata) ProtoMessage() {} + +func (x *GetMetadata_FunctionMetadata) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadata_FunctionMetadata.ProtoReflect.Descriptor instead. +func (*GetMetadata_FunctionMetadata) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{9, 2} +} + +func (x *GetMetadata_FunctionMetadata) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type GetMetadata_DataSourceMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` +} + +func (x *GetMetadata_DataSourceMetadata) Reset() { + *x = GetMetadata_DataSourceMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMetadata_DataSourceMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMetadata_DataSourceMetadata) ProtoMessage() {} + +func (x *GetMetadata_DataSourceMetadata) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadata_DataSourceMetadata.ProtoReflect.Descriptor instead. +func (*GetMetadata_DataSourceMetadata) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{9, 3} +} + +func (x *GetMetadata_DataSourceMetadata) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +type GetMetadata_ResourceMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` +} + +func (x *GetMetadata_ResourceMetadata) Reset() { + *x = GetMetadata_ResourceMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMetadata_ResourceMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMetadata_ResourceMetadata) ProtoMessage() {} + +func (x *GetMetadata_ResourceMetadata) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadata_ResourceMetadata.ProtoReflect.Descriptor instead. +func (*GetMetadata_ResourceMetadata) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{9, 4} +} + +func (x *GetMetadata_ResourceMetadata) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +type GetProviderSchema_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetProviderSchema_Request) Reset() { + *x = GetProviderSchema_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProviderSchema_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProviderSchema_Request) ProtoMessage() {} + +func (x *GetProviderSchema_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProviderSchema_Request.ProtoReflect.Descriptor instead. +func (*GetProviderSchema_Request) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{10, 0} +} + +type GetProviderSchema_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Provider *Schema `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` + ResourceSchemas map[string]*Schema `protobuf:"bytes,2,rep,name=resource_schemas,json=resourceSchemas,proto3" json:"resource_schemas,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + DataSourceSchemas map[string]*Schema `protobuf:"bytes,3,rep,name=data_source_schemas,json=dataSourceSchemas,proto3" json:"data_source_schemas,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Diagnostics []*Diagnostic `protobuf:"bytes,4,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + ProviderMeta *Schema `protobuf:"bytes,5,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` + ServerCapabilities *ServerCapabilities `protobuf:"bytes,6,opt,name=server_capabilities,json=serverCapabilities,proto3" json:"server_capabilities,omitempty"` + // functions is a mapping of function names to definitions. + Functions map[string]*Function `protobuf:"bytes,7,rep,name=functions,proto3" json:"functions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetProviderSchema_Response) Reset() { + *x = GetProviderSchema_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProviderSchema_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProviderSchema_Response) ProtoMessage() {} + +func (x *GetProviderSchema_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProviderSchema_Response.ProtoReflect.Descriptor instead. +func (*GetProviderSchema_Response) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{10, 1} +} + +func (x *GetProviderSchema_Response) GetProvider() *Schema { + if x != nil { + return x.Provider + } + return nil +} + +func (x *GetProviderSchema_Response) GetResourceSchemas() map[string]*Schema { + if x != nil { + return x.ResourceSchemas + } + return nil +} + +func (x *GetProviderSchema_Response) GetDataSourceSchemas() map[string]*Schema { + if x != nil { + return x.DataSourceSchemas + } + return nil +} + +func (x *GetProviderSchema_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +func (x *GetProviderSchema_Response) GetProviderMeta() *Schema { + if x != nil { + return x.ProviderMeta + } + return nil +} + +func (x *GetProviderSchema_Response) GetServerCapabilities() *ServerCapabilities { + if x != nil { + return x.ServerCapabilities + } + return nil +} + +func (x *GetProviderSchema_Response) GetFunctions() map[string]*Function { + if x != nil { + return x.Functions + } + return nil +} + +type PrepareProviderConfig_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Config *DynamicValue `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` +} + +func (x *PrepareProviderConfig_Request) Reset() { + *x = PrepareProviderConfig_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PrepareProviderConfig_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PrepareProviderConfig_Request) ProtoMessage() {} + +func (x *PrepareProviderConfig_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1734,7 +2485,7 @@ func (x *PrepareProviderConfig_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use PrepareProviderConfig_Request.ProtoReflect.Descriptor instead. func (*PrepareProviderConfig_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{7, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{11, 0} } func (x *PrepareProviderConfig_Request) GetConfig() *DynamicValue { @@ -1756,7 +2507,7 @@ type PrepareProviderConfig_Response struct { func (x *PrepareProviderConfig_Response) Reset() { *x = PrepareProviderConfig_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[33] + mi := &file_tfplugin5_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1769,7 +2520,7 @@ func (x *PrepareProviderConfig_Response) String() string { func (*PrepareProviderConfig_Response) ProtoMessage() {} func (x *PrepareProviderConfig_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[33] + mi := &file_tfplugin5_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1782,7 +2533,7 @@ func (x *PrepareProviderConfig_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use PrepareProviderConfig_Response.ProtoReflect.Descriptor instead. func (*PrepareProviderConfig_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{7, 1} + return file_tfplugin5_proto_rawDescGZIP(), []int{11, 1} } func (x *PrepareProviderConfig_Response) GetPreparedConfig() *DynamicValue { @@ -1827,7 +2578,7 @@ type UpgradeResourceState_Request struct { func (x *UpgradeResourceState_Request) Reset() { *x = UpgradeResourceState_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[34] + mi := &file_tfplugin5_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1840,7 +2591,7 @@ func (x *UpgradeResourceState_Request) String() string { func (*UpgradeResourceState_Request) ProtoMessage() {} func (x *UpgradeResourceState_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[34] + mi := &file_tfplugin5_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1853,7 +2604,7 @@ func (x *UpgradeResourceState_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use UpgradeResourceState_Request.ProtoReflect.Descriptor instead. func (*UpgradeResourceState_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{8, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{12, 0} } func (x *UpgradeResourceState_Request) GetTypeName() string { @@ -1895,7 +2646,7 @@ type UpgradeResourceState_Response struct { func (x *UpgradeResourceState_Response) Reset() { *x = UpgradeResourceState_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[35] + mi := &file_tfplugin5_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1908,7 +2659,7 @@ func (x *UpgradeResourceState_Response) String() string { func (*UpgradeResourceState_Response) ProtoMessage() {} func (x *UpgradeResourceState_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[35] + mi := &file_tfplugin5_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1921,7 +2672,7 @@ func (x *UpgradeResourceState_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use UpgradeResourceState_Response.ProtoReflect.Descriptor instead. func (*UpgradeResourceState_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{8, 1} + return file_tfplugin5_proto_rawDescGZIP(), []int{12, 1} } func (x *UpgradeResourceState_Response) GetUpgradedState() *DynamicValue { @@ -1950,7 +2701,7 @@ type ValidateResourceTypeConfig_Request struct { func (x *ValidateResourceTypeConfig_Request) Reset() { *x = ValidateResourceTypeConfig_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[36] + mi := &file_tfplugin5_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1963,7 +2714,7 @@ func (x *ValidateResourceTypeConfig_Request) String() string { func (*ValidateResourceTypeConfig_Request) ProtoMessage() {} func (x *ValidateResourceTypeConfig_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[36] + mi := &file_tfplugin5_proto_msgTypes[50] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1976,7 +2727,7 @@ func (x *ValidateResourceTypeConfig_Request) ProtoReflect() protoreflect.Message // Deprecated: Use ValidateResourceTypeConfig_Request.ProtoReflect.Descriptor instead. func (*ValidateResourceTypeConfig_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{9, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{13, 0} } func (x *ValidateResourceTypeConfig_Request) GetTypeName() string { @@ -2004,7 +2755,7 @@ type ValidateResourceTypeConfig_Response struct { func (x *ValidateResourceTypeConfig_Response) Reset() { *x = ValidateResourceTypeConfig_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[37] + mi := &file_tfplugin5_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2017,7 +2768,7 @@ func (x *ValidateResourceTypeConfig_Response) String() string { func (*ValidateResourceTypeConfig_Response) ProtoMessage() {} func (x *ValidateResourceTypeConfig_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[37] + mi := &file_tfplugin5_proto_msgTypes[51] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2030,7 +2781,7 @@ func (x *ValidateResourceTypeConfig_Response) ProtoReflect() protoreflect.Messag // Deprecated: Use ValidateResourceTypeConfig_Response.ProtoReflect.Descriptor instead. func (*ValidateResourceTypeConfig_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{9, 1} + return file_tfplugin5_proto_rawDescGZIP(), []int{13, 1} } func (x *ValidateResourceTypeConfig_Response) GetDiagnostics() []*Diagnostic { @@ -2052,7 +2803,7 @@ type ValidateDataSourceConfig_Request struct { func (x *ValidateDataSourceConfig_Request) Reset() { *x = ValidateDataSourceConfig_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[38] + mi := &file_tfplugin5_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2065,7 +2816,7 @@ func (x *ValidateDataSourceConfig_Request) String() string { func (*ValidateDataSourceConfig_Request) ProtoMessage() {} func (x *ValidateDataSourceConfig_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[38] + mi := &file_tfplugin5_proto_msgTypes[52] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2078,7 +2829,7 @@ func (x *ValidateDataSourceConfig_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateDataSourceConfig_Request.ProtoReflect.Descriptor instead. func (*ValidateDataSourceConfig_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{10, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{14, 0} } func (x *ValidateDataSourceConfig_Request) GetTypeName() string { @@ -2106,7 +2857,7 @@ type ValidateDataSourceConfig_Response struct { func (x *ValidateDataSourceConfig_Response) Reset() { *x = ValidateDataSourceConfig_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[39] + mi := &file_tfplugin5_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2119,7 +2870,7 @@ func (x *ValidateDataSourceConfig_Response) String() string { func (*ValidateDataSourceConfig_Response) ProtoMessage() {} func (x *ValidateDataSourceConfig_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[39] + mi := &file_tfplugin5_proto_msgTypes[53] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2132,7 +2883,7 @@ func (x *ValidateDataSourceConfig_Response) ProtoReflect() protoreflect.Message // Deprecated: Use ValidateDataSourceConfig_Response.ProtoReflect.Descriptor instead. func (*ValidateDataSourceConfig_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{10, 1} + return file_tfplugin5_proto_rawDescGZIP(), []int{14, 1} } func (x *ValidateDataSourceConfig_Response) GetDiagnostics() []*Diagnostic { @@ -2154,7 +2905,7 @@ type Configure_Request struct { func (x *Configure_Request) Reset() { *x = Configure_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[40] + mi := &file_tfplugin5_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2167,7 +2918,7 @@ func (x *Configure_Request) String() string { func (*Configure_Request) ProtoMessage() {} func (x *Configure_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[40] + mi := &file_tfplugin5_proto_msgTypes[54] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2180,7 +2931,7 @@ func (x *Configure_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use Configure_Request.ProtoReflect.Descriptor instead. func (*Configure_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{11, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{15, 0} } func (x *Configure_Request) GetTerraformVersion() string { @@ -2208,7 +2959,7 @@ type Configure_Response struct { func (x *Configure_Response) Reset() { *x = Configure_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[41] + mi := &file_tfplugin5_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2221,7 +2972,7 @@ func (x *Configure_Response) String() string { func (*Configure_Response) ProtoMessage() {} func (x *Configure_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[41] + mi := &file_tfplugin5_proto_msgTypes[55] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2234,7 +2985,7 @@ func (x *Configure_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Configure_Response.ProtoReflect.Descriptor instead. func (*Configure_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{11, 1} + return file_tfplugin5_proto_rawDescGZIP(), []int{15, 1} } func (x *Configure_Response) GetDiagnostics() []*Diagnostic { @@ -2266,7 +3017,7 @@ type ReadResource_Request struct { func (x *ReadResource_Request) Reset() { *x = ReadResource_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[42] + mi := &file_tfplugin5_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2279,7 +3030,7 @@ func (x *ReadResource_Request) String() string { func (*ReadResource_Request) ProtoMessage() {} func (x *ReadResource_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[42] + mi := &file_tfplugin5_proto_msgTypes[56] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2292,7 +3043,7 @@ func (x *ReadResource_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadResource_Request.ProtoReflect.Descriptor instead. func (*ReadResource_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{12, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{16, 0} } func (x *ReadResource_Request) GetTypeName() string { @@ -2336,7 +3087,7 @@ type ReadResource_Response struct { func (x *ReadResource_Response) Reset() { *x = ReadResource_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[43] + mi := &file_tfplugin5_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2349,7 +3100,7 @@ func (x *ReadResource_Response) String() string { func (*ReadResource_Response) ProtoMessage() {} func (x *ReadResource_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[43] + mi := &file_tfplugin5_proto_msgTypes[57] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2362,7 +3113,7 @@ func (x *ReadResource_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadResource_Response.ProtoReflect.Descriptor instead. func (*ReadResource_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{12, 1} + return file_tfplugin5_proto_rawDescGZIP(), []int{16, 1} } func (x *ReadResource_Response) GetNewState() *DynamicValue { @@ -2402,7 +3153,7 @@ type PlanResourceChange_Request struct { func (x *PlanResourceChange_Request) Reset() { *x = PlanResourceChange_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[44] + mi := &file_tfplugin5_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2415,7 +3166,7 @@ func (x *PlanResourceChange_Request) String() string { func (*PlanResourceChange_Request) ProtoMessage() {} func (x *PlanResourceChange_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[44] + mi := &file_tfplugin5_proto_msgTypes[58] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2428,7 +3179,7 @@ func (x *PlanResourceChange_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanResourceChange_Request.ProtoReflect.Descriptor instead. func (*PlanResourceChange_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{13, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{17, 0} } func (x *PlanResourceChange_Request) GetTypeName() string { @@ -2499,7 +3250,7 @@ type PlanResourceChange_Response struct { func (x *PlanResourceChange_Response) Reset() { *x = PlanResourceChange_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[45] + mi := &file_tfplugin5_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2512,7 +3263,7 @@ func (x *PlanResourceChange_Response) String() string { func (*PlanResourceChange_Response) ProtoMessage() {} func (x *PlanResourceChange_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[45] + mi := &file_tfplugin5_proto_msgTypes[59] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2525,7 +3276,7 @@ func (x *PlanResourceChange_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanResourceChange_Response.ProtoReflect.Descriptor instead. func (*PlanResourceChange_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{13, 1} + return file_tfplugin5_proto_rawDescGZIP(), []int{17, 1} } func (x *PlanResourceChange_Response) GetPlannedState() *DynamicValue { @@ -2579,7 +3330,7 @@ type ApplyResourceChange_Request struct { func (x *ApplyResourceChange_Request) Reset() { *x = ApplyResourceChange_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[46] + mi := &file_tfplugin5_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2592,7 +3343,7 @@ func (x *ApplyResourceChange_Request) String() string { func (*ApplyResourceChange_Request) ProtoMessage() {} func (x *ApplyResourceChange_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[46] + mi := &file_tfplugin5_proto_msgTypes[60] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2605,7 +3356,7 @@ func (x *ApplyResourceChange_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyResourceChange_Request.ProtoReflect.Descriptor instead. func (*ApplyResourceChange_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{14, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{18, 0} } func (x *ApplyResourceChange_Request) GetTypeName() string { @@ -2675,7 +3426,7 @@ type ApplyResourceChange_Response struct { func (x *ApplyResourceChange_Response) Reset() { *x = ApplyResourceChange_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[47] + mi := &file_tfplugin5_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2688,7 +3439,7 @@ func (x *ApplyResourceChange_Response) String() string { func (*ApplyResourceChange_Response) ProtoMessage() {} func (x *ApplyResourceChange_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[47] + mi := &file_tfplugin5_proto_msgTypes[61] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2701,7 +3452,7 @@ func (x *ApplyResourceChange_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyResourceChange_Response.ProtoReflect.Descriptor instead. func (*ApplyResourceChange_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{14, 1} + return file_tfplugin5_proto_rawDescGZIP(), []int{18, 1} } func (x *ApplyResourceChange_Response) GetNewState() *DynamicValue { @@ -2744,7 +3495,7 @@ type ImportResourceState_Request struct { func (x *ImportResourceState_Request) Reset() { *x = ImportResourceState_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[48] + mi := &file_tfplugin5_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2757,7 +3508,7 @@ func (x *ImportResourceState_Request) String() string { func (*ImportResourceState_Request) ProtoMessage() {} func (x *ImportResourceState_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[48] + mi := &file_tfplugin5_proto_msgTypes[62] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2770,7 +3521,7 @@ func (x *ImportResourceState_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportResourceState_Request.ProtoReflect.Descriptor instead. func (*ImportResourceState_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{15, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{19, 0} } func (x *ImportResourceState_Request) GetTypeName() string { @@ -2787,33 +3538,163 @@ func (x *ImportResourceState_Request) GetId() string { return "" } -type ImportResourceState_ImportedResource struct { +type ImportResourceState_ImportedResource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + State *DynamicValue `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` + Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` +} + +func (x *ImportResourceState_ImportedResource) Reset() { + *x = ImportResourceState_ImportedResource{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[63] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ImportResourceState_ImportedResource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportResourceState_ImportedResource) ProtoMessage() {} + +func (x *ImportResourceState_ImportedResource) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[63] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImportResourceState_ImportedResource.ProtoReflect.Descriptor instead. +func (*ImportResourceState_ImportedResource) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{19, 1} +} + +func (x *ImportResourceState_ImportedResource) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *ImportResourceState_ImportedResource) GetState() *DynamicValue { + if x != nil { + return x.State + } + return nil +} + +func (x *ImportResourceState_ImportedResource) GetPrivate() []byte { + if x != nil { + return x.Private + } + return nil +} + +type ImportResourceState_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ImportedResources []*ImportResourceState_ImportedResource `protobuf:"bytes,1,rep,name=imported_resources,json=importedResources,proto3" json:"imported_resources,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *ImportResourceState_Response) Reset() { + *x = ImportResourceState_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ImportResourceState_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportResourceState_Response) ProtoMessage() {} + +func (x *ImportResourceState_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[64] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImportResourceState_Response.ProtoReflect.Descriptor instead. +func (*ImportResourceState_Response) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{19, 2} +} + +func (x *ImportResourceState_Response) GetImportedResources() []*ImportResourceState_ImportedResource { + if x != nil { + return x.ImportedResources + } + return nil +} + +func (x *ImportResourceState_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type MoveResourceState_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` - State *DynamicValue `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` - Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` -} - -func (x *ImportResourceState_ImportedResource) Reset() { - *x = ImportResourceState_ImportedResource{} + // The address of the provider the resource is being moved from. + SourceProviderAddress string `protobuf:"bytes,1,opt,name=source_provider_address,json=sourceProviderAddress,proto3" json:"source_provider_address,omitempty"` + // The resource type that the resource is being moved from. + SourceTypeName string `protobuf:"bytes,2,opt,name=source_type_name,json=sourceTypeName,proto3" json:"source_type_name,omitempty"` + // The schema version of the resource type that the resource is being + // moved from. + SourceSchemaVersion int64 `protobuf:"varint,3,opt,name=source_schema_version,json=sourceSchemaVersion,proto3" json:"source_schema_version,omitempty"` + // The raw state of the resource being moved. Only the json field is + // populated, as there should be no legacy providers using the flatmap + // format that support newly introduced RPCs. + SourceState *RawState `protobuf:"bytes,4,opt,name=source_state,json=sourceState,proto3" json:"source_state,omitempty"` + // The resource type that the resource is being moved to. + TargetTypeName string `protobuf:"bytes,5,opt,name=target_type_name,json=targetTypeName,proto3" json:"target_type_name,omitempty"` + // The private state of the resource being moved. + SourcePrivate []byte `protobuf:"bytes,6,opt,name=source_private,json=sourcePrivate,proto3" json:"source_private,omitempty"` +} + +func (x *MoveResourceState_Request) Reset() { + *x = MoveResourceState_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[49] + mi := &file_tfplugin5_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ImportResourceState_ImportedResource) String() string { +func (x *MoveResourceState_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ImportResourceState_ImportedResource) ProtoMessage() {} +func (*MoveResourceState_Request) ProtoMessage() {} -func (x *ImportResourceState_ImportedResource) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[49] +func (x *MoveResourceState_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[65] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2824,58 +3705,83 @@ func (x *ImportResourceState_ImportedResource) ProtoReflect() protoreflect.Messa return mi.MessageOf(x) } -// Deprecated: Use ImportResourceState_ImportedResource.ProtoReflect.Descriptor instead. -func (*ImportResourceState_ImportedResource) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{15, 1} +// Deprecated: Use MoveResourceState_Request.ProtoReflect.Descriptor instead. +func (*MoveResourceState_Request) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{20, 0} } -func (x *ImportResourceState_ImportedResource) GetTypeName() string { +func (x *MoveResourceState_Request) GetSourceProviderAddress() string { if x != nil { - return x.TypeName + return x.SourceProviderAddress } return "" } -func (x *ImportResourceState_ImportedResource) GetState() *DynamicValue { +func (x *MoveResourceState_Request) GetSourceTypeName() string { if x != nil { - return x.State + return x.SourceTypeName + } + return "" +} + +func (x *MoveResourceState_Request) GetSourceSchemaVersion() int64 { + if x != nil { + return x.SourceSchemaVersion + } + return 0 +} + +func (x *MoveResourceState_Request) GetSourceState() *RawState { + if x != nil { + return x.SourceState } return nil } -func (x *ImportResourceState_ImportedResource) GetPrivate() []byte { +func (x *MoveResourceState_Request) GetTargetTypeName() string { if x != nil { - return x.Private + return x.TargetTypeName + } + return "" +} + +func (x *MoveResourceState_Request) GetSourcePrivate() []byte { + if x != nil { + return x.SourcePrivate } return nil } -type ImportResourceState_Response struct { +type MoveResourceState_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ImportedResources []*ImportResourceState_ImportedResource `protobuf:"bytes,1,rep,name=imported_resources,json=importedResources,proto3" json:"imported_resources,omitempty"` - Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + // The state of the resource after it has been moved. + TargetState *DynamicValue `protobuf:"bytes,1,opt,name=target_state,json=targetState,proto3" json:"target_state,omitempty"` + // Any diagnostics that occurred during the move. + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + // The private state of the resource after it has been moved. + TargetPrivate []byte `protobuf:"bytes,3,opt,name=target_private,json=targetPrivate,proto3" json:"target_private,omitempty"` } -func (x *ImportResourceState_Response) Reset() { - *x = ImportResourceState_Response{} +func (x *MoveResourceState_Response) Reset() { + *x = MoveResourceState_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[50] + mi := &file_tfplugin5_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ImportResourceState_Response) String() string { +func (x *MoveResourceState_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ImportResourceState_Response) ProtoMessage() {} +func (*MoveResourceState_Response) ProtoMessage() {} -func (x *ImportResourceState_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[50] +func (x *MoveResourceState_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2886,25 +3792,32 @@ func (x *ImportResourceState_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ImportResourceState_Response.ProtoReflect.Descriptor instead. -func (*ImportResourceState_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{15, 2} +// Deprecated: Use MoveResourceState_Response.ProtoReflect.Descriptor instead. +func (*MoveResourceState_Response) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{20, 1} } -func (x *ImportResourceState_Response) GetImportedResources() []*ImportResourceState_ImportedResource { +func (x *MoveResourceState_Response) GetTargetState() *DynamicValue { if x != nil { - return x.ImportedResources + return x.TargetState } return nil } -func (x *ImportResourceState_Response) GetDiagnostics() []*Diagnostic { +func (x *MoveResourceState_Response) GetDiagnostics() []*Diagnostic { if x != nil { return x.Diagnostics } return nil } +func (x *MoveResourceState_Response) GetTargetPrivate() []byte { + if x != nil { + return x.TargetPrivate + } + return nil +} + type ReadDataSource_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2918,7 +3831,7 @@ type ReadDataSource_Request struct { func (x *ReadDataSource_Request) Reset() { *x = ReadDataSource_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[51] + mi := &file_tfplugin5_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2931,7 +3844,7 @@ func (x *ReadDataSource_Request) String() string { func (*ReadDataSource_Request) ProtoMessage() {} func (x *ReadDataSource_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[51] + mi := &file_tfplugin5_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2944,7 +3857,7 @@ func (x *ReadDataSource_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadDataSource_Request.ProtoReflect.Descriptor instead. func (*ReadDataSource_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{16, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{21, 0} } func (x *ReadDataSource_Request) GetTypeName() string { @@ -2980,7 +3893,7 @@ type ReadDataSource_Response struct { func (x *ReadDataSource_Response) Reset() { *x = ReadDataSource_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[52] + mi := &file_tfplugin5_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2993,7 +3906,7 @@ func (x *ReadDataSource_Response) String() string { func (*ReadDataSource_Response) ProtoMessage() {} func (x *ReadDataSource_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[52] + mi := &file_tfplugin5_proto_msgTypes[68] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3006,7 +3919,7 @@ func (x *ReadDataSource_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadDataSource_Response.ProtoReflect.Descriptor instead. func (*ReadDataSource_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{16, 1} + return file_tfplugin5_proto_rawDescGZIP(), []int{21, 1} } func (x *ReadDataSource_Response) GetState() *DynamicValue { @@ -3032,7 +3945,7 @@ type GetProvisionerSchema_Request struct { func (x *GetProvisionerSchema_Request) Reset() { *x = GetProvisionerSchema_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[53] + mi := &file_tfplugin5_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3045,7 +3958,7 @@ func (x *GetProvisionerSchema_Request) String() string { func (*GetProvisionerSchema_Request) ProtoMessage() {} func (x *GetProvisionerSchema_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[53] + mi := &file_tfplugin5_proto_msgTypes[69] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3058,7 +3971,7 @@ func (x *GetProvisionerSchema_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProvisionerSchema_Request.ProtoReflect.Descriptor instead. func (*GetProvisionerSchema_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{17, 0} + return file_tfplugin5_proto_rawDescGZIP(), []int{22, 0} } type GetProvisionerSchema_Response struct { @@ -3073,20 +3986,224 @@ type GetProvisionerSchema_Response struct { func (x *GetProvisionerSchema_Response) Reset() { *x = GetProvisionerSchema_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[54] + mi := &file_tfplugin5_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProvisionerSchema_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProvisionerSchema_Response) ProtoMessage() {} + +func (x *GetProvisionerSchema_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[70] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProvisionerSchema_Response.ProtoReflect.Descriptor instead. +func (*GetProvisionerSchema_Response) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{22, 1} +} + +func (x *GetProvisionerSchema_Response) GetProvisioner() *Schema { + if x != nil { + return x.Provisioner + } + return nil +} + +func (x *GetProvisionerSchema_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type ValidateProvisionerConfig_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Config *DynamicValue `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` +} + +func (x *ValidateProvisionerConfig_Request) Reset() { + *x = ValidateProvisionerConfig_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[71] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateProvisionerConfig_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateProvisionerConfig_Request) ProtoMessage() {} + +func (x *ValidateProvisionerConfig_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[71] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateProvisionerConfig_Request.ProtoReflect.Descriptor instead. +func (*ValidateProvisionerConfig_Request) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{23, 0} +} + +func (x *ValidateProvisionerConfig_Request) GetConfig() *DynamicValue { + if x != nil { + return x.Config + } + return nil +} + +type ValidateProvisionerConfig_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Diagnostics []*Diagnostic `protobuf:"bytes,1,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *ValidateProvisionerConfig_Response) Reset() { + *x = ValidateProvisionerConfig_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[72] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateProvisionerConfig_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateProvisionerConfig_Response) ProtoMessage() {} + +func (x *ValidateProvisionerConfig_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[72] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateProvisionerConfig_Response.ProtoReflect.Descriptor instead. +func (*ValidateProvisionerConfig_Response) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{23, 1} +} + +func (x *ValidateProvisionerConfig_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type ProvisionResource_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Config *DynamicValue `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` + Connection *DynamicValue `protobuf:"bytes,2,opt,name=connection,proto3" json:"connection,omitempty"` +} + +func (x *ProvisionResource_Request) Reset() { + *x = ProvisionResource_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProvisionResource_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionResource_Request) ProtoMessage() {} + +func (x *ProvisionResource_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[73] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionResource_Request.ProtoReflect.Descriptor instead. +func (*ProvisionResource_Request) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{24, 0} +} + +func (x *ProvisionResource_Request) GetConfig() *DynamicValue { + if x != nil { + return x.Config + } + return nil +} + +func (x *ProvisionResource_Request) GetConnection() *DynamicValue { + if x != nil { + return x.Connection + } + return nil +} + +type ProvisionResource_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Output string `protobuf:"bytes,1,opt,name=output,proto3" json:"output,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *ProvisionResource_Response) Reset() { + *x = ProvisionResource_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin5_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetProvisionerSchema_Response) String() string { +func (x *ProvisionResource_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetProvisionerSchema_Response) ProtoMessage() {} +func (*ProvisionResource_Response) ProtoMessage() {} -func (x *GetProvisionerSchema_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[54] +func (x *ProvisionResource_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[74] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3097,50 +4214,48 @@ func (x *GetProvisionerSchema_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetProvisionerSchema_Response.ProtoReflect.Descriptor instead. -func (*GetProvisionerSchema_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{17, 1} +// Deprecated: Use ProvisionResource_Response.ProtoReflect.Descriptor instead. +func (*ProvisionResource_Response) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{24, 1} } -func (x *GetProvisionerSchema_Response) GetProvisioner() *Schema { +func (x *ProvisionResource_Response) GetOutput() string { if x != nil { - return x.Provisioner + return x.Output } - return nil + return "" } -func (x *GetProvisionerSchema_Response) GetDiagnostics() []*Diagnostic { +func (x *ProvisionResource_Response) GetDiagnostics() []*Diagnostic { if x != nil { return x.Diagnostics } return nil } -type ValidateProvisionerConfig_Request struct { +type GetFunctions_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - Config *DynamicValue `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` } -func (x *ValidateProvisionerConfig_Request) Reset() { - *x = ValidateProvisionerConfig_Request{} +func (x *GetFunctions_Request) Reset() { + *x = GetFunctions_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[55] + mi := &file_tfplugin5_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ValidateProvisionerConfig_Request) String() string { +func (x *GetFunctions_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ValidateProvisionerConfig_Request) ProtoMessage() {} +func (*GetFunctions_Request) ProtoMessage() {} -func (x *ValidateProvisionerConfig_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[55] +func (x *GetFunctions_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[75] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3151,43 +4266,39 @@ func (x *ValidateProvisionerConfig_Request) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ValidateProvisionerConfig_Request.ProtoReflect.Descriptor instead. -func (*ValidateProvisionerConfig_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{18, 0} -} - -func (x *ValidateProvisionerConfig_Request) GetConfig() *DynamicValue { - if x != nil { - return x.Config - } - return nil +// Deprecated: Use GetFunctions_Request.ProtoReflect.Descriptor instead. +func (*GetFunctions_Request) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{25, 0} } -type ValidateProvisionerConfig_Response struct { +type GetFunctions_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Diagnostics []*Diagnostic `protobuf:"bytes,1,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + // functions is a mapping of function names to definitions. + Functions map[string]*Function `protobuf:"bytes,1,rep,name=functions,proto3" json:"functions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // diagnostics is any warnings or errors. + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` } -func (x *ValidateProvisionerConfig_Response) Reset() { - *x = ValidateProvisionerConfig_Response{} +func (x *GetFunctions_Response) Reset() { + *x = GetFunctions_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[56] + mi := &file_tfplugin5_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ValidateProvisionerConfig_Response) String() string { +func (x *GetFunctions_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ValidateProvisionerConfig_Response) ProtoMessage() {} +func (*GetFunctions_Response) ProtoMessage() {} -func (x *ValidateProvisionerConfig_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[56] +func (x *GetFunctions_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[76] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3198,44 +4309,53 @@ func (x *ValidateProvisionerConfig_Response) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ValidateProvisionerConfig_Response.ProtoReflect.Descriptor instead. -func (*ValidateProvisionerConfig_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{18, 1} +// Deprecated: Use GetFunctions_Response.ProtoReflect.Descriptor instead. +func (*GetFunctions_Response) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{25, 1} } -func (x *ValidateProvisionerConfig_Response) GetDiagnostics() []*Diagnostic { +func (x *GetFunctions_Response) GetFunctions() map[string]*Function { + if x != nil { + return x.Functions + } + return nil +} + +func (x *GetFunctions_Response) GetDiagnostics() []*Diagnostic { if x != nil { return x.Diagnostics } return nil } -type ProvisionResource_Request struct { +type CallFunction_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Config *DynamicValue `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` - Connection *DynamicValue `protobuf:"bytes,2,opt,name=connection,proto3" json:"connection,omitempty"` + // name is the name of the function being called. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // arguments is the data of each function argument value. + Arguments []*DynamicValue `protobuf:"bytes,2,rep,name=arguments,proto3" json:"arguments,omitempty"` } -func (x *ProvisionResource_Request) Reset() { - *x = ProvisionResource_Request{} +func (x *CallFunction_Request) Reset() { + *x = CallFunction_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[57] + mi := &file_tfplugin5_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ProvisionResource_Request) String() string { +func (x *CallFunction_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ProvisionResource_Request) ProtoMessage() {} +func (*CallFunction_Request) ProtoMessage() {} -func (x *ProvisionResource_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[57] +func (x *CallFunction_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[78] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3246,51 +4366,53 @@ func (x *ProvisionResource_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ProvisionResource_Request.ProtoReflect.Descriptor instead. -func (*ProvisionResource_Request) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{19, 0} +// Deprecated: Use CallFunction_Request.ProtoReflect.Descriptor instead. +func (*CallFunction_Request) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{26, 0} } -func (x *ProvisionResource_Request) GetConfig() *DynamicValue { +func (x *CallFunction_Request) GetName() string { if x != nil { - return x.Config + return x.Name } - return nil + return "" } -func (x *ProvisionResource_Request) GetConnection() *DynamicValue { +func (x *CallFunction_Request) GetArguments() []*DynamicValue { if x != nil { - return x.Connection + return x.Arguments } return nil } -type ProvisionResource_Response struct { +type CallFunction_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Output string `protobuf:"bytes,1,opt,name=output,proto3" json:"output,omitempty"` - Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + // result is result value after running the function logic. + Result *DynamicValue `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"` + // error is any error from the function logic. + Error *FunctionError `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` } -func (x *ProvisionResource_Response) Reset() { - *x = ProvisionResource_Response{} +func (x *CallFunction_Response) Reset() { + *x = CallFunction_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin5_proto_msgTypes[58] + mi := &file_tfplugin5_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ProvisionResource_Response) String() string { +func (x *CallFunction_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ProvisionResource_Response) ProtoMessage() {} +func (*CallFunction_Response) ProtoMessage() {} -func (x *ProvisionResource_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin5_proto_msgTypes[58] +func (x *CallFunction_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin5_proto_msgTypes[79] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3301,21 +4423,21 @@ func (x *ProvisionResource_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ProvisionResource_Response.ProtoReflect.Descriptor instead. -func (*ProvisionResource_Response) Descriptor() ([]byte, []int) { - return file_tfplugin5_proto_rawDescGZIP(), []int{19, 1} +// Deprecated: Use CallFunction_Response.ProtoReflect.Descriptor instead. +func (*CallFunction_Response) Descriptor() ([]byte, []int) { + return file_tfplugin5_proto_rawDescGZIP(), []int{26, 1} } -func (x *ProvisionResource_Response) GetOutput() string { +func (x *CallFunction_Response) GetResult() *DynamicValue { if x != nil { - return x.Output + return x.Result } - return "" + return nil } -func (x *ProvisionResource_Response) GetDiagnostics() []*Diagnostic { +func (x *CallFunction_Response) GetError() *FunctionError { if x != nil { - return x.Diagnostics + return x.Error } return nil } @@ -3343,381 +4465,544 @@ var file_tfplugin5_proto_rawDesc = []byte{ 0x2f, 0x0a, 0x08, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x02, - 0x22, 0xdc, 0x01, 0x0a, 0x0d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, - 0x74, 0x68, 0x12, 0x33, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x53, 0x74, 0x65, 0x70, - 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x95, 0x01, 0x0a, 0x04, 0x53, 0x74, 0x65, 0x70, - 0x12, 0x27, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x65, 0x6c, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x10, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x6c, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x03, 0x48, 0x00, 0x52, 0x0d, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, - 0x49, 0x6e, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, - 0x33, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x1a, 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x20, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x22, 0x96, 0x01, 0x0a, 0x08, 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x07, 0x66, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x35, 0x2e, 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x46, 0x6c, 0x61, 0x74, - 0x6d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x66, 0x6c, 0x61, 0x74, 0x6d, 0x61, - 0x70, 0x1a, 0x3a, 0x0a, 0x0c, 0x46, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xcc, 0x07, - 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x1a, 0xa2, 0x02, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x66, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, - 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, - 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, - 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, - 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x1a, 0xa9, 0x02, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, - 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, - 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, - 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, - 0x12, 0x40, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, - 0x64, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x69, - 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, - 0x65, 0x64, 0x1a, 0xa7, 0x02, 0x0a, 0x0b, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x22, 0x6b, 0x0a, 0x0d, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x30, 0x0a, 0x11, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x48, 0x00, 0x52, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0xdc, 0x01, + 0x0a, 0x0d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x33, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, + 0x74, 0x65, 0x70, 0x73, 0x1a, 0x95, 0x01, 0x0a, 0x04, 0x53, 0x74, 0x65, 0x70, 0x12, 0x27, 0x0a, + 0x0e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x10, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, + 0x00, 0x52, 0x0d, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x6e, 0x74, + 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x33, 0x0a, 0x04, + 0x53, 0x74, 0x6f, 0x70, 0x1a, 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x20, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x22, 0x96, 0x01, 0x0a, 0x08, 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6a, 0x73, + 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x07, 0x66, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, + 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x46, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x66, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x1a, 0x3a, + 0x0a, 0x0c, 0x46, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xcc, 0x07, 0x0a, 0x06, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x43, - 0x0a, 0x07, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x29, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x4e, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x07, 0x6e, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, - 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x4d, 0x0a, - 0x0b, 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0b, 0x0a, 0x07, - 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x4e, - 0x47, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x02, 0x12, - 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x41, 0x50, 0x10, - 0x04, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x05, 0x22, 0xeb, 0x05, 0x0a, - 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x1a, 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x91, 0x05, - 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, - 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x65, 0x0a, 0x10, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, - 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, - 0x12, 0x6c, 0x0a, 0x13, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, - 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x64, 0x61, 0x74, - 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x12, 0x37, - 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, - 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, - 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x61, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0xa2, + 0x02, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, + 0x3e, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, + 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x40, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, + 0x6e, 0x64, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, + 0x69, 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, + 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, + 0x74, 0x65, 0x64, 0x1a, 0xa9, 0x02, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x12, + 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x40, 0x0a, + 0x10, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, + 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0f, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x12, + 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x1a, + 0xa7, 0x02, 0x0a, 0x0b, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, + 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x05, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x43, 0x0a, 0x07, 0x6e, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, + 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x4e, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x07, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, + 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, + 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x4d, 0x0a, 0x0b, 0x4e, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x4e, 0x47, 0x4c, 0x45, + 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, + 0x53, 0x45, 0x54, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x41, 0x50, 0x10, 0x04, 0x12, 0x09, + 0x0a, 0x05, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x05, 0x22, 0xa8, 0x01, 0x0a, 0x12, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, + 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x6c, 0x61, 0x6e, 0x44, 0x65, 0x73, 0x74, + 0x72, 0x6f, 0x79, 0x12, 0x3f, 0x0a, 0x1c, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x67, 0x65, 0x74, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x11, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x22, 0x8e, 0x05, 0x0a, 0x08, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x3d, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x35, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x12, 0x4c, 0x0a, 0x12, 0x76, 0x61, 0x72, 0x69, 0x61, 0x64, 0x69, 0x63, 0x5f, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x11, 0x76, 0x61, 0x72, + 0x69, 0x61, 0x64, 0x69, 0x63, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x32, + 0x0a, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x52, 0x06, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, + 0x0a, 0x10, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, + 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, 0x64, 0x52, + 0x0f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x69, 0x6e, 0x64, + 0x12, 0x2f, 0x0a, 0x13, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x64, + 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x1a, 0xf3, 0x01, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x75, 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x30, 0x0a, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x12, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x1a, 0x1c, 0x0a, 0x06, 0x52, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x96, 0x04, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0xef, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, + 0x13, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x66, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x12, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x37, 0x0a, + 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, + 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x4c, 0x0a, 0x0c, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x09, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x1a, 0x26, 0x0a, 0x10, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x31, 0x0a, 0x12, 0x44, 0x61, + 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x2f, 0x0a, + 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xc7, + 0x06, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x1a, 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0xa6, 0x06, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x12, - 0x60, 0x0a, 0x13, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, - 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x61, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x65, 0x0a, 0x10, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x35, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x73, 0x12, 0x6c, 0x0a, 0x13, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x3c, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x64, + 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, + 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, + 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, + 0x61, 0x12, 0x4e, 0x0a, 0x13, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x12, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, - 0x73, 0x1a, 0x55, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x57, 0x0a, 0x16, 0x44, 0x61, 0x74, 0x61, - 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x1a, 0x37, 0x0a, 0x12, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x6c, 0x61, 0x6e, 0x5f, - 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, - 0x6c, 0x61, 0x6e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x22, 0xdb, 0x01, 0x0a, 0x15, 0x50, - 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x3a, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, - 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x1a, 0x85, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, - 0x0f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x73, 0x12, 0x52, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, + 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x55, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x57, 0x0a, 0x16, + 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x51, 0x0a, 0x0e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xdb, 0x01, 0x0a, 0x15, 0x50, 0x72, 0x65, + 0x70, 0x61, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x1a, 0x3a, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, + 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, + 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x85, + 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0f, 0x70, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, + 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x70, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x37, 0x0a, + 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, + 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0x90, 0x02, 0x0a, 0x14, 0x55, 0x70, 0x67, 0x72, 0x61, + 0x64, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, + 0x72, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, + 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x30, 0x0a, 0x09, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, + 0x2e, 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x72, 0x61, 0x77, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x1a, 0x83, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3e, 0x0a, 0x0e, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x0d, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, + 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xba, 0x01, 0x0a, 0x1a, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x57, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, + 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, + 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, + 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xb8, 0x01, 0x0a, 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x1a, 0x57, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, + 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, + 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, + 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x1a, + 0x67, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x65, + 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, + 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, + 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xe3, 0x02, + 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0xbc, + 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, + 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, + 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x0e, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, - 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, - 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0x90, 0x02, 0x0a, 0x14, 0x55, 0x70, 0x67, - 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x1a, 0x72, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x93, 0x01, + 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x6e, 0x65, + 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, + 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, + 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x22, 0xf2, 0x04, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x1a, 0xbb, 0x02, 0x0a, 0x07, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x45, 0x0a, + 0x12, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x4e, 0x65, 0x77, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, + 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x70, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, + 0x69, 0x6f, 0x72, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, + 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x9d, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, + 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x73, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x6c, 0x61, 0x6e, + 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, + 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x65, + 0x67, 0x61, 0x63, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x54, 0x79, + 0x70, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x92, 0x04, 0x0a, 0x13, 0x41, 0x70, 0x70, + 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x1a, 0xb6, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x09, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x35, 0x2e, 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x72, 0x61, 0x77, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x83, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0e, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, + 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x72, 0x69, + 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, - 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xba, 0x01, 0x0a, 0x1a, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x57, 0x0a, 0x07, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, + 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, + 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x70, 0x6c, 0x61, + 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, - 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, - 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, - 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xb8, 0x01, 0x0a, 0x18, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x57, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0xc1, 0x01, 0x0a, 0x08, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, + 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, + 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, + 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, 0x65, 0x67, + 0x61, 0x63, 0x79, 0x54, 0x79, 0x70, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0xed, 0x02, + 0x0a, 0x13, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x36, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, - 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x1a, 0x78, 0x0a, + 0x10, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2d, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, + 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x1a, 0xa3, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x12, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x49, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x11, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, + 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, + 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xe7, 0x03, + 0x0a, 0x11, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x1a, 0xa8, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x36, 0x0a, 0x17, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x15, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x13, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x28, 0x0a, + 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x1a, 0xa6, + 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, + 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, + 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, + 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0x9c, 0x02, 0x0a, 0x0e, 0x52, 0x65, 0x61, 0x64, + 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x95, 0x01, 0x0a, 0x07, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, + 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, + 0x74, 0x61, 0x1a, 0x72, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, + 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, + 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, + 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0x9b, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x1a, + 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x78, 0x0a, 0x08, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x0b, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x0b, 0x64, + 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, + 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x22, 0x9c, 0x01, 0x0a, 0x19, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x1a, 0x3a, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, + 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, - 0x69, 0x63, 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, - 0x65, 0x1a, 0x67, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x11, - 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, - 0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x69, 0x63, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x73, 0x0a, 0x07, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, + 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x37, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, - 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, - 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, - 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, - 0xe3, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x1a, 0xbc, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x63, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, - 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, - 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, - 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, - 0x93, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x09, - 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, - 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, + 0x75, 0x65, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x5b, + 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, - 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, - 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, - 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0xf2, 0x04, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x1a, 0xbb, 0x02, 0x0a, - 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, - 0x45, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x6e, 0x65, 0x77, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, - 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x4e, 0x65, - 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6f, 0x72, - 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, - 0x70, 0x72, 0x69, 0x6f, 0x72, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, - 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x9d, 0x02, 0x0a, 0x08, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x6e, 0x6e, - 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, - 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x18, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x6c, - 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, - 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, - 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x2c, 0x0a, 0x12, - 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, - 0x54, 0x79, 0x70, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x92, 0x04, 0x0a, 0x13, 0x41, - 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x1a, 0xb6, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, - 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x70, - 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, - 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6f, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, - 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, - 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, - 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x5f, - 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x70, - 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, - 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, - 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0xc1, 0x01, 0x0a, 0x08, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, - 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, - 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, - 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, - 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, - 0x65, 0x67, 0x61, 0x63, 0x79, 0x54, 0x79, 0x70, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, - 0xed, 0x02, 0x0a, 0x13, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x36, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x1a, - 0x78, 0x0a, 0x10, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, - 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x1a, 0xa3, 0x01, 0x0a, 0x08, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x12, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x49, - 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x11, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, - 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, - 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, - 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, - 0x9c, 0x02, 0x0a, 0x0e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x1a, 0x95, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, - 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, - 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x0d, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, - 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x72, 0x0a, 0x08, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, - 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, - 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0x9b, - 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, - 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x1a, 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x78, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, - 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, + 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0x81, 0x02, 0x0a, 0x0c, + 0x47, 0x65, 0x74, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x09, 0x0a, 0x07, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0xe5, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, - 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0x9c, 0x01, 0x0a, - 0x19, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x3a, 0x0a, 0x07, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, - 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x11, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x1a, 0x73, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x06, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, - 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x37, 0x0a, - 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x79, - 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x5b, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, - 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, 0x69, 0x61, 0x67, - 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, - 0x69, 0x63, 0x73, 0x2a, 0x25, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, + 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x1a, 0x51, 0x0a, 0x0e, + 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x46, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0xd1, 0x01, 0x0a, 0x0c, 0x43, 0x61, 0x6c, 0x6c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x1a, 0x54, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x35, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x6b, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x44, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x2a, 0x25, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, - 0x4d, 0x41, 0x52, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x32, 0x97, 0x09, 0x0a, 0x08, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x58, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x63, + 0x4d, 0x41, 0x52, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x32, 0xef, 0x0b, 0x0a, 0x08, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x24, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x66, 0x70, @@ -3781,45 +5066,62 @@ var file_tfplugin5_proto_rawDesc = []byte{ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x57, 0x0a, 0x0e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x21, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x52, - 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x35, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x04, 0x53, 0x74, 0x6f, - 0x70, 0x12, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x74, - 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x74, 0x66, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x86, 0x03, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x65, 0x72, 0x12, 0x5e, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x12, 0x27, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, - 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x74, 0x66, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x19, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x2c, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, - 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, - 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x66, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x30, 0x01, 0x12, 0x39, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x17, 0x2e, 0x74, 0x66, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, - 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x47, 0x5a, - 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2d, - 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x74, 0x66, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x76, 0x35, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x66, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x60, 0x0a, 0x11, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x24, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x35, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x21, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, + 0x2e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x35, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0c, 0x47, + 0x65, 0x74, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, + 0x0a, 0x0c, 0x43, 0x61, 0x6c, 0x6c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x20, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x43, 0x61, 0x6c, 0x6c, + 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x39, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, + 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x86, 0x03, 0x0a, + 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x12, 0x5e, 0x0a, 0x09, + 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x27, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x47, + 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x19, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2c, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x35, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x39, 0x0a, 0x04, 0x53, 0x74, + 0x6f, 0x70, 0x12, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, + 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x47, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x74, 0x65, + 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2d, 0x67, + 0x6f, 0x2f, 0x74, 0x66, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x76, 0x35, 0x2f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x35, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3835,171 +5137,221 @@ func file_tfplugin5_proto_rawDescGZIP() []byte { } var file_tfplugin5_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_tfplugin5_proto_msgTypes = make([]protoimpl.MessageInfo, 59) +var file_tfplugin5_proto_msgTypes = make([]protoimpl.MessageInfo, 80) var file_tfplugin5_proto_goTypes = []interface{}{ (StringKind)(0), // 0: tfplugin5.StringKind (Diagnostic_Severity)(0), // 1: tfplugin5.Diagnostic.Severity (Schema_NestedBlock_NestingMode)(0), // 2: tfplugin5.Schema.NestedBlock.NestingMode (*DynamicValue)(nil), // 3: tfplugin5.DynamicValue (*Diagnostic)(nil), // 4: tfplugin5.Diagnostic - (*AttributePath)(nil), // 5: tfplugin5.AttributePath - (*Stop)(nil), // 6: tfplugin5.Stop - (*RawState)(nil), // 7: tfplugin5.RawState - (*Schema)(nil), // 8: tfplugin5.Schema - (*GetProviderSchema)(nil), // 9: tfplugin5.GetProviderSchema - (*PrepareProviderConfig)(nil), // 10: tfplugin5.PrepareProviderConfig - (*UpgradeResourceState)(nil), // 11: tfplugin5.UpgradeResourceState - (*ValidateResourceTypeConfig)(nil), // 12: tfplugin5.ValidateResourceTypeConfig - (*ValidateDataSourceConfig)(nil), // 13: tfplugin5.ValidateDataSourceConfig - (*Configure)(nil), // 14: tfplugin5.Configure - (*ReadResource)(nil), // 15: tfplugin5.ReadResource - (*PlanResourceChange)(nil), // 16: tfplugin5.PlanResourceChange - (*ApplyResourceChange)(nil), // 17: tfplugin5.ApplyResourceChange - (*ImportResourceState)(nil), // 18: tfplugin5.ImportResourceState - (*ReadDataSource)(nil), // 19: tfplugin5.ReadDataSource - (*GetProvisionerSchema)(nil), // 20: tfplugin5.GetProvisionerSchema - (*ValidateProvisionerConfig)(nil), // 21: tfplugin5.ValidateProvisionerConfig - (*ProvisionResource)(nil), // 22: tfplugin5.ProvisionResource - (*AttributePath_Step)(nil), // 23: tfplugin5.AttributePath.Step - (*Stop_Request)(nil), // 24: tfplugin5.Stop.Request - (*Stop_Response)(nil), // 25: tfplugin5.Stop.Response - nil, // 26: tfplugin5.RawState.FlatmapEntry - (*Schema_Block)(nil), // 27: tfplugin5.Schema.Block - (*Schema_Attribute)(nil), // 28: tfplugin5.Schema.Attribute - (*Schema_NestedBlock)(nil), // 29: tfplugin5.Schema.NestedBlock - (*GetProviderSchema_Request)(nil), // 30: tfplugin5.GetProviderSchema.Request - (*GetProviderSchema_Response)(nil), // 31: tfplugin5.GetProviderSchema.Response - (*GetProviderSchema_ServerCapabilities)(nil), // 32: tfplugin5.GetProviderSchema.ServerCapabilities - nil, // 33: tfplugin5.GetProviderSchema.Response.ResourceSchemasEntry - nil, // 34: tfplugin5.GetProviderSchema.Response.DataSourceSchemasEntry - (*PrepareProviderConfig_Request)(nil), // 35: tfplugin5.PrepareProviderConfig.Request - (*PrepareProviderConfig_Response)(nil), // 36: tfplugin5.PrepareProviderConfig.Response - (*UpgradeResourceState_Request)(nil), // 37: tfplugin5.UpgradeResourceState.Request - (*UpgradeResourceState_Response)(nil), // 38: tfplugin5.UpgradeResourceState.Response - (*ValidateResourceTypeConfig_Request)(nil), // 39: tfplugin5.ValidateResourceTypeConfig.Request - (*ValidateResourceTypeConfig_Response)(nil), // 40: tfplugin5.ValidateResourceTypeConfig.Response - (*ValidateDataSourceConfig_Request)(nil), // 41: tfplugin5.ValidateDataSourceConfig.Request - (*ValidateDataSourceConfig_Response)(nil), // 42: tfplugin5.ValidateDataSourceConfig.Response - (*Configure_Request)(nil), // 43: tfplugin5.Configure.Request - (*Configure_Response)(nil), // 44: tfplugin5.Configure.Response - (*ReadResource_Request)(nil), // 45: tfplugin5.ReadResource.Request - (*ReadResource_Response)(nil), // 46: tfplugin5.ReadResource.Response - (*PlanResourceChange_Request)(nil), // 47: tfplugin5.PlanResourceChange.Request - (*PlanResourceChange_Response)(nil), // 48: tfplugin5.PlanResourceChange.Response - (*ApplyResourceChange_Request)(nil), // 49: tfplugin5.ApplyResourceChange.Request - (*ApplyResourceChange_Response)(nil), // 50: tfplugin5.ApplyResourceChange.Response - (*ImportResourceState_Request)(nil), // 51: tfplugin5.ImportResourceState.Request - (*ImportResourceState_ImportedResource)(nil), // 52: tfplugin5.ImportResourceState.ImportedResource - (*ImportResourceState_Response)(nil), // 53: tfplugin5.ImportResourceState.Response - (*ReadDataSource_Request)(nil), // 54: tfplugin5.ReadDataSource.Request - (*ReadDataSource_Response)(nil), // 55: tfplugin5.ReadDataSource.Response - (*GetProvisionerSchema_Request)(nil), // 56: tfplugin5.GetProvisionerSchema.Request - (*GetProvisionerSchema_Response)(nil), // 57: tfplugin5.GetProvisionerSchema.Response - (*ValidateProvisionerConfig_Request)(nil), // 58: tfplugin5.ValidateProvisionerConfig.Request - (*ValidateProvisionerConfig_Response)(nil), // 59: tfplugin5.ValidateProvisionerConfig.Response - (*ProvisionResource_Request)(nil), // 60: tfplugin5.ProvisionResource.Request - (*ProvisionResource_Response)(nil), // 61: tfplugin5.ProvisionResource.Response + (*FunctionError)(nil), // 5: tfplugin5.FunctionError + (*AttributePath)(nil), // 6: tfplugin5.AttributePath + (*Stop)(nil), // 7: tfplugin5.Stop + (*RawState)(nil), // 8: tfplugin5.RawState + (*Schema)(nil), // 9: tfplugin5.Schema + (*ServerCapabilities)(nil), // 10: tfplugin5.ServerCapabilities + (*Function)(nil), // 11: tfplugin5.Function + (*GetMetadata)(nil), // 12: tfplugin5.GetMetadata + (*GetProviderSchema)(nil), // 13: tfplugin5.GetProviderSchema + (*PrepareProviderConfig)(nil), // 14: tfplugin5.PrepareProviderConfig + (*UpgradeResourceState)(nil), // 15: tfplugin5.UpgradeResourceState + (*ValidateResourceTypeConfig)(nil), // 16: tfplugin5.ValidateResourceTypeConfig + (*ValidateDataSourceConfig)(nil), // 17: tfplugin5.ValidateDataSourceConfig + (*Configure)(nil), // 18: tfplugin5.Configure + (*ReadResource)(nil), // 19: tfplugin5.ReadResource + (*PlanResourceChange)(nil), // 20: tfplugin5.PlanResourceChange + (*ApplyResourceChange)(nil), // 21: tfplugin5.ApplyResourceChange + (*ImportResourceState)(nil), // 22: tfplugin5.ImportResourceState + (*MoveResourceState)(nil), // 23: tfplugin5.MoveResourceState + (*ReadDataSource)(nil), // 24: tfplugin5.ReadDataSource + (*GetProvisionerSchema)(nil), // 25: tfplugin5.GetProvisionerSchema + (*ValidateProvisionerConfig)(nil), // 26: tfplugin5.ValidateProvisionerConfig + (*ProvisionResource)(nil), // 27: tfplugin5.ProvisionResource + (*GetFunctions)(nil), // 28: tfplugin5.GetFunctions + (*CallFunction)(nil), // 29: tfplugin5.CallFunction + (*AttributePath_Step)(nil), // 30: tfplugin5.AttributePath.Step + (*Stop_Request)(nil), // 31: tfplugin5.Stop.Request + (*Stop_Response)(nil), // 32: tfplugin5.Stop.Response + nil, // 33: tfplugin5.RawState.FlatmapEntry + (*Schema_Block)(nil), // 34: tfplugin5.Schema.Block + (*Schema_Attribute)(nil), // 35: tfplugin5.Schema.Attribute + (*Schema_NestedBlock)(nil), // 36: tfplugin5.Schema.NestedBlock + (*Function_Parameter)(nil), // 37: tfplugin5.Function.Parameter + (*Function_Return)(nil), // 38: tfplugin5.Function.Return + (*GetMetadata_Request)(nil), // 39: tfplugin5.GetMetadata.Request + (*GetMetadata_Response)(nil), // 40: tfplugin5.GetMetadata.Response + (*GetMetadata_FunctionMetadata)(nil), // 41: tfplugin5.GetMetadata.FunctionMetadata + (*GetMetadata_DataSourceMetadata)(nil), // 42: tfplugin5.GetMetadata.DataSourceMetadata + (*GetMetadata_ResourceMetadata)(nil), // 43: tfplugin5.GetMetadata.ResourceMetadata + (*GetProviderSchema_Request)(nil), // 44: tfplugin5.GetProviderSchema.Request + (*GetProviderSchema_Response)(nil), // 45: tfplugin5.GetProviderSchema.Response + nil, // 46: tfplugin5.GetProviderSchema.Response.ResourceSchemasEntry + nil, // 47: tfplugin5.GetProviderSchema.Response.DataSourceSchemasEntry + nil, // 48: tfplugin5.GetProviderSchema.Response.FunctionsEntry + (*PrepareProviderConfig_Request)(nil), // 49: tfplugin5.PrepareProviderConfig.Request + (*PrepareProviderConfig_Response)(nil), // 50: tfplugin5.PrepareProviderConfig.Response + (*UpgradeResourceState_Request)(nil), // 51: tfplugin5.UpgradeResourceState.Request + (*UpgradeResourceState_Response)(nil), // 52: tfplugin5.UpgradeResourceState.Response + (*ValidateResourceTypeConfig_Request)(nil), // 53: tfplugin5.ValidateResourceTypeConfig.Request + (*ValidateResourceTypeConfig_Response)(nil), // 54: tfplugin5.ValidateResourceTypeConfig.Response + (*ValidateDataSourceConfig_Request)(nil), // 55: tfplugin5.ValidateDataSourceConfig.Request + (*ValidateDataSourceConfig_Response)(nil), // 56: tfplugin5.ValidateDataSourceConfig.Response + (*Configure_Request)(nil), // 57: tfplugin5.Configure.Request + (*Configure_Response)(nil), // 58: tfplugin5.Configure.Response + (*ReadResource_Request)(nil), // 59: tfplugin5.ReadResource.Request + (*ReadResource_Response)(nil), // 60: tfplugin5.ReadResource.Response + (*PlanResourceChange_Request)(nil), // 61: tfplugin5.PlanResourceChange.Request + (*PlanResourceChange_Response)(nil), // 62: tfplugin5.PlanResourceChange.Response + (*ApplyResourceChange_Request)(nil), // 63: tfplugin5.ApplyResourceChange.Request + (*ApplyResourceChange_Response)(nil), // 64: tfplugin5.ApplyResourceChange.Response + (*ImportResourceState_Request)(nil), // 65: tfplugin5.ImportResourceState.Request + (*ImportResourceState_ImportedResource)(nil), // 66: tfplugin5.ImportResourceState.ImportedResource + (*ImportResourceState_Response)(nil), // 67: tfplugin5.ImportResourceState.Response + (*MoveResourceState_Request)(nil), // 68: tfplugin5.MoveResourceState.Request + (*MoveResourceState_Response)(nil), // 69: tfplugin5.MoveResourceState.Response + (*ReadDataSource_Request)(nil), // 70: tfplugin5.ReadDataSource.Request + (*ReadDataSource_Response)(nil), // 71: tfplugin5.ReadDataSource.Response + (*GetProvisionerSchema_Request)(nil), // 72: tfplugin5.GetProvisionerSchema.Request + (*GetProvisionerSchema_Response)(nil), // 73: tfplugin5.GetProvisionerSchema.Response + (*ValidateProvisionerConfig_Request)(nil), // 74: tfplugin5.ValidateProvisionerConfig.Request + (*ValidateProvisionerConfig_Response)(nil), // 75: tfplugin5.ValidateProvisionerConfig.Response + (*ProvisionResource_Request)(nil), // 76: tfplugin5.ProvisionResource.Request + (*ProvisionResource_Response)(nil), // 77: tfplugin5.ProvisionResource.Response + (*GetFunctions_Request)(nil), // 78: tfplugin5.GetFunctions.Request + (*GetFunctions_Response)(nil), // 79: tfplugin5.GetFunctions.Response + nil, // 80: tfplugin5.GetFunctions.Response.FunctionsEntry + (*CallFunction_Request)(nil), // 81: tfplugin5.CallFunction.Request + (*CallFunction_Response)(nil), // 82: tfplugin5.CallFunction.Response } var file_tfplugin5_proto_depIdxs = []int32{ - 1, // 0: tfplugin5.Diagnostic.severity:type_name -> tfplugin5.Diagnostic.Severity - 5, // 1: tfplugin5.Diagnostic.attribute:type_name -> tfplugin5.AttributePath - 23, // 2: tfplugin5.AttributePath.steps:type_name -> tfplugin5.AttributePath.Step - 26, // 3: tfplugin5.RawState.flatmap:type_name -> tfplugin5.RawState.FlatmapEntry - 27, // 4: tfplugin5.Schema.block:type_name -> tfplugin5.Schema.Block - 28, // 5: tfplugin5.Schema.Block.attributes:type_name -> tfplugin5.Schema.Attribute - 29, // 6: tfplugin5.Schema.Block.block_types:type_name -> tfplugin5.Schema.NestedBlock - 0, // 7: tfplugin5.Schema.Block.description_kind:type_name -> tfplugin5.StringKind - 0, // 8: tfplugin5.Schema.Attribute.description_kind:type_name -> tfplugin5.StringKind - 27, // 9: tfplugin5.Schema.NestedBlock.block:type_name -> tfplugin5.Schema.Block - 2, // 10: tfplugin5.Schema.NestedBlock.nesting:type_name -> tfplugin5.Schema.NestedBlock.NestingMode - 8, // 11: tfplugin5.GetProviderSchema.Response.provider:type_name -> tfplugin5.Schema - 33, // 12: tfplugin5.GetProviderSchema.Response.resource_schemas:type_name -> tfplugin5.GetProviderSchema.Response.ResourceSchemasEntry - 34, // 13: tfplugin5.GetProviderSchema.Response.data_source_schemas:type_name -> tfplugin5.GetProviderSchema.Response.DataSourceSchemasEntry - 4, // 14: tfplugin5.GetProviderSchema.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 8, // 15: tfplugin5.GetProviderSchema.Response.provider_meta:type_name -> tfplugin5.Schema - 32, // 16: tfplugin5.GetProviderSchema.Response.server_capabilities:type_name -> tfplugin5.GetProviderSchema.ServerCapabilities - 8, // 17: tfplugin5.GetProviderSchema.Response.ResourceSchemasEntry.value:type_name -> tfplugin5.Schema - 8, // 18: tfplugin5.GetProviderSchema.Response.DataSourceSchemasEntry.value:type_name -> tfplugin5.Schema - 3, // 19: tfplugin5.PrepareProviderConfig.Request.config:type_name -> tfplugin5.DynamicValue - 3, // 20: tfplugin5.PrepareProviderConfig.Response.prepared_config:type_name -> tfplugin5.DynamicValue - 4, // 21: tfplugin5.PrepareProviderConfig.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 7, // 22: tfplugin5.UpgradeResourceState.Request.raw_state:type_name -> tfplugin5.RawState - 3, // 23: tfplugin5.UpgradeResourceState.Response.upgraded_state:type_name -> tfplugin5.DynamicValue - 4, // 24: tfplugin5.UpgradeResourceState.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 3, // 25: tfplugin5.ValidateResourceTypeConfig.Request.config:type_name -> tfplugin5.DynamicValue - 4, // 26: tfplugin5.ValidateResourceTypeConfig.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 3, // 27: tfplugin5.ValidateDataSourceConfig.Request.config:type_name -> tfplugin5.DynamicValue - 4, // 28: tfplugin5.ValidateDataSourceConfig.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 3, // 29: tfplugin5.Configure.Request.config:type_name -> tfplugin5.DynamicValue - 4, // 30: tfplugin5.Configure.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 3, // 31: tfplugin5.ReadResource.Request.current_state:type_name -> tfplugin5.DynamicValue - 3, // 32: tfplugin5.ReadResource.Request.provider_meta:type_name -> tfplugin5.DynamicValue - 3, // 33: tfplugin5.ReadResource.Response.new_state:type_name -> tfplugin5.DynamicValue - 4, // 34: tfplugin5.ReadResource.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 3, // 35: tfplugin5.PlanResourceChange.Request.prior_state:type_name -> tfplugin5.DynamicValue - 3, // 36: tfplugin5.PlanResourceChange.Request.proposed_new_state:type_name -> tfplugin5.DynamicValue - 3, // 37: tfplugin5.PlanResourceChange.Request.config:type_name -> tfplugin5.DynamicValue - 3, // 38: tfplugin5.PlanResourceChange.Request.provider_meta:type_name -> tfplugin5.DynamicValue - 3, // 39: tfplugin5.PlanResourceChange.Response.planned_state:type_name -> tfplugin5.DynamicValue - 5, // 40: tfplugin5.PlanResourceChange.Response.requires_replace:type_name -> tfplugin5.AttributePath - 4, // 41: tfplugin5.PlanResourceChange.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 3, // 42: tfplugin5.ApplyResourceChange.Request.prior_state:type_name -> tfplugin5.DynamicValue - 3, // 43: tfplugin5.ApplyResourceChange.Request.planned_state:type_name -> tfplugin5.DynamicValue - 3, // 44: tfplugin5.ApplyResourceChange.Request.config:type_name -> tfplugin5.DynamicValue - 3, // 45: tfplugin5.ApplyResourceChange.Request.provider_meta:type_name -> tfplugin5.DynamicValue - 3, // 46: tfplugin5.ApplyResourceChange.Response.new_state:type_name -> tfplugin5.DynamicValue - 4, // 47: tfplugin5.ApplyResourceChange.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 3, // 48: tfplugin5.ImportResourceState.ImportedResource.state:type_name -> tfplugin5.DynamicValue - 52, // 49: tfplugin5.ImportResourceState.Response.imported_resources:type_name -> tfplugin5.ImportResourceState.ImportedResource - 4, // 50: tfplugin5.ImportResourceState.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 3, // 51: tfplugin5.ReadDataSource.Request.config:type_name -> tfplugin5.DynamicValue - 3, // 52: tfplugin5.ReadDataSource.Request.provider_meta:type_name -> tfplugin5.DynamicValue - 3, // 53: tfplugin5.ReadDataSource.Response.state:type_name -> tfplugin5.DynamicValue - 4, // 54: tfplugin5.ReadDataSource.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 8, // 55: tfplugin5.GetProvisionerSchema.Response.provisioner:type_name -> tfplugin5.Schema - 4, // 56: tfplugin5.GetProvisionerSchema.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 3, // 57: tfplugin5.ValidateProvisionerConfig.Request.config:type_name -> tfplugin5.DynamicValue - 4, // 58: tfplugin5.ValidateProvisionerConfig.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 3, // 59: tfplugin5.ProvisionResource.Request.config:type_name -> tfplugin5.DynamicValue - 3, // 60: tfplugin5.ProvisionResource.Request.connection:type_name -> tfplugin5.DynamicValue - 4, // 61: tfplugin5.ProvisionResource.Response.diagnostics:type_name -> tfplugin5.Diagnostic - 30, // 62: tfplugin5.Provider.GetSchema:input_type -> tfplugin5.GetProviderSchema.Request - 35, // 63: tfplugin5.Provider.PrepareProviderConfig:input_type -> tfplugin5.PrepareProviderConfig.Request - 39, // 64: tfplugin5.Provider.ValidateResourceTypeConfig:input_type -> tfplugin5.ValidateResourceTypeConfig.Request - 41, // 65: tfplugin5.Provider.ValidateDataSourceConfig:input_type -> tfplugin5.ValidateDataSourceConfig.Request - 37, // 66: tfplugin5.Provider.UpgradeResourceState:input_type -> tfplugin5.UpgradeResourceState.Request - 43, // 67: tfplugin5.Provider.Configure:input_type -> tfplugin5.Configure.Request - 45, // 68: tfplugin5.Provider.ReadResource:input_type -> tfplugin5.ReadResource.Request - 47, // 69: tfplugin5.Provider.PlanResourceChange:input_type -> tfplugin5.PlanResourceChange.Request - 49, // 70: tfplugin5.Provider.ApplyResourceChange:input_type -> tfplugin5.ApplyResourceChange.Request - 51, // 71: tfplugin5.Provider.ImportResourceState:input_type -> tfplugin5.ImportResourceState.Request - 54, // 72: tfplugin5.Provider.ReadDataSource:input_type -> tfplugin5.ReadDataSource.Request - 24, // 73: tfplugin5.Provider.Stop:input_type -> tfplugin5.Stop.Request - 56, // 74: tfplugin5.Provisioner.GetSchema:input_type -> tfplugin5.GetProvisionerSchema.Request - 58, // 75: tfplugin5.Provisioner.ValidateProvisionerConfig:input_type -> tfplugin5.ValidateProvisionerConfig.Request - 60, // 76: tfplugin5.Provisioner.ProvisionResource:input_type -> tfplugin5.ProvisionResource.Request - 24, // 77: tfplugin5.Provisioner.Stop:input_type -> tfplugin5.Stop.Request - 31, // 78: tfplugin5.Provider.GetSchema:output_type -> tfplugin5.GetProviderSchema.Response - 36, // 79: tfplugin5.Provider.PrepareProviderConfig:output_type -> tfplugin5.PrepareProviderConfig.Response - 40, // 80: tfplugin5.Provider.ValidateResourceTypeConfig:output_type -> tfplugin5.ValidateResourceTypeConfig.Response - 42, // 81: tfplugin5.Provider.ValidateDataSourceConfig:output_type -> tfplugin5.ValidateDataSourceConfig.Response - 38, // 82: tfplugin5.Provider.UpgradeResourceState:output_type -> tfplugin5.UpgradeResourceState.Response - 44, // 83: tfplugin5.Provider.Configure:output_type -> tfplugin5.Configure.Response - 46, // 84: tfplugin5.Provider.ReadResource:output_type -> tfplugin5.ReadResource.Response - 48, // 85: tfplugin5.Provider.PlanResourceChange:output_type -> tfplugin5.PlanResourceChange.Response - 50, // 86: tfplugin5.Provider.ApplyResourceChange:output_type -> tfplugin5.ApplyResourceChange.Response - 53, // 87: tfplugin5.Provider.ImportResourceState:output_type -> tfplugin5.ImportResourceState.Response - 55, // 88: tfplugin5.Provider.ReadDataSource:output_type -> tfplugin5.ReadDataSource.Response - 25, // 89: tfplugin5.Provider.Stop:output_type -> tfplugin5.Stop.Response - 57, // 90: tfplugin5.Provisioner.GetSchema:output_type -> tfplugin5.GetProvisionerSchema.Response - 59, // 91: tfplugin5.Provisioner.ValidateProvisionerConfig:output_type -> tfplugin5.ValidateProvisionerConfig.Response - 61, // 92: tfplugin5.Provisioner.ProvisionResource:output_type -> tfplugin5.ProvisionResource.Response - 25, // 93: tfplugin5.Provisioner.Stop:output_type -> tfplugin5.Stop.Response - 78, // [78:94] is the sub-list for method output_type - 62, // [62:78] is the sub-list for method input_type - 62, // [62:62] is the sub-list for extension type_name - 62, // [62:62] is the sub-list for extension extendee - 0, // [0:62] is the sub-list for field type_name + 1, // 0: tfplugin5.Diagnostic.severity:type_name -> tfplugin5.Diagnostic.Severity + 6, // 1: tfplugin5.Diagnostic.attribute:type_name -> tfplugin5.AttributePath + 30, // 2: tfplugin5.AttributePath.steps:type_name -> tfplugin5.AttributePath.Step + 33, // 3: tfplugin5.RawState.flatmap:type_name -> tfplugin5.RawState.FlatmapEntry + 34, // 4: tfplugin5.Schema.block:type_name -> tfplugin5.Schema.Block + 37, // 5: tfplugin5.Function.parameters:type_name -> tfplugin5.Function.Parameter + 37, // 6: tfplugin5.Function.variadic_parameter:type_name -> tfplugin5.Function.Parameter + 38, // 7: tfplugin5.Function.return:type_name -> tfplugin5.Function.Return + 0, // 8: tfplugin5.Function.description_kind:type_name -> tfplugin5.StringKind + 35, // 9: tfplugin5.Schema.Block.attributes:type_name -> tfplugin5.Schema.Attribute + 36, // 10: tfplugin5.Schema.Block.block_types:type_name -> tfplugin5.Schema.NestedBlock + 0, // 11: tfplugin5.Schema.Block.description_kind:type_name -> tfplugin5.StringKind + 0, // 12: tfplugin5.Schema.Attribute.description_kind:type_name -> tfplugin5.StringKind + 34, // 13: tfplugin5.Schema.NestedBlock.block:type_name -> tfplugin5.Schema.Block + 2, // 14: tfplugin5.Schema.NestedBlock.nesting:type_name -> tfplugin5.Schema.NestedBlock.NestingMode + 0, // 15: tfplugin5.Function.Parameter.description_kind:type_name -> tfplugin5.StringKind + 10, // 16: tfplugin5.GetMetadata.Response.server_capabilities:type_name -> tfplugin5.ServerCapabilities + 4, // 17: tfplugin5.GetMetadata.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 42, // 18: tfplugin5.GetMetadata.Response.data_sources:type_name -> tfplugin5.GetMetadata.DataSourceMetadata + 43, // 19: tfplugin5.GetMetadata.Response.resources:type_name -> tfplugin5.GetMetadata.ResourceMetadata + 41, // 20: tfplugin5.GetMetadata.Response.functions:type_name -> tfplugin5.GetMetadata.FunctionMetadata + 9, // 21: tfplugin5.GetProviderSchema.Response.provider:type_name -> tfplugin5.Schema + 46, // 22: tfplugin5.GetProviderSchema.Response.resource_schemas:type_name -> tfplugin5.GetProviderSchema.Response.ResourceSchemasEntry + 47, // 23: tfplugin5.GetProviderSchema.Response.data_source_schemas:type_name -> tfplugin5.GetProviderSchema.Response.DataSourceSchemasEntry + 4, // 24: tfplugin5.GetProviderSchema.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 9, // 25: tfplugin5.GetProviderSchema.Response.provider_meta:type_name -> tfplugin5.Schema + 10, // 26: tfplugin5.GetProviderSchema.Response.server_capabilities:type_name -> tfplugin5.ServerCapabilities + 48, // 27: tfplugin5.GetProviderSchema.Response.functions:type_name -> tfplugin5.GetProviderSchema.Response.FunctionsEntry + 9, // 28: tfplugin5.GetProviderSchema.Response.ResourceSchemasEntry.value:type_name -> tfplugin5.Schema + 9, // 29: tfplugin5.GetProviderSchema.Response.DataSourceSchemasEntry.value:type_name -> tfplugin5.Schema + 11, // 30: tfplugin5.GetProviderSchema.Response.FunctionsEntry.value:type_name -> tfplugin5.Function + 3, // 31: tfplugin5.PrepareProviderConfig.Request.config:type_name -> tfplugin5.DynamicValue + 3, // 32: tfplugin5.PrepareProviderConfig.Response.prepared_config:type_name -> tfplugin5.DynamicValue + 4, // 33: tfplugin5.PrepareProviderConfig.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 8, // 34: tfplugin5.UpgradeResourceState.Request.raw_state:type_name -> tfplugin5.RawState + 3, // 35: tfplugin5.UpgradeResourceState.Response.upgraded_state:type_name -> tfplugin5.DynamicValue + 4, // 36: tfplugin5.UpgradeResourceState.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 3, // 37: tfplugin5.ValidateResourceTypeConfig.Request.config:type_name -> tfplugin5.DynamicValue + 4, // 38: tfplugin5.ValidateResourceTypeConfig.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 3, // 39: tfplugin5.ValidateDataSourceConfig.Request.config:type_name -> tfplugin5.DynamicValue + 4, // 40: tfplugin5.ValidateDataSourceConfig.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 3, // 41: tfplugin5.Configure.Request.config:type_name -> tfplugin5.DynamicValue + 4, // 42: tfplugin5.Configure.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 3, // 43: tfplugin5.ReadResource.Request.current_state:type_name -> tfplugin5.DynamicValue + 3, // 44: tfplugin5.ReadResource.Request.provider_meta:type_name -> tfplugin5.DynamicValue + 3, // 45: tfplugin5.ReadResource.Response.new_state:type_name -> tfplugin5.DynamicValue + 4, // 46: tfplugin5.ReadResource.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 3, // 47: tfplugin5.PlanResourceChange.Request.prior_state:type_name -> tfplugin5.DynamicValue + 3, // 48: tfplugin5.PlanResourceChange.Request.proposed_new_state:type_name -> tfplugin5.DynamicValue + 3, // 49: tfplugin5.PlanResourceChange.Request.config:type_name -> tfplugin5.DynamicValue + 3, // 50: tfplugin5.PlanResourceChange.Request.provider_meta:type_name -> tfplugin5.DynamicValue + 3, // 51: tfplugin5.PlanResourceChange.Response.planned_state:type_name -> tfplugin5.DynamicValue + 6, // 52: tfplugin5.PlanResourceChange.Response.requires_replace:type_name -> tfplugin5.AttributePath + 4, // 53: tfplugin5.PlanResourceChange.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 3, // 54: tfplugin5.ApplyResourceChange.Request.prior_state:type_name -> tfplugin5.DynamicValue + 3, // 55: tfplugin5.ApplyResourceChange.Request.planned_state:type_name -> tfplugin5.DynamicValue + 3, // 56: tfplugin5.ApplyResourceChange.Request.config:type_name -> tfplugin5.DynamicValue + 3, // 57: tfplugin5.ApplyResourceChange.Request.provider_meta:type_name -> tfplugin5.DynamicValue + 3, // 58: tfplugin5.ApplyResourceChange.Response.new_state:type_name -> tfplugin5.DynamicValue + 4, // 59: tfplugin5.ApplyResourceChange.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 3, // 60: tfplugin5.ImportResourceState.ImportedResource.state:type_name -> tfplugin5.DynamicValue + 66, // 61: tfplugin5.ImportResourceState.Response.imported_resources:type_name -> tfplugin5.ImportResourceState.ImportedResource + 4, // 62: tfplugin5.ImportResourceState.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 8, // 63: tfplugin5.MoveResourceState.Request.source_state:type_name -> tfplugin5.RawState + 3, // 64: tfplugin5.MoveResourceState.Response.target_state:type_name -> tfplugin5.DynamicValue + 4, // 65: tfplugin5.MoveResourceState.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 3, // 66: tfplugin5.ReadDataSource.Request.config:type_name -> tfplugin5.DynamicValue + 3, // 67: tfplugin5.ReadDataSource.Request.provider_meta:type_name -> tfplugin5.DynamicValue + 3, // 68: tfplugin5.ReadDataSource.Response.state:type_name -> tfplugin5.DynamicValue + 4, // 69: tfplugin5.ReadDataSource.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 9, // 70: tfplugin5.GetProvisionerSchema.Response.provisioner:type_name -> tfplugin5.Schema + 4, // 71: tfplugin5.GetProvisionerSchema.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 3, // 72: tfplugin5.ValidateProvisionerConfig.Request.config:type_name -> tfplugin5.DynamicValue + 4, // 73: tfplugin5.ValidateProvisionerConfig.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 3, // 74: tfplugin5.ProvisionResource.Request.config:type_name -> tfplugin5.DynamicValue + 3, // 75: tfplugin5.ProvisionResource.Request.connection:type_name -> tfplugin5.DynamicValue + 4, // 76: tfplugin5.ProvisionResource.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 80, // 77: tfplugin5.GetFunctions.Response.functions:type_name -> tfplugin5.GetFunctions.Response.FunctionsEntry + 4, // 78: tfplugin5.GetFunctions.Response.diagnostics:type_name -> tfplugin5.Diagnostic + 11, // 79: tfplugin5.GetFunctions.Response.FunctionsEntry.value:type_name -> tfplugin5.Function + 3, // 80: tfplugin5.CallFunction.Request.arguments:type_name -> tfplugin5.DynamicValue + 3, // 81: tfplugin5.CallFunction.Response.result:type_name -> tfplugin5.DynamicValue + 5, // 82: tfplugin5.CallFunction.Response.error:type_name -> tfplugin5.FunctionError + 39, // 83: tfplugin5.Provider.GetMetadata:input_type -> tfplugin5.GetMetadata.Request + 44, // 84: tfplugin5.Provider.GetSchema:input_type -> tfplugin5.GetProviderSchema.Request + 49, // 85: tfplugin5.Provider.PrepareProviderConfig:input_type -> tfplugin5.PrepareProviderConfig.Request + 53, // 86: tfplugin5.Provider.ValidateResourceTypeConfig:input_type -> tfplugin5.ValidateResourceTypeConfig.Request + 55, // 87: tfplugin5.Provider.ValidateDataSourceConfig:input_type -> tfplugin5.ValidateDataSourceConfig.Request + 51, // 88: tfplugin5.Provider.UpgradeResourceState:input_type -> tfplugin5.UpgradeResourceState.Request + 57, // 89: tfplugin5.Provider.Configure:input_type -> tfplugin5.Configure.Request + 59, // 90: tfplugin5.Provider.ReadResource:input_type -> tfplugin5.ReadResource.Request + 61, // 91: tfplugin5.Provider.PlanResourceChange:input_type -> tfplugin5.PlanResourceChange.Request + 63, // 92: tfplugin5.Provider.ApplyResourceChange:input_type -> tfplugin5.ApplyResourceChange.Request + 65, // 93: tfplugin5.Provider.ImportResourceState:input_type -> tfplugin5.ImportResourceState.Request + 68, // 94: tfplugin5.Provider.MoveResourceState:input_type -> tfplugin5.MoveResourceState.Request + 70, // 95: tfplugin5.Provider.ReadDataSource:input_type -> tfplugin5.ReadDataSource.Request + 78, // 96: tfplugin5.Provider.GetFunctions:input_type -> tfplugin5.GetFunctions.Request + 81, // 97: tfplugin5.Provider.CallFunction:input_type -> tfplugin5.CallFunction.Request + 31, // 98: tfplugin5.Provider.Stop:input_type -> tfplugin5.Stop.Request + 72, // 99: tfplugin5.Provisioner.GetSchema:input_type -> tfplugin5.GetProvisionerSchema.Request + 74, // 100: tfplugin5.Provisioner.ValidateProvisionerConfig:input_type -> tfplugin5.ValidateProvisionerConfig.Request + 76, // 101: tfplugin5.Provisioner.ProvisionResource:input_type -> tfplugin5.ProvisionResource.Request + 31, // 102: tfplugin5.Provisioner.Stop:input_type -> tfplugin5.Stop.Request + 40, // 103: tfplugin5.Provider.GetMetadata:output_type -> tfplugin5.GetMetadata.Response + 45, // 104: tfplugin5.Provider.GetSchema:output_type -> tfplugin5.GetProviderSchema.Response + 50, // 105: tfplugin5.Provider.PrepareProviderConfig:output_type -> tfplugin5.PrepareProviderConfig.Response + 54, // 106: tfplugin5.Provider.ValidateResourceTypeConfig:output_type -> tfplugin5.ValidateResourceTypeConfig.Response + 56, // 107: tfplugin5.Provider.ValidateDataSourceConfig:output_type -> tfplugin5.ValidateDataSourceConfig.Response + 52, // 108: tfplugin5.Provider.UpgradeResourceState:output_type -> tfplugin5.UpgradeResourceState.Response + 58, // 109: tfplugin5.Provider.Configure:output_type -> tfplugin5.Configure.Response + 60, // 110: tfplugin5.Provider.ReadResource:output_type -> tfplugin5.ReadResource.Response + 62, // 111: tfplugin5.Provider.PlanResourceChange:output_type -> tfplugin5.PlanResourceChange.Response + 64, // 112: tfplugin5.Provider.ApplyResourceChange:output_type -> tfplugin5.ApplyResourceChange.Response + 67, // 113: tfplugin5.Provider.ImportResourceState:output_type -> tfplugin5.ImportResourceState.Response + 69, // 114: tfplugin5.Provider.MoveResourceState:output_type -> tfplugin5.MoveResourceState.Response + 71, // 115: tfplugin5.Provider.ReadDataSource:output_type -> tfplugin5.ReadDataSource.Response + 79, // 116: tfplugin5.Provider.GetFunctions:output_type -> tfplugin5.GetFunctions.Response + 82, // 117: tfplugin5.Provider.CallFunction:output_type -> tfplugin5.CallFunction.Response + 32, // 118: tfplugin5.Provider.Stop:output_type -> tfplugin5.Stop.Response + 73, // 119: tfplugin5.Provisioner.GetSchema:output_type -> tfplugin5.GetProvisionerSchema.Response + 75, // 120: tfplugin5.Provisioner.ValidateProvisionerConfig:output_type -> tfplugin5.ValidateProvisionerConfig.Response + 77, // 121: tfplugin5.Provisioner.ProvisionResource:output_type -> tfplugin5.ProvisionResource.Response + 32, // 122: tfplugin5.Provisioner.Stop:output_type -> tfplugin5.Stop.Response + 103, // [103:123] is the sub-list for method output_type + 83, // [83:103] is the sub-list for method input_type + 83, // [83:83] is the sub-list for extension type_name + 83, // [83:83] is the sub-list for extension extendee + 0, // [0:83] is the sub-list for field type_name } func init() { file_tfplugin5_proto_init() } @@ -4020,8 +5372,92 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Diagnostic); i { + file_tfplugin5_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Diagnostic); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FunctionError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AttributePath); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Stop); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RawState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Schema); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerCapabilities); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Function); i { case 0: return &v.state case 1: @@ -4032,8 +5468,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AttributePath); i { + file_tfplugin5_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata); i { case 0: return &v.state case 1: @@ -4044,8 +5480,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Stop); i { + file_tfplugin5_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProviderSchema); i { case 0: return &v.state case 1: @@ -4056,8 +5492,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RawState); i { + file_tfplugin5_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PrepareProviderConfig); i { case 0: return &v.state case 1: @@ -4068,8 +5504,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Schema); i { + file_tfplugin5_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpgradeResourceState); i { case 0: return &v.state case 1: @@ -4080,8 +5516,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProviderSchema); i { + file_tfplugin5_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateResourceTypeConfig); i { case 0: return &v.state case 1: @@ -4092,8 +5528,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PrepareProviderConfig); i { + file_tfplugin5_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateDataSourceConfig); i { case 0: return &v.state case 1: @@ -4104,8 +5540,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpgradeResourceState); i { + file_tfplugin5_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configure); i { case 0: return &v.state case 1: @@ -4116,8 +5552,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateResourceTypeConfig); i { + file_tfplugin5_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadResource); i { case 0: return &v.state case 1: @@ -4128,8 +5564,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateDataSourceConfig); i { + file_tfplugin5_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlanResourceChange); i { case 0: return &v.state case 1: @@ -4140,8 +5576,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Configure); i { + file_tfplugin5_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyResourceChange); i { case 0: return &v.state case 1: @@ -4152,8 +5588,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadResource); i { + file_tfplugin5_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ImportResourceState); i { case 0: return &v.state case 1: @@ -4164,8 +5600,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlanResourceChange); i { + file_tfplugin5_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MoveResourceState); i { case 0: return &v.state case 1: @@ -4176,8 +5612,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApplyResourceChange); i { + file_tfplugin5_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadDataSource); i { case 0: return &v.state case 1: @@ -4188,8 +5624,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ImportResourceState); i { + file_tfplugin5_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProvisionerSchema); i { case 0: return &v.state case 1: @@ -4200,8 +5636,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReadDataSource); i { + file_tfplugin5_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateProvisionerConfig); i { case 0: return &v.state case 1: @@ -4212,8 +5648,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProvisionerSchema); i { + file_tfplugin5_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProvisionResource); i { case 0: return &v.state case 1: @@ -4224,8 +5660,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateProvisionerConfig); i { + file_tfplugin5_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFunctions); i { case 0: return &v.state case 1: @@ -4236,8 +5672,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProvisionResource); i { + file_tfplugin5_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CallFunction); i { case 0: return &v.state case 1: @@ -4248,7 +5684,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AttributePath_Step); i { case 0: return &v.state @@ -4260,7 +5696,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Stop_Request); i { case 0: return &v.state @@ -4272,7 +5708,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Stop_Response); i { case 0: return &v.state @@ -4284,7 +5720,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Schema_Block); i { case 0: return &v.state @@ -4296,7 +5732,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Schema_Attribute); i { case 0: return &v.state @@ -4308,7 +5744,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Schema_NestedBlock); i { case 0: return &v.state @@ -4320,8 +5756,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProviderSchema_Request); i { + file_tfplugin5_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Function_Parameter); i { case 0: return &v.state case 1: @@ -4332,8 +5768,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProviderSchema_Response); i { + file_tfplugin5_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Function_Return); i { case 0: return &v.state case 1: @@ -4344,8 +5780,8 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProviderSchema_ServerCapabilities); i { + file_tfplugin5_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata_Request); i { case 0: return &v.state case 1: @@ -4356,7 +5792,79 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata_FunctionMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata_DataSourceMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata_ResourceMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProviderSchema_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProviderSchema_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PrepareProviderConfig_Request); i { case 0: return &v.state @@ -4368,7 +5876,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PrepareProviderConfig_Response); i { case 0: return &v.state @@ -4380,7 +5888,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpgradeResourceState_Request); i { case 0: return &v.state @@ -4392,7 +5900,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpgradeResourceState_Response); i { case 0: return &v.state @@ -4404,7 +5912,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateResourceTypeConfig_Request); i { case 0: return &v.state @@ -4416,7 +5924,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateResourceTypeConfig_Response); i { case 0: return &v.state @@ -4428,7 +5936,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateDataSourceConfig_Request); i { case 0: return &v.state @@ -4440,7 +5948,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateDataSourceConfig_Response); i { case 0: return &v.state @@ -4452,7 +5960,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Configure_Request); i { case 0: return &v.state @@ -4464,7 +5972,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Configure_Response); i { case 0: return &v.state @@ -4476,7 +5984,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadResource_Request); i { case 0: return &v.state @@ -4488,7 +5996,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadResource_Response); i { case 0: return &v.state @@ -4500,7 +6008,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlanResourceChange_Request); i { case 0: return &v.state @@ -4512,7 +6020,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlanResourceChange_Response); i { case 0: return &v.state @@ -4524,7 +6032,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyResourceChange_Request); i { case 0: return &v.state @@ -4536,7 +6044,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyResourceChange_Response); i { case 0: return &v.state @@ -4548,7 +6056,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ImportResourceState_Request); i { case 0: return &v.state @@ -4560,7 +6068,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ImportResourceState_ImportedResource); i { case 0: return &v.state @@ -4572,7 +6080,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ImportResourceState_Response); i { case 0: return &v.state @@ -4584,7 +6092,31 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MoveResourceState_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MoveResourceState_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadDataSource_Request); i { case 0: return &v.state @@ -4596,7 +6128,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadDataSource_Response); i { case 0: return &v.state @@ -4608,7 +6140,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetProvisionerSchema_Request); i { case 0: return &v.state @@ -4620,7 +6152,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetProvisionerSchema_Response); i { case 0: return &v.state @@ -4632,7 +6164,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateProvisionerConfig_Request); i { case 0: return &v.state @@ -4644,7 +6176,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateProvisionerConfig_Response); i { case 0: return &v.state @@ -4656,7 +6188,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProvisionResource_Request); i { case 0: return &v.state @@ -4668,7 +6200,7 @@ func file_tfplugin5_proto_init() { return nil } } - file_tfplugin5_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin5_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProvisionResource_Response); i { case 0: return &v.state @@ -4680,8 +6212,57 @@ func file_tfplugin5_proto_init() { return nil } } + file_tfplugin5_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFunctions_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFunctions_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CallFunction_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin5_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CallFunction_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } - file_tfplugin5_proto_msgTypes[20].OneofWrappers = []interface{}{ + file_tfplugin5_proto_msgTypes[2].OneofWrappers = []interface{}{} + file_tfplugin5_proto_msgTypes[27].OneofWrappers = []interface{}{ (*AttributePath_Step_AttributeName)(nil), (*AttributePath_Step_ElementKeyString)(nil), (*AttributePath_Step_ElementKeyInt)(nil), @@ -4692,7 +6273,7 @@ func file_tfplugin5_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tfplugin5_proto_rawDesc, NumEnums: 3, - NumMessages: 59, + NumMessages: 80, NumExtensions: 0, NumServices: 2, }, diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5.proto b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5.proto index f79feee4..1266a510 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5.proto +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5.proto @@ -1,9 +1,9 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -// Terraform Plugin RPC protocol version 5.3 +// Terraform Plugin RPC protocol version 5.5 // -// This file defines version 5.3 of the RPC protocol. To implement a plugin +// This file defines version 5.5 of the RPC protocol. To implement a plugin // against this protocol, copy this definition into your own codebase and // use protoc to generate stubs for your target language. // @@ -20,9 +20,9 @@ // branch or any other development branch. // syntax = "proto3"; +option go_package = "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5"; package tfplugin5; -option go_package = "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5"; // DynamicValue is an opaque encoding of terraform data, with the field name // indicating the encoding scheme used. @@ -43,6 +43,13 @@ message Diagnostic { AttributePath attribute = 4; } +message FunctionError { + string text = 1; + // The optional function_argument records the index position of the + // argument which caused the error. + optional int64 function_argument = 2; +} + message AttributePath { message Step { oneof selector { @@ -128,8 +135,94 @@ message Schema { Block block = 2; } +// ServerCapabilities allows providers to communicate extra information +// regarding supported protocol features. This is used to indicate +// availability of certain forward-compatible changes which may be optional +// in a major protocol version, but cannot be tested for directly. +message ServerCapabilities { + // The plan_destroy capability signals that a provider expects a call + // to PlanResourceChange when a resource is going to be destroyed. + bool plan_destroy = 1; + + // The get_provider_schema_optional capability indicates that this + // provider does not require calling GetProviderSchema to operate + // normally, and the caller can used a cached copy of the provider's + // schema. + bool get_provider_schema_optional = 2; + + // The move_resource_state capability signals that a provider supports the + // MoveResourceState RPC. + bool move_resource_state = 3; +} + +message Function { + // parameters is the ordered list of positional function parameters. + repeated Parameter parameters = 1; + + // variadic_parameter is an optional final parameter which accepts + // zero or more argument values, in which Terraform will send an + // ordered list of the parameter type. + Parameter variadic_parameter = 2; + + // return is the function result. + Return return = 3; + + // summary is the human-readable shortened documentation for the function. + string summary = 4; + + // description is human-readable documentation for the function. + string description = 5; + + // description_kind is the formatting of the description. + StringKind description_kind = 6; + + // deprecation_message is human-readable documentation if the + // function is deprecated. + string deprecation_message = 7; + + message Parameter { + // name is the human-readable display name for the parameter. + string name = 1; + + // type is the type constraint for the parameter. + bytes type = 2; + + // allow_null_value when enabled denotes that a null argument value can + // be passed to the provider. When disabled, Terraform returns an error + // if the argument value is null. + bool allow_null_value = 3; + + // allow_unknown_values when enabled denotes that only wholly known + // argument values will be passed to the provider. When disabled, + // Terraform skips the function call entirely and assumes an unknown + // value result from the function. + bool allow_unknown_values = 4; + + // description is human-readable documentation for the parameter. + string description = 5; + + // description_kind is the formatting of the description. + StringKind description_kind = 6; + } + + message Return { + // type is the type constraint for the function result. + bytes type = 1; + } +} + service Provider { //////// Information about what a provider supports/expects + + // GetMetadata returns upfront information about server capabilities and + // supported resource types without requiring the server to instantiate all + // schema information, which may be memory intensive. This RPC is optional, + // where clients may receive an unimplemented RPC error. Clients should + // ignore the error and call the GetSchema RPC as a fallback. + rpc GetMetadata(GetMetadata.Request) returns (GetMetadata.Response); + + // GetSchema returns schema information for the provider, data resources, + // and managed resources. rpc GetSchema(GetProviderSchema.Request) returns (GetProviderSchema.Response); rpc PrepareProviderConfig(PrepareProviderConfig.Request) returns (PrepareProviderConfig.Response); rpc ValidateResourceTypeConfig(ValidateResourceTypeConfig.Request) returns (ValidateResourceTypeConfig.Response); @@ -144,13 +237,50 @@ service Provider { rpc PlanResourceChange(PlanResourceChange.Request) returns (PlanResourceChange.Response); rpc ApplyResourceChange(ApplyResourceChange.Request) returns (ApplyResourceChange.Response); rpc ImportResourceState(ImportResourceState.Request) returns (ImportResourceState.Response); - + rpc MoveResourceState(MoveResourceState.Request) returns (MoveResourceState.Response); rpc ReadDataSource(ReadDataSource.Request) returns (ReadDataSource.Response); + // Functions + + // GetFunctions returns the definitions of all functions. + rpc GetFunctions(GetFunctions.Request) returns (GetFunctions.Response); + + // CallFunction runs the provider-defined function logic and returns + // the result with any diagnostics. + rpc CallFunction(CallFunction.Request) returns (CallFunction.Response); + //////// Graceful Shutdown rpc Stop(Stop.Request) returns (Stop.Response); } +message GetMetadata { + message Request { + } + + message Response { + ServerCapabilities server_capabilities = 1; + repeated Diagnostic diagnostics = 2; + repeated DataSourceMetadata data_sources = 3; + repeated ResourceMetadata resources = 4; + + // functions returns metadata for any functions. + repeated FunctionMetadata functions = 5; + } + + message FunctionMetadata { + // name is the function name. + string name = 1; + } + + message DataSourceMetadata { + string type_name = 1; + } + + message ResourceMetadata { + string type_name = 1; + } +} + message GetProviderSchema { message Request { } @@ -161,17 +291,9 @@ message GetProviderSchema { repeated Diagnostic diagnostics = 4; Schema provider_meta = 5; ServerCapabilities server_capabilities = 6; - } - - // ServerCapabilities allows providers to communicate extra information - // regarding supported protocol features. This is used to indicate - // availability of certain forward-compatible changes which may be optional - // in a major protocol version, but cannot be tested for directly. - message ServerCapabilities { - // The plan_destroy capability signals that a provider expects a call - // to PlanResourceChange when a resource is going to be destroyed. - bool plan_destroy = 1; + // functions is a mapping of function names to definitions. + map functions = 7; } } @@ -352,6 +474,42 @@ message ImportResourceState { } } +message MoveResourceState { + message Request { + // The address of the provider the resource is being moved from. + string source_provider_address = 1; + + // The resource type that the resource is being moved from. + string source_type_name = 2; + + // The schema version of the resource type that the resource is being + // moved from. + int64 source_schema_version = 3; + + // The raw state of the resource being moved. Only the json field is + // populated, as there should be no legacy providers using the flatmap + // format that support newly introduced RPCs. + RawState source_state = 4; + + // The resource type that the resource is being moved to. + string target_type_name = 5; + + // The private state of the resource being moved. + bytes source_private = 6; + } + + message Response { + // The state of the resource after it has been moved. + DynamicValue target_state = 1; + + // Any diagnostics that occurred during the move. + repeated Diagnostic diagnostics = 2; + + // The private state of the resource after it has been moved. + bytes target_private = 3; + } +} + message ReadDataSource { message Request { string type_name = 1; @@ -399,3 +557,33 @@ message ProvisionResource { repeated Diagnostic diagnostics = 2; } } + +message GetFunctions { + message Request {} + + message Response { + // functions is a mapping of function names to definitions. + map functions = 1; + + // diagnostics is any warnings or errors. + repeated Diagnostic diagnostics = 2; + } +} + +message CallFunction { + message Request { + // name is the name of the function being called. + string name = 1; + + // arguments is the data of each function argument value. + repeated DynamicValue arguments = 2; + } + + message Response { + // result is result value after running the function logic. + DynamicValue result = 1; + + // error is any error from the function logic. + FunctionError error = 2; + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go index 548f9661..fc016846 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go @@ -1,9 +1,9 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -// Terraform Plugin RPC protocol version 5.3 +// Terraform Plugin RPC protocol version 5.5 // -// This file defines version 5.3 of the RPC protocol. To implement a plugin +// This file defines version 5.5 of the RPC protocol. To implement a plugin // against this protocol, copy this definition into your own codebase and // use protoc to generate stubs for your target language. // @@ -23,7 +23,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v4.23.2 +// - protoc v4.25.1 // source: tfplugin5.proto package tfplugin5 @@ -41,6 +41,7 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( + Provider_GetMetadata_FullMethodName = "/tfplugin5.Provider/GetMetadata" Provider_GetSchema_FullMethodName = "/tfplugin5.Provider/GetSchema" Provider_PrepareProviderConfig_FullMethodName = "/tfplugin5.Provider/PrepareProviderConfig" Provider_ValidateResourceTypeConfig_FullMethodName = "/tfplugin5.Provider/ValidateResourceTypeConfig" @@ -51,7 +52,10 @@ const ( Provider_PlanResourceChange_FullMethodName = "/tfplugin5.Provider/PlanResourceChange" Provider_ApplyResourceChange_FullMethodName = "/tfplugin5.Provider/ApplyResourceChange" Provider_ImportResourceState_FullMethodName = "/tfplugin5.Provider/ImportResourceState" + Provider_MoveResourceState_FullMethodName = "/tfplugin5.Provider/MoveResourceState" Provider_ReadDataSource_FullMethodName = "/tfplugin5.Provider/ReadDataSource" + Provider_GetFunctions_FullMethodName = "/tfplugin5.Provider/GetFunctions" + Provider_CallFunction_FullMethodName = "/tfplugin5.Provider/CallFunction" Provider_Stop_FullMethodName = "/tfplugin5.Provider/Stop" ) @@ -59,7 +63,14 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ProviderClient interface { - // ////// Information about what a provider supports/expects + // GetMetadata returns upfront information about server capabilities and + // supported resource types without requiring the server to instantiate all + // schema information, which may be memory intensive. This RPC is optional, + // where clients may receive an unimplemented RPC error. Clients should + // ignore the error and call the GetSchema RPC as a fallback. + GetMetadata(ctx context.Context, in *GetMetadata_Request, opts ...grpc.CallOption) (*GetMetadata_Response, error) + // GetSchema returns schema information for the provider, data resources, + // and managed resources. GetSchema(ctx context.Context, in *GetProviderSchema_Request, opts ...grpc.CallOption) (*GetProviderSchema_Response, error) PrepareProviderConfig(ctx context.Context, in *PrepareProviderConfig_Request, opts ...grpc.CallOption) (*PrepareProviderConfig_Response, error) ValidateResourceTypeConfig(ctx context.Context, in *ValidateResourceTypeConfig_Request, opts ...grpc.CallOption) (*ValidateResourceTypeConfig_Response, error) @@ -72,7 +83,13 @@ type ProviderClient interface { PlanResourceChange(ctx context.Context, in *PlanResourceChange_Request, opts ...grpc.CallOption) (*PlanResourceChange_Response, error) ApplyResourceChange(ctx context.Context, in *ApplyResourceChange_Request, opts ...grpc.CallOption) (*ApplyResourceChange_Response, error) ImportResourceState(ctx context.Context, in *ImportResourceState_Request, opts ...grpc.CallOption) (*ImportResourceState_Response, error) + MoveResourceState(ctx context.Context, in *MoveResourceState_Request, opts ...grpc.CallOption) (*MoveResourceState_Response, error) ReadDataSource(ctx context.Context, in *ReadDataSource_Request, opts ...grpc.CallOption) (*ReadDataSource_Response, error) + // GetFunctions returns the definitions of all functions. + GetFunctions(ctx context.Context, in *GetFunctions_Request, opts ...grpc.CallOption) (*GetFunctions_Response, error) + // CallFunction runs the provider-defined function logic and returns + // the result with any diagnostics. + CallFunction(ctx context.Context, in *CallFunction_Request, opts ...grpc.CallOption) (*CallFunction_Response, error) // ////// Graceful Shutdown Stop(ctx context.Context, in *Stop_Request, opts ...grpc.CallOption) (*Stop_Response, error) } @@ -85,6 +102,15 @@ func NewProviderClient(cc grpc.ClientConnInterface) ProviderClient { return &providerClient{cc} } +func (c *providerClient) GetMetadata(ctx context.Context, in *GetMetadata_Request, opts ...grpc.CallOption) (*GetMetadata_Response, error) { + out := new(GetMetadata_Response) + err := c.cc.Invoke(ctx, Provider_GetMetadata_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *providerClient) GetSchema(ctx context.Context, in *GetProviderSchema_Request, opts ...grpc.CallOption) (*GetProviderSchema_Response, error) { out := new(GetProviderSchema_Response) err := c.cc.Invoke(ctx, Provider_GetSchema_FullMethodName, in, out, opts...) @@ -175,6 +201,15 @@ func (c *providerClient) ImportResourceState(ctx context.Context, in *ImportReso return out, nil } +func (c *providerClient) MoveResourceState(ctx context.Context, in *MoveResourceState_Request, opts ...grpc.CallOption) (*MoveResourceState_Response, error) { + out := new(MoveResourceState_Response) + err := c.cc.Invoke(ctx, Provider_MoveResourceState_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *providerClient) ReadDataSource(ctx context.Context, in *ReadDataSource_Request, opts ...grpc.CallOption) (*ReadDataSource_Response, error) { out := new(ReadDataSource_Response) err := c.cc.Invoke(ctx, Provider_ReadDataSource_FullMethodName, in, out, opts...) @@ -184,6 +219,24 @@ func (c *providerClient) ReadDataSource(ctx context.Context, in *ReadDataSource_ return out, nil } +func (c *providerClient) GetFunctions(ctx context.Context, in *GetFunctions_Request, opts ...grpc.CallOption) (*GetFunctions_Response, error) { + out := new(GetFunctions_Response) + err := c.cc.Invoke(ctx, Provider_GetFunctions_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) CallFunction(ctx context.Context, in *CallFunction_Request, opts ...grpc.CallOption) (*CallFunction_Response, error) { + out := new(CallFunction_Response) + err := c.cc.Invoke(ctx, Provider_CallFunction_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *providerClient) Stop(ctx context.Context, in *Stop_Request, opts ...grpc.CallOption) (*Stop_Response, error) { out := new(Stop_Response) err := c.cc.Invoke(ctx, Provider_Stop_FullMethodName, in, out, opts...) @@ -197,7 +250,14 @@ func (c *providerClient) Stop(ctx context.Context, in *Stop_Request, opts ...grp // All implementations must embed UnimplementedProviderServer // for forward compatibility type ProviderServer interface { - // ////// Information about what a provider supports/expects + // GetMetadata returns upfront information about server capabilities and + // supported resource types without requiring the server to instantiate all + // schema information, which may be memory intensive. This RPC is optional, + // where clients may receive an unimplemented RPC error. Clients should + // ignore the error and call the GetSchema RPC as a fallback. + GetMetadata(context.Context, *GetMetadata_Request) (*GetMetadata_Response, error) + // GetSchema returns schema information for the provider, data resources, + // and managed resources. GetSchema(context.Context, *GetProviderSchema_Request) (*GetProviderSchema_Response, error) PrepareProviderConfig(context.Context, *PrepareProviderConfig_Request) (*PrepareProviderConfig_Response, error) ValidateResourceTypeConfig(context.Context, *ValidateResourceTypeConfig_Request) (*ValidateResourceTypeConfig_Response, error) @@ -210,7 +270,13 @@ type ProviderServer interface { PlanResourceChange(context.Context, *PlanResourceChange_Request) (*PlanResourceChange_Response, error) ApplyResourceChange(context.Context, *ApplyResourceChange_Request) (*ApplyResourceChange_Response, error) ImportResourceState(context.Context, *ImportResourceState_Request) (*ImportResourceState_Response, error) + MoveResourceState(context.Context, *MoveResourceState_Request) (*MoveResourceState_Response, error) ReadDataSource(context.Context, *ReadDataSource_Request) (*ReadDataSource_Response, error) + // GetFunctions returns the definitions of all functions. + GetFunctions(context.Context, *GetFunctions_Request) (*GetFunctions_Response, error) + // CallFunction runs the provider-defined function logic and returns + // the result with any diagnostics. + CallFunction(context.Context, *CallFunction_Request) (*CallFunction_Response, error) // ////// Graceful Shutdown Stop(context.Context, *Stop_Request) (*Stop_Response, error) mustEmbedUnimplementedProviderServer() @@ -220,6 +286,9 @@ type ProviderServer interface { type UnimplementedProviderServer struct { } +func (UnimplementedProviderServer) GetMetadata(context.Context, *GetMetadata_Request) (*GetMetadata_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMetadata not implemented") +} func (UnimplementedProviderServer) GetSchema(context.Context, *GetProviderSchema_Request) (*GetProviderSchema_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method GetSchema not implemented") } @@ -250,9 +319,18 @@ func (UnimplementedProviderServer) ApplyResourceChange(context.Context, *ApplyRe func (UnimplementedProviderServer) ImportResourceState(context.Context, *ImportResourceState_Request) (*ImportResourceState_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method ImportResourceState not implemented") } +func (UnimplementedProviderServer) MoveResourceState(context.Context, *MoveResourceState_Request) (*MoveResourceState_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method MoveResourceState not implemented") +} func (UnimplementedProviderServer) ReadDataSource(context.Context, *ReadDataSource_Request) (*ReadDataSource_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method ReadDataSource not implemented") } +func (UnimplementedProviderServer) GetFunctions(context.Context, *GetFunctions_Request) (*GetFunctions_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetFunctions not implemented") +} +func (UnimplementedProviderServer) CallFunction(context.Context, *CallFunction_Request) (*CallFunction_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method CallFunction not implemented") +} func (UnimplementedProviderServer) Stop(context.Context, *Stop_Request) (*Stop_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method Stop not implemented") } @@ -269,6 +347,24 @@ func RegisterProviderServer(s grpc.ServiceRegistrar, srv ProviderServer) { s.RegisterService(&Provider_ServiceDesc, srv) } +func _Provider_GetMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetMetadata_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).GetMetadata(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Provider_GetMetadata_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).GetMetadata(ctx, req.(*GetMetadata_Request)) + } + return interceptor(ctx, in, info, handler) +} + func _Provider_GetSchema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetProviderSchema_Request) if err := dec(in); err != nil { @@ -449,6 +545,24 @@ func _Provider_ImportResourceState_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _Provider_MoveResourceState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MoveResourceState_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).MoveResourceState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Provider_MoveResourceState_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).MoveResourceState(ctx, req.(*MoveResourceState_Request)) + } + return interceptor(ctx, in, info, handler) +} + func _Provider_ReadDataSource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ReadDataSource_Request) if err := dec(in); err != nil { @@ -467,6 +581,42 @@ func _Provider_ReadDataSource_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Provider_GetFunctions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetFunctions_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).GetFunctions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Provider_GetFunctions_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).GetFunctions(ctx, req.(*GetFunctions_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_CallFunction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CallFunction_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).CallFunction(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Provider_CallFunction_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).CallFunction(ctx, req.(*CallFunction_Request)) + } + return interceptor(ctx, in, info, handler) +} + func _Provider_Stop_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Stop_Request) if err := dec(in); err != nil { @@ -492,6 +642,10 @@ var Provider_ServiceDesc = grpc.ServiceDesc{ ServiceName: "tfplugin5.Provider", HandlerType: (*ProviderServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "GetMetadata", + Handler: _Provider_GetMetadata_Handler, + }, { MethodName: "GetSchema", Handler: _Provider_GetSchema_Handler, @@ -532,10 +686,22 @@ var Provider_ServiceDesc = grpc.ServiceDesc{ MethodName: "ImportResourceState", Handler: _Provider_ImportResourceState_Handler, }, + { + MethodName: "MoveResourceState", + Handler: _Provider_MoveResourceState_Handler, + }, { MethodName: "ReadDataSource", Handler: _Provider_ReadDataSource_Handler, }, + { + MethodName: "GetFunctions", + Handler: _Provider_GetFunctions_Handler, + }, + { + MethodName: "CallFunction", + Handler: _Provider_CallFunction_Handler, + }, { MethodName: "Stop", Handler: _Provider_Stop_Handler, diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/attribute_path.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/attribute_path.go index 58397ebd..4a469b14 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/attribute_path.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/attribute_path.go @@ -1,98 +1,92 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( - "errors" + "fmt" "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" "github.com/hashicorp/terraform-plugin-go/tftypes" ) -var ErrUnknownAttributePathStepType = errors.New("unknown type of AttributePath_Step") - -func AttributePath(in *tftypes.AttributePath) (*tfplugin5.AttributePath, error) { +func AttributePath(in *tftypes.AttributePath) *tfplugin5.AttributePath { if in == nil { - return nil, nil + return nil } - steps, err := AttributePath_Steps(in.Steps()) - if err != nil { - return nil, err + + resp := &tfplugin5.AttributePath{ + Steps: AttributePath_Steps(in.Steps()), } - return &tfplugin5.AttributePath{ - Steps: steps, - }, nil + + return resp } -func AttributePaths(in []*tftypes.AttributePath) ([]*tfplugin5.AttributePath, error) { +func AttributePaths(in []*tftypes.AttributePath) []*tfplugin5.AttributePath { resp := make([]*tfplugin5.AttributePath, 0, len(in)) + for _, a := range in { - if a == nil { - resp = append(resp, nil) - continue - } - attr, err := AttributePath(a) - if err != nil { - return resp, err - } - resp = append(resp, attr) + resp = append(resp, AttributePath(a)) } - return resp, nil + + return resp } -func AttributePath_Step(step tftypes.AttributePathStep) (*tfplugin5.AttributePath_Step, error) { - var resp tfplugin5.AttributePath_Step - if name, ok := step.(tftypes.AttributeName); ok { - resp.Selector = &tfplugin5.AttributePath_Step_AttributeName{ - AttributeName: string(name), - } - return &resp, nil +func AttributePath_Step(step tftypes.AttributePathStep) *tfplugin5.AttributePath_Step { + if step == nil { + return nil } - if key, ok := step.(tftypes.ElementKeyString); ok { - resp.Selector = &tfplugin5.AttributePath_Step_ElementKeyString{ - ElementKeyString: string(key), + + switch step := step.(type) { + case tftypes.AttributeName: + return &tfplugin5.AttributePath_Step{ + Selector: &tfplugin5.AttributePath_Step_AttributeName{ + AttributeName: string(step), + }, } - return &resp, nil - } - if key, ok := step.(tftypes.ElementKeyInt); ok { - resp.Selector = &tfplugin5.AttributePath_Step_ElementKeyInt{ - ElementKeyInt: int64(key), + case tftypes.ElementKeyInt: + return &tfplugin5.AttributePath_Step{ + Selector: &tfplugin5.AttributePath_Step_ElementKeyInt{ + ElementKeyInt: int64(step), + }, } - return &resp, nil - } - if _, ok := step.(tftypes.ElementKeyValue); ok { - // the protocol has no equivalent of an ElementKeyValue, so we - // return nil for both the step and the error here, to signal - // that we've hit a step we can't convey back to Terraform - return nil, nil + case tftypes.ElementKeyString: + return &tfplugin5.AttributePath_Step{ + Selector: &tfplugin5.AttributePath_Step_ElementKeyString{ + ElementKeyString: string(step), + }, + } + case tftypes.ElementKeyValue: + // The protocol has no equivalent of an ElementKeyValue, so this + // returns nil for the step to signal a step we cannot convey back + // to Terraform. + return nil } - return nil, ErrUnknownAttributePathStepType + + // It is not currently possible to create tftypes.AttributePathStep + // implementations outside the tftypes package and these implementations + // should rarely change, if ever, since they are critical to how + // Terraform understands attribute paths. If this panic was reached, it + // implies that a new step type was introduced and needs to be + // implemented as a new case above or that this logic needs to be + // otherwise changed to handle some new attribute path system. + panic(fmt.Sprintf("unimplemented tftypes.AttributePathStep type: %T", step)) } -func AttributePath_Steps(in []tftypes.AttributePathStep) ([]*tfplugin5.AttributePath_Step, error) { +func AttributePath_Steps(in []tftypes.AttributePathStep) []*tfplugin5.AttributePath_Step { resp := make([]*tfplugin5.AttributePath_Step, 0, len(in)) + for _, step := range in { - if step == nil { - resp = append(resp, nil) - continue - } - s, err := AttributePath_Step(step) - if err != nil { - return resp, err - } - // in the face of a set, the protocol has no way to represent - // the index, so we just bail and return the prefix we can - // return. + s := AttributePath_Step(step) + + // In the face of a ElementKeyValue or missing step, Terraform has no + // way to represent the attribute path, so only return the prefix. if s == nil { - return resp, nil + return resp } + resp = append(resp, s) } - return resp, nil -} -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/data_source.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/data_source.go index 516812cd..a62f3cde 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/data_source.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/data_source.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( @@ -5,57 +8,39 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" ) -func ValidateDataSourceConfig_Request(in *tfprotov5.ValidateDataSourceConfigRequest) (*tfplugin5.ValidateDataSourceConfig_Request, error) { - resp := &tfplugin5.ValidateDataSourceConfig_Request{ - TypeName: in.TypeName, +func GetMetadata_DataSourceMetadata(in *tfprotov5.DataSourceMetadata) *tfplugin5.GetMetadata_DataSourceMetadata { + if in == nil { + return nil } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - return resp, nil -} -func ValidateDataSourceConfig_Response(in *tfprotov5.ValidateDataSourceConfigResponse) (*tfplugin5.ValidateDataSourceConfig_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err + resp := &tfplugin5.GetMetadata_DataSourceMetadata{ + TypeName: in.TypeName, } - return &tfplugin5.ValidateDataSourceConfig_Response{ - Diagnostics: diags, - }, nil + + return resp } -func ReadDataSource_Request(in *tfprotov5.ReadDataSourceRequest) (*tfplugin5.ReadDataSource_Request, error) { - resp := &tfplugin5.ReadDataSource_Request{ - TypeName: in.TypeName, +func ValidateDataSourceConfig_Response(in *tfprotov5.ValidateDataSourceConfigResponse) *tfplugin5.ValidateDataSourceConfig_Response { + if in == nil { + return nil } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) + + resp := &tfplugin5.ValidateDataSourceConfig_Response{ + Diagnostics: Diagnostics(in.Diagnostics), } - return resp, nil + + return resp } -func ReadDataSource_Response(in *tfprotov5.ReadDataSourceResponse) (*tfplugin5.ReadDataSource_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func ReadDataSource_Response(in *tfprotov5.ReadDataSourceResponse) *tfplugin5.ReadDataSource_Response { + if in == nil { + return nil } + resp := &tfplugin5.ReadDataSource_Response{ - Diagnostics: diags, + Diagnostics: Diagnostics(in.Diagnostics), + State: DynamicValue(in.State), } - if in.State != nil { - resp.State = DynamicValue(in.State) - } - return resp, nil -} -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/diagnostic.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/diagnostic.go index 81d692ce..bf30765e 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/diagnostic.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/diagnostic.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( @@ -7,43 +10,36 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" ) -func Diagnostic(in *tfprotov5.Diagnostic) (*tfplugin5.Diagnostic, error) { - diag := &tfplugin5.Diagnostic{ - Severity: Diagnostic_Severity(in.Severity), - Summary: forceValidUTF8(in.Summary), - Detail: forceValidUTF8(in.Detail), +func Diagnostic(in *tfprotov5.Diagnostic) *tfplugin5.Diagnostic { + if in == nil { + return nil } - if in.Attribute != nil { - attr, err := AttributePath(in.Attribute) - if err != nil { - return diag, err - } - diag.Attribute = attr + + resp := &tfplugin5.Diagnostic{ + Attribute: AttributePath(in.Attribute), + Detail: ForceValidUTF8(in.Detail), + Severity: Diagnostic_Severity(in.Severity), + Summary: ForceValidUTF8(in.Summary), } - return diag, nil + + return resp } func Diagnostic_Severity(in tfprotov5.DiagnosticSeverity) tfplugin5.Diagnostic_Severity { return tfplugin5.Diagnostic_Severity(in) } -func Diagnostics(in []*tfprotov5.Diagnostic) ([]*tfplugin5.Diagnostic, error) { - diagnostics := make([]*tfplugin5.Diagnostic, 0, len(in)) +func Diagnostics(in []*tfprotov5.Diagnostic) []*tfplugin5.Diagnostic { + resp := make([]*tfplugin5.Diagnostic, 0, len(in)) + for _, diag := range in { - if diag == nil { - diagnostics = append(diagnostics, nil) - continue - } - d, err := Diagnostic(diag) - if err != nil { - return diagnostics, err - } - diagnostics = append(diagnostics, d) + resp = append(resp, Diagnostic(diag)) } - return diagnostics, nil + + return resp } -// forceValidUTF8 returns a string guaranteed to be valid UTF-8 even if the +// ForceValidUTF8 returns a string guaranteed to be valid UTF-8 even if the // input isn't, by replacing any invalid bytes with a valid UTF-8 encoding of // the Unicode Replacement Character (\uFFFD). // @@ -62,7 +58,7 @@ func Diagnostics(in []*tfprotov5.Diagnostic) ([]*tfplugin5.Diagnostic, error) { // it's ultimately up to the user and their terminal or web browser to // interpret the result. Don't use this for strings that have machine-readable // meaning. -func forceValidUTF8(s string) string { +func ForceValidUTF8(s string) string { // Most strings that pass through here will already be valid UTF-8 and // utf8.ValidString has a fast path which will beat our rune-by-rune // analysis below, so it's worth the cost of walking the string twice @@ -95,11 +91,3 @@ func forceValidUTF8(s string) string { } return string(ret) } - -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/doc.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/doc.go new file mode 100644 index 00000000..91b961e8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package toproto converts terraform-plugin-go tfprotov5 types to Protocol +// Buffers generated tfplugin5 types. +package toproto diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/dynamic_value.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/dynamic_value.go index 325e929a..7f86517a 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/dynamic_value.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/dynamic_value.go @@ -1,35 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( - "fmt" - "github.com/hashicorp/terraform-plugin-go/tfprotov5" "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" "github.com/hashicorp/terraform-plugin-go/tftypes" ) func DynamicValue(in *tfprotov5.DynamicValue) *tfplugin5.DynamicValue { - return &tfplugin5.DynamicValue{ + if in == nil { + return nil + } + + resp := &tfplugin5.DynamicValue{ Msgpack: in.MsgPack, Json: in.JSON, } + + return resp } -func CtyType(in tftypes.Type) ([]byte, error) { - switch { - case in.Is(tftypes.String), in.Is(tftypes.Bool), in.Is(tftypes.Number), - in.Is(tftypes.List{}), in.Is(tftypes.Map{}), - in.Is(tftypes.Set{}), in.Is(tftypes.Object{}), - in.Is(tftypes.Tuple{}), in.Is(tftypes.DynamicPseudoType): - return in.MarshalJSON() //nolint:staticcheck +func CtyType(in tftypes.Type) []byte { + if in == nil { + return nil } - return nil, fmt.Errorf("unknown type %s", in) -} -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. + // MarshalJSON is always error safe. + // nolint:staticcheck // Intended first-party usage + resp, _ := in.MarshalJSON() + + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/function.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/function.go new file mode 100644 index 00000000..319c7fa0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/function.go @@ -0,0 +1,102 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto + +import ( + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" +) + +func CallFunction_Response(in *tfprotov5.CallFunctionResponse) *tfplugin5.CallFunction_Response { + if in == nil { + return nil + } + + resp := &tfplugin5.CallFunction_Response{ + Error: FunctionError(in.Error), + Result: DynamicValue(in.Result), + } + + return resp +} + +func Function(in *tfprotov5.Function) *tfplugin5.Function { + if in == nil { + return nil + } + + resp := &tfplugin5.Function{ + Description: in.Description, + DescriptionKind: StringKind(in.DescriptionKind), + DeprecationMessage: in.DeprecationMessage, + Parameters: make([]*tfplugin5.Function_Parameter, 0, len(in.Parameters)), + Return: Function_Return(in.Return), + Summary: in.Summary, + VariadicParameter: Function_Parameter(in.VariadicParameter), + } + + for _, parameter := range in.Parameters { + resp.Parameters = append(resp.Parameters, Function_Parameter(parameter)) + } + + return resp +} + +func Function_Parameter(in *tfprotov5.FunctionParameter) *tfplugin5.Function_Parameter { + if in == nil { + return nil + } + + resp := &tfplugin5.Function_Parameter{ + AllowNullValue: in.AllowNullValue, + AllowUnknownValues: in.AllowUnknownValues, + Description: in.Description, + DescriptionKind: StringKind(in.DescriptionKind), + Name: in.Name, + Type: CtyType(in.Type), + } + + return resp +} + +func Function_Return(in *tfprotov5.FunctionReturn) *tfplugin5.Function_Return { + if in == nil { + return nil + } + + resp := &tfplugin5.Function_Return{ + Type: CtyType(in.Type), + } + + return resp +} + +func GetFunctions_Response(in *tfprotov5.GetFunctionsResponse) *tfplugin5.GetFunctions_Response { + if in == nil { + return nil + } + + resp := &tfplugin5.GetFunctions_Response{ + Diagnostics: Diagnostics(in.Diagnostics), + Functions: make(map[string]*tfplugin5.Function, len(in.Functions)), + } + + for name, function := range in.Functions { + resp.Functions[name] = Function(function) + } + + return resp +} + +func GetMetadata_FunctionMetadata(in *tfprotov5.FunctionMetadata) *tfplugin5.GetMetadata_FunctionMetadata { + if in == nil { + return nil + } + + resp := &tfplugin5.GetMetadata_FunctionMetadata{ + Name: in.Name, + } + + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/function_error.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/function_error.go new file mode 100644 index 00000000..1dab5b43 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/function_error.go @@ -0,0 +1,22 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto + +import ( + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" +) + +func FunctionError(in *tfprotov5.FunctionError) *tfplugin5.FunctionError { + if in == nil { + return nil + } + + resp := &tfplugin5.FunctionError{ + FunctionArgument: in.FunctionArgument, + Text: ForceValidUTF8(in.Text), + } + + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/provider.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/provider.go index 9b0d9ac2..4891c538 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/provider.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/provider.go @@ -1,125 +1,104 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( - "fmt" - "github.com/hashicorp/terraform-plugin-go/tfprotov5" "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" ) -func GetProviderSchema_Request(in *tfprotov5.GetProviderSchemaRequest) (*tfplugin5.GetProviderSchema_Request, error) { - return &tfplugin5.GetProviderSchema_Request{}, nil +func GetMetadata_Response(in *tfprotov5.GetMetadataResponse) *tfplugin5.GetMetadata_Response { + if in == nil { + return nil + } + + resp := &tfplugin5.GetMetadata_Response{ + DataSources: make([]*tfplugin5.GetMetadata_DataSourceMetadata, 0, len(in.DataSources)), + Diagnostics: Diagnostics(in.Diagnostics), + Functions: make([]*tfplugin5.GetMetadata_FunctionMetadata, 0, len(in.Functions)), + Resources: make([]*tfplugin5.GetMetadata_ResourceMetadata, 0, len(in.Resources)), + ServerCapabilities: ServerCapabilities(in.ServerCapabilities), + } + + for _, datasource := range in.DataSources { + resp.DataSources = append(resp.DataSources, GetMetadata_DataSourceMetadata(&datasource)) + } + + for _, function := range in.Functions { + resp.Functions = append(resp.Functions, GetMetadata_FunctionMetadata(&function)) + } + + for _, resource := range in.Resources { + resp.Resources = append(resp.Resources, GetMetadata_ResourceMetadata(&resource)) + } + + return resp } -func GetProviderSchema_Response(in *tfprotov5.GetProviderSchemaResponse) (*tfplugin5.GetProviderSchema_Response, error) { +func GetProviderSchema_Response(in *tfprotov5.GetProviderSchemaResponse) *tfplugin5.GetProviderSchema_Response { if in == nil { - return nil, nil - } - resp := tfplugin5.GetProviderSchema_Response{ - ServerCapabilities: GetProviderSchema_ServerCapabilities(in.ServerCapabilities), - } - if in.Provider != nil { - schema, err := Schema(in.Provider) - if err != nil { - return &resp, fmt.Errorf("error marshaling provider schema: %w", err) - } - resp.Provider = schema - } - if in.ProviderMeta != nil { - schema, err := Schema(in.ProviderMeta) - if err != nil { - return &resp, fmt.Errorf("error marshaling provider_meta schema: %w", err) - } - resp.ProviderMeta = schema - } - resp.ResourceSchemas = make(map[string]*tfplugin5.Schema, len(in.ResourceSchemas)) - for k, v := range in.ResourceSchemas { - if v == nil { - resp.ResourceSchemas[k] = nil - continue - } - schema, err := Schema(v) - if err != nil { - return &resp, fmt.Errorf("error marshaling resource schema for %q: %w", k, err) - } - resp.ResourceSchemas[k] = schema - } - resp.DataSourceSchemas = make(map[string]*tfplugin5.Schema, len(in.DataSourceSchemas)) - for k, v := range in.DataSourceSchemas { - if v == nil { - resp.DataSourceSchemas[k] = nil - continue - } - schema, err := Schema(v) - if err != nil { - return &resp, fmt.Errorf("error marshaling data source schema for %q: %w", k, err) - } - resp.DataSourceSchemas[k] = schema - } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return &resp, err - } - resp.Diagnostics = diags - return &resp, nil -} + return nil + } -func PrepareProviderConfig_Request(in *tfprotov5.PrepareProviderConfigRequest) (*tfplugin5.PrepareProviderConfig_Request, error) { - resp := &tfplugin5.PrepareProviderConfig_Request{} - if in.Config != nil { - resp.Config = DynamicValue(in.Config) + resp := &tfplugin5.GetProviderSchema_Response{ + DataSourceSchemas: make(map[string]*tfplugin5.Schema, len(in.DataSourceSchemas)), + Diagnostics: Diagnostics(in.Diagnostics), + Functions: make(map[string]*tfplugin5.Function, len(in.Functions)), + Provider: Schema(in.Provider), + ProviderMeta: Schema(in.ProviderMeta), + ResourceSchemas: make(map[string]*tfplugin5.Schema, len(in.ResourceSchemas)), + ServerCapabilities: ServerCapabilities(in.ServerCapabilities), } - return resp, nil -} -func PrepareProviderConfig_Response(in *tfprotov5.PrepareProviderConfigResponse) (*tfplugin5.PrepareProviderConfig_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err + for name, schema := range in.ResourceSchemas { + resp.ResourceSchemas[name] = Schema(schema) } - resp := &tfplugin5.PrepareProviderConfig_Response{ - Diagnostics: diags, + + for name, schema := range in.DataSourceSchemas { + resp.DataSourceSchemas[name] = Schema(schema) } - if in.PreparedConfig != nil { - resp.PreparedConfig = DynamicValue(in.PreparedConfig) + + for name, function := range in.Functions { + resp.Functions[name] = Function(function) } - return resp, nil + + return resp } -func Configure_Request(in *tfprotov5.ConfigureProviderRequest) (*tfplugin5.Configure_Request, error) { - resp := &tfplugin5.Configure_Request{ - TerraformVersion: in.TerraformVersion, +func PrepareProviderConfig_Response(in *tfprotov5.PrepareProviderConfigResponse) *tfplugin5.PrepareProviderConfig_Response { + if in == nil { + return nil } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) + + resp := &tfplugin5.PrepareProviderConfig_Response{ + Diagnostics: Diagnostics(in.Diagnostics), + PreparedConfig: DynamicValue(in.PreparedConfig), } - return resp, nil + + return resp } -func Configure_Response(in *tfprotov5.ConfigureProviderResponse) (*tfplugin5.Configure_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func Configure_Response(in *tfprotov5.ConfigureProviderResponse) *tfplugin5.Configure_Response { + if in == nil { + return nil } - return &tfplugin5.Configure_Response{ - Diagnostics: diags, - }, nil -} -func Stop_Request(in *tfprotov5.StopProviderRequest) (*tfplugin5.Stop_Request, error) { - return &tfplugin5.Stop_Request{}, nil + resp := &tfplugin5.Configure_Response{ + Diagnostics: Diagnostics(in.Diagnostics), + } + + return resp } -func Stop_Response(in *tfprotov5.StopProviderResponse) (*tfplugin5.Stop_Response, error) { - return &tfplugin5.Stop_Response{ +func Stop_Response(in *tfprotov5.StopProviderResponse) *tfplugin5.Stop_Response { + if in == nil { + return nil + } + + resp := &tfplugin5.Stop_Response{ Error: in.Error, - }, nil -} + } -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/resource.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/resource.go index 77eba487..0ba9ab46 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/resource.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/resource.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( @@ -5,210 +8,135 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" ) -func ValidateResourceTypeConfig_Request(in *tfprotov5.ValidateResourceTypeConfigRequest) (*tfplugin5.ValidateResourceTypeConfig_Request, error) { - resp := &tfplugin5.ValidateResourceTypeConfig_Request{ - TypeName: in.TypeName, +func GetMetadata_ResourceMetadata(in *tfprotov5.ResourceMetadata) *tfplugin5.GetMetadata_ResourceMetadata { + if in == nil { + return nil } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - return resp, nil -} -func ValidateResourceTypeConfig_Response(in *tfprotov5.ValidateResourceTypeConfigResponse) (*tfplugin5.ValidateResourceTypeConfig_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err + resp := &tfplugin5.GetMetadata_ResourceMetadata{ + TypeName: in.TypeName, } - return &tfplugin5.ValidateResourceTypeConfig_Response{ - Diagnostics: diags, - }, nil + + return resp } -func UpgradeResourceState_Request(in *tfprotov5.UpgradeResourceStateRequest) (*tfplugin5.UpgradeResourceState_Request, error) { - resp := &tfplugin5.UpgradeResourceState_Request{ - TypeName: in.TypeName, - Version: in.Version, +func ValidateResourceTypeConfig_Response(in *tfprotov5.ValidateResourceTypeConfigResponse) *tfplugin5.ValidateResourceTypeConfig_Response { + if in == nil { + return nil } - if in.RawState != nil { - resp.RawState = RawState(in.RawState) + + resp := &tfplugin5.ValidateResourceTypeConfig_Response{ + Diagnostics: Diagnostics(in.Diagnostics), } - return resp, nil + + return resp } -func UpgradeResourceState_Response(in *tfprotov5.UpgradeResourceStateResponse) (*tfplugin5.UpgradeResourceState_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func UpgradeResourceState_Response(in *tfprotov5.UpgradeResourceStateResponse) *tfplugin5.UpgradeResourceState_Response { + if in == nil { + return nil } + resp := &tfplugin5.UpgradeResourceState_Response{ - Diagnostics: diags, + Diagnostics: Diagnostics(in.Diagnostics), + UpgradedState: DynamicValue(in.UpgradedState), } - if in.UpgradedState != nil { - resp.UpgradedState = DynamicValue(in.UpgradedState) - } - return resp, nil + + return resp } -func ReadResource_Request(in *tfprotov5.ReadResourceRequest) (*tfplugin5.ReadResource_Request, error) { - resp := &tfplugin5.ReadResource_Request{ - TypeName: in.TypeName, - Private: in.Private, - } - if in.CurrentState != nil { - resp.CurrentState = DynamicValue(in.CurrentState) +func ReadResource_Response(in *tfprotov5.ReadResourceResponse) *tfplugin5.ReadResource_Response { + if in == nil { + return nil } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) - } - return resp, nil -} -func ReadResource_Response(in *tfprotov5.ReadResourceResponse) (*tfplugin5.ReadResource_Response, error) { resp := &tfplugin5.ReadResource_Response{ - Private: in.Private, - } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err - } - resp.Diagnostics = diags - if in.NewState != nil { - resp.NewState = DynamicValue(in.NewState) + Diagnostics: Diagnostics(in.Diagnostics), + NewState: DynamicValue(in.NewState), + Private: in.Private, } - return resp, nil + + return resp } -func PlanResourceChange_Request(in *tfprotov5.PlanResourceChangeRequest) (*tfplugin5.PlanResourceChange_Request, error) { - resp := &tfplugin5.PlanResourceChange_Request{ - TypeName: in.TypeName, - PriorPrivate: in.PriorPrivate, - } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - if in.PriorState != nil { - resp.PriorState = DynamicValue(in.PriorState) +func PlanResourceChange_Response(in *tfprotov5.PlanResourceChangeResponse) *tfplugin5.PlanResourceChange_Response { + if in == nil { + return nil } - if in.ProposedNewState != nil { - resp.ProposedNewState = DynamicValue(in.ProposedNewState) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) - } - return resp, nil -} -func PlanResourceChange_Response(in *tfprotov5.PlanResourceChangeResponse) (*tfplugin5.PlanResourceChange_Response, error) { resp := &tfplugin5.PlanResourceChange_Response{ - PlannedPrivate: in.PlannedPrivate, + Diagnostics: Diagnostics(in.Diagnostics), LegacyTypeSystem: in.UnsafeToUseLegacyTypeSystem, //nolint:staticcheck + PlannedPrivate: in.PlannedPrivate, + PlannedState: DynamicValue(in.PlannedState), + RequiresReplace: AttributePaths(in.RequiresReplace), } - requiresReplace, err := AttributePaths(in.RequiresReplace) - if err != nil { - return resp, err - } - resp.RequiresReplace = requiresReplace - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err - } - resp.Diagnostics = diags - if in.PlannedState != nil { - resp.PlannedState = DynamicValue(in.PlannedState) - } - return resp, nil + + return resp } -func ApplyResourceChange_Request(in *tfprotov5.ApplyResourceChangeRequest) (*tfplugin5.ApplyResourceChange_Request, error) { - resp := &tfplugin5.ApplyResourceChange_Request{ - TypeName: in.TypeName, - PlannedPrivate: in.PlannedPrivate, - } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - if in.PriorState != nil { - resp.PriorState = DynamicValue(in.PriorState) +func ApplyResourceChange_Response(in *tfprotov5.ApplyResourceChangeResponse) *tfplugin5.ApplyResourceChange_Response { + if in == nil { + return nil } - if in.PlannedState != nil { - resp.PlannedState = DynamicValue(in.PlannedState) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) - } - return resp, nil -} -func ApplyResourceChange_Response(in *tfprotov5.ApplyResourceChangeResponse) (*tfplugin5.ApplyResourceChange_Response, error) { resp := &tfplugin5.ApplyResourceChange_Response{ - Private: in.Private, + Diagnostics: Diagnostics(in.Diagnostics), LegacyTypeSystem: in.UnsafeToUseLegacyTypeSystem, //nolint:staticcheck + NewState: DynamicValue(in.NewState), + Private: in.Private, } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err - } - resp.Diagnostics = diags - if in.NewState != nil { - resp.NewState = DynamicValue(in.NewState) - } - return resp, nil -} -func ImportResourceState_Request(in *tfprotov5.ImportResourceStateRequest) (*tfplugin5.ImportResourceState_Request, error) { - return &tfplugin5.ImportResourceState_Request{ - TypeName: in.TypeName, - Id: in.ID, - }, nil + return resp } -func ImportResourceState_Response(in *tfprotov5.ImportResourceStateResponse) (*tfplugin5.ImportResourceState_Response, error) { - importedResources, err := ImportResourceState_ImportedResources(in.ImportedResources) - if err != nil { - return nil, err +func ImportResourceState_Response(in *tfprotov5.ImportResourceStateResponse) *tfplugin5.ImportResourceState_Response { + if in == nil { + return nil } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err + + resp := &tfplugin5.ImportResourceState_Response{ + Diagnostics: Diagnostics(in.Diagnostics), + ImportedResources: ImportResourceState_ImportedResources(in.ImportedResources), } - return &tfplugin5.ImportResourceState_Response{ - ImportedResources: importedResources, - Diagnostics: diags, - }, nil + + return resp } -func ImportResourceState_ImportedResource(in *tfprotov5.ImportedResource) (*tfplugin5.ImportResourceState_ImportedResource, error) { +func ImportResourceState_ImportedResource(in *tfprotov5.ImportedResource) *tfplugin5.ImportResourceState_ImportedResource { + if in == nil { + return nil + } + resp := &tfplugin5.ImportResourceState_ImportedResource{ - TypeName: in.TypeName, Private: in.Private, + State: DynamicValue(in.State), + TypeName: in.TypeName, } - if in.State != nil { - resp.State = DynamicValue(in.State) - } - return resp, nil + + return resp } -func ImportResourceState_ImportedResources(in []*tfprotov5.ImportedResource) ([]*tfplugin5.ImportResourceState_ImportedResource, error) { +func ImportResourceState_ImportedResources(in []*tfprotov5.ImportedResource) []*tfplugin5.ImportResourceState_ImportedResource { resp := make([]*tfplugin5.ImportResourceState_ImportedResource, 0, len(in)) + for _, i := range in { - if i == nil { - resp = append(resp, nil) - continue - } - r, err := ImportResourceState_ImportedResource(i) - if err != nil { - return resp, err - } - resp = append(resp, r) - } - return resp, nil + resp = append(resp, ImportResourceState_ImportedResource(i)) + } + + return resp } -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. +func MoveResourceState_Response(in *tfprotov5.MoveResourceStateResponse) *tfplugin5.MoveResourceState_Response { + if in == nil { + return nil + } + + resp := &tfplugin5.MoveResourceState_Response{ + Diagnostics: Diagnostics(in.Diagnostics), + TargetPrivate: in.TargetPrivate, + TargetState: DynamicValue(in.TargetState), + } + + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/schema.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/schema.go index c39ee2a4..69d47af1 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/schema.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/schema.go @@ -1,121 +1,99 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( - "fmt" - "github.com/hashicorp/terraform-plugin-go/tfprotov5" "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" ) -func Schema(in *tfprotov5.Schema) (*tfplugin5.Schema, error) { - var resp tfplugin5.Schema - resp.Version = in.Version - if in.Block != nil { - block, err := Schema_Block(in.Block) - if err != nil { - return &resp, fmt.Errorf("error marshalling block: %w", err) - } - resp.Block = block +func Schema(in *tfprotov5.Schema) *tfplugin5.Schema { + if in == nil { + return nil + } + + resp := &tfplugin5.Schema{ + Block: Schema_Block(in.Block), + Version: in.Version, } - return &resp, nil + + return resp } -func Schema_Block(in *tfprotov5.SchemaBlock) (*tfplugin5.Schema_Block, error) { +func Schema_Block(in *tfprotov5.SchemaBlock) *tfplugin5.Schema_Block { + if in == nil { + return nil + } + resp := &tfplugin5.Schema_Block{ - Version: in.Version, + Attributes: Schema_Attributes(in.Attributes), + BlockTypes: Schema_NestedBlocks(in.BlockTypes), + Deprecated: in.Deprecated, Description: in.Description, DescriptionKind: StringKind(in.DescriptionKind), - Deprecated: in.Deprecated, - } - attrs, err := Schema_Attributes(in.Attributes) - if err != nil { - return resp, err - } - resp.Attributes = attrs - blocks, err := Schema_NestedBlocks(in.BlockTypes) - if err != nil { - return resp, err + Version: in.Version, } - resp.BlockTypes = blocks - return resp, nil + + return resp } -func Schema_Attribute(in *tfprotov5.SchemaAttribute) (*tfplugin5.Schema_Attribute, error) { +func Schema_Attribute(in *tfprotov5.SchemaAttribute) *tfplugin5.Schema_Attribute { + if in == nil { + return nil + } + resp := &tfplugin5.Schema_Attribute{ - Name: in.Name, + Computed: in.Computed, + Deprecated: in.Deprecated, Description: in.Description, - Required: in.Required, + DescriptionKind: StringKind(in.DescriptionKind), + Name: in.Name, Optional: in.Optional, - Computed: in.Computed, + Required: in.Required, Sensitive: in.Sensitive, - DescriptionKind: StringKind(in.DescriptionKind), - Deprecated: in.Deprecated, - } - t, err := CtyType(in.Type) - if err != nil { - return resp, fmt.Errorf("error marshaling type to JSON: %w", err) + Type: CtyType(in.Type), } - resp.Type = t - return resp, nil + + return resp } -func Schema_Attributes(in []*tfprotov5.SchemaAttribute) ([]*tfplugin5.Schema_Attribute, error) { +func Schema_Attributes(in []*tfprotov5.SchemaAttribute) []*tfplugin5.Schema_Attribute { resp := make([]*tfplugin5.Schema_Attribute, 0, len(in)) + for _, a := range in { - if a == nil { - resp = append(resp, nil) - continue - } - attr, err := Schema_Attribute(a) - if err != nil { - return nil, err - } - resp = append(resp, attr) + resp = append(resp, Schema_Attribute(a)) } - return resp, nil + + return resp } -func Schema_NestedBlock(in *tfprotov5.SchemaNestedBlock) (*tfplugin5.Schema_NestedBlock, error) { +func Schema_NestedBlock(in *tfprotov5.SchemaNestedBlock) *tfplugin5.Schema_NestedBlock { + if in == nil { + return nil + } + resp := &tfplugin5.Schema_NestedBlock{ - TypeName: in.TypeName, - Nesting: Schema_NestedBlock_NestingMode(in.Nesting), - MinItems: in.MinItems, + Block: Schema_Block(in.Block), MaxItems: in.MaxItems, + MinItems: in.MinItems, + Nesting: Schema_NestedBlock_NestingMode(in.Nesting), + TypeName: in.TypeName, } - if in.Block != nil { - block, err := Schema_Block(in.Block) - if err != nil { - return resp, fmt.Errorf("error marshaling nested block: %w", err) - } - resp.Block = block - } - return resp, nil + + return resp } -func Schema_NestedBlocks(in []*tfprotov5.SchemaNestedBlock) ([]*tfplugin5.Schema_NestedBlock, error) { +func Schema_NestedBlocks(in []*tfprotov5.SchemaNestedBlock) []*tfplugin5.Schema_NestedBlock { resp := make([]*tfplugin5.Schema_NestedBlock, 0, len(in)) + for _, b := range in { - if b == nil { - resp = append(resp, nil) - continue - } - block, err := Schema_NestedBlock(b) - if err != nil { - return nil, err - } - resp = append(resp, block) + resp = append(resp, Schema_NestedBlock(b)) } - return resp, nil + + return resp } func Schema_NestedBlock_NestingMode(in tfprotov5.SchemaNestedBlockNestingMode) tfplugin5.Schema_NestedBlock_NestingMode { return tfplugin5.Schema_NestedBlock_NestingMode(in) } - -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/server_capabilities.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/server_capabilities.go index bde7d4bf..9fcbe0e6 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/server_capabilities.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/server_capabilities.go @@ -8,12 +8,16 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" ) -func GetProviderSchema_ServerCapabilities(in *tfprotov5.ServerCapabilities) *tfplugin5.GetProviderSchema_ServerCapabilities { +func ServerCapabilities(in *tfprotov5.ServerCapabilities) *tfplugin5.ServerCapabilities { if in == nil { return nil } - return &tfplugin5.GetProviderSchema_ServerCapabilities{ - PlanDestroy: in.PlanDestroy, + resp := &tfplugin5.ServerCapabilities{ + GetProviderSchemaOptional: in.GetProviderSchemaOptional, + MoveResourceState: in.MoveResourceState, + PlanDestroy: in.PlanDestroy, } + + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/state.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/state.go deleted file mode 100644 index 3a13d1f4..00000000 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/state.go +++ /dev/null @@ -1,21 +0,0 @@ -package toproto - -import ( - "github.com/hashicorp/terraform-plugin-go/tfprotov5" - "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" -) - -func RawState(in *tfprotov5.RawState) *tfplugin5.RawState { - return &tfplugin5.RawState{ - Json: in.JSON, - Flatmap: in.Flatmap, - } -} - -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/string_kind.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/string_kind.go index 1ea6628c..fbb399c0 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/string_kind.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto/string_kind.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( @@ -8,11 +11,3 @@ import ( func StringKind(in tfprotov5.StringKind) tfplugin5.StringKind { return tfplugin5.StringKind(in) } - -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/provider.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/provider.go index 63112fe0..fa85a8e0 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/provider.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/provider.go @@ -10,6 +10,13 @@ import ( // ProviderServer is an interface that reflects that Terraform protocol. // Providers must implement this interface. type ProviderServer interface { + // GetMetadata returns upfront information about server capabilities and + // supported resource types without requiring the server to instantiate all + // schema information, which may be memory intensive. This RPC is optional, + // where clients may receive an unimplemented RPC error. Clients should + // ignore the error and call the GetProviderSchema RPC as a fallback. + GetMetadata(context.Context, *GetMetadataRequest) (*GetMetadataResponse, error) + // GetProviderSchema is called when Terraform needs to know what the // provider's schema is, along with the schemas of all its resources // and data sources. @@ -40,6 +47,40 @@ type ProviderServer interface { // data source is to terraform-plugin-go, so they're their own // interface that is composed into ProviderServer. DataSourceServer + + // FunctionServer is an interface encapsulating all the function-related RPC + // requests. ProviderServer implementations must implement them, but they + // are a handy interface for defining what a function is to + // terraform-plugin-go, so they are their own interface that is composed + // into ProviderServer. + // + // This will be required in an upcoming release. + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353 + // FunctionServer +} + +// GetMetadataRequest represents a GetMetadata RPC request. +type GetMetadataRequest struct{} + +// GetMetadataResponse represents a GetMetadata RPC response. +type GetMetadataResponse struct { + // ServerCapabilities defines optionally supported protocol features, + // such as forward-compatible Terraform behavior changes. + ServerCapabilities *ServerCapabilities + + // Diagnostics report errors or warnings related to returning the + // provider's schemas. Returning an empty slice indicates success, with + // no errors or warnings generated. + Diagnostics []*Diagnostic + + // DataSources returns metadata for all data resources. + DataSources []DataSourceMetadata + + // Functions returns metadata for all functions. + Functions []FunctionMetadata + + // Resources returns metadata for all managed resources. + Resources []ResourceMetadata } // GetProviderSchemaRequest represents a Terraform RPC request for the @@ -78,6 +119,14 @@ type GetProviderSchemaResponse struct { // `data` in a user's configuration. DataSourceSchemas map[string]*Schema + // Functions is a map of function names to their definition. + // + // Unlike data resources and managed resources, the name should NOT be + // prefixed with the provider name and an underscore. Configuration + // references to functions use a separate namespacing syntax that already + // includes the provider name. + Functions map[string]*Function + // Diagnostics report errors or warnings related to returning the // provider's schemas. Returning an empty slice indicates success, with // no errors or warnings generated. diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/resource.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/resource.go index e2c15374..3090d298 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/resource.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/resource.go @@ -9,6 +9,13 @@ import ( "github.com/hashicorp/terraform-plugin-go/tftypes" ) +// ResourceMetadata describes metadata for a managed resource in the GetMetadata +// RPC. +type ResourceMetadata struct { + // TypeName is the name of the managed resource. + TypeName string +} + // ResourceServer is an interface containing the methods a resource // implementation needs to fill. type ResourceServer interface { @@ -47,6 +54,27 @@ type ResourceServer interface { ImportResourceState(context.Context, *ImportResourceStateRequest) (*ImportResourceStateResponse, error) } +// ResourceServerWithMoveResourceState is a temporary interface for servers +// to implement MoveResourceState RPC handling. +// +// Deprecated: The MoveResourceState method will be moved into the +// ResourceServer interface and this interface will be removed in a future +// version. +type ResourceServerWithMoveResourceState interface { + ResourceServer + + // MoveResourceState is called when Terraform is asked to change a resource + // type for an existing resource. The provider must accept the change as + // valid by ensuring the source resource type, schema version, and provider + // address are compatible to convert the source state into the target + // resource type and latest state version. + // + // This functionality is only supported in Terraform 1.8 and later. The + // provider must have enabled the MoveResourceState server capability to + // enable these requests. + MoveResourceState(context.Context, *MoveResourceStateRequest) (*MoveResourceStateResponse, error) +} + // ValidateResourceTypeConfigRequest is the request Terraform sends when it // wants to validate a resource's configuration. type ValidateResourceTypeConfigRequest struct { @@ -472,3 +500,47 @@ type ImportedResource struct { // the resource, but will not be considered when calculating diffs. Private []byte } + +// MoveResourceStateRequest is the request Terraform sends when it requests a +// provider to move the state of a source resource into the target resource. +// Target resource types generally must opt into accepting each source resource +// type since any transformation logic requires knowledge of the source state. +// +// This functionality is only supported in Terraform 1.8 and later. The provider +// must have enabled the MoveResourceState server capability to enable these +// requests. +type MoveResourceStateRequest struct { + // SourcePrivate is the private state of the source resource. + SourcePrivate []byte + + // SourceProviderAddress is the address of the provider for the source + // resource type. + SourceProviderAddress string + + // SourceSchemaVersion is the version of the source resource state. + SourceSchemaVersion int64 + + // SourceState is the raw state of the source resource. + // + // Only the underlying JSON field is populated. + SourceState *RawState + + // SourceTypeName is the source resource type for the move request. + SourceTypeName string + + // TargetTypeName is the target resource type for the move request. + TargetTypeName string +} + +// MoveResourceStateResponse is the response from the provider containing +// the moved state for the given resource. +type MoveResourceStateResponse struct { + // TargetPrivate is the target resource private state after the move. + TargetPrivate []byte + + // TargetState is the target resource state after the move. + TargetState *DynamicValue + + // Diagnostics report any warnings or errors related to moving the state. + Diagnostics []*Diagnostic +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/server_capabilities.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/server_capabilities.go index 32ffe9a9..f5065fd8 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/server_capabilities.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/server_capabilities.go @@ -9,6 +9,15 @@ package tfprotov5 // This information is used in GetProviderSchemaResponse as capabilities are // static features which must be known upfront in the provider server. type ServerCapabilities struct { + // GetProviderSchemaOptional signals that this provider does not require + // having the GetProviderSchema RPC called first to operate normally. This + // means the caller can use a cached copy of the provider's schema instead. + GetProviderSchemaOptional bool + + // MoveResourceState signals that a provider supports the MoveResourceState + // RPC. + MoveResourceState bool + // PlanDestroy signals that a provider expects a call to // PlanResourceChange when a resource is going to be destroyed. This is // opt-in to prevent unexpected errors or panics since the diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server/server.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server/server.go index 9afebe9b..feb35962 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server/server.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server/server.go @@ -16,19 +16,20 @@ import ( "sync" "time" + "google.golang.org/grpc" + "github.com/hashicorp/terraform-plugin-go/internal/logging" "github.com/hashicorp/terraform-plugin-go/tfprotov5" "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto" "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tf5serverlogging" "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" "github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto" - "google.golang.org/grpc" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-plugin" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-log/tfsdklog" - testing "github.com/mitchellh/go-testing-interface" + "github.com/mitchellh/go-testing-interface" ) const ( @@ -48,7 +49,7 @@ const ( // // In the future, it may be possible to include this information directly // in the protocol buffers rather than recreating a constant here. - protocolVersionMinor uint = 3 + protocolVersionMinor uint = 4 ) // protocolVersion represents the combined major and minor version numbers of @@ -486,88 +487,114 @@ func New(name string, serve tfprotov5.ProviderServer, opts ...ServeOpt) tfplugin } } -func (s *server) GetSchema(ctx context.Context, req *tfplugin5.GetProviderSchema_Request) (*tfplugin5.GetProviderSchema_Response, error) { - rpc := "GetProviderSchema" +func (s *server) GetMetadata(ctx context.Context, protoReq *tfplugin5.GetMetadata_Request) (*tfplugin5.GetMetadata_Response, error) { + rpc := "GetMetadata" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.GetProviderSchemaRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } + + req := fromproto.GetMetadataRequest(protoReq) + ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.GetProviderSchema(ctx, r) + + resp, err := s.downstream.GetMetadata(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) - ret, err := toproto.GetProviderSchema_Response(resp) + tf5serverlogging.ServerCapabilities(ctx, resp.ServerCapabilities) + + protoResp := toproto.GetMetadata_Response(resp) + + return protoResp, nil +} + +func (s *server) GetSchema(ctx context.Context, protoReq *tfplugin5.GetProviderSchema_Request) (*tfplugin5.GetProviderSchema_Response, error) { + rpc := "GetProviderSchema" + ctx = s.loggingContext(ctx) + ctx = logging.RpcContext(ctx, rpc) + ctx = s.stoppableContext(ctx) + logging.ProtocolTrace(ctx, "Received request") + defer logging.ProtocolTrace(ctx, "Served request") + + req := fromproto.GetProviderSchemaRequest(protoReq) + + ctx = tf5serverlogging.DownstreamRequest(ctx) + + resp, err := s.downstream.GetProviderSchema(ctx, req) + if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) + logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } - return ret, nil + + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) + tf5serverlogging.ServerCapabilities(ctx, resp.ServerCapabilities) + + protoResp := toproto.GetProviderSchema_Response(resp) + + return protoResp, nil } -func (s *server) PrepareProviderConfig(ctx context.Context, req *tfplugin5.PrepareProviderConfig_Request) (*tfplugin5.PrepareProviderConfig_Response, error) { +func (s *server) PrepareProviderConfig(ctx context.Context, protoReq *tfplugin5.PrepareProviderConfig_Request) (*tfplugin5.PrepareProviderConfig_Response, error) { rpc := "PrepareProviderConfig" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.PrepareProviderConfigRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) + + req := fromproto.PrepareProviderConfigRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.PrepareProviderConfig(ctx, r) + + resp, err := s.downstream.PrepareProviderConfig(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "PreparedConfig", resp.PreparedConfig) - ret, err := toproto.PrepareProviderConfig_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.PrepareProviderConfig_Response(resp) + + return protoResp, nil } -func (s *server) Configure(ctx context.Context, req *tfplugin5.Configure_Request) (*tfplugin5.Configure_Response, error) { +func (s *server) Configure(ctx context.Context, protoReq *tfplugin5.Configure_Request) (*tfplugin5.Configure_Response, error) { rpc := "Configure" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ConfigureProviderRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) + req := fromproto.ConfigureProviderRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ConfigureProvider(ctx, r) + + resp, err := s.downstream.ConfigureProvider(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) - ret, err := toproto.Configure_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.Configure_Response(resp) + + return protoResp, nil } // stop closes the stopCh associated with the server and replaces it with a new @@ -583,285 +610,434 @@ func (s *server) stop() { s.stopCh = make(chan struct{}) } -func (s *server) Stop(ctx context.Context, req *tfplugin5.Stop_Request) (*tfplugin5.Stop_Response, error) { +func (s *server) Stop(ctx context.Context, protoReq *tfplugin5.Stop_Request) (*tfplugin5.Stop_Response, error) { rpc := "Stop" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.StopProviderRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } + + req := fromproto.StopProviderRequest(protoReq) + ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.StopProvider(ctx, r) + + resp, err := s.downstream.StopProvider(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, nil) logging.ProtocolTrace(ctx, "Closing all our contexts") s.stop() logging.ProtocolTrace(ctx, "Closed all our contexts") - ret, err := toproto.Stop_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.Stop_Response(resp) + + return protoResp, nil } -func (s *server) ValidateDataSourceConfig(ctx context.Context, req *tfplugin5.ValidateDataSourceConfig_Request) (*tfplugin5.ValidateDataSourceConfig_Response, error) { +func (s *server) ValidateDataSourceConfig(ctx context.Context, protoReq *tfplugin5.ValidateDataSourceConfig_Request) (*tfplugin5.ValidateDataSourceConfig_Response, error) { rpc := "ValidateDataSourceConfig" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.DataSourceContext(ctx, req.TypeName) + ctx = logging.DataSourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ValidateDataSourceConfigRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) + + req := fromproto.ValidateDataSourceConfigRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ValidateDataSourceConfig(ctx, r) + + resp, err := s.downstream.ValidateDataSourceConfig(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) - ret, err := toproto.ValidateDataSourceConfig_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ValidateDataSourceConfig_Response(resp) + + return protoResp, nil } -func (s *server) ReadDataSource(ctx context.Context, req *tfplugin5.ReadDataSource_Request) (*tfplugin5.ReadDataSource_Response, error) { +func (s *server) ReadDataSource(ctx context.Context, protoReq *tfplugin5.ReadDataSource_Request) (*tfplugin5.ReadDataSource_Response, error) { rpc := "ReadDataSource" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.DataSourceContext(ctx, req.TypeName) + ctx = logging.DataSourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ReadDataSourceRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", r.ProviderMeta) + + req := fromproto.ReadDataSourceRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", req.ProviderMeta) ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ReadDataSource(ctx, r) + + resp, err := s.downstream.ReadDataSource(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "State", resp.State) - ret, err := toproto.ReadDataSource_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ReadDataSource_Response(resp) + + return protoResp, nil } -func (s *server) ValidateResourceTypeConfig(ctx context.Context, req *tfplugin5.ValidateResourceTypeConfig_Request) (*tfplugin5.ValidateResourceTypeConfig_Response, error) { +func (s *server) ValidateResourceTypeConfig(ctx context.Context, protoReq *tfplugin5.ValidateResourceTypeConfig_Request) (*tfplugin5.ValidateResourceTypeConfig_Response, error) { rpc := "ValidateResourceTypeConfig" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ValidateResourceTypeConfigRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) + + req := fromproto.ValidateResourceTypeConfigRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ValidateResourceTypeConfig(ctx, r) + + resp, err := s.downstream.ValidateResourceTypeConfig(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) - ret, err := toproto.ValidateResourceTypeConfig_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ValidateResourceTypeConfig_Response(resp) + + return protoResp, nil } -func (s *server) UpgradeResourceState(ctx context.Context, req *tfplugin5.UpgradeResourceState_Request) (*tfplugin5.UpgradeResourceState_Response, error) { +func (s *server) UpgradeResourceState(ctx context.Context, protoReq *tfplugin5.UpgradeResourceState_Request) (*tfplugin5.UpgradeResourceState_Response, error) { rpc := "UpgradeResourceState" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.UpgradeResourceStateRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } + + req := fromproto.UpgradeResourceStateRequest(protoReq) + ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.UpgradeResourceState(ctx, r) + + resp, err := s.downstream.UpgradeResourceState(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "UpgradedState", resp.UpgradedState) - ret, err := toproto.UpgradeResourceState_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.UpgradeResourceState_Response(resp) + + return protoResp, nil } -func (s *server) ReadResource(ctx context.Context, req *tfplugin5.ReadResource_Request) (*tfplugin5.ReadResource_Response, error) { +func (s *server) ReadResource(ctx context.Context, protoReq *tfplugin5.ReadResource_Request) (*tfplugin5.ReadResource_Response, error) { rpc := "ReadResource" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ReadResourceRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "CurrentState", r.CurrentState) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", r.ProviderMeta) - logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "Private", r.Private) + + req := fromproto.ReadResourceRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "CurrentState", req.CurrentState) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", req.ProviderMeta) + logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "Private", req.Private) + ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ReadResource(ctx, r) + + resp, err := s.downstream.ReadResource(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "NewState", resp.NewState) logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Response", "Private", resp.Private) - ret, err := toproto.ReadResource_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ReadResource_Response(resp) + + return protoResp, nil } -func (s *server) PlanResourceChange(ctx context.Context, req *tfplugin5.PlanResourceChange_Request) (*tfplugin5.PlanResourceChange_Response, error) { +func (s *server) PlanResourceChange(ctx context.Context, protoReq *tfplugin5.PlanResourceChange_Request) (*tfplugin5.PlanResourceChange_Response, error) { rpc := "PlanResourceChange" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.PlanResourceChangeRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PriorState", r.PriorState) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProposedNewState", r.ProposedNewState) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", r.ProviderMeta) - logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "PriorPrivate", r.PriorPrivate) + + req := fromproto.PlanResourceChangeRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PriorState", req.PriorState) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProposedNewState", req.ProposedNewState) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", req.ProviderMeta) + logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "PriorPrivate", req.PriorPrivate) + ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.PlanResourceChange(ctx, r) + + resp, err := s.downstream.PlanResourceChange(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "PlannedState", resp.PlannedState) logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Response", "PlannedPrivate", resp.PlannedPrivate) - ret, err := toproto.PlanResourceChange_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.PlanResourceChange_Response(resp) + + return protoResp, nil } -func (s *server) ApplyResourceChange(ctx context.Context, req *tfplugin5.ApplyResourceChange_Request) (*tfplugin5.ApplyResourceChange_Response, error) { +func (s *server) ApplyResourceChange(ctx context.Context, protoReq *tfplugin5.ApplyResourceChange_Request) (*tfplugin5.ApplyResourceChange_Response, error) { rpc := "ApplyResourceChange" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ApplyResourceChangeRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PlannedState", r.PlannedState) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PriorState", r.PriorState) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", r.ProviderMeta) - logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "PlannedPrivate", r.PlannedPrivate) + + req := fromproto.ApplyResourceChangeRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PlannedState", req.PlannedState) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PriorState", req.PriorState) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", req.ProviderMeta) + logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "PlannedPrivate", req.PlannedPrivate) + ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ApplyResourceChange(ctx, r) + + resp, err := s.downstream.ApplyResourceChange(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "NewState", resp.NewState) logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Response", "Private", resp.Private) - ret, err := toproto.ApplyResourceChange_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ApplyResourceChange_Response(resp) + + return protoResp, nil } -func (s *server) ImportResourceState(ctx context.Context, req *tfplugin5.ImportResourceState_Request) (*tfplugin5.ImportResourceState_Response, error) { +func (s *server) ImportResourceState(ctx context.Context, protoReq *tfplugin5.ImportResourceState_Request) (*tfplugin5.ImportResourceState_Response, error) { rpc := "ImportResourceState" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ImportResourceStateRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } + + req := fromproto.ImportResourceStateRequest(protoReq) + ctx = tf5serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ImportResourceState(ctx, r) + + resp, err := s.downstream.ImportResourceState(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) + for _, importedResource := range resp.ImportedResources { logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response_ImportedResource", "State", importedResource.State) logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Response_ImportedResource", "Private", importedResource.Private) } - ret, err := toproto.ImportResourceState_Response(resp) + + protoResp := toproto.ImportResourceState_Response(resp) + + return protoResp, nil +} + +func (s *server) MoveResourceState(ctx context.Context, protoReq *tfplugin5.MoveResourceState_Request) (*tfplugin5.MoveResourceState_Response, error) { + rpc := "MoveResourceState" + ctx = s.loggingContext(ctx) + ctx = logging.RpcContext(ctx, rpc) + ctx = logging.ResourceContext(ctx, protoReq.TargetTypeName) + ctx = s.stoppableContext(ctx) + logging.ProtocolTrace(ctx, "Received request") + defer logging.ProtocolTrace(ctx, "Served request") + + // Remove this check and error in preference of + // s.downstream.MoveResourceState below once ResourceServer interface + // implements the MoveResourceState method. + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/363 + // nolint:staticcheck + resourceServerWMRS, ok := s.downstream.(tfprotov5.ResourceServerWithMoveResourceState) + + if !ok { + logging.ProtocolError(ctx, "ProviderServer does not implement ResourceServerWithMoveResourceState") + + protoResp := &tfplugin5.MoveResourceState_Response{ + Diagnostics: []*tfplugin5.Diagnostic{ + { + Severity: tfplugin5.Diagnostic_ERROR, + Summary: "Provider Move Resource State Not Implemented", + Detail: "A MoveResourceState call was received by the provider, however the provider does not implement the call. " + + "Either upgrade the provider to a version that implements move resource state support or this is a bug in Terraform that should be reported to the Terraform maintainers.", + }, + }, + } + + return protoResp, nil + } + + req := fromproto.MoveResourceStateRequest(protoReq) + + ctx = tf5serverlogging.DownstreamRequest(ctx) + + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/363 + // resp, err := s.downstream.MoveResourceState(ctx, req) + resp, err := resourceServerWMRS.MoveResourceState(ctx, req) + + if err != nil { + logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) + + return nil, err + } + + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "TargetState", resp.TargetState) + + protoResp := toproto.MoveResourceState_Response(resp) + + return protoResp, nil +} + +func (s *server) CallFunction(ctx context.Context, protoReq *tfplugin5.CallFunction_Request) (*tfplugin5.CallFunction_Response, error) { + rpc := "CallFunction" + ctx = s.loggingContext(ctx) + ctx = logging.RpcContext(ctx, rpc) + ctx = s.stoppableContext(ctx) + logging.ProtocolTrace(ctx, "Received request") + defer logging.ProtocolTrace(ctx, "Served request") + + // Remove this check and error in preference of s.downstream.CallFunction + // below once ProviderServer interface requires FunctionServer. + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353 + functionServer, ok := s.downstream.(tfprotov5.FunctionServer) + + if !ok { + logging.ProtocolError(ctx, "ProviderServer does not implement FunctionServer") + + text := "Provider Functions Not Implemented: A provider-defined function call was received by the provider, however the provider does not implement functions. " + + "Either upgrade the provider to a version that implements provider-defined functions or this is a bug in Terraform that should be reported to the Terraform maintainers." + + protoResp := &tfplugin5.CallFunction_Response{ + Error: &tfplugin5.FunctionError{ + Text: text, + }, + } + + return protoResp, nil + } + + req := fromproto.CallFunctionRequest(protoReq) + + for position, argument := range req.Arguments { + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", fmt.Sprintf("Arguments_%d", position), argument) + } + + ctx = tf5serverlogging.DownstreamRequest(ctx) + + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353 + // resp, err := s.downstream.CallFunction(ctx, req) + resp, err := functionServer.CallFunction(ctx, req) + + if err != nil { + logging.ProtocolError(ctx, "Error from downstream", map[string]any{logging.KeyError: err}) + return nil, err + } + + tf5serverlogging.DownstreamResponseWithError(ctx, resp.Error) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "Result", resp.Result) + + protoResp := toproto.CallFunction_Response(resp) + + return protoResp, nil +} + +func (s *server) GetFunctions(ctx context.Context, protoReq *tfplugin5.GetFunctions_Request) (*tfplugin5.GetFunctions_Response, error) { + rpc := "GetFunctions" + ctx = s.loggingContext(ctx) + ctx = logging.RpcContext(ctx, rpc) + ctx = s.stoppableContext(ctx) + logging.ProtocolTrace(ctx, "Received request") + defer logging.ProtocolTrace(ctx, "Served request") + + // Remove this check and response in preference of s.downstream.GetFunctions + // below once ProviderServer interface requires FunctionServer. + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353 + functionServer, ok := s.downstream.(tfprotov5.FunctionServer) + + if !ok { + logging.ProtocolWarn(ctx, "ProviderServer does not implement FunctionServer") + + protoResp := &tfplugin5.GetFunctions_Response{ + Functions: map[string]*tfplugin5.Function{}, + } + + return protoResp, nil + } + + req := fromproto.GetFunctionsRequest(protoReq) + + ctx = tf5serverlogging.DownstreamRequest(ctx) + + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353 + // resp, err := s.downstream.GetFunctions(ctx, req) + resp, err := functionServer.GetFunctions(ctx, req) + if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) + logging.ProtocolError(ctx, "Error from downstream", map[string]any{logging.KeyError: err}) return nil, err } - return ret, nil + + tf5serverlogging.DownstreamResponse(ctx, resp.Diagnostics) + + protoResp := toproto.GetFunctions_Response(resp) + + return protoResp, nil } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/data_source.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/data_source.go index f6871cee..ebb2cbd3 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/data_source.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/data_source.go @@ -7,6 +7,13 @@ import ( "context" ) +// DataSourceMetadata describes metadata for a data resource in the GetMetadata +// RPC. +type DataSourceMetadata struct { + // TypeName is the name of the data resource. + TypeName string +} + // DataSourceServer is an interface containing the methods a data source // implementation needs to fill. type DataSourceServer interface { diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/function.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/function.go new file mode 100644 index 00000000..6105b1ce --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/function.go @@ -0,0 +1,141 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfprotov6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Function describes the definition of a function. Result must be defined. +type Function struct { + // Parameters is the ordered list of positional function parameters. + Parameters []*FunctionParameter + + // VariadicParameter is an optional final parameter which accepts zero or + // more argument values, in which Terraform will send an ordered list of the + // parameter type. + VariadicParameter *FunctionParameter + + // Return is the function result. + Return *FunctionReturn + + // Summary is the shortened human-readable documentation for the function. + Summary string + + // Description is the longer human-readable documentation for the function. + Description string + + // DescriptionKind indicates the formatting and encoding that the + // Description field is using. + DescriptionKind StringKind + + // DeprecationMessage is the human-readable documentation if the function + // is deprecated. This message should be practitioner oriented to explain + // how their configuration should be updated. + DeprecationMessage string +} + +// FunctionMetadata describes metadata for a function in the GetMetadata RPC. +type FunctionMetadata struct { + // Name is the name of the function. + Name string +} + +// FunctionParameter describes the definition of a function parameter. Type must +// be defined. +type FunctionParameter struct { + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the provider. When disabled, Terraform returns an error if the + // argument value is null. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that any unknown argument value + // (recursively checked for collections) can be passed to the provider. When + // disabled and an unknown value is present, Terraform skips the function + // call entirely and returns an unknown value result from the function. + AllowUnknownValues bool + + // Description is the human-readable documentation for the parameter. + Description string + + // DescriptionKind indicates the formatting and encoding that the + // Description field is using. + DescriptionKind StringKind + + // Name is the human-readable display name for the parameter. Parameters + // are by definition positional and this name is only used in documentation. + Name string + + // Type indicates the type of data the parameter expects. + Type tftypes.Type +} + +// FunctionReturn describes the definition of a function result. Type must be +// defined. +type FunctionReturn struct { + // Type indicates the type of return data. + Type tftypes.Type +} + +// FunctionServer is an interface containing the methods a function +// implementation needs to fill. +type FunctionServer interface { + // CallFunction is called when Terraform wants to execute the logic of a + // function referenced in the configuration. + CallFunction(context.Context, *CallFunctionRequest) (*CallFunctionResponse, error) + + // GetFunctions is called when Terraform wants to lookup which functions a + // provider supports when not calling GetProviderSchema. + GetFunctions(context.Context, *GetFunctionsRequest) (*GetFunctionsResponse, error) +} + +// CallFunctionRequest is the request Terraform sends when it wants to execute +// the logic of function referenced in the configuration. +type CallFunctionRequest struct { + // Name is the function name being called. + Name string + + // Arguments is the configuration value of each argument the practitioner + // supplied for the function call. The ordering and value of each element + // matches the function parameters and their associated type. If the + // function definition includes a final variadic parameter, its value is an + // ordered list of the variadic parameter type. + Arguments []*DynamicValue +} + +// CallFunctionResponse is the response from the provider with the result of +// executing the logic of the function. +type CallFunctionResponse struct { + // Error reports errors related to the execution of the + // function logic. Returning a nil error indicates a successful response + // with no errors presented to practitioners. + Error *FunctionError + + // Result is the return value from the called function, matching the result + // type in the function definition. + Result *DynamicValue +} + +// GetFunctionsRequest is the request Terraform sends when it wants to lookup +// which functions a provider supports when not calling GetProviderSchema. +type GetFunctionsRequest struct{} + +// GetFunctionsResponse is the response from the provider about the implemented +// functions. +type GetFunctionsResponse struct { + // Diagnostics report errors or warnings related to the provider + // implementation. Returning an empty slice indicates a successful response + // with no warnings or errors presented to practitioners. + Diagnostics []*Diagnostic + + // Functions is a map of function names to their definition. + // + // Unlike data resources and managed resources, the name should NOT be + // prefixed with the provider name and an underscore. Configuration + // references to functions use a separate namespacing syntax that already + // includes the provider name. + Functions map[string]*Function +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/function_error.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/function_error.go new file mode 100644 index 00000000..17f9d8a1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/function_error.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfprotov6 + +// FunctionError is used to convey information back to the user running Terraform. +type FunctionError struct { + // Text is the description of the error. + Text string + + // FunctionArgument is the positional function argument for aligning + // configuration source. + FunctionArgument *int64 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/attribute_path.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/attribute_path.go deleted file mode 100644 index 267bc223..00000000 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/attribute_path.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package fromproto - -import ( - "errors" - - "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -var ErrUnknownAttributePathStepType = errors.New("unknown type of AttributePath_Step") - -func AttributePath(in *tfplugin6.AttributePath) (*tftypes.AttributePath, error) { - steps, err := AttributePathSteps(in.Steps) - if err != nil { - return nil, err - } - return tftypes.NewAttributePathWithSteps(steps), nil -} - -func AttributePaths(in []*tfplugin6.AttributePath) ([]*tftypes.AttributePath, error) { - resp := make([]*tftypes.AttributePath, 0, len(in)) - for _, a := range in { - if a == nil { - resp = append(resp, nil) - continue - } - attr, err := AttributePath(a) - if err != nil { - return resp, err - } - resp = append(resp, attr) - } - return resp, nil -} - -func AttributePathStep(step *tfplugin6.AttributePath_Step) (tftypes.AttributePathStep, error) { - selector := step.GetSelector() - if v, ok := selector.(*tfplugin6.AttributePath_Step_AttributeName); ok { - return tftypes.AttributeName(v.AttributeName), nil - } - if v, ok := selector.(*tfplugin6.AttributePath_Step_ElementKeyString); ok { - return tftypes.ElementKeyString(v.ElementKeyString), nil - } - if v, ok := selector.(*tfplugin6.AttributePath_Step_ElementKeyInt); ok { - return tftypes.ElementKeyInt(v.ElementKeyInt), nil - } - return nil, ErrUnknownAttributePathStepType -} - -func AttributePathSteps(in []*tfplugin6.AttributePath_Step) ([]tftypes.AttributePathStep, error) { - resp := make([]tftypes.AttributePathStep, 0, len(in)) - for _, step := range in { - if step == nil { - continue - } - s, err := AttributePathStep(step) - if err != nil { - return resp, err - } - resp = append(resp, s) - } - return resp, nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/data_source.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/data_source.go index 3abff4ba..2544e12f 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/data_source.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/data_source.go @@ -8,49 +8,29 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" ) -func ValidateDataResourceConfigRequest(in *tfplugin6.ValidateDataResourceConfig_Request) (*tfprotov6.ValidateDataResourceConfigRequest, error) { +func ValidateDataResourceConfigRequest(in *tfplugin6.ValidateDataResourceConfig_Request) *tfprotov6.ValidateDataResourceConfigRequest { + if in == nil { + return nil + } + resp := &tfprotov6.ValidateDataResourceConfigRequest{ + Config: DynamicValue(in.Config), TypeName: in.TypeName, } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - return resp, nil + + return resp } -func ValidateDataResourceConfigResponse(in *tfplugin6.ValidateDataResourceConfig_Response) (*tfprotov6.ValidateDataResourceConfigResponse, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func ReadDataSourceRequest(in *tfplugin6.ReadDataSource_Request) *tfprotov6.ReadDataSourceRequest { + if in == nil { + return nil } - return &tfprotov6.ValidateDataResourceConfigResponse{ - Diagnostics: diags, - }, nil -} -func ReadDataSourceRequest(in *tfplugin6.ReadDataSource_Request) (*tfprotov6.ReadDataSourceRequest, error) { resp := &tfprotov6.ReadDataSourceRequest{ - TypeName: in.TypeName, + Config: DynamicValue(in.Config), + ProviderMeta: DynamicValue(in.ProviderMeta), + TypeName: in.TypeName, } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) - } - return resp, nil -} -func ReadDataSourceResponse(in *tfplugin6.ReadDataSource_Response) (*tfprotov6.ReadDataSourceResponse, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err - } - resp := &tfprotov6.ReadDataSourceResponse{ - Diagnostics: diags, - } - if in.State != nil { - resp.State = DynamicValue(in.State) - } - return resp, nil + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/diagnostic.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/diagnostic.go deleted file mode 100644 index 21673ca0..00000000 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/diagnostic.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package fromproto - -import ( - "github.com/hashicorp/terraform-plugin-go/tfprotov6" - "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" -) - -func Diagnostic(in *tfplugin6.Diagnostic) (*tfprotov6.Diagnostic, error) { - diag := &tfprotov6.Diagnostic{ - Severity: DiagnosticSeverity(in.Severity), - Summary: in.Summary, - Detail: in.Detail, - } - if in.Attribute != nil { - attr, err := AttributePath(in.Attribute) - if err != nil { - return diag, err - } - diag.Attribute = attr - } - return diag, nil -} - -func DiagnosticSeverity(in tfplugin6.Diagnostic_Severity) tfprotov6.DiagnosticSeverity { - return tfprotov6.DiagnosticSeverity(in) -} - -func Diagnostics(in []*tfplugin6.Diagnostic) ([]*tfprotov6.Diagnostic, error) { - diagnostics := make([]*tfprotov6.Diagnostic, 0, len(in)) - for _, diag := range in { - if diag == nil { - diagnostics = append(diagnostics, nil) - continue - } - d, err := Diagnostic(diag) - if err != nil { - return diagnostics, err - } - diagnostics = append(diagnostics, d) - } - return diagnostics, nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/doc.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/doc.go new file mode 100644 index 00000000..a9996dff --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package fromproto converts Protocol Buffers generated tfplugin6 types into +// terraform-plugin-go tfprotov6 types. +package fromproto diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/types.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/dynamic_value.go similarity index 81% rename from vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/types.go rename to vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/dynamic_value.go index 967256b7..d66d3dd0 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/types.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/dynamic_value.go @@ -9,8 +9,14 @@ import ( ) func DynamicValue(in *tfplugin6.DynamicValue) *tfprotov6.DynamicValue { - return &tfprotov6.DynamicValue{ + if in == nil { + return nil + } + + resp := &tfprotov6.DynamicValue{ MsgPack: in.Msgpack, JSON: in.Json, } + + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/function.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/function.go new file mode 100644 index 00000000..a2535173 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/function.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto + +import ( + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" +) + +func CallFunctionRequest(in *tfplugin6.CallFunction_Request) *tfprotov6.CallFunctionRequest { + if in == nil { + return nil + } + + resp := &tfprotov6.CallFunctionRequest{ + Arguments: make([]*tfprotov6.DynamicValue, 0, len(in.Arguments)), + Name: in.Name, + } + + for _, argument := range in.Arguments { + resp.Arguments = append(resp.Arguments, DynamicValue(argument)) + } + + return resp +} + +func GetFunctionsRequest(in *tfplugin6.GetFunctions_Request) *tfprotov6.GetFunctionsRequest { + if in == nil { + return nil + } + + resp := &tfprotov6.GetFunctionsRequest{} + + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/provider.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/provider.go index b302b5d6..91228868 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/provider.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/provider.go @@ -8,102 +8,57 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" ) -func GetProviderSchemaRequest(in *tfplugin6.GetProviderSchema_Request) (*tfprotov6.GetProviderSchemaRequest, error) { - return &tfprotov6.GetProviderSchemaRequest{}, nil +func GetMetadataRequest(in *tfplugin6.GetMetadata_Request) *tfprotov6.GetMetadataRequest { + if in == nil { + return nil + } + + resp := &tfprotov6.GetMetadataRequest{} + + return resp } -func GetProviderSchemaResponse(in *tfplugin6.GetProviderSchema_Response) (*tfprotov6.GetProviderSchemaResponse, error) { - var resp tfprotov6.GetProviderSchemaResponse - if in.Provider != nil { - schema, err := Schema(in.Provider) - if err != nil { - return &resp, err - } - resp.Provider = schema - } - if in.ProviderMeta != nil { - schema, err := Schema(in.ProviderMeta) - if err != nil { - return &resp, err - } - resp.ProviderMeta = schema - } - resp.ResourceSchemas = make(map[string]*tfprotov6.Schema, len(in.ResourceSchemas)) - for k, v := range in.ResourceSchemas { - if v == nil { - resp.ResourceSchemas[k] = nil - continue - } - schema, err := Schema(v) - if err != nil { - return &resp, err - } - resp.ResourceSchemas[k] = schema +func GetProviderSchemaRequest(in *tfplugin6.GetProviderSchema_Request) *tfprotov6.GetProviderSchemaRequest { + if in == nil { + return nil } - resp.DataSourceSchemas = make(map[string]*tfprotov6.Schema, len(in.DataSourceSchemas)) - for k, v := range in.DataSourceSchemas { - if v == nil { - resp.DataSourceSchemas[k] = nil - continue - } - schema, err := Schema(v) - if err != nil { - return &resp, err - } - resp.DataSourceSchemas[k] = schema - } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return &resp, err - } - resp.Diagnostics = diags - return &resp, nil + + resp := &tfprotov6.GetProviderSchemaRequest{} + + return resp } -func ValidateProviderConfigRequest(in *tfplugin6.ValidateProviderConfig_Request) (*tfprotov6.ValidateProviderConfigRequest, error) { - var resp tfprotov6.ValidateProviderConfigRequest - if in.Config != nil { - resp.Config = DynamicValue(in.Config) +func ValidateProviderConfigRequest(in *tfplugin6.ValidateProviderConfig_Request) *tfprotov6.ValidateProviderConfigRequest { + if in == nil { + return nil } - return &resp, nil -} -func ValidateProviderConfigResponse(in *tfplugin6.ValidateProviderConfig_Response) (*tfprotov6.ValidateProviderConfigResponse, error) { - var resp tfprotov6.ValidateProviderConfigResponse - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err + resp := &tfprotov6.ValidateProviderConfigRequest{ + Config: DynamicValue(in.Config), } - resp.Diagnostics = diags - return &resp, nil + + return resp } -func ConfigureProviderRequest(in *tfplugin6.ConfigureProvider_Request) (*tfprotov6.ConfigureProviderRequest, error) { +func ConfigureProviderRequest(in *tfplugin6.ConfigureProvider_Request) *tfprotov6.ConfigureProviderRequest { + if in == nil { + return nil + } + resp := &tfprotov6.ConfigureProviderRequest{ + Config: DynamicValue(in.Config), TerraformVersion: in.TerraformVersion, } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - return resp, nil + + return resp } -func ConfigureProviderResponse(in *tfplugin6.ConfigureProvider_Response) (*tfprotov6.ConfigureProviderResponse, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func StopProviderRequest(in *tfplugin6.StopProvider_Request) *tfprotov6.StopProviderRequest { + if in == nil { + return nil } - return &tfprotov6.ConfigureProviderResponse{ - Diagnostics: diags, - }, nil -} -func StopProviderRequest(in *tfplugin6.StopProvider_Request) (*tfprotov6.StopProviderRequest, error) { - return &tfprotov6.StopProviderRequest{}, nil -} + resp := &tfprotov6.StopProviderRequest{} -func StopProviderResponse(in *tfplugin6.StopProvider_Response) (*tfprotov6.StopProviderResponse, error) { - return &tfprotov6.StopProviderResponse{ - Error: in.Error, - }, nil + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/state.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/raw_state.go similarity index 81% rename from vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/state.go rename to vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/raw_state.go index e5470b50..559b0826 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/state.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/raw_state.go @@ -9,8 +9,14 @@ import ( ) func RawState(in *tfplugin6.RawState) *tfprotov6.RawState { - return &tfprotov6.RawState{ + if in == nil { + return nil + } + + resp := &tfprotov6.RawState{ JSON: in.Json, Flatmap: in.Flatmap, } + + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/resource.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/resource.go index d69e3822..1b5997c7 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/resource.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/resource.go @@ -4,208 +4,112 @@ package fromproto import ( - "fmt" - "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" ) -func ValidateResourceConfigRequest(in *tfplugin6.ValidateResourceConfig_Request) (*tfprotov6.ValidateResourceConfigRequest, error) { +func ValidateResourceConfigRequest(in *tfplugin6.ValidateResourceConfig_Request) *tfprotov6.ValidateResourceConfigRequest { + if in == nil { + return nil + } + resp := &tfprotov6.ValidateResourceConfigRequest{ + Config: DynamicValue(in.Config), TypeName: in.TypeName, } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - return resp, nil + + return resp } -func ValidateResourceConfigResponse(in *tfplugin6.ValidateResourceConfig_Response) (*tfprotov6.ValidateResourceConfigResponse, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func UpgradeResourceStateRequest(in *tfplugin6.UpgradeResourceState_Request) *tfprotov6.UpgradeResourceStateRequest { + if in == nil { + return nil } - return &tfprotov6.ValidateResourceConfigResponse{ - Diagnostics: diags, - }, nil -} -func UpgradeResourceStateRequest(in *tfplugin6.UpgradeResourceState_Request) (*tfprotov6.UpgradeResourceStateRequest, error) { resp := &tfprotov6.UpgradeResourceStateRequest{ + RawState: RawState(in.RawState), TypeName: in.TypeName, Version: in.Version, } - if in.RawState != nil { - resp.RawState = RawState(in.RawState) - } - return resp, nil + + return resp } -func UpgradeResourceStateResponse(in *tfplugin6.UpgradeResourceState_Response) (*tfprotov6.UpgradeResourceStateResponse, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err - } - resp := &tfprotov6.UpgradeResourceStateResponse{ - Diagnostics: diags, +func ReadResourceRequest(in *tfplugin6.ReadResource_Request) *tfprotov6.ReadResourceRequest { + if in == nil { + return nil } - if in.UpgradedState != nil { - resp.UpgradedState = DynamicValue(in.UpgradedState) - } - return resp, nil -} -func ReadResourceRequest(in *tfplugin6.ReadResource_Request) (*tfprotov6.ReadResourceRequest, error) { resp := &tfprotov6.ReadResourceRequest{ - TypeName: in.TypeName, - Private: in.Private, - } - if in.CurrentState != nil { - resp.CurrentState = DynamicValue(in.CurrentState) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) + CurrentState: DynamicValue(in.CurrentState), + Private: in.Private, + ProviderMeta: DynamicValue(in.ProviderMeta), + TypeName: in.TypeName, } - return resp, nil + + return resp } -func ReadResourceResponse(in *tfplugin6.ReadResource_Response) (*tfprotov6.ReadResourceResponse, error) { - resp := &tfprotov6.ReadResourceResponse{ - Private: in.Private, - } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err - } - resp.Diagnostics = diags - if in.NewState != nil { - resp.NewState = DynamicValue(in.NewState) +func PlanResourceChangeRequest(in *tfplugin6.PlanResourceChange_Request) *tfprotov6.PlanResourceChangeRequest { + if in == nil { + return nil } - return resp, nil -} -func PlanResourceChangeRequest(in *tfplugin6.PlanResourceChange_Request) (*tfprotov6.PlanResourceChangeRequest, error) { resp := &tfprotov6.PlanResourceChangeRequest{ - TypeName: in.TypeName, - PriorPrivate: in.PriorPrivate, - } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - if in.PriorState != nil { - resp.PriorState = DynamicValue(in.PriorState) - } - if in.ProposedNewState != nil { - resp.ProposedNewState = DynamicValue(in.ProposedNewState) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) + Config: DynamicValue(in.Config), + PriorPrivate: in.PriorPrivate, + PriorState: DynamicValue(in.PriorState), + ProposedNewState: DynamicValue(in.ProposedNewState), + ProviderMeta: DynamicValue(in.ProviderMeta), + TypeName: in.TypeName, } - return resp, nil + + return resp } -func PlanResourceChangeResponse(in *tfplugin6.PlanResourceChange_Response) (*tfprotov6.PlanResourceChangeResponse, error) { - resp := &tfprotov6.PlanResourceChangeResponse{ - PlannedPrivate: in.PlannedPrivate, - UnsafeToUseLegacyTypeSystem: in.LegacyTypeSystem, - } - attributePaths, err := AttributePaths(in.RequiresReplace) - if err != nil { - return resp, err - } - resp.RequiresReplace = attributePaths - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err +func ApplyResourceChangeRequest(in *tfplugin6.ApplyResourceChange_Request) *tfprotov6.ApplyResourceChangeRequest { + if in == nil { + return nil } - resp.Diagnostics = diags - if in.PlannedState != nil { - resp.PlannedState = DynamicValue(in.PlannedState) - } - return resp, nil -} -func ApplyResourceChangeRequest(in *tfplugin6.ApplyResourceChange_Request) (*tfprotov6.ApplyResourceChangeRequest, error) { resp := &tfprotov6.ApplyResourceChangeRequest{ - TypeName: in.TypeName, + Config: DynamicValue(in.Config), PlannedPrivate: in.PlannedPrivate, + PlannedState: DynamicValue(in.PlannedState), + PriorState: DynamicValue(in.PriorState), + ProviderMeta: DynamicValue(in.ProviderMeta), + TypeName: in.TypeName, } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - if in.PriorState != nil { - resp.PriorState = DynamicValue(in.PriorState) - } - if in.PlannedState != nil { - resp.PlannedState = DynamicValue(in.PlannedState) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) - } - return resp, nil + + return resp } -func ApplyResourceChangeResponse(in *tfplugin6.ApplyResourceChange_Response) (*tfprotov6.ApplyResourceChangeResponse, error) { - resp := &tfprotov6.ApplyResourceChangeResponse{ - Private: in.Private, - UnsafeToUseLegacyTypeSystem: in.LegacyTypeSystem, +func ImportResourceStateRequest(in *tfplugin6.ImportResourceState_Request) *tfprotov6.ImportResourceStateRequest { + if in == nil { + return nil } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err - } - resp.Diagnostics = diags - if in.NewState != nil { - resp.NewState = DynamicValue(in.NewState) - } - return resp, nil -} -func ImportResourceStateRequest(in *tfplugin6.ImportResourceState_Request) (*tfprotov6.ImportResourceStateRequest, error) { - return &tfprotov6.ImportResourceStateRequest{ + resp := &tfprotov6.ImportResourceStateRequest{ TypeName: in.TypeName, ID: in.Id, - }, nil -} - -func ImportResourceStateResponse(in *tfplugin6.ImportResourceState_Response) (*tfprotov6.ImportResourceStateResponse, error) { - imported, err := ImportedResources(in.ImportedResources) - if err != nil { - return nil, err - } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err } - return &tfprotov6.ImportResourceStateResponse{ - ImportedResources: imported, - Diagnostics: diags, - }, nil + + return resp } -func ImportedResource(in *tfplugin6.ImportResourceState_ImportedResource) (*tfprotov6.ImportedResource, error) { - resp := &tfprotov6.ImportedResource{ - TypeName: in.TypeName, - Private: in.Private, - } - if in.State != nil { - resp.State = DynamicValue(in.State) +func MoveResourceStateRequest(in *tfplugin6.MoveResourceState_Request) *tfprotov6.MoveResourceStateRequest { + if in == nil { + return nil } - return resp, nil -} -func ImportedResources(in []*tfplugin6.ImportResourceState_ImportedResource) ([]*tfprotov6.ImportedResource, error) { - resp := make([]*tfprotov6.ImportedResource, 0, len(in)) - for pos, i := range in { - if i == nil { - resp = append(resp, nil) - continue - } - r, err := ImportedResource(i) - if err != nil { - return resp, fmt.Errorf("Error converting imported resource %d/%d: %w", pos+1, len(in), err) - } - resp = append(resp, r) + resp := &tfprotov6.MoveResourceStateRequest{ + SourcePrivate: in.SourcePrivate, + SourceProviderAddress: in.SourceProviderAddress, + SourceSchemaVersion: in.SourceSchemaVersion, + SourceState: RawState(in.SourceState), + SourceTypeName: in.SourceTypeName, + TargetTypeName: in.TargetTypeName, } - return resp, nil + + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/schema.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/schema.go deleted file mode 100644 index b4cb1399..00000000 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/schema.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package fromproto - -import ( - "fmt" - - "github.com/hashicorp/terraform-plugin-go/tfprotov6" - "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -func Schema(in *tfplugin6.Schema) (*tfprotov6.Schema, error) { - var resp tfprotov6.Schema - resp.Version = in.Version - if in.Block != nil { - block, err := SchemaBlock(in.Block) - if err != nil { - return &resp, err - } - resp.Block = block - } - return &resp, nil -} - -func SchemaBlock(in *tfplugin6.Schema_Block) (*tfprotov6.SchemaBlock, error) { - resp := &tfprotov6.SchemaBlock{ - Version: in.Version, - Description: in.Description, - DescriptionKind: StringKind(in.DescriptionKind), - Deprecated: in.Deprecated, - } - attrs, err := SchemaAttributes(in.Attributes) - if err != nil { - return resp, err - } - resp.Attributes = attrs - blocks, err := SchemaNestedBlocks(in.BlockTypes) - if err != nil { - return resp, err - } - resp.BlockTypes = blocks - return resp, nil -} - -func SchemaAttribute(in *tfplugin6.Schema_Attribute) (*tfprotov6.SchemaAttribute, error) { - resp := &tfprotov6.SchemaAttribute{ - Name: in.Name, - Description: in.Description, - Required: in.Required, - Optional: in.Optional, - Computed: in.Computed, - Sensitive: in.Sensitive, - DescriptionKind: StringKind(in.DescriptionKind), - Deprecated: in.Deprecated, - } - - if in.Type != nil { - typ, err := tftypes.ParseJSONType(in.Type) //nolint:staticcheck - if err != nil { - return resp, err - } - resp.Type = typ - } - - if in.NestedType != nil { - nb, err := SchemaObject(in.NestedType) - if err != nil { - return resp, err - } - resp.NestedType = nb - } - - return resp, nil -} - -func SchemaAttributes(in []*tfplugin6.Schema_Attribute) ([]*tfprotov6.SchemaAttribute, error) { - resp := make([]*tfprotov6.SchemaAttribute, 0, len(in)) - for pos, a := range in { - if a == nil { - resp = append(resp, nil) - continue - } - attr, err := SchemaAttribute(a) - if err != nil { - return resp, fmt.Errorf("error converting schema attribute %d: %w", pos, err) - } - resp = append(resp, attr) - } - return resp, nil -} - -func SchemaNestedBlock(in *tfplugin6.Schema_NestedBlock) (*tfprotov6.SchemaNestedBlock, error) { - resp := &tfprotov6.SchemaNestedBlock{ - TypeName: in.TypeName, - Nesting: SchemaNestedBlockNestingMode(in.Nesting), - MinItems: in.MinItems, - MaxItems: in.MaxItems, - } - if in.Block != nil { - block, err := SchemaBlock(in.Block) - if err != nil { - return resp, err - } - resp.Block = block - } - return resp, nil -} - -func SchemaNestedBlocks(in []*tfplugin6.Schema_NestedBlock) ([]*tfprotov6.SchemaNestedBlock, error) { - resp := make([]*tfprotov6.SchemaNestedBlock, 0, len(in)) - for pos, b := range in { - if b == nil { - resp = append(resp, nil) - continue - } - block, err := SchemaNestedBlock(b) - if err != nil { - return resp, fmt.Errorf("error converting nested block %d: %w", pos, err) - } - resp = append(resp, block) - } - return resp, nil -} - -func SchemaNestedBlockNestingMode(in tfplugin6.Schema_NestedBlock_NestingMode) tfprotov6.SchemaNestedBlockNestingMode { - return tfprotov6.SchemaNestedBlockNestingMode(in) -} - -func SchemaObjectNestingMode(in tfplugin6.Schema_Object_NestingMode) tfprotov6.SchemaObjectNestingMode { - return tfprotov6.SchemaObjectNestingMode(in) -} - -func SchemaObject(in *tfplugin6.Schema_Object) (*tfprotov6.SchemaObject, error) { - resp := &tfprotov6.SchemaObject{ - Nesting: SchemaObjectNestingMode(in.Nesting), - } - - attrs, err := SchemaAttributes(in.Attributes) - if err != nil { - return nil, err - } - - resp.Attributes = attrs - return resp, nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/string_kind.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/string_kind.go deleted file mode 100644 index bfe82ca8..00000000 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto/string_kind.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package fromproto - -import ( - "github.com/hashicorp/terraform-plugin-go/tfprotov6" - "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" -) - -func StringKind(in tfplugin6.StringKind) tfprotov6.StringKind { - return tfprotov6.StringKind(in) -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/funcerr/doc.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/funcerr/doc.go new file mode 100644 index 00000000..9b9f61f0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/funcerr/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package funcerr contains function error helpers. These implementations are +// intentionally outside the public API. +package funcerr diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/funcerr/function_error.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/funcerr/function_error.go new file mode 100644 index 00000000..0d6f6655 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/funcerr/function_error.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package funcerr + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/internal/logging" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// FunctionError is a single FunctionError. +type FunctionError tfprotov6.FunctionError + +// HasError returns true if the FunctionError is not empty. +func (e *FunctionError) HasError() bool { + if e == nil { + return false + } + + return e.Text != "" || e.FunctionArgument != nil +} + +// Log will log the function error: +func (e *FunctionError) Log(ctx context.Context) { + if e == nil { + return + } + + if !e.HasError() { + return + } + + switch { + case e.FunctionArgument != nil && e.Text != "": + logging.ProtocolError(ctx, "Response contains function error", map[string]interface{}{ + logging.KeyFunctionErrorText: e.Text, + logging.KeyFunctionErrorArgument: *e.FunctionArgument, + }) + case e.FunctionArgument != nil: + logging.ProtocolError(ctx, "Response contains function error", map[string]interface{}{ + logging.KeyFunctionErrorArgument: *e.FunctionArgument, + }) + case e.Text != "": + logging.ProtocolError(ctx, "Response contains function error", map[string]interface{}{ + logging.KeyFunctionErrorText: e.Text, + }) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tf6serverlogging/downstream_request.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tf6serverlogging/downstream_request.go index 0fd36326..9c27d417 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tf6serverlogging/downstream_request.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tf6serverlogging/downstream_request.go @@ -8,7 +8,9 @@ import ( "time" "github.com/hashicorp/terraform-plugin-go/internal/logging" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/diag" + "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/funcerr" ) // DownstreamRequest sets a request duration start time context key and @@ -40,3 +42,23 @@ func DownstreamResponse(ctx context.Context, diagnostics diag.Diagnostics) { logging.ProtocolTrace(ctx, "Received downstream response", responseFields) diagnostics.Log(ctx) } + +// DownstreamResponseWithError generates the following logging: +// +// - TRACE "Received downstream response" log with request duration and +// whether a function error is present +// - Log with function error details +func DownstreamResponseWithError(ctx context.Context, funcErr *tfprotov6.FunctionError) { + fe := (*funcerr.FunctionError)(funcErr) + + responseFields := map[string]interface{}{ + logging.KeyFunctionErrorExists: fe.HasError(), + } + + if requestStart, ok := ctx.Value(ContextKeyDownstreamRequestStartTime{}).(time.Time); ok { + responseFields[logging.KeyRequestDurationMs] = time.Since(requestStart).Milliseconds() + } + + logging.ProtocolTrace(ctx, "Received downstream response", responseFields) + fe.Log(ctx) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tf6serverlogging/server_capabilities.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tf6serverlogging/server_capabilities.go new file mode 100644 index 00000000..f6aaf953 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tf6serverlogging/server_capabilities.go @@ -0,0 +1,26 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tf6serverlogging + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/internal/logging" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ServerCapabilities generates a TRACE "Announced server capabilities" log. +func ServerCapabilities(ctx context.Context, capabilities *tfprotov6.ServerCapabilities) { + responseFields := map[string]interface{}{ + logging.KeyServerCapabilityGetProviderSchemaOptional: false, + logging.KeyServerCapabilityPlanDestroy: false, + } + + if capabilities != nil { + responseFields[logging.KeyServerCapabilityGetProviderSchemaOptional] = capabilities.GetProviderSchemaOptional + responseFields[logging.KeyServerCapabilityPlanDestroy] = capabilities.PlanDestroy + } + + logging.ProtocolTrace(ctx, "Announced server capabilities", responseFields) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6.pb.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6.pb.go index 221ad51e..9016dfe4 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6.pb.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6.pb.go @@ -1,9 +1,9 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -// Terraform Plugin RPC protocol version 6.3 +// Terraform Plugin RPC protocol version 6.5 // -// This file defines version 6.3 of the RPC protocol. To implement a plugin +// This file defines version 6.5 of the RPC protocol. To implement a plugin // against this protocol, copy this definition into your own codebase and // use protoc to generate stubs for your target language. // @@ -22,8 +22,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v4.23.2 +// protoc-gen-go v1.33.0 +// protoc v4.25.1 // source: tfplugin6.proto package tfplugin6 @@ -192,7 +192,7 @@ func (x Schema_NestedBlock_NestingMode) Number() protoreflect.EnumNumber { // Deprecated: Use Schema_NestedBlock_NestingMode.Descriptor instead. func (Schema_NestedBlock_NestingMode) EnumDescriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{5, 2, 0} + return file_tfplugin6_proto_rawDescGZIP(), []int{6, 2, 0} } type Schema_Object_NestingMode int32 @@ -247,7 +247,7 @@ func (x Schema_Object_NestingMode) Number() protoreflect.EnumNumber { // Deprecated: Use Schema_Object_NestingMode.Descriptor instead. func (Schema_Object_NestingMode) EnumDescriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{5, 3, 0} + return file_tfplugin6_proto_rawDescGZIP(), []int{6, 3, 0} } // DynamicValue is an opaque encoding of terraform data, with the field name @@ -378,6 +378,63 @@ func (x *Diagnostic) GetAttribute() *AttributePath { return nil } +type FunctionError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` + // The optional function_argument records the index position of the + // argument which caused the error. + FunctionArgument *int64 `protobuf:"varint,2,opt,name=function_argument,json=functionArgument,proto3,oneof" json:"function_argument,omitempty"` +} + +func (x *FunctionError) Reset() { + *x = FunctionError{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FunctionError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FunctionError) ProtoMessage() {} + +func (x *FunctionError) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FunctionError.ProtoReflect.Descriptor instead. +func (*FunctionError) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{2} +} + +func (x *FunctionError) GetText() string { + if x != nil { + return x.Text + } + return "" +} + +func (x *FunctionError) GetFunctionArgument() int64 { + if x != nil && x.FunctionArgument != nil { + return *x.FunctionArgument + } + return 0 +} + type AttributePath struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -389,7 +446,7 @@ type AttributePath struct { func (x *AttributePath) Reset() { *x = AttributePath{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[2] + mi := &file_tfplugin6_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -402,7 +459,7 @@ func (x *AttributePath) String() string { func (*AttributePath) ProtoMessage() {} func (x *AttributePath) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[2] + mi := &file_tfplugin6_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -415,7 +472,7 @@ func (x *AttributePath) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributePath.ProtoReflect.Descriptor instead. func (*AttributePath) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{2} + return file_tfplugin6_proto_rawDescGZIP(), []int{3} } func (x *AttributePath) GetSteps() []*AttributePath_Step { @@ -434,7 +491,7 @@ type StopProvider struct { func (x *StopProvider) Reset() { *x = StopProvider{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[3] + mi := &file_tfplugin6_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -447,7 +504,7 @@ func (x *StopProvider) String() string { func (*StopProvider) ProtoMessage() {} func (x *StopProvider) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[3] + mi := &file_tfplugin6_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -460,7 +517,7 @@ func (x *StopProvider) ProtoReflect() protoreflect.Message { // Deprecated: Use StopProvider.ProtoReflect.Descriptor instead. func (*StopProvider) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{3} + return file_tfplugin6_proto_rawDescGZIP(), []int{4} } // RawState holds the stored state for a resource to be upgraded by the @@ -478,7 +535,7 @@ type RawState struct { func (x *RawState) Reset() { *x = RawState{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[4] + mi := &file_tfplugin6_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -491,7 +548,7 @@ func (x *RawState) String() string { func (*RawState) ProtoMessage() {} func (x *RawState) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[4] + mi := &file_tfplugin6_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -504,7 +561,7 @@ func (x *RawState) ProtoReflect() protoreflect.Message { // Deprecated: Use RawState.ProtoReflect.Descriptor instead. func (*RawState) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{4} + return file_tfplugin6_proto_rawDescGZIP(), []int{5} } func (x *RawState) GetJson() []byte { @@ -538,7 +595,7 @@ type Schema struct { func (x *Schema) Reset() { *x = Schema{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[5] + mi := &file_tfplugin6_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -551,7 +608,7 @@ func (x *Schema) String() string { func (*Schema) ProtoMessage() {} func (x *Schema) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[5] + mi := &file_tfplugin6_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -564,7 +621,7 @@ func (x *Schema) ProtoReflect() protoreflect.Message { // Deprecated: Use Schema.ProtoReflect.Descriptor instead. func (*Schema) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{5} + return file_tfplugin6_proto_rawDescGZIP(), []int{6} } func (x *Schema) GetVersion() int64 { @@ -581,29 +638,47 @@ func (x *Schema) GetBlock() *Schema_Block { return nil } -type GetProviderSchema struct { +type Function struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields -} -func (x *GetProviderSchema) Reset() { - *x = GetProviderSchema{} + // parameters is the ordered list of positional function parameters. + Parameters []*Function_Parameter `protobuf:"bytes,1,rep,name=parameters,proto3" json:"parameters,omitempty"` + // variadic_parameter is an optional final parameter which accepts + // zero or more argument values, in which Terraform will send an + // ordered list of the parameter type. + VariadicParameter *Function_Parameter `protobuf:"bytes,2,opt,name=variadic_parameter,json=variadicParameter,proto3" json:"variadic_parameter,omitempty"` + // return is the function result. + Return *Function_Return `protobuf:"bytes,3,opt,name=return,proto3" json:"return,omitempty"` + // summary is the human-readable shortened documentation for the function. + Summary string `protobuf:"bytes,4,opt,name=summary,proto3" json:"summary,omitempty"` + // description is human-readable documentation for the function. + Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` + // description_kind is the formatting of the description. + DescriptionKind StringKind `protobuf:"varint,6,opt,name=description_kind,json=descriptionKind,proto3,enum=tfplugin6.StringKind" json:"description_kind,omitempty"` + // deprecation_message is human-readable documentation if the + // function is deprecated. + DeprecationMessage string `protobuf:"bytes,7,opt,name=deprecation_message,json=deprecationMessage,proto3" json:"deprecation_message,omitempty"` +} + +func (x *Function) Reset() { + *x = Function{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[6] + mi := &file_tfplugin6_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetProviderSchema) String() string { +func (x *Function) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetProviderSchema) ProtoMessage() {} +func (*Function) ProtoMessage() {} -func (x *GetProviderSchema) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[6] +func (x *Function) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -614,57 +689,84 @@ func (x *GetProviderSchema) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetProviderSchema.ProtoReflect.Descriptor instead. -func (*GetProviderSchema) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{6} +// Deprecated: Use Function.ProtoReflect.Descriptor instead. +func (*Function) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{7} } -type ValidateProviderConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields +func (x *Function) GetParameters() []*Function_Parameter { + if x != nil { + return x.Parameters + } + return nil } -func (x *ValidateProviderConfig) Reset() { - *x = ValidateProviderConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *Function) GetVariadicParameter() *Function_Parameter { + if x != nil { + return x.VariadicParameter } + return nil } -func (x *ValidateProviderConfig) String() string { - return protoimpl.X.MessageStringOf(x) +func (x *Function) GetReturn() *Function_Return { + if x != nil { + return x.Return + } + return nil } -func (*ValidateProviderConfig) ProtoMessage() {} +func (x *Function) GetSummary() string { + if x != nil { + return x.Summary + } + return "" +} -func (x *ValidateProviderConfig) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms +func (x *Function) GetDescription() string { + if x != nil { + return x.Description } - return mi.MessageOf(x) + return "" } -// Deprecated: Use ValidateProviderConfig.ProtoReflect.Descriptor instead. -func (*ValidateProviderConfig) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{7} +func (x *Function) GetDescriptionKind() StringKind { + if x != nil { + return x.DescriptionKind + } + return StringKind_PLAIN } -type UpgradeResourceState struct { +func (x *Function) GetDeprecationMessage() string { + if x != nil { + return x.DeprecationMessage + } + return "" +} + +// ServerCapabilities allows providers to communicate extra information +// regarding supported protocol features. This is used to indicate +// availability of certain forward-compatible changes which may be optional +// in a major protocol version, but cannot be tested for directly. +type ServerCapabilities struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields -} -func (x *UpgradeResourceState) Reset() { - *x = UpgradeResourceState{} + // The plan_destroy capability signals that a provider expects a call + // to PlanResourceChange when a resource is going to be destroyed. + PlanDestroy bool `protobuf:"varint,1,opt,name=plan_destroy,json=planDestroy,proto3" json:"plan_destroy,omitempty"` + // The get_provider_schema_optional capability indicates that this + // provider does not require calling GetProviderSchema to operate + // normally, and the caller can used a cached copy of the provider's + // schema. + GetProviderSchemaOptional bool `protobuf:"varint,2,opt,name=get_provider_schema_optional,json=getProviderSchemaOptional,proto3" json:"get_provider_schema_optional,omitempty"` + // The move_resource_state capability signals that a provider supports the + // MoveResourceState RPC. + MoveResourceState bool `protobuf:"varint,3,opt,name=move_resource_state,json=moveResourceState,proto3" json:"move_resource_state,omitempty"` +} + +func (x *ServerCapabilities) Reset() { + *x = ServerCapabilities{} if protoimpl.UnsafeEnabled { mi := &file_tfplugin6_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -672,13 +774,13 @@ func (x *UpgradeResourceState) Reset() { } } -func (x *UpgradeResourceState) String() string { +func (x *ServerCapabilities) String() string { return protoimpl.X.MessageStringOf(x) } -func (*UpgradeResourceState) ProtoMessage() {} +func (*ServerCapabilities) ProtoMessage() {} -func (x *UpgradeResourceState) ProtoReflect() protoreflect.Message { +func (x *ServerCapabilities) ProtoReflect() protoreflect.Message { mi := &file_tfplugin6_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -690,19 +792,40 @@ func (x *UpgradeResourceState) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use UpgradeResourceState.ProtoReflect.Descriptor instead. -func (*UpgradeResourceState) Descriptor() ([]byte, []int) { +// Deprecated: Use ServerCapabilities.ProtoReflect.Descriptor instead. +func (*ServerCapabilities) Descriptor() ([]byte, []int) { return file_tfplugin6_proto_rawDescGZIP(), []int{8} } -type ValidateResourceConfig struct { +func (x *ServerCapabilities) GetPlanDestroy() bool { + if x != nil { + return x.PlanDestroy + } + return false +} + +func (x *ServerCapabilities) GetGetProviderSchemaOptional() bool { + if x != nil { + return x.GetProviderSchemaOptional + } + return false +} + +func (x *ServerCapabilities) GetMoveResourceState() bool { + if x != nil { + return x.MoveResourceState + } + return false +} + +type GetMetadata struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *ValidateResourceConfig) Reset() { - *x = ValidateResourceConfig{} +func (x *GetMetadata) Reset() { + *x = GetMetadata{} if protoimpl.UnsafeEnabled { mi := &file_tfplugin6_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -710,13 +833,13 @@ func (x *ValidateResourceConfig) Reset() { } } -func (x *ValidateResourceConfig) String() string { +func (x *GetMetadata) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ValidateResourceConfig) ProtoMessage() {} +func (*GetMetadata) ProtoMessage() {} -func (x *ValidateResourceConfig) ProtoReflect() protoreflect.Message { +func (x *GetMetadata) ProtoReflect() protoreflect.Message { mi := &file_tfplugin6_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -728,19 +851,19 @@ func (x *ValidateResourceConfig) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ValidateResourceConfig.ProtoReflect.Descriptor instead. -func (*ValidateResourceConfig) Descriptor() ([]byte, []int) { +// Deprecated: Use GetMetadata.ProtoReflect.Descriptor instead. +func (*GetMetadata) Descriptor() ([]byte, []int) { return file_tfplugin6_proto_rawDescGZIP(), []int{9} } -type ValidateDataResourceConfig struct { +type GetProviderSchema struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *ValidateDataResourceConfig) Reset() { - *x = ValidateDataResourceConfig{} +func (x *GetProviderSchema) Reset() { + *x = GetProviderSchema{} if protoimpl.UnsafeEnabled { mi := &file_tfplugin6_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -748,13 +871,13 @@ func (x *ValidateDataResourceConfig) Reset() { } } -func (x *ValidateDataResourceConfig) String() string { +func (x *GetProviderSchema) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ValidateDataResourceConfig) ProtoMessage() {} +func (*GetProviderSchema) ProtoMessage() {} -func (x *ValidateDataResourceConfig) ProtoReflect() protoreflect.Message { +func (x *GetProviderSchema) ProtoReflect() protoreflect.Message { mi := &file_tfplugin6_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -766,19 +889,19 @@ func (x *ValidateDataResourceConfig) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ValidateDataResourceConfig.ProtoReflect.Descriptor instead. -func (*ValidateDataResourceConfig) Descriptor() ([]byte, []int) { +// Deprecated: Use GetProviderSchema.ProtoReflect.Descriptor instead. +func (*GetProviderSchema) Descriptor() ([]byte, []int) { return file_tfplugin6_proto_rawDescGZIP(), []int{10} } -type ConfigureProvider struct { +type ValidateProviderConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *ConfigureProvider) Reset() { - *x = ConfigureProvider{} +func (x *ValidateProviderConfig) Reset() { + *x = ValidateProviderConfig{} if protoimpl.UnsafeEnabled { mi := &file_tfplugin6_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -786,13 +909,13 @@ func (x *ConfigureProvider) Reset() { } } -func (x *ConfigureProvider) String() string { +func (x *ValidateProviderConfig) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ConfigureProvider) ProtoMessage() {} +func (*ValidateProviderConfig) ProtoMessage() {} -func (x *ConfigureProvider) ProtoReflect() protoreflect.Message { +func (x *ValidateProviderConfig) ProtoReflect() protoreflect.Message { mi := &file_tfplugin6_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -804,19 +927,19 @@ func (x *ConfigureProvider) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ConfigureProvider.ProtoReflect.Descriptor instead. -func (*ConfigureProvider) Descriptor() ([]byte, []int) { +// Deprecated: Use ValidateProviderConfig.ProtoReflect.Descriptor instead. +func (*ValidateProviderConfig) Descriptor() ([]byte, []int) { return file_tfplugin6_proto_rawDescGZIP(), []int{11} } -type ReadResource struct { +type UpgradeResourceState struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *ReadResource) Reset() { - *x = ReadResource{} +func (x *UpgradeResourceState) Reset() { + *x = UpgradeResourceState{} if protoimpl.UnsafeEnabled { mi := &file_tfplugin6_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -824,13 +947,13 @@ func (x *ReadResource) Reset() { } } -func (x *ReadResource) String() string { +func (x *UpgradeResourceState) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ReadResource) ProtoMessage() {} +func (*UpgradeResourceState) ProtoMessage() {} -func (x *ReadResource) ProtoReflect() protoreflect.Message { +func (x *UpgradeResourceState) ProtoReflect() protoreflect.Message { mi := &file_tfplugin6_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -842,19 +965,19 @@ func (x *ReadResource) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ReadResource.ProtoReflect.Descriptor instead. -func (*ReadResource) Descriptor() ([]byte, []int) { +// Deprecated: Use UpgradeResourceState.ProtoReflect.Descriptor instead. +func (*UpgradeResourceState) Descriptor() ([]byte, []int) { return file_tfplugin6_proto_rawDescGZIP(), []int{12} } -type PlanResourceChange struct { +type ValidateResourceConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *PlanResourceChange) Reset() { - *x = PlanResourceChange{} +func (x *ValidateResourceConfig) Reset() { + *x = ValidateResourceConfig{} if protoimpl.UnsafeEnabled { mi := &file_tfplugin6_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -862,13 +985,13 @@ func (x *PlanResourceChange) Reset() { } } -func (x *PlanResourceChange) String() string { +func (x *ValidateResourceConfig) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PlanResourceChange) ProtoMessage() {} +func (*ValidateResourceConfig) ProtoMessage() {} -func (x *PlanResourceChange) ProtoReflect() protoreflect.Message { +func (x *ValidateResourceConfig) ProtoReflect() protoreflect.Message { mi := &file_tfplugin6_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -880,19 +1003,19 @@ func (x *PlanResourceChange) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PlanResourceChange.ProtoReflect.Descriptor instead. -func (*PlanResourceChange) Descriptor() ([]byte, []int) { +// Deprecated: Use ValidateResourceConfig.ProtoReflect.Descriptor instead. +func (*ValidateResourceConfig) Descriptor() ([]byte, []int) { return file_tfplugin6_proto_rawDescGZIP(), []int{13} } -type ApplyResourceChange struct { +type ValidateDataResourceConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *ApplyResourceChange) Reset() { - *x = ApplyResourceChange{} +func (x *ValidateDataResourceConfig) Reset() { + *x = ValidateDataResourceConfig{} if protoimpl.UnsafeEnabled { mi := &file_tfplugin6_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -900,13 +1023,13 @@ func (x *ApplyResourceChange) Reset() { } } -func (x *ApplyResourceChange) String() string { +func (x *ValidateDataResourceConfig) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ApplyResourceChange) ProtoMessage() {} +func (*ValidateDataResourceConfig) ProtoMessage() {} -func (x *ApplyResourceChange) ProtoReflect() protoreflect.Message { +func (x *ValidateDataResourceConfig) ProtoReflect() protoreflect.Message { mi := &file_tfplugin6_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -918,19 +1041,19 @@ func (x *ApplyResourceChange) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ApplyResourceChange.ProtoReflect.Descriptor instead. -func (*ApplyResourceChange) Descriptor() ([]byte, []int) { +// Deprecated: Use ValidateDataResourceConfig.ProtoReflect.Descriptor instead. +func (*ValidateDataResourceConfig) Descriptor() ([]byte, []int) { return file_tfplugin6_proto_rawDescGZIP(), []int{14} } -type ImportResourceState struct { +type ConfigureProvider struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *ImportResourceState) Reset() { - *x = ImportResourceState{} +func (x *ConfigureProvider) Reset() { + *x = ConfigureProvider{} if protoimpl.UnsafeEnabled { mi := &file_tfplugin6_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -938,13 +1061,13 @@ func (x *ImportResourceState) Reset() { } } -func (x *ImportResourceState) String() string { +func (x *ConfigureProvider) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ImportResourceState) ProtoMessage() {} +func (*ConfigureProvider) ProtoMessage() {} -func (x *ImportResourceState) ProtoReflect() protoreflect.Message { +func (x *ConfigureProvider) ProtoReflect() protoreflect.Message { mi := &file_tfplugin6_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -956,19 +1079,19 @@ func (x *ImportResourceState) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ImportResourceState.ProtoReflect.Descriptor instead. -func (*ImportResourceState) Descriptor() ([]byte, []int) { +// Deprecated: Use ConfigureProvider.ProtoReflect.Descriptor instead. +func (*ConfigureProvider) Descriptor() ([]byte, []int) { return file_tfplugin6_proto_rawDescGZIP(), []int{15} } -type ReadDataSource struct { +type ReadResource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *ReadDataSource) Reset() { - *x = ReadDataSource{} +func (x *ReadResource) Reset() { + *x = ReadResource{} if protoimpl.UnsafeEnabled { mi := &file_tfplugin6_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -976,13 +1099,13 @@ func (x *ReadDataSource) Reset() { } } -func (x *ReadDataSource) String() string { +func (x *ReadResource) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ReadDataSource) ProtoMessage() {} +func (*ReadResource) ProtoMessage() {} -func (x *ReadDataSource) ProtoReflect() protoreflect.Message { +func (x *ReadResource) ProtoReflect() protoreflect.Message { mi := &file_tfplugin6_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -994,26 +1117,19 @@ func (x *ReadDataSource) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ReadDataSource.ProtoReflect.Descriptor instead. -func (*ReadDataSource) Descriptor() ([]byte, []int) { +// Deprecated: Use ReadResource.ProtoReflect.Descriptor instead. +func (*ReadResource) Descriptor() ([]byte, []int) { return file_tfplugin6_proto_rawDescGZIP(), []int{16} } -type AttributePath_Step struct { +type PlanResourceChange struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - // Types that are assignable to Selector: - // - // *AttributePath_Step_AttributeName - // *AttributePath_Step_ElementKeyString - // *AttributePath_Step_ElementKeyInt - Selector isAttributePath_Step_Selector `protobuf_oneof:"selector"` } -func (x *AttributePath_Step) Reset() { - *x = AttributePath_Step{} +func (x *PlanResourceChange) Reset() { + *x = PlanResourceChange{} if protoimpl.UnsafeEnabled { mi := &file_tfplugin6_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1021,13 +1137,13 @@ func (x *AttributePath_Step) Reset() { } } -func (x *AttributePath_Step) String() string { +func (x *PlanResourceChange) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AttributePath_Step) ProtoMessage() {} +func (*PlanResourceChange) ProtoMessage() {} -func (x *AttributePath_Step) ProtoReflect() protoreflect.Message { +func (x *PlanResourceChange) ProtoReflect() protoreflect.Message { mi := &file_tfplugin6_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1039,88 +1155,72 @@ func (x *AttributePath_Step) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AttributePath_Step.ProtoReflect.Descriptor instead. -func (*AttributePath_Step) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{2, 0} -} - -func (m *AttributePath_Step) GetSelector() isAttributePath_Step_Selector { - if m != nil { - return m.Selector - } - return nil -} - -func (x *AttributePath_Step) GetAttributeName() string { - if x, ok := x.GetSelector().(*AttributePath_Step_AttributeName); ok { - return x.AttributeName - } - return "" +// Deprecated: Use PlanResourceChange.ProtoReflect.Descriptor instead. +func (*PlanResourceChange) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{17} } -func (x *AttributePath_Step) GetElementKeyString() string { - if x, ok := x.GetSelector().(*AttributePath_Step_ElementKeyString); ok { - return x.ElementKeyString - } - return "" +type ApplyResourceChange struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (x *AttributePath_Step) GetElementKeyInt() int64 { - if x, ok := x.GetSelector().(*AttributePath_Step_ElementKeyInt); ok { - return x.ElementKeyInt +func (x *ApplyResourceChange) Reset() { + *x = ApplyResourceChange{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return 0 } -type isAttributePath_Step_Selector interface { - isAttributePath_Step_Selector() +func (x *ApplyResourceChange) String() string { + return protoimpl.X.MessageStringOf(x) } -type AttributePath_Step_AttributeName struct { - // Set "attribute_name" to represent looking up an attribute - // in the current object value. - AttributeName string `protobuf:"bytes,1,opt,name=attribute_name,json=attributeName,proto3,oneof"` -} +func (*ApplyResourceChange) ProtoMessage() {} -type AttributePath_Step_ElementKeyString struct { - // Set "element_key_*" to represent looking up an element in - // an indexable collection type. - ElementKeyString string `protobuf:"bytes,2,opt,name=element_key_string,json=elementKeyString,proto3,oneof"` +func (x *ApplyResourceChange) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -type AttributePath_Step_ElementKeyInt struct { - ElementKeyInt int64 `protobuf:"varint,3,opt,name=element_key_int,json=elementKeyInt,proto3,oneof"` +// Deprecated: Use ApplyResourceChange.ProtoReflect.Descriptor instead. +func (*ApplyResourceChange) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{18} } -func (*AttributePath_Step_AttributeName) isAttributePath_Step_Selector() {} - -func (*AttributePath_Step_ElementKeyString) isAttributePath_Step_Selector() {} - -func (*AttributePath_Step_ElementKeyInt) isAttributePath_Step_Selector() {} - -type StopProvider_Request struct { +type ImportResourceState struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *StopProvider_Request) Reset() { - *x = StopProvider_Request{} +func (x *ImportResourceState) Reset() { + *x = ImportResourceState{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[18] + mi := &file_tfplugin6_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *StopProvider_Request) String() string { +func (x *ImportResourceState) String() string { return protoimpl.X.MessageStringOf(x) } -func (*StopProvider_Request) ProtoMessage() {} +func (*ImportResourceState) ProtoMessage() {} -func (x *StopProvider_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[18] +func (x *ImportResourceState) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1131,36 +1231,34 @@ func (x *StopProvider_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use StopProvider_Request.ProtoReflect.Descriptor instead. -func (*StopProvider_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{3, 0} +// Deprecated: Use ImportResourceState.ProtoReflect.Descriptor instead. +func (*ImportResourceState) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{19} } -type StopProvider_Response struct { +type MoveResourceState struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - Error string `protobuf:"bytes,1,opt,name=Error,proto3" json:"Error,omitempty"` } -func (x *StopProvider_Response) Reset() { - *x = StopProvider_Response{} +func (x *MoveResourceState) Reset() { + *x = MoveResourceState{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[19] + mi := &file_tfplugin6_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *StopProvider_Response) String() string { +func (x *MoveResourceState) String() string { return protoimpl.X.MessageStringOf(x) } -func (*StopProvider_Response) ProtoMessage() {} +func (*MoveResourceState) ProtoMessage() {} -func (x *StopProvider_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[19] +func (x *MoveResourceState) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1171,33 +1269,19 @@ func (x *StopProvider_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use StopProvider_Response.ProtoReflect.Descriptor instead. -func (*StopProvider_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{3, 1} -} - -func (x *StopProvider_Response) GetError() string { - if x != nil { - return x.Error - } - return "" +// Deprecated: Use MoveResourceState.ProtoReflect.Descriptor instead. +func (*MoveResourceState) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{20} } -type Schema_Block struct { +type ReadDataSource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - Version int64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` - Attributes []*Schema_Attribute `protobuf:"bytes,2,rep,name=attributes,proto3" json:"attributes,omitempty"` - BlockTypes []*Schema_NestedBlock `protobuf:"bytes,3,rep,name=block_types,json=blockTypes,proto3" json:"block_types,omitempty"` - Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` - DescriptionKind StringKind `protobuf:"varint,5,opt,name=description_kind,json=descriptionKind,proto3,enum=tfplugin6.StringKind" json:"description_kind,omitempty"` - Deprecated bool `protobuf:"varint,6,opt,name=deprecated,proto3" json:"deprecated,omitempty"` } -func (x *Schema_Block) Reset() { - *x = Schema_Block{} +func (x *ReadDataSource) Reset() { + *x = ReadDataSource{} if protoimpl.UnsafeEnabled { mi := &file_tfplugin6_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1205,13 +1289,13 @@ func (x *Schema_Block) Reset() { } } -func (x *Schema_Block) String() string { +func (x *ReadDataSource) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Schema_Block) ProtoMessage() {} +func (*ReadDataSource) ProtoMessage() {} -func (x *Schema_Block) ProtoReflect() protoreflect.Message { +func (x *ReadDataSource) ProtoReflect() protoreflect.Message { mi := &file_tfplugin6_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1223,87 +1307,72 @@ func (x *Schema_Block) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Schema_Block.ProtoReflect.Descriptor instead. -func (*Schema_Block) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{5, 0} +// Deprecated: Use ReadDataSource.ProtoReflect.Descriptor instead. +func (*ReadDataSource) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{21} } -func (x *Schema_Block) GetVersion() int64 { - if x != nil { - return x.Version - } - return 0 +type GetFunctions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (x *Schema_Block) GetAttributes() []*Schema_Attribute { - if x != nil { - return x.Attributes +func (x *GetFunctions) Reset() { + *x = GetFunctions{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return nil } -func (x *Schema_Block) GetBlockTypes() []*Schema_NestedBlock { - if x != nil { - return x.BlockTypes - } - return nil +func (x *GetFunctions) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *Schema_Block) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} +func (*GetFunctions) ProtoMessage() {} -func (x *Schema_Block) GetDescriptionKind() StringKind { - if x != nil { - return x.DescriptionKind +func (x *GetFunctions) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return StringKind_PLAIN + return mi.MessageOf(x) } -func (x *Schema_Block) GetDeprecated() bool { - if x != nil { - return x.Deprecated - } - return false +// Deprecated: Use GetFunctions.ProtoReflect.Descriptor instead. +func (*GetFunctions) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{22} } -type Schema_Attribute struct { +type CallFunction struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Type []byte `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` - NestedType *Schema_Object `protobuf:"bytes,10,opt,name=nested_type,json=nestedType,proto3" json:"nested_type,omitempty"` - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - Required bool `protobuf:"varint,4,opt,name=required,proto3" json:"required,omitempty"` - Optional bool `protobuf:"varint,5,opt,name=optional,proto3" json:"optional,omitempty"` - Computed bool `protobuf:"varint,6,opt,name=computed,proto3" json:"computed,omitempty"` - Sensitive bool `protobuf:"varint,7,opt,name=sensitive,proto3" json:"sensitive,omitempty"` - DescriptionKind StringKind `protobuf:"varint,8,opt,name=description_kind,json=descriptionKind,proto3,enum=tfplugin6.StringKind" json:"description_kind,omitempty"` - Deprecated bool `protobuf:"varint,9,opt,name=deprecated,proto3" json:"deprecated,omitempty"` } -func (x *Schema_Attribute) Reset() { - *x = Schema_Attribute{} +func (x *CallFunction) Reset() { + *x = CallFunction{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[22] + mi := &file_tfplugin6_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *Schema_Attribute) String() string { +func (x *CallFunction) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Schema_Attribute) ProtoMessage() {} +func (*CallFunction) ProtoMessage() {} -func (x *Schema_Attribute) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[22] +func (x *CallFunction) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1314,110 +1383,1170 @@ func (x *Schema_Attribute) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Schema_Attribute.ProtoReflect.Descriptor instead. -func (*Schema_Attribute) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{5, 1} +// Deprecated: Use CallFunction.ProtoReflect.Descriptor instead. +func (*CallFunction) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{23} } -func (x *Schema_Attribute) GetName() string { - if x != nil { - return x.Name - } - return "" -} +type AttributePath_Step struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (x *Schema_Attribute) GetType() []byte { - if x != nil { - return x.Type + // Types that are assignable to Selector: + // + // *AttributePath_Step_AttributeName + // *AttributePath_Step_ElementKeyString + // *AttributePath_Step_ElementKeyInt + Selector isAttributePath_Step_Selector `protobuf_oneof:"selector"` +} + +func (x *AttributePath_Step) Reset() { + *x = AttributePath_Step{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return nil } -func (x *Schema_Attribute) GetNestedType() *Schema_Object { - if x != nil { - return x.NestedType +func (x *AttributePath_Step) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AttributePath_Step) ProtoMessage() {} + +func (x *AttributePath_Step) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AttributePath_Step.ProtoReflect.Descriptor instead. +func (*AttributePath_Step) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{3, 0} +} + +func (m *AttributePath_Step) GetSelector() isAttributePath_Step_Selector { + if m != nil { + return m.Selector } return nil } -func (x *Schema_Attribute) GetDescription() string { +func (x *AttributePath_Step) GetAttributeName() string { + if x, ok := x.GetSelector().(*AttributePath_Step_AttributeName); ok { + return x.AttributeName + } + return "" +} + +func (x *AttributePath_Step) GetElementKeyString() string { + if x, ok := x.GetSelector().(*AttributePath_Step_ElementKeyString); ok { + return x.ElementKeyString + } + return "" +} + +func (x *AttributePath_Step) GetElementKeyInt() int64 { + if x, ok := x.GetSelector().(*AttributePath_Step_ElementKeyInt); ok { + return x.ElementKeyInt + } + return 0 +} + +type isAttributePath_Step_Selector interface { + isAttributePath_Step_Selector() +} + +type AttributePath_Step_AttributeName struct { + // Set "attribute_name" to represent looking up an attribute + // in the current object value. + AttributeName string `protobuf:"bytes,1,opt,name=attribute_name,json=attributeName,proto3,oneof"` +} + +type AttributePath_Step_ElementKeyString struct { + // Set "element_key_*" to represent looking up an element in + // an indexable collection type. + ElementKeyString string `protobuf:"bytes,2,opt,name=element_key_string,json=elementKeyString,proto3,oneof"` +} + +type AttributePath_Step_ElementKeyInt struct { + ElementKeyInt int64 `protobuf:"varint,3,opt,name=element_key_int,json=elementKeyInt,proto3,oneof"` +} + +func (*AttributePath_Step_AttributeName) isAttributePath_Step_Selector() {} + +func (*AttributePath_Step_ElementKeyString) isAttributePath_Step_Selector() {} + +func (*AttributePath_Step_ElementKeyInt) isAttributePath_Step_Selector() {} + +type StopProvider_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *StopProvider_Request) Reset() { + *x = StopProvider_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StopProvider_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StopProvider_Request) ProtoMessage() {} + +func (x *StopProvider_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StopProvider_Request.ProtoReflect.Descriptor instead. +func (*StopProvider_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{4, 0} +} + +type StopProvider_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Error string `protobuf:"bytes,1,opt,name=Error,proto3" json:"Error,omitempty"` +} + +func (x *StopProvider_Response) Reset() { + *x = StopProvider_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StopProvider_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StopProvider_Response) ProtoMessage() {} + +func (x *StopProvider_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StopProvider_Response.ProtoReflect.Descriptor instead. +func (*StopProvider_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{4, 1} +} + +func (x *StopProvider_Response) GetError() string { if x != nil { - return x.Description + return x.Error } return "" } -func (x *Schema_Attribute) GetRequired() bool { +type Schema_Block struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version int64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + Attributes []*Schema_Attribute `protobuf:"bytes,2,rep,name=attributes,proto3" json:"attributes,omitempty"` + BlockTypes []*Schema_NestedBlock `protobuf:"bytes,3,rep,name=block_types,json=blockTypes,proto3" json:"block_types,omitempty"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + DescriptionKind StringKind `protobuf:"varint,5,opt,name=description_kind,json=descriptionKind,proto3,enum=tfplugin6.StringKind" json:"description_kind,omitempty"` + Deprecated bool `protobuf:"varint,6,opt,name=deprecated,proto3" json:"deprecated,omitempty"` +} + +func (x *Schema_Block) Reset() { + *x = Schema_Block{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Schema_Block) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Schema_Block) ProtoMessage() {} + +func (x *Schema_Block) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Schema_Block.ProtoReflect.Descriptor instead. +func (*Schema_Block) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{6, 0} +} + +func (x *Schema_Block) GetVersion() int64 { if x != nil { - return x.Required + return x.Version } - return false + return 0 } -func (x *Schema_Attribute) GetOptional() bool { +func (x *Schema_Block) GetAttributes() []*Schema_Attribute { if x != nil { - return x.Optional + return x.Attributes } - return false + return nil } -func (x *Schema_Attribute) GetComputed() bool { +func (x *Schema_Block) GetBlockTypes() []*Schema_NestedBlock { if x != nil { - return x.Computed + return x.BlockTypes } - return false + return nil } -func (x *Schema_Attribute) GetSensitive() bool { +func (x *Schema_Block) GetDescription() string { if x != nil { - return x.Sensitive + return x.Description } - return false + return "" } -func (x *Schema_Attribute) GetDescriptionKind() StringKind { +func (x *Schema_Block) GetDescriptionKind() StringKind { if x != nil { return x.DescriptionKind } return StringKind_PLAIN } -func (x *Schema_Attribute) GetDeprecated() bool { +func (x *Schema_Block) GetDeprecated() bool { + if x != nil { + return x.Deprecated + } + return false +} + +type Schema_Attribute struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type []byte `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + NestedType *Schema_Object `protobuf:"bytes,10,opt,name=nested_type,json=nestedType,proto3" json:"nested_type,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Required bool `protobuf:"varint,4,opt,name=required,proto3" json:"required,omitempty"` + Optional bool `protobuf:"varint,5,opt,name=optional,proto3" json:"optional,omitempty"` + Computed bool `protobuf:"varint,6,opt,name=computed,proto3" json:"computed,omitempty"` + Sensitive bool `protobuf:"varint,7,opt,name=sensitive,proto3" json:"sensitive,omitempty"` + DescriptionKind StringKind `protobuf:"varint,8,opt,name=description_kind,json=descriptionKind,proto3,enum=tfplugin6.StringKind" json:"description_kind,omitempty"` + Deprecated bool `protobuf:"varint,9,opt,name=deprecated,proto3" json:"deprecated,omitempty"` +} + +func (x *Schema_Attribute) Reset() { + *x = Schema_Attribute{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Schema_Attribute) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Schema_Attribute) ProtoMessage() {} + +func (x *Schema_Attribute) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Schema_Attribute.ProtoReflect.Descriptor instead. +func (*Schema_Attribute) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{6, 1} +} + +func (x *Schema_Attribute) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Schema_Attribute) GetType() []byte { + if x != nil { + return x.Type + } + return nil +} + +func (x *Schema_Attribute) GetNestedType() *Schema_Object { + if x != nil { + return x.NestedType + } + return nil +} + +func (x *Schema_Attribute) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Schema_Attribute) GetRequired() bool { + if x != nil { + return x.Required + } + return false +} + +func (x *Schema_Attribute) GetOptional() bool { + if x != nil { + return x.Optional + } + return false +} + +func (x *Schema_Attribute) GetComputed() bool { + if x != nil { + return x.Computed + } + return false +} + +func (x *Schema_Attribute) GetSensitive() bool { + if x != nil { + return x.Sensitive + } + return false +} + +func (x *Schema_Attribute) GetDescriptionKind() StringKind { + if x != nil { + return x.DescriptionKind + } + return StringKind_PLAIN +} + +func (x *Schema_Attribute) GetDeprecated() bool { + if x != nil { + return x.Deprecated + } + return false +} + +type Schema_NestedBlock struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + Block *Schema_Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"` + Nesting Schema_NestedBlock_NestingMode `protobuf:"varint,3,opt,name=nesting,proto3,enum=tfplugin6.Schema_NestedBlock_NestingMode" json:"nesting,omitempty"` + MinItems int64 `protobuf:"varint,4,opt,name=min_items,json=minItems,proto3" json:"min_items,omitempty"` + MaxItems int64 `protobuf:"varint,5,opt,name=max_items,json=maxItems,proto3" json:"max_items,omitempty"` +} + +func (x *Schema_NestedBlock) Reset() { + *x = Schema_NestedBlock{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Schema_NestedBlock) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Schema_NestedBlock) ProtoMessage() {} + +func (x *Schema_NestedBlock) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Schema_NestedBlock.ProtoReflect.Descriptor instead. +func (*Schema_NestedBlock) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{6, 2} +} + +func (x *Schema_NestedBlock) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *Schema_NestedBlock) GetBlock() *Schema_Block { + if x != nil { + return x.Block + } + return nil +} + +func (x *Schema_NestedBlock) GetNesting() Schema_NestedBlock_NestingMode { + if x != nil { + return x.Nesting + } + return Schema_NestedBlock_INVALID +} + +func (x *Schema_NestedBlock) GetMinItems() int64 { + if x != nil { + return x.MinItems + } + return 0 +} + +func (x *Schema_NestedBlock) GetMaxItems() int64 { + if x != nil { + return x.MaxItems + } + return 0 +} + +type Schema_Object struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Attributes []*Schema_Attribute `protobuf:"bytes,1,rep,name=attributes,proto3" json:"attributes,omitempty"` + Nesting Schema_Object_NestingMode `protobuf:"varint,3,opt,name=nesting,proto3,enum=tfplugin6.Schema_Object_NestingMode" json:"nesting,omitempty"` + // MinItems and MaxItems were never used in the protocol, and have no + // effect on validation. + // + // Deprecated: Marked as deprecated in tfplugin6.proto. + MinItems int64 `protobuf:"varint,4,opt,name=min_items,json=minItems,proto3" json:"min_items,omitempty"` + // Deprecated: Marked as deprecated in tfplugin6.proto. + MaxItems int64 `protobuf:"varint,5,opt,name=max_items,json=maxItems,proto3" json:"max_items,omitempty"` +} + +func (x *Schema_Object) Reset() { + *x = Schema_Object{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Schema_Object) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Schema_Object) ProtoMessage() {} + +func (x *Schema_Object) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Schema_Object.ProtoReflect.Descriptor instead. +func (*Schema_Object) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{6, 3} +} + +func (x *Schema_Object) GetAttributes() []*Schema_Attribute { + if x != nil { + return x.Attributes + } + return nil +} + +func (x *Schema_Object) GetNesting() Schema_Object_NestingMode { + if x != nil { + return x.Nesting + } + return Schema_Object_INVALID +} + +// Deprecated: Marked as deprecated in tfplugin6.proto. +func (x *Schema_Object) GetMinItems() int64 { + if x != nil { + return x.MinItems + } + return 0 +} + +// Deprecated: Marked as deprecated in tfplugin6.proto. +func (x *Schema_Object) GetMaxItems() int64 { + if x != nil { + return x.MaxItems + } + return 0 +} + +type Function_Parameter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the human-readable display name for the parameter. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // type is the type constraint for the parameter. + Type []byte `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + // allow_null_value when enabled denotes that a null argument value can + // be passed to the provider. When disabled, Terraform returns an error + // if the argument value is null. + AllowNullValue bool `protobuf:"varint,3,opt,name=allow_null_value,json=allowNullValue,proto3" json:"allow_null_value,omitempty"` + // allow_unknown_values when enabled denotes that only wholly known + // argument values will be passed to the provider. When disabled, + // Terraform skips the function call entirely and assumes an unknown + // value result from the function. + AllowUnknownValues bool `protobuf:"varint,4,opt,name=allow_unknown_values,json=allowUnknownValues,proto3" json:"allow_unknown_values,omitempty"` + // description is human-readable documentation for the parameter. + Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` + // description_kind is the formatting of the description. + DescriptionKind StringKind `protobuf:"varint,6,opt,name=description_kind,json=descriptionKind,proto3,enum=tfplugin6.StringKind" json:"description_kind,omitempty"` +} + +func (x *Function_Parameter) Reset() { + *x = Function_Parameter{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Function_Parameter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Function_Parameter) ProtoMessage() {} + +func (x *Function_Parameter) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Function_Parameter.ProtoReflect.Descriptor instead. +func (*Function_Parameter) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{7, 0} +} + +func (x *Function_Parameter) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Function_Parameter) GetType() []byte { + if x != nil { + return x.Type + } + return nil +} + +func (x *Function_Parameter) GetAllowNullValue() bool { + if x != nil { + return x.AllowNullValue + } + return false +} + +func (x *Function_Parameter) GetAllowUnknownValues() bool { + if x != nil { + return x.AllowUnknownValues + } + return false +} + +func (x *Function_Parameter) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Function_Parameter) GetDescriptionKind() StringKind { + if x != nil { + return x.DescriptionKind + } + return StringKind_PLAIN +} + +type Function_Return struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // type is the type constraint for the function result. + Type []byte `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` +} + +func (x *Function_Return) Reset() { + *x = Function_Return{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Function_Return) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Function_Return) ProtoMessage() {} + +func (x *Function_Return) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Function_Return.ProtoReflect.Descriptor instead. +func (*Function_Return) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{7, 1} +} + +func (x *Function_Return) GetType() []byte { + if x != nil { + return x.Type + } + return nil +} + +type GetMetadata_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetMetadata_Request) Reset() { + *x = GetMetadata_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMetadata_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMetadata_Request) ProtoMessage() {} + +func (x *GetMetadata_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadata_Request.ProtoReflect.Descriptor instead. +func (*GetMetadata_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{9, 0} +} + +type GetMetadata_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServerCapabilities *ServerCapabilities `protobuf:"bytes,1,opt,name=server_capabilities,json=serverCapabilities,proto3" json:"server_capabilities,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + DataSources []*GetMetadata_DataSourceMetadata `protobuf:"bytes,3,rep,name=data_sources,json=dataSources,proto3" json:"data_sources,omitempty"` + Resources []*GetMetadata_ResourceMetadata `protobuf:"bytes,4,rep,name=resources,proto3" json:"resources,omitempty"` + // functions returns metadata for any functions. + Functions []*GetMetadata_FunctionMetadata `protobuf:"bytes,5,rep,name=functions,proto3" json:"functions,omitempty"` +} + +func (x *GetMetadata_Response) Reset() { + *x = GetMetadata_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMetadata_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMetadata_Response) ProtoMessage() {} + +func (x *GetMetadata_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadata_Response.ProtoReflect.Descriptor instead. +func (*GetMetadata_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{9, 1} +} + +func (x *GetMetadata_Response) GetServerCapabilities() *ServerCapabilities { + if x != nil { + return x.ServerCapabilities + } + return nil +} + +func (x *GetMetadata_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +func (x *GetMetadata_Response) GetDataSources() []*GetMetadata_DataSourceMetadata { + if x != nil { + return x.DataSources + } + return nil +} + +func (x *GetMetadata_Response) GetResources() []*GetMetadata_ResourceMetadata { + if x != nil { + return x.Resources + } + return nil +} + +func (x *GetMetadata_Response) GetFunctions() []*GetMetadata_FunctionMetadata { + if x != nil { + return x.Functions + } + return nil +} + +type GetMetadata_FunctionMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the function name. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *GetMetadata_FunctionMetadata) Reset() { + *x = GetMetadata_FunctionMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMetadata_FunctionMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMetadata_FunctionMetadata) ProtoMessage() {} + +func (x *GetMetadata_FunctionMetadata) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadata_FunctionMetadata.ProtoReflect.Descriptor instead. +func (*GetMetadata_FunctionMetadata) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{9, 2} +} + +func (x *GetMetadata_FunctionMetadata) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type GetMetadata_DataSourceMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` +} + +func (x *GetMetadata_DataSourceMetadata) Reset() { + *x = GetMetadata_DataSourceMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMetadata_DataSourceMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMetadata_DataSourceMetadata) ProtoMessage() {} + +func (x *GetMetadata_DataSourceMetadata) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadata_DataSourceMetadata.ProtoReflect.Descriptor instead. +func (*GetMetadata_DataSourceMetadata) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{9, 3} +} + +func (x *GetMetadata_DataSourceMetadata) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +type GetMetadata_ResourceMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` +} + +func (x *GetMetadata_ResourceMetadata) Reset() { + *x = GetMetadata_ResourceMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMetadata_ResourceMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMetadata_ResourceMetadata) ProtoMessage() {} + +func (x *GetMetadata_ResourceMetadata) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadata_ResourceMetadata.ProtoReflect.Descriptor instead. +func (*GetMetadata_ResourceMetadata) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{9, 4} +} + +func (x *GetMetadata_ResourceMetadata) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +type GetProviderSchema_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetProviderSchema_Request) Reset() { + *x = GetProviderSchema_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProviderSchema_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProviderSchema_Request) ProtoMessage() {} + +func (x *GetProviderSchema_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProviderSchema_Request.ProtoReflect.Descriptor instead. +func (*GetProviderSchema_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{10, 0} +} + +type GetProviderSchema_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Provider *Schema `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` + ResourceSchemas map[string]*Schema `protobuf:"bytes,2,rep,name=resource_schemas,json=resourceSchemas,proto3" json:"resource_schemas,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + DataSourceSchemas map[string]*Schema `protobuf:"bytes,3,rep,name=data_source_schemas,json=dataSourceSchemas,proto3" json:"data_source_schemas,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Diagnostics []*Diagnostic `protobuf:"bytes,4,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + ProviderMeta *Schema `protobuf:"bytes,5,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` + ServerCapabilities *ServerCapabilities `protobuf:"bytes,6,opt,name=server_capabilities,json=serverCapabilities,proto3" json:"server_capabilities,omitempty"` + // functions is a mapping of function names to definitions. + Functions map[string]*Function `protobuf:"bytes,7,rep,name=functions,proto3" json:"functions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetProviderSchema_Response) Reset() { + *x = GetProviderSchema_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProviderSchema_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProviderSchema_Response) ProtoMessage() {} + +func (x *GetProviderSchema_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProviderSchema_Response.ProtoReflect.Descriptor instead. +func (*GetProviderSchema_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{10, 1} +} + +func (x *GetProviderSchema_Response) GetProvider() *Schema { + if x != nil { + return x.Provider + } + return nil +} + +func (x *GetProviderSchema_Response) GetResourceSchemas() map[string]*Schema { + if x != nil { + return x.ResourceSchemas + } + return nil +} + +func (x *GetProviderSchema_Response) GetDataSourceSchemas() map[string]*Schema { + if x != nil { + return x.DataSourceSchemas + } + return nil +} + +func (x *GetProviderSchema_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +func (x *GetProviderSchema_Response) GetProviderMeta() *Schema { + if x != nil { + return x.ProviderMeta + } + return nil +} + +func (x *GetProviderSchema_Response) GetServerCapabilities() *ServerCapabilities { + if x != nil { + return x.ServerCapabilities + } + return nil +} + +func (x *GetProviderSchema_Response) GetFunctions() map[string]*Function { + if x != nil { + return x.Functions + } + return nil +} + +type ValidateProviderConfig_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Config *DynamicValue `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` +} + +func (x *ValidateProviderConfig_Request) Reset() { + *x = ValidateProviderConfig_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateProviderConfig_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateProviderConfig_Request) ProtoMessage() {} + +func (x *ValidateProviderConfig_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateProviderConfig_Request.ProtoReflect.Descriptor instead. +func (*ValidateProviderConfig_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{11, 0} +} + +func (x *ValidateProviderConfig_Request) GetConfig() *DynamicValue { if x != nil { - return x.Deprecated + return x.Config } - return false + return nil } -type Schema_NestedBlock struct { +type ValidateProviderConfig_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` - Block *Schema_Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"` - Nesting Schema_NestedBlock_NestingMode `protobuf:"varint,3,opt,name=nesting,proto3,enum=tfplugin6.Schema_NestedBlock_NestingMode" json:"nesting,omitempty"` - MinItems int64 `protobuf:"varint,4,opt,name=min_items,json=minItems,proto3" json:"min_items,omitempty"` - MaxItems int64 `protobuf:"varint,5,opt,name=max_items,json=maxItems,proto3" json:"max_items,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` } -func (x *Schema_NestedBlock) Reset() { - *x = Schema_NestedBlock{} +func (x *ValidateProviderConfig_Response) Reset() { + *x = ValidateProviderConfig_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[23] + mi := &file_tfplugin6_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *Schema_NestedBlock) String() string { +func (x *ValidateProviderConfig_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Schema_NestedBlock) ProtoMessage() {} +func (*ValidateProviderConfig_Response) ProtoMessage() {} -func (x *Schema_NestedBlock) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[23] +func (x *ValidateProviderConfig_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1428,79 +2557,60 @@ func (x *Schema_NestedBlock) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Schema_NestedBlock.ProtoReflect.Descriptor instead. -func (*Schema_NestedBlock) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{5, 2} -} - -func (x *Schema_NestedBlock) GetTypeName() string { - if x != nil { - return x.TypeName - } - return "" +// Deprecated: Use ValidateProviderConfig_Response.ProtoReflect.Descriptor instead. +func (*ValidateProviderConfig_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{11, 1} } -func (x *Schema_NestedBlock) GetBlock() *Schema_Block { +func (x *ValidateProviderConfig_Response) GetDiagnostics() []*Diagnostic { if x != nil { - return x.Block + return x.Diagnostics } return nil } -func (x *Schema_NestedBlock) GetNesting() Schema_NestedBlock_NestingMode { - if x != nil { - return x.Nesting - } - return Schema_NestedBlock_INVALID -} - -func (x *Schema_NestedBlock) GetMinItems() int64 { - if x != nil { - return x.MinItems - } - return 0 -} - -func (x *Schema_NestedBlock) GetMaxItems() int64 { - if x != nil { - return x.MaxItems - } - return 0 -} - -type Schema_Object struct { +// Request is the message that is sent to the provider during the +// UpgradeResourceState RPC. +// +// This message intentionally does not include configuration data as any +// configuration-based or configuration-conditional changes should occur +// during the PlanResourceChange RPC. Additionally, the configuration is +// not guaranteed to exist (in the case of resource destruction), be wholly +// known, nor match the given prior state, which could lead to unexpected +// provider behaviors for practitioners. +type UpgradeResourceState_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Attributes []*Schema_Attribute `protobuf:"bytes,1,rep,name=attributes,proto3" json:"attributes,omitempty"` - Nesting Schema_Object_NestingMode `protobuf:"varint,3,opt,name=nesting,proto3,enum=tfplugin6.Schema_Object_NestingMode" json:"nesting,omitempty"` - // MinItems and MaxItems were never used in the protocol, and have no - // effect on validation. - // - // Deprecated: Marked as deprecated in tfplugin6.proto. - MinItems int64 `protobuf:"varint,4,opt,name=min_items,json=minItems,proto3" json:"min_items,omitempty"` - // Deprecated: Marked as deprecated in tfplugin6.proto. - MaxItems int64 `protobuf:"varint,5,opt,name=max_items,json=maxItems,proto3" json:"max_items,omitempty"` + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + // version is the schema_version number recorded in the state file + Version int64 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"` + // raw_state is the raw states as stored for the resource. Core does + // not have access to the schema of prior_version, so it's the + // provider's responsibility to interpret this value using the + // appropriate older schema. The raw_state will be the json encoded + // state, or a legacy flat-mapped format. + RawState *RawState `protobuf:"bytes,3,opt,name=raw_state,json=rawState,proto3" json:"raw_state,omitempty"` } -func (x *Schema_Object) Reset() { - *x = Schema_Object{} +func (x *UpgradeResourceState_Request) Reset() { + *x = UpgradeResourceState_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[24] + mi := &file_tfplugin6_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *Schema_Object) String() string { +func (x *UpgradeResourceState_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Schema_Object) ProtoMessage() {} +func (*UpgradeResourceState_Request) ProtoMessage() {} -func (x *Schema_Object) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[24] +func (x *UpgradeResourceState_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1511,64 +2621,64 @@ func (x *Schema_Object) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Schema_Object.ProtoReflect.Descriptor instead. -func (*Schema_Object) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{5, 3} -} - -func (x *Schema_Object) GetAttributes() []*Schema_Attribute { - if x != nil { - return x.Attributes - } - return nil +// Deprecated: Use UpgradeResourceState_Request.ProtoReflect.Descriptor instead. +func (*UpgradeResourceState_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{12, 0} } -func (x *Schema_Object) GetNesting() Schema_Object_NestingMode { +func (x *UpgradeResourceState_Request) GetTypeName() string { if x != nil { - return x.Nesting + return x.TypeName } - return Schema_Object_INVALID + return "" } -// Deprecated: Marked as deprecated in tfplugin6.proto. -func (x *Schema_Object) GetMinItems() int64 { +func (x *UpgradeResourceState_Request) GetVersion() int64 { if x != nil { - return x.MinItems + return x.Version } return 0 } -// Deprecated: Marked as deprecated in tfplugin6.proto. -func (x *Schema_Object) GetMaxItems() int64 { +func (x *UpgradeResourceState_Request) GetRawState() *RawState { if x != nil { - return x.MaxItems + return x.RawState } - return 0 + return nil } -type GetProviderSchema_Request struct { +type UpgradeResourceState_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // new_state is a msgpack-encoded data structure that, when interpreted with + // the _current_ schema for this resource type, is functionally equivalent to + // that which was given in prior_state_raw. + UpgradedState *DynamicValue `protobuf:"bytes,1,opt,name=upgraded_state,json=upgradedState,proto3" json:"upgraded_state,omitempty"` + // diagnostics describes any errors encountered during migration that could not + // be safely resolved, and warnings about any possibly-risky assumptions made + // in the upgrade process. + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` } -func (x *GetProviderSchema_Request) Reset() { - *x = GetProviderSchema_Request{} +func (x *UpgradeResourceState_Response) Reset() { + *x = UpgradeResourceState_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[25] + mi := &file_tfplugin6_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetProviderSchema_Request) String() string { +func (x *UpgradeResourceState_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetProviderSchema_Request) ProtoMessage() {} +func (*UpgradeResourceState_Response) ProtoMessage() {} -func (x *GetProviderSchema_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[25] +func (x *UpgradeResourceState_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1579,41 +2689,51 @@ func (x *GetProviderSchema_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetProviderSchema_Request.ProtoReflect.Descriptor instead. -func (*GetProviderSchema_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{6, 0} +// Deprecated: Use UpgradeResourceState_Response.ProtoReflect.Descriptor instead. +func (*UpgradeResourceState_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{12, 1} } -type GetProviderSchema_Response struct { +func (x *UpgradeResourceState_Response) GetUpgradedState() *DynamicValue { + if x != nil { + return x.UpgradedState + } + return nil +} + +func (x *UpgradeResourceState_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type ValidateResourceConfig_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Provider *Schema `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` - ResourceSchemas map[string]*Schema `protobuf:"bytes,2,rep,name=resource_schemas,json=resourceSchemas,proto3" json:"resource_schemas,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - DataSourceSchemas map[string]*Schema `protobuf:"bytes,3,rep,name=data_source_schemas,json=dataSourceSchemas,proto3" json:"data_source_schemas,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - Diagnostics []*Diagnostic `protobuf:"bytes,4,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` - ProviderMeta *Schema `protobuf:"bytes,5,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` - ServerCapabilities *GetProviderSchema_ServerCapabilities `protobuf:"bytes,6,opt,name=server_capabilities,json=serverCapabilities,proto3" json:"server_capabilities,omitempty"` + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` } -func (x *GetProviderSchema_Response) Reset() { - *x = GetProviderSchema_Response{} +func (x *ValidateResourceConfig_Request) Reset() { + *x = ValidateResourceConfig_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[26] + mi := &file_tfplugin6_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetProviderSchema_Response) String() string { +func (x *ValidateResourceConfig_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetProviderSchema_Response) ProtoMessage() {} +func (*ValidateResourceConfig_Request) ProtoMessage() {} -func (x *GetProviderSchema_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[26] +func (x *ValidateResourceConfig_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1624,84 +2744,50 @@ func (x *GetProviderSchema_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetProviderSchema_Response.ProtoReflect.Descriptor instead. -func (*GetProviderSchema_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{6, 1} -} - -func (x *GetProviderSchema_Response) GetProvider() *Schema { - if x != nil { - return x.Provider - } - return nil -} - -func (x *GetProviderSchema_Response) GetResourceSchemas() map[string]*Schema { - if x != nil { - return x.ResourceSchemas - } - return nil -} - -func (x *GetProviderSchema_Response) GetDataSourceSchemas() map[string]*Schema { - if x != nil { - return x.DataSourceSchemas - } - return nil -} - -func (x *GetProviderSchema_Response) GetDiagnostics() []*Diagnostic { - if x != nil { - return x.Diagnostics - } - return nil +// Deprecated: Use ValidateResourceConfig_Request.ProtoReflect.Descriptor instead. +func (*ValidateResourceConfig_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{13, 0} } -func (x *GetProviderSchema_Response) GetProviderMeta() *Schema { +func (x *ValidateResourceConfig_Request) GetTypeName() string { if x != nil { - return x.ProviderMeta + return x.TypeName } - return nil + return "" } -func (x *GetProviderSchema_Response) GetServerCapabilities() *GetProviderSchema_ServerCapabilities { +func (x *ValidateResourceConfig_Request) GetConfig() *DynamicValue { if x != nil { - return x.ServerCapabilities + return x.Config } return nil } -// ServerCapabilities allows providers to communicate extra information -// regarding supported protocol features. This is used to indicate -// availability of certain forward-compatible changes which may be optional -// in a major protocol version, but cannot be tested for directly. -type GetProviderSchema_ServerCapabilities struct { +type ValidateResourceConfig_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The plan_destroy capability signals that a provider expects a call - // to PlanResourceChange when a resource is going to be destroyed. - PlanDestroy bool `protobuf:"varint,1,opt,name=plan_destroy,json=planDestroy,proto3" json:"plan_destroy,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,1,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` } -func (x *GetProviderSchema_ServerCapabilities) Reset() { - *x = GetProviderSchema_ServerCapabilities{} +func (x *ValidateResourceConfig_Response) Reset() { + *x = ValidateResourceConfig_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[27] + mi := &file_tfplugin6_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetProviderSchema_ServerCapabilities) String() string { +func (x *ValidateResourceConfig_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetProviderSchema_ServerCapabilities) ProtoMessage() {} +func (*ValidateResourceConfig_Response) ProtoMessage() {} -func (x *GetProviderSchema_ServerCapabilities) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[27] +func (x *ValidateResourceConfig_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1712,43 +2798,44 @@ func (x *GetProviderSchema_ServerCapabilities) ProtoReflect() protoreflect.Messa return mi.MessageOf(x) } -// Deprecated: Use GetProviderSchema_ServerCapabilities.ProtoReflect.Descriptor instead. -func (*GetProviderSchema_ServerCapabilities) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{6, 2} +// Deprecated: Use ValidateResourceConfig_Response.ProtoReflect.Descriptor instead. +func (*ValidateResourceConfig_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{13, 1} } -func (x *GetProviderSchema_ServerCapabilities) GetPlanDestroy() bool { +func (x *ValidateResourceConfig_Response) GetDiagnostics() []*Diagnostic { if x != nil { - return x.PlanDestroy + return x.Diagnostics } - return false + return nil } -type ValidateProviderConfig_Request struct { +type ValidateDataResourceConfig_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Config *DynamicValue `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` } -func (x *ValidateProviderConfig_Request) Reset() { - *x = ValidateProviderConfig_Request{} +func (x *ValidateDataResourceConfig_Request) Reset() { + *x = ValidateDataResourceConfig_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[30] + mi := &file_tfplugin6_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ValidateProviderConfig_Request) String() string { +func (x *ValidateDataResourceConfig_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ValidateProviderConfig_Request) ProtoMessage() {} +func (*ValidateDataResourceConfig_Request) ProtoMessage() {} -func (x *ValidateProviderConfig_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[30] +func (x *ValidateDataResourceConfig_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[50] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1759,43 +2846,50 @@ func (x *ValidateProviderConfig_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ValidateProviderConfig_Request.ProtoReflect.Descriptor instead. -func (*ValidateProviderConfig_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{7, 0} +// Deprecated: Use ValidateDataResourceConfig_Request.ProtoReflect.Descriptor instead. +func (*ValidateDataResourceConfig_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{14, 0} } -func (x *ValidateProviderConfig_Request) GetConfig() *DynamicValue { +func (x *ValidateDataResourceConfig_Request) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *ValidateDataResourceConfig_Request) GetConfig() *DynamicValue { if x != nil { return x.Config } return nil } -type ValidateProviderConfig_Response struct { +type ValidateDataResourceConfig_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,1,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` } -func (x *ValidateProviderConfig_Response) Reset() { - *x = ValidateProviderConfig_Response{} +func (x *ValidateDataResourceConfig_Response) Reset() { + *x = ValidateDataResourceConfig_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[31] + mi := &file_tfplugin6_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ValidateProviderConfig_Response) String() string { +func (x *ValidateDataResourceConfig_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ValidateProviderConfig_Response) ProtoMessage() {} +func (*ValidateDataResourceConfig_Response) ProtoMessage() {} -func (x *ValidateProviderConfig_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[31] +func (x *ValidateDataResourceConfig_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[51] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1806,60 +2900,44 @@ func (x *ValidateProviderConfig_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ValidateProviderConfig_Response.ProtoReflect.Descriptor instead. -func (*ValidateProviderConfig_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{7, 1} +// Deprecated: Use ValidateDataResourceConfig_Response.ProtoReflect.Descriptor instead. +func (*ValidateDataResourceConfig_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{14, 1} } -func (x *ValidateProviderConfig_Response) GetDiagnostics() []*Diagnostic { +func (x *ValidateDataResourceConfig_Response) GetDiagnostics() []*Diagnostic { if x != nil { return x.Diagnostics } return nil } -// Request is the message that is sent to the provider during the -// UpgradeResourceState RPC. -// -// This message intentionally does not include configuration data as any -// configuration-based or configuration-conditional changes should occur -// during the PlanResourceChange RPC. Additionally, the configuration is -// not guaranteed to exist (in the case of resource destruction), be wholly -// known, nor match the given prior state, which could lead to unexpected -// provider behaviors for practitioners. -type UpgradeResourceState_Request struct { +type ConfigureProvider_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` - // version is the schema_version number recorded in the state file - Version int64 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"` - // raw_state is the raw states as stored for the resource. Core does - // not have access to the schema of prior_version, so it's the - // provider's responsibility to interpret this value using the - // appropriate older schema. The raw_state will be the json encoded - // state, or a legacy flat-mapped format. - RawState *RawState `protobuf:"bytes,3,opt,name=raw_state,json=rawState,proto3" json:"raw_state,omitempty"` + TerraformVersion string `protobuf:"bytes,1,opt,name=terraform_version,json=terraformVersion,proto3" json:"terraform_version,omitempty"` + Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` } -func (x *UpgradeResourceState_Request) Reset() { - *x = UpgradeResourceState_Request{} +func (x *ConfigureProvider_Request) Reset() { + *x = ConfigureProvider_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[32] + mi := &file_tfplugin6_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *UpgradeResourceState_Request) String() string { +func (x *ConfigureProvider_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*UpgradeResourceState_Request) ProtoMessage() {} +func (*ConfigureProvider_Request) ProtoMessage() {} -func (x *UpgradeResourceState_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[32] +func (x *ConfigureProvider_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[52] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1870,64 +2948,50 @@ func (x *UpgradeResourceState_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use UpgradeResourceState_Request.ProtoReflect.Descriptor instead. -func (*UpgradeResourceState_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{8, 0} +// Deprecated: Use ConfigureProvider_Request.ProtoReflect.Descriptor instead. +func (*ConfigureProvider_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{15, 0} } -func (x *UpgradeResourceState_Request) GetTypeName() string { +func (x *ConfigureProvider_Request) GetTerraformVersion() string { if x != nil { - return x.TypeName + return x.TerraformVersion } return "" } -func (x *UpgradeResourceState_Request) GetVersion() int64 { - if x != nil { - return x.Version - } - return 0 -} - -func (x *UpgradeResourceState_Request) GetRawState() *RawState { +func (x *ConfigureProvider_Request) GetConfig() *DynamicValue { if x != nil { - return x.RawState + return x.Config } return nil } -type UpgradeResourceState_Response struct { +type ConfigureProvider_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // new_state is a msgpack-encoded data structure that, when interpreted with - // the _current_ schema for this resource type, is functionally equivalent to - // that which was given in prior_state_raw. - UpgradedState *DynamicValue `protobuf:"bytes,1,opt,name=upgraded_state,json=upgradedState,proto3" json:"upgraded_state,omitempty"` - // diagnostics describes any errors encountered during migration that could not - // be safely resolved, and warnings about any possibly-risky assumptions made - // in the upgrade process. - Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,1,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` } -func (x *UpgradeResourceState_Response) Reset() { - *x = UpgradeResourceState_Response{} +func (x *ConfigureProvider_Response) Reset() { + *x = ConfigureProvider_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[33] + mi := &file_tfplugin6_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *UpgradeResourceState_Response) String() string { +func (x *ConfigureProvider_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*UpgradeResourceState_Response) ProtoMessage() {} +func (*ConfigureProvider_Response) ProtoMessage() {} -func (x *UpgradeResourceState_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[33] +func (x *ConfigureProvider_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[53] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1938,51 +3002,54 @@ func (x *UpgradeResourceState_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use UpgradeResourceState_Response.ProtoReflect.Descriptor instead. -func (*UpgradeResourceState_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{8, 1} -} - -func (x *UpgradeResourceState_Response) GetUpgradedState() *DynamicValue { - if x != nil { - return x.UpgradedState - } - return nil +// Deprecated: Use ConfigureProvider_Response.ProtoReflect.Descriptor instead. +func (*ConfigureProvider_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{15, 1} } -func (x *UpgradeResourceState_Response) GetDiagnostics() []*Diagnostic { +func (x *ConfigureProvider_Response) GetDiagnostics() []*Diagnostic { if x != nil { return x.Diagnostics } return nil } -type ValidateResourceConfig_Request struct { +// Request is the message that is sent to the provider during the +// ReadResource RPC. +// +// This message intentionally does not include configuration data as any +// configuration-based or configuration-conditional changes should occur +// during the PlanResourceChange RPC. Additionally, the configuration is +// not guaranteed to be wholly known nor match the given prior state, which +// could lead to unexpected provider behaviors for practitioners. +type ReadResource_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` - Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + CurrentState *DynamicValue `protobuf:"bytes,2,opt,name=current_state,json=currentState,proto3" json:"current_state,omitempty"` + Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` + ProviderMeta *DynamicValue `protobuf:"bytes,4,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` } -func (x *ValidateResourceConfig_Request) Reset() { - *x = ValidateResourceConfig_Request{} +func (x *ReadResource_Request) Reset() { + *x = ReadResource_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[34] + mi := &file_tfplugin6_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ValidateResourceConfig_Request) String() string { +func (x *ReadResource_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ValidateResourceConfig_Request) ProtoMessage() {} +func (*ReadResource_Request) ProtoMessage() {} -func (x *ValidateResourceConfig_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[34] +func (x *ReadResource_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[54] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1993,50 +3060,66 @@ func (x *ValidateResourceConfig_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ValidateResourceConfig_Request.ProtoReflect.Descriptor instead. -func (*ValidateResourceConfig_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{9, 0} +// Deprecated: Use ReadResource_Request.ProtoReflect.Descriptor instead. +func (*ReadResource_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{16, 0} } -func (x *ValidateResourceConfig_Request) GetTypeName() string { +func (x *ReadResource_Request) GetTypeName() string { if x != nil { return x.TypeName } return "" } -func (x *ValidateResourceConfig_Request) GetConfig() *DynamicValue { +func (x *ReadResource_Request) GetCurrentState() *DynamicValue { if x != nil { - return x.Config + return x.CurrentState } return nil } -type ValidateResourceConfig_Response struct { +func (x *ReadResource_Request) GetPrivate() []byte { + if x != nil { + return x.Private + } + return nil +} + +func (x *ReadResource_Request) GetProviderMeta() *DynamicValue { + if x != nil { + return x.ProviderMeta + } + return nil +} + +type ReadResource_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Diagnostics []*Diagnostic `protobuf:"bytes,1,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + NewState *DynamicValue `protobuf:"bytes,1,opt,name=new_state,json=newState,proto3" json:"new_state,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` } -func (x *ValidateResourceConfig_Response) Reset() { - *x = ValidateResourceConfig_Response{} +func (x *ReadResource_Response) Reset() { + *x = ReadResource_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[35] + mi := &file_tfplugin6_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ValidateResourceConfig_Response) String() string { +func (x *ReadResource_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ValidateResourceConfig_Response) ProtoMessage() {} +func (*ReadResource_Response) ProtoMessage() {} -func (x *ValidateResourceConfig_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[35] +func (x *ReadResource_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[55] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2047,44 +3130,62 @@ func (x *ValidateResourceConfig_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ValidateResourceConfig_Response.ProtoReflect.Descriptor instead. -func (*ValidateResourceConfig_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{9, 1} +// Deprecated: Use ReadResource_Response.ProtoReflect.Descriptor instead. +func (*ReadResource_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{16, 1} +} + +func (x *ReadResource_Response) GetNewState() *DynamicValue { + if x != nil { + return x.NewState + } + return nil +} + +func (x *ReadResource_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil } -func (x *ValidateResourceConfig_Response) GetDiagnostics() []*Diagnostic { +func (x *ReadResource_Response) GetPrivate() []byte { if x != nil { - return x.Diagnostics + return x.Private } return nil } -type ValidateDataResourceConfig_Request struct { +type PlanResourceChange_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` - Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + PriorState *DynamicValue `protobuf:"bytes,2,opt,name=prior_state,json=priorState,proto3" json:"prior_state,omitempty"` + ProposedNewState *DynamicValue `protobuf:"bytes,3,opt,name=proposed_new_state,json=proposedNewState,proto3" json:"proposed_new_state,omitempty"` + Config *DynamicValue `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` + PriorPrivate []byte `protobuf:"bytes,5,opt,name=prior_private,json=priorPrivate,proto3" json:"prior_private,omitempty"` + ProviderMeta *DynamicValue `protobuf:"bytes,6,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` } -func (x *ValidateDataResourceConfig_Request) Reset() { - *x = ValidateDataResourceConfig_Request{} +func (x *PlanResourceChange_Request) Reset() { + *x = PlanResourceChange_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[36] + mi := &file_tfplugin6_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ValidateDataResourceConfig_Request) String() string { +func (x *PlanResourceChange_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ValidateDataResourceConfig_Request) ProtoMessage() {} +func (*PlanResourceChange_Request) ProtoMessage() {} -func (x *ValidateDataResourceConfig_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[36] +func (x *PlanResourceChange_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[56] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2095,50 +3196,93 @@ func (x *ValidateDataResourceConfig_Request) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ValidateDataResourceConfig_Request.ProtoReflect.Descriptor instead. -func (*ValidateDataResourceConfig_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{10, 0} +// Deprecated: Use PlanResourceChange_Request.ProtoReflect.Descriptor instead. +func (*PlanResourceChange_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{17, 0} } -func (x *ValidateDataResourceConfig_Request) GetTypeName() string { +func (x *PlanResourceChange_Request) GetTypeName() string { if x != nil { return x.TypeName } return "" } -func (x *ValidateDataResourceConfig_Request) GetConfig() *DynamicValue { +func (x *PlanResourceChange_Request) GetPriorState() *DynamicValue { + if x != nil { + return x.PriorState + } + return nil +} + +func (x *PlanResourceChange_Request) GetProposedNewState() *DynamicValue { + if x != nil { + return x.ProposedNewState + } + return nil +} + +func (x *PlanResourceChange_Request) GetConfig() *DynamicValue { if x != nil { return x.Config } return nil } -type ValidateDataResourceConfig_Response struct { +func (x *PlanResourceChange_Request) GetPriorPrivate() []byte { + if x != nil { + return x.PriorPrivate + } + return nil +} + +func (x *PlanResourceChange_Request) GetProviderMeta() *DynamicValue { + if x != nil { + return x.ProviderMeta + } + return nil +} + +type PlanResourceChange_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Diagnostics []*Diagnostic `protobuf:"bytes,1,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + PlannedState *DynamicValue `protobuf:"bytes,1,opt,name=planned_state,json=plannedState,proto3" json:"planned_state,omitempty"` + RequiresReplace []*AttributePath `protobuf:"bytes,2,rep,name=requires_replace,json=requiresReplace,proto3" json:"requires_replace,omitempty"` + PlannedPrivate []byte `protobuf:"bytes,3,opt,name=planned_private,json=plannedPrivate,proto3" json:"planned_private,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,4,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + // This may be set only by the helper/schema "SDK" in the main Terraform + // repository, to request that Terraform Core >=0.12 permit additional + // inconsistencies that can result from the legacy SDK type system + // and its imprecise mapping to the >=0.12 type system. + // The change in behavior implied by this flag makes sense only for the + // specific details of the legacy SDK type system, and are not a general + // mechanism to avoid proper type handling in providers. + // + // ==== DO NOT USE THIS ==== + // ==== THIS MUST BE LEFT UNSET IN ALL OTHER SDKS ==== + // ==== DO NOT USE THIS ==== + LegacyTypeSystem bool `protobuf:"varint,5,opt,name=legacy_type_system,json=legacyTypeSystem,proto3" json:"legacy_type_system,omitempty"` } -func (x *ValidateDataResourceConfig_Response) Reset() { - *x = ValidateDataResourceConfig_Response{} +func (x *PlanResourceChange_Response) Reset() { + *x = PlanResourceChange_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[37] + mi := &file_tfplugin6_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ValidateDataResourceConfig_Response) String() string { +func (x *PlanResourceChange_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ValidateDataResourceConfig_Response) ProtoMessage() {} +func (*PlanResourceChange_Response) ProtoMessage() {} -func (x *ValidateDataResourceConfig_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[37] +func (x *PlanResourceChange_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[57] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2149,44 +3293,76 @@ func (x *ValidateDataResourceConfig_Response) ProtoReflect() protoreflect.Messag return mi.MessageOf(x) } -// Deprecated: Use ValidateDataResourceConfig_Response.ProtoReflect.Descriptor instead. -func (*ValidateDataResourceConfig_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{10, 1} +// Deprecated: Use PlanResourceChange_Response.ProtoReflect.Descriptor instead. +func (*PlanResourceChange_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{17, 1} } -func (x *ValidateDataResourceConfig_Response) GetDiagnostics() []*Diagnostic { +func (x *PlanResourceChange_Response) GetPlannedState() *DynamicValue { + if x != nil { + return x.PlannedState + } + return nil +} + +func (x *PlanResourceChange_Response) GetRequiresReplace() []*AttributePath { + if x != nil { + return x.RequiresReplace + } + return nil +} + +func (x *PlanResourceChange_Response) GetPlannedPrivate() []byte { + if x != nil { + return x.PlannedPrivate + } + return nil +} + +func (x *PlanResourceChange_Response) GetDiagnostics() []*Diagnostic { if x != nil { return x.Diagnostics } return nil } -type ConfigureProvider_Request struct { +func (x *PlanResourceChange_Response) GetLegacyTypeSystem() bool { + if x != nil { + return x.LegacyTypeSystem + } + return false +} + +type ApplyResourceChange_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TerraformVersion string `protobuf:"bytes,1,opt,name=terraform_version,json=terraformVersion,proto3" json:"terraform_version,omitempty"` - Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + PriorState *DynamicValue `protobuf:"bytes,2,opt,name=prior_state,json=priorState,proto3" json:"prior_state,omitempty"` + PlannedState *DynamicValue `protobuf:"bytes,3,opt,name=planned_state,json=plannedState,proto3" json:"planned_state,omitempty"` + Config *DynamicValue `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` + PlannedPrivate []byte `protobuf:"bytes,5,opt,name=planned_private,json=plannedPrivate,proto3" json:"planned_private,omitempty"` + ProviderMeta *DynamicValue `protobuf:"bytes,6,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` } -func (x *ConfigureProvider_Request) Reset() { - *x = ConfigureProvider_Request{} +func (x *ApplyResourceChange_Request) Reset() { + *x = ApplyResourceChange_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[38] + mi := &file_tfplugin6_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ConfigureProvider_Request) String() string { +func (x *ApplyResourceChange_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ConfigureProvider_Request) ProtoMessage() {} +func (*ApplyResourceChange_Request) ProtoMessage() {} -func (x *ConfigureProvider_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[38] +func (x *ApplyResourceChange_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[58] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2197,50 +3373,92 @@ func (x *ConfigureProvider_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ConfigureProvider_Request.ProtoReflect.Descriptor instead. -func (*ConfigureProvider_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{11, 0} +// Deprecated: Use ApplyResourceChange_Request.ProtoReflect.Descriptor instead. +func (*ApplyResourceChange_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{18, 0} } -func (x *ConfigureProvider_Request) GetTerraformVersion() string { +func (x *ApplyResourceChange_Request) GetTypeName() string { if x != nil { - return x.TerraformVersion + return x.TypeName } return "" } -func (x *ConfigureProvider_Request) GetConfig() *DynamicValue { +func (x *ApplyResourceChange_Request) GetPriorState() *DynamicValue { + if x != nil { + return x.PriorState + } + return nil +} + +func (x *ApplyResourceChange_Request) GetPlannedState() *DynamicValue { + if x != nil { + return x.PlannedState + } + return nil +} + +func (x *ApplyResourceChange_Request) GetConfig() *DynamicValue { if x != nil { return x.Config } return nil } -type ConfigureProvider_Response struct { +func (x *ApplyResourceChange_Request) GetPlannedPrivate() []byte { + if x != nil { + return x.PlannedPrivate + } + return nil +} + +func (x *ApplyResourceChange_Request) GetProviderMeta() *DynamicValue { + if x != nil { + return x.ProviderMeta + } + return nil +} + +type ApplyResourceChange_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Diagnostics []*Diagnostic `protobuf:"bytes,1,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + NewState *DynamicValue `protobuf:"bytes,1,opt,name=new_state,json=newState,proto3" json:"new_state,omitempty"` + Private []byte `protobuf:"bytes,2,opt,name=private,proto3" json:"private,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,3,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + // This may be set only by the helper/schema "SDK" in the main Terraform + // repository, to request that Terraform Core >=0.12 permit additional + // inconsistencies that can result from the legacy SDK type system + // and its imprecise mapping to the >=0.12 type system. + // The change in behavior implied by this flag makes sense only for the + // specific details of the legacy SDK type system, and are not a general + // mechanism to avoid proper type handling in providers. + // + // ==== DO NOT USE THIS ==== + // ==== THIS MUST BE LEFT UNSET IN ALL OTHER SDKS ==== + // ==== DO NOT USE THIS ==== + LegacyTypeSystem bool `protobuf:"varint,4,opt,name=legacy_type_system,json=legacyTypeSystem,proto3" json:"legacy_type_system,omitempty"` } -func (x *ConfigureProvider_Response) Reset() { - *x = ConfigureProvider_Response{} +func (x *ApplyResourceChange_Response) Reset() { + *x = ApplyResourceChange_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[39] + mi := &file_tfplugin6_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ConfigureProvider_Response) String() string { +func (x *ApplyResourceChange_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ConfigureProvider_Response) ProtoMessage() {} +func (*ApplyResourceChange_Response) ProtoMessage() {} -func (x *ConfigureProvider_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[39] +func (x *ApplyResourceChange_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[59] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2251,54 +3469,65 @@ func (x *ConfigureProvider_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ConfigureProvider_Response.ProtoReflect.Descriptor instead. -func (*ConfigureProvider_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{11, 1} +// Deprecated: Use ApplyResourceChange_Response.ProtoReflect.Descriptor instead. +func (*ApplyResourceChange_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{18, 1} } -func (x *ConfigureProvider_Response) GetDiagnostics() []*Diagnostic { +func (x *ApplyResourceChange_Response) GetNewState() *DynamicValue { + if x != nil { + return x.NewState + } + return nil +} + +func (x *ApplyResourceChange_Response) GetPrivate() []byte { + if x != nil { + return x.Private + } + return nil +} + +func (x *ApplyResourceChange_Response) GetDiagnostics() []*Diagnostic { if x != nil { return x.Diagnostics } return nil } -// Request is the message that is sent to the provider during the -// ReadResource RPC. -// -// This message intentionally does not include configuration data as any -// configuration-based or configuration-conditional changes should occur -// during the PlanResourceChange RPC. Additionally, the configuration is -// not guaranteed to be wholly known nor match the given prior state, which -// could lead to unexpected provider behaviors for practitioners. -type ReadResource_Request struct { +func (x *ApplyResourceChange_Response) GetLegacyTypeSystem() bool { + if x != nil { + return x.LegacyTypeSystem + } + return false +} + +type ImportResourceState_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` - CurrentState *DynamicValue `protobuf:"bytes,2,opt,name=current_state,json=currentState,proto3" json:"current_state,omitempty"` - Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` - ProviderMeta *DynamicValue `protobuf:"bytes,4,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` } -func (x *ReadResource_Request) Reset() { - *x = ReadResource_Request{} +func (x *ImportResourceState_Request) Reset() { + *x = ImportResourceState_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[40] + mi := &file_tfplugin6_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ReadResource_Request) String() string { +func (x *ImportResourceState_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ReadResource_Request) ProtoMessage() {} +func (*ImportResourceState_Request) ProtoMessage() {} -func (x *ReadResource_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[40] +func (x *ImportResourceState_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[60] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2309,66 +3538,52 @@ func (x *ReadResource_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ReadResource_Request.ProtoReflect.Descriptor instead. -func (*ReadResource_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{12, 0} +// Deprecated: Use ImportResourceState_Request.ProtoReflect.Descriptor instead. +func (*ImportResourceState_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{19, 0} } -func (x *ReadResource_Request) GetTypeName() string { +func (x *ImportResourceState_Request) GetTypeName() string { if x != nil { return x.TypeName } return "" } -func (x *ReadResource_Request) GetCurrentState() *DynamicValue { - if x != nil { - return x.CurrentState - } - return nil -} - -func (x *ReadResource_Request) GetPrivate() []byte { - if x != nil { - return x.Private - } - return nil -} - -func (x *ReadResource_Request) GetProviderMeta() *DynamicValue { +func (x *ImportResourceState_Request) GetId() string { if x != nil { - return x.ProviderMeta + return x.Id } - return nil + return "" } -type ReadResource_Response struct { +type ImportResourceState_ImportedResource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - NewState *DynamicValue `protobuf:"bytes,1,opt,name=new_state,json=newState,proto3" json:"new_state,omitempty"` - Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` - Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + State *DynamicValue `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` + Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` } -func (x *ReadResource_Response) Reset() { - *x = ReadResource_Response{} +func (x *ImportResourceState_ImportedResource) Reset() { + *x = ImportResourceState_ImportedResource{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[41] + mi := &file_tfplugin6_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ReadResource_Response) String() string { +func (x *ImportResourceState_ImportedResource) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ReadResource_Response) ProtoMessage() {} +func (*ImportResourceState_ImportedResource) ProtoMessage() {} -func (x *ReadResource_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[41] +func (x *ImportResourceState_ImportedResource) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[61] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2379,62 +3594,58 @@ func (x *ReadResource_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ReadResource_Response.ProtoReflect.Descriptor instead. -func (*ReadResource_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{12, 1} +// Deprecated: Use ImportResourceState_ImportedResource.ProtoReflect.Descriptor instead. +func (*ImportResourceState_ImportedResource) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{19, 1} } -func (x *ReadResource_Response) GetNewState() *DynamicValue { +func (x *ImportResourceState_ImportedResource) GetTypeName() string { if x != nil { - return x.NewState + return x.TypeName } - return nil + return "" } -func (x *ReadResource_Response) GetDiagnostics() []*Diagnostic { +func (x *ImportResourceState_ImportedResource) GetState() *DynamicValue { if x != nil { - return x.Diagnostics + return x.State } return nil } -func (x *ReadResource_Response) GetPrivate() []byte { +func (x *ImportResourceState_ImportedResource) GetPrivate() []byte { if x != nil { return x.Private } return nil } -type PlanResourceChange_Request struct { +type ImportResourceState_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` - PriorState *DynamicValue `protobuf:"bytes,2,opt,name=prior_state,json=priorState,proto3" json:"prior_state,omitempty"` - ProposedNewState *DynamicValue `protobuf:"bytes,3,opt,name=proposed_new_state,json=proposedNewState,proto3" json:"proposed_new_state,omitempty"` - Config *DynamicValue `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` - PriorPrivate []byte `protobuf:"bytes,5,opt,name=prior_private,json=priorPrivate,proto3" json:"prior_private,omitempty"` - ProviderMeta *DynamicValue `protobuf:"bytes,6,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` + ImportedResources []*ImportResourceState_ImportedResource `protobuf:"bytes,1,rep,name=imported_resources,json=importedResources,proto3" json:"imported_resources,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` } -func (x *PlanResourceChange_Request) Reset() { - *x = PlanResourceChange_Request{} +func (x *ImportResourceState_Response) Reset() { + *x = ImportResourceState_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[42] + mi := &file_tfplugin6_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *PlanResourceChange_Request) String() string { +func (x *ImportResourceState_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PlanResourceChange_Request) ProtoMessage() {} +func (*ImportResourceState_Response) ProtoMessage() {} -func (x *PlanResourceChange_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[42] +func (x *ImportResourceState_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[62] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2445,93 +3656,64 @@ func (x *PlanResourceChange_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PlanResourceChange_Request.ProtoReflect.Descriptor instead. -func (*PlanResourceChange_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{13, 0} -} - -func (x *PlanResourceChange_Request) GetTypeName() string { - if x != nil { - return x.TypeName - } - return "" -} - -func (x *PlanResourceChange_Request) GetPriorState() *DynamicValue { - if x != nil { - return x.PriorState - } - return nil -} - -func (x *PlanResourceChange_Request) GetProposedNewState() *DynamicValue { - if x != nil { - return x.ProposedNewState - } - return nil -} - -func (x *PlanResourceChange_Request) GetConfig() *DynamicValue { - if x != nil { - return x.Config - } - return nil +// Deprecated: Use ImportResourceState_Response.ProtoReflect.Descriptor instead. +func (*ImportResourceState_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{19, 2} } -func (x *PlanResourceChange_Request) GetPriorPrivate() []byte { +func (x *ImportResourceState_Response) GetImportedResources() []*ImportResourceState_ImportedResource { if x != nil { - return x.PriorPrivate + return x.ImportedResources } return nil } -func (x *PlanResourceChange_Request) GetProviderMeta() *DynamicValue { +func (x *ImportResourceState_Response) GetDiagnostics() []*Diagnostic { if x != nil { - return x.ProviderMeta + return x.Diagnostics } return nil } -type PlanResourceChange_Response struct { +type MoveResourceState_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - PlannedState *DynamicValue `protobuf:"bytes,1,opt,name=planned_state,json=plannedState,proto3" json:"planned_state,omitempty"` - RequiresReplace []*AttributePath `protobuf:"bytes,2,rep,name=requires_replace,json=requiresReplace,proto3" json:"requires_replace,omitempty"` - PlannedPrivate []byte `protobuf:"bytes,3,opt,name=planned_private,json=plannedPrivate,proto3" json:"planned_private,omitempty"` - Diagnostics []*Diagnostic `protobuf:"bytes,4,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` - // This may be set only by the helper/schema "SDK" in the main Terraform - // repository, to request that Terraform Core >=0.12 permit additional - // inconsistencies that can result from the legacy SDK type system - // and its imprecise mapping to the >=0.12 type system. - // The change in behavior implied by this flag makes sense only for the - // specific details of the legacy SDK type system, and are not a general - // mechanism to avoid proper type handling in providers. - // - // ==== DO NOT USE THIS ==== - // ==== THIS MUST BE LEFT UNSET IN ALL OTHER SDKS ==== - // ==== DO NOT USE THIS ==== - LegacyTypeSystem bool `protobuf:"varint,5,opt,name=legacy_type_system,json=legacyTypeSystem,proto3" json:"legacy_type_system,omitempty"` -} - -func (x *PlanResourceChange_Response) Reset() { - *x = PlanResourceChange_Response{} + // The address of the provider the resource is being moved from. + SourceProviderAddress string `protobuf:"bytes,1,opt,name=source_provider_address,json=sourceProviderAddress,proto3" json:"source_provider_address,omitempty"` + // The resource type that the resource is being moved from. + SourceTypeName string `protobuf:"bytes,2,opt,name=source_type_name,json=sourceTypeName,proto3" json:"source_type_name,omitempty"` + // The schema version of the resource type that the resource is being + // moved from. + SourceSchemaVersion int64 `protobuf:"varint,3,opt,name=source_schema_version,json=sourceSchemaVersion,proto3" json:"source_schema_version,omitempty"` + // The raw state of the resource being moved. Only the json field is + // populated, as there should be no legacy providers using the flatmap + // format that support newly introduced RPCs. + SourceState *RawState `protobuf:"bytes,4,opt,name=source_state,json=sourceState,proto3" json:"source_state,omitempty"` + // The resource type that the resource is being moved to. + TargetTypeName string `protobuf:"bytes,5,opt,name=target_type_name,json=targetTypeName,proto3" json:"target_type_name,omitempty"` + // The private state of the resource being moved. + SourcePrivate []byte `protobuf:"bytes,6,opt,name=source_private,json=sourcePrivate,proto3" json:"source_private,omitempty"` +} + +func (x *MoveResourceState_Request) Reset() { + *x = MoveResourceState_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[43] + mi := &file_tfplugin6_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *PlanResourceChange_Response) String() string { +func (x *MoveResourceState_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PlanResourceChange_Response) ProtoMessage() {} +func (*MoveResourceState_Request) ProtoMessage() {} -func (x *PlanResourceChange_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[43] +func (x *MoveResourceState_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[63] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2542,76 +3724,83 @@ func (x *PlanResourceChange_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PlanResourceChange_Response.ProtoReflect.Descriptor instead. -func (*PlanResourceChange_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{13, 1} +// Deprecated: Use MoveResourceState_Request.ProtoReflect.Descriptor instead. +func (*MoveResourceState_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{20, 0} } -func (x *PlanResourceChange_Response) GetPlannedState() *DynamicValue { +func (x *MoveResourceState_Request) GetSourceProviderAddress() string { if x != nil { - return x.PlannedState + return x.SourceProviderAddress } - return nil + return "" } -func (x *PlanResourceChange_Response) GetRequiresReplace() []*AttributePath { +func (x *MoveResourceState_Request) GetSourceTypeName() string { if x != nil { - return x.RequiresReplace + return x.SourceTypeName } - return nil + return "" } -func (x *PlanResourceChange_Response) GetPlannedPrivate() []byte { +func (x *MoveResourceState_Request) GetSourceSchemaVersion() int64 { if x != nil { - return x.PlannedPrivate + return x.SourceSchemaVersion } - return nil + return 0 } -func (x *PlanResourceChange_Response) GetDiagnostics() []*Diagnostic { +func (x *MoveResourceState_Request) GetSourceState() *RawState { if x != nil { - return x.Diagnostics + return x.SourceState } return nil } -func (x *PlanResourceChange_Response) GetLegacyTypeSystem() bool { +func (x *MoveResourceState_Request) GetTargetTypeName() string { if x != nil { - return x.LegacyTypeSystem + return x.TargetTypeName } - return false + return "" } -type ApplyResourceChange_Request struct { +func (x *MoveResourceState_Request) GetSourcePrivate() []byte { + if x != nil { + return x.SourcePrivate + } + return nil +} + +type MoveResourceState_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` - PriorState *DynamicValue `protobuf:"bytes,2,opt,name=prior_state,json=priorState,proto3" json:"prior_state,omitempty"` - PlannedState *DynamicValue `protobuf:"bytes,3,opt,name=planned_state,json=plannedState,proto3" json:"planned_state,omitempty"` - Config *DynamicValue `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` - PlannedPrivate []byte `protobuf:"bytes,5,opt,name=planned_private,json=plannedPrivate,proto3" json:"planned_private,omitempty"` - ProviderMeta *DynamicValue `protobuf:"bytes,6,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` + // The state of the resource after it has been moved. + TargetState *DynamicValue `protobuf:"bytes,1,opt,name=target_state,json=targetState,proto3" json:"target_state,omitempty"` + // Any diagnostics that occurred during the move. + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + // The private state of the resource after it has been moved. + TargetPrivate []byte `protobuf:"bytes,3,opt,name=target_private,json=targetPrivate,proto3" json:"target_private,omitempty"` } -func (x *ApplyResourceChange_Request) Reset() { - *x = ApplyResourceChange_Request{} +func (x *MoveResourceState_Response) Reset() { + *x = MoveResourceState_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[44] + mi := &file_tfplugin6_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ApplyResourceChange_Request) String() string { +func (x *MoveResourceState_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ApplyResourceChange_Request) ProtoMessage() {} +func (*MoveResourceState_Response) ProtoMessage() {} -func (x *ApplyResourceChange_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[44] +func (x *MoveResourceState_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[64] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2622,92 +3811,59 @@ func (x *ApplyResourceChange_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ApplyResourceChange_Request.ProtoReflect.Descriptor instead. -func (*ApplyResourceChange_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{14, 0} -} - -func (x *ApplyResourceChange_Request) GetTypeName() string { - if x != nil { - return x.TypeName - } - return "" -} - -func (x *ApplyResourceChange_Request) GetPriorState() *DynamicValue { - if x != nil { - return x.PriorState - } - return nil -} - -func (x *ApplyResourceChange_Request) GetPlannedState() *DynamicValue { - if x != nil { - return x.PlannedState - } - return nil +// Deprecated: Use MoveResourceState_Response.ProtoReflect.Descriptor instead. +func (*MoveResourceState_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{20, 1} } -func (x *ApplyResourceChange_Request) GetConfig() *DynamicValue { +func (x *MoveResourceState_Response) GetTargetState() *DynamicValue { if x != nil { - return x.Config + return x.TargetState } return nil } -func (x *ApplyResourceChange_Request) GetPlannedPrivate() []byte { +func (x *MoveResourceState_Response) GetDiagnostics() []*Diagnostic { if x != nil { - return x.PlannedPrivate + return x.Diagnostics } return nil } -func (x *ApplyResourceChange_Request) GetProviderMeta() *DynamicValue { +func (x *MoveResourceState_Response) GetTargetPrivate() []byte { if x != nil { - return x.ProviderMeta + return x.TargetPrivate } return nil } -type ApplyResourceChange_Response struct { +type ReadDataSource_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - NewState *DynamicValue `protobuf:"bytes,1,opt,name=new_state,json=newState,proto3" json:"new_state,omitempty"` - Private []byte `protobuf:"bytes,2,opt,name=private,proto3" json:"private,omitempty"` - Diagnostics []*Diagnostic `protobuf:"bytes,3,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` - // This may be set only by the helper/schema "SDK" in the main Terraform - // repository, to request that Terraform Core >=0.12 permit additional - // inconsistencies that can result from the legacy SDK type system - // and its imprecise mapping to the >=0.12 type system. - // The change in behavior implied by this flag makes sense only for the - // specific details of the legacy SDK type system, and are not a general - // mechanism to avoid proper type handling in providers. - // - // ==== DO NOT USE THIS ==== - // ==== THIS MUST BE LEFT UNSET IN ALL OTHER SDKS ==== - // ==== DO NOT USE THIS ==== - LegacyTypeSystem bool `protobuf:"varint,4,opt,name=legacy_type_system,json=legacyTypeSystem,proto3" json:"legacy_type_system,omitempty"` + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` + ProviderMeta *DynamicValue `protobuf:"bytes,3,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` } -func (x *ApplyResourceChange_Response) Reset() { - *x = ApplyResourceChange_Response{} +func (x *ReadDataSource_Request) Reset() { + *x = ReadDataSource_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[45] + mi := &file_tfplugin6_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ApplyResourceChange_Response) String() string { +func (x *ReadDataSource_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ApplyResourceChange_Response) ProtoMessage() {} +func (*ReadDataSource_Request) ProtoMessage() {} -func (x *ApplyResourceChange_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[45] +func (x *ReadDataSource_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[65] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2718,65 +3874,58 @@ func (x *ApplyResourceChange_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ApplyResourceChange_Response.ProtoReflect.Descriptor instead. -func (*ApplyResourceChange_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{14, 1} +// Deprecated: Use ReadDataSource_Request.ProtoReflect.Descriptor instead. +func (*ReadDataSource_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{21, 0} } -func (x *ApplyResourceChange_Response) GetNewState() *DynamicValue { +func (x *ReadDataSource_Request) GetTypeName() string { if x != nil { - return x.NewState + return x.TypeName } - return nil + return "" } -func (x *ApplyResourceChange_Response) GetPrivate() []byte { +func (x *ReadDataSource_Request) GetConfig() *DynamicValue { if x != nil { - return x.Private + return x.Config } return nil } -func (x *ApplyResourceChange_Response) GetDiagnostics() []*Diagnostic { +func (x *ReadDataSource_Request) GetProviderMeta() *DynamicValue { if x != nil { - return x.Diagnostics + return x.ProviderMeta } return nil } -func (x *ApplyResourceChange_Response) GetLegacyTypeSystem() bool { - if x != nil { - return x.LegacyTypeSystem - } - return false -} - -type ImportResourceState_Request struct { +type ReadDataSource_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + State *DynamicValue `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` } -func (x *ImportResourceState_Request) Reset() { - *x = ImportResourceState_Request{} +func (x *ReadDataSource_Response) Reset() { + *x = ReadDataSource_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[46] + mi := &file_tfplugin6_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ImportResourceState_Request) String() string { +func (x *ReadDataSource_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ImportResourceState_Request) ProtoMessage() {} +func (*ReadDataSource_Response) ProtoMessage() {} -func (x *ImportResourceState_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[46] +func (x *ReadDataSource_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2787,52 +3936,48 @@ func (x *ImportResourceState_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ImportResourceState_Request.ProtoReflect.Descriptor instead. -func (*ImportResourceState_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{15, 0} +// Deprecated: Use ReadDataSource_Response.ProtoReflect.Descriptor instead. +func (*ReadDataSource_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{21, 1} } -func (x *ImportResourceState_Request) GetTypeName() string { +func (x *ReadDataSource_Response) GetState() *DynamicValue { if x != nil { - return x.TypeName + return x.State } - return "" + return nil } -func (x *ImportResourceState_Request) GetId() string { +func (x *ReadDataSource_Response) GetDiagnostics() []*Diagnostic { if x != nil { - return x.Id + return x.Diagnostics } - return "" + return nil } -type ImportResourceState_ImportedResource struct { +type GetFunctions_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` - State *DynamicValue `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` - Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` } -func (x *ImportResourceState_ImportedResource) Reset() { - *x = ImportResourceState_ImportedResource{} +func (x *GetFunctions_Request) Reset() { + *x = GetFunctions_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[47] + mi := &file_tfplugin6_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ImportResourceState_ImportedResource) String() string { +func (x *GetFunctions_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ImportResourceState_ImportedResource) ProtoMessage() {} +func (*GetFunctions_Request) ProtoMessage() {} -func (x *ImportResourceState_ImportedResource) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[47] +func (x *GetFunctions_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2843,58 +3988,39 @@ func (x *ImportResourceState_ImportedResource) ProtoReflect() protoreflect.Messa return mi.MessageOf(x) } -// Deprecated: Use ImportResourceState_ImportedResource.ProtoReflect.Descriptor instead. -func (*ImportResourceState_ImportedResource) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{15, 1} -} - -func (x *ImportResourceState_ImportedResource) GetTypeName() string { - if x != nil { - return x.TypeName - } - return "" -} - -func (x *ImportResourceState_ImportedResource) GetState() *DynamicValue { - if x != nil { - return x.State - } - return nil -} - -func (x *ImportResourceState_ImportedResource) GetPrivate() []byte { - if x != nil { - return x.Private - } - return nil +// Deprecated: Use GetFunctions_Request.ProtoReflect.Descriptor instead. +func (*GetFunctions_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{22, 0} } -type ImportResourceState_Response struct { +type GetFunctions_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ImportedResources []*ImportResourceState_ImportedResource `protobuf:"bytes,1,rep,name=imported_resources,json=importedResources,proto3" json:"imported_resources,omitempty"` - Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + // functions is a mapping of function names to definitions. + Functions map[string]*Function `protobuf:"bytes,1,rep,name=functions,proto3" json:"functions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // diagnostics is any warnings or errors. + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` } -func (x *ImportResourceState_Response) Reset() { - *x = ImportResourceState_Response{} +func (x *GetFunctions_Response) Reset() { + *x = GetFunctions_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[48] + mi := &file_tfplugin6_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ImportResourceState_Response) String() string { +func (x *GetFunctions_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ImportResourceState_Response) ProtoMessage() {} +func (*GetFunctions_Response) ProtoMessage() {} -func (x *ImportResourceState_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[48] +func (x *GetFunctions_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[68] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2905,52 +4031,53 @@ func (x *ImportResourceState_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ImportResourceState_Response.ProtoReflect.Descriptor instead. -func (*ImportResourceState_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{15, 2} +// Deprecated: Use GetFunctions_Response.ProtoReflect.Descriptor instead. +func (*GetFunctions_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{22, 1} } -func (x *ImportResourceState_Response) GetImportedResources() []*ImportResourceState_ImportedResource { +func (x *GetFunctions_Response) GetFunctions() map[string]*Function { if x != nil { - return x.ImportedResources + return x.Functions } return nil } -func (x *ImportResourceState_Response) GetDiagnostics() []*Diagnostic { +func (x *GetFunctions_Response) GetDiagnostics() []*Diagnostic { if x != nil { return x.Diagnostics } return nil } -type ReadDataSource_Request struct { +type CallFunction_Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` - Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` - ProviderMeta *DynamicValue `protobuf:"bytes,3,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` + // name is the name of the function being called. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // arguments is the data of each function argument value. + Arguments []*DynamicValue `protobuf:"bytes,2,rep,name=arguments,proto3" json:"arguments,omitempty"` } -func (x *ReadDataSource_Request) Reset() { - *x = ReadDataSource_Request{} +func (x *CallFunction_Request) Reset() { + *x = CallFunction_Request{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[49] + mi := &file_tfplugin6_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ReadDataSource_Request) String() string { +func (x *CallFunction_Request) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ReadDataSource_Request) ProtoMessage() {} +func (*CallFunction_Request) ProtoMessage() {} -func (x *ReadDataSource_Request) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[49] +func (x *CallFunction_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[70] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2961,58 +4088,53 @@ func (x *ReadDataSource_Request) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ReadDataSource_Request.ProtoReflect.Descriptor instead. -func (*ReadDataSource_Request) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{16, 0} +// Deprecated: Use CallFunction_Request.ProtoReflect.Descriptor instead. +func (*CallFunction_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{23, 0} } -func (x *ReadDataSource_Request) GetTypeName() string { +func (x *CallFunction_Request) GetName() string { if x != nil { - return x.TypeName + return x.Name } return "" } -func (x *ReadDataSource_Request) GetConfig() *DynamicValue { - if x != nil { - return x.Config - } - return nil -} - -func (x *ReadDataSource_Request) GetProviderMeta() *DynamicValue { +func (x *CallFunction_Request) GetArguments() []*DynamicValue { if x != nil { - return x.ProviderMeta + return x.Arguments } return nil } -type ReadDataSource_Response struct { +type CallFunction_Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - State *DynamicValue `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"` - Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + // result is result value after running the function logic. + Result *DynamicValue `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"` + // error is any errors from the function logic. + Error *FunctionError `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` } -func (x *ReadDataSource_Response) Reset() { - *x = ReadDataSource_Response{} +func (x *CallFunction_Response) Reset() { + *x = CallFunction_Response{} if protoimpl.UnsafeEnabled { - mi := &file_tfplugin6_proto_msgTypes[50] + mi := &file_tfplugin6_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ReadDataSource_Response) String() string { +func (x *CallFunction_Response) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ReadDataSource_Response) ProtoMessage() {} +func (*CallFunction_Response) ProtoMessage() {} -func (x *ReadDataSource_Response) ProtoReflect() protoreflect.Message { - mi := &file_tfplugin6_proto_msgTypes[50] +func (x *CallFunction_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[71] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3023,21 +4145,21 @@ func (x *ReadDataSource_Response) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ReadDataSource_Response.ProtoReflect.Descriptor instead. -func (*ReadDataSource_Response) Descriptor() ([]byte, []int) { - return file_tfplugin6_proto_rawDescGZIP(), []int{16, 1} +// Deprecated: Use CallFunction_Response.ProtoReflect.Descriptor instead. +func (*CallFunction_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{23, 1} } -func (x *ReadDataSource_Response) GetState() *DynamicValue { +func (x *CallFunction_Response) GetResult() *DynamicValue { if x != nil { - return x.State + return x.Result } return nil } -func (x *ReadDataSource_Response) GetDiagnostics() []*Diagnostic { +func (x *CallFunction_Response) GetError() *FunctionError { if x != nil { - return x.Diagnostics + return x.Error } return nil } @@ -3065,364 +4187,527 @@ var file_tfplugin6_proto_rawDesc = []byte{ 0x2f, 0x0a, 0x08, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x02, - 0x22, 0xdc, 0x01, 0x0a, 0x0d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, - 0x74, 0x68, 0x12, 0x33, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x53, 0x74, 0x65, 0x70, - 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x95, 0x01, 0x0a, 0x04, 0x53, 0x74, 0x65, 0x70, - 0x12, 0x27, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x65, 0x6c, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x10, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x6c, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x03, 0x48, 0x00, 0x52, 0x0d, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, - 0x49, 0x6e, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, - 0x3b, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x1a, - 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x0a, 0x08, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x96, 0x01, 0x0a, - 0x08, 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, - 0x07, 0x66, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, - 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, 0x61, 0x77, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x46, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x07, 0x66, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x1a, 0x3a, 0x0a, 0x0c, 0x46, 0x6c, 0x61, - 0x74, 0x6d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x95, 0x0a, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x22, 0x6b, 0x0a, 0x0d, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x30, 0x0a, 0x11, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x48, 0x00, 0x52, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0xdc, 0x01, + 0x0a, 0x0d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x33, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, + 0x74, 0x65, 0x70, 0x73, 0x1a, 0x95, 0x01, 0x0a, 0x04, 0x53, 0x74, 0x65, 0x70, 0x12, 0x27, 0x0a, + 0x0e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x10, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, + 0x00, 0x52, 0x0d, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x6e, 0x74, + 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x3b, 0x0a, 0x0c, + 0x53, 0x74, 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x1a, 0x09, 0x0a, 0x07, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x96, 0x01, 0x0a, 0x08, 0x52, 0x61, + 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x07, 0x66, 0x6c, + 0x61, 0x74, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x2e, 0x46, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x66, + 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x1a, 0x3a, 0x0a, 0x0c, 0x46, 0x6c, 0x61, 0x74, 0x6d, 0x61, + 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0x95, 0x0a, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, + 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0xa2, 0x02, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x05, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0xa2, 0x02, 0x0a, 0x05, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, - 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x0b, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x0a, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x10, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0f, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1e, - 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x1a, 0xe4, - 0x02, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x66, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x0a, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x1a, 0x0a, - 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, - 0x70, 0x75, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, - 0x70, 0x75, 0x74, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, - 0x76, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, - 0x69, 0x76, 0x65, 0x12, 0x40, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, - 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, - 0x74, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, - 0x63, 0x61, 0x74, 0x65, 0x64, 0x1a, 0xa7, 0x02, 0x0a, 0x0b, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x12, 0x43, 0x0a, 0x07, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x07, 0x6e, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x74, - 0x65, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x49, 0x74, - 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, - 0x22, 0x4d, 0x0a, 0x0b, 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, - 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, - 0x53, 0x49, 0x4e, 0x47, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x53, 0x54, - 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x4d, - 0x41, 0x50, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x05, 0x1a, - 0x8b, 0x02, 0x0a, 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x3b, 0x0a, 0x0a, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, + 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x0a, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x07, 0x6e, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x07, - 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, - 0x74, 0x65, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, - 0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1f, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, - 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x42, 0x02, 0x18, 0x01, 0x52, - 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x42, 0x0a, 0x0b, 0x4e, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x4e, 0x47, 0x4c, 0x45, 0x10, - 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x53, - 0x45, 0x54, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x41, 0x50, 0x10, 0x04, 0x22, 0xeb, 0x05, - 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x1a, 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x91, - 0x05, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x65, 0x0a, 0x10, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, - 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x73, 0x12, 0x6c, 0x0a, 0x13, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, - 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x64, 0x61, - 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x12, - 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, - 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, - 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, - 0x12, 0x60, 0x0a, 0x13, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, - 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x12, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, - 0x65, 0x73, 0x1a, 0x55, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, - 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x57, 0x0a, 0x16, 0x44, 0x61, 0x74, - 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, - 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x1a, 0x37, 0x0a, 0x12, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x6c, 0x61, 0x6e, - 0x5f, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, - 0x70, 0x6c, 0x61, 0x6e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x22, 0x99, 0x01, 0x0a, 0x16, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x3a, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, - 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, + 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x0a, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x10, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, + 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x1a, 0xe4, 0x02, 0x0a, 0x09, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x52, 0x0a, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, + 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, + 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, + 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, + 0x12, 0x40, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, + 0x64, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x69, + 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, + 0x65, 0x64, 0x1a, 0xa7, 0x02, 0x0a, 0x0b, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x2d, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x43, + 0x0a, 0x07, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x29, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x4e, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x07, 0x6e, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, + 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x4d, 0x0a, + 0x0b, 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0b, 0x0a, 0x07, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x4e, + 0x47, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x02, 0x12, + 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x41, 0x50, 0x10, + 0x04, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x05, 0x1a, 0x8b, 0x02, 0x0a, + 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x3b, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x07, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, + 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x07, 0x6e, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x6d, 0x69, 0x6e, + 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1f, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x6d, 0x61, + 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x42, 0x0a, 0x0b, 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, + 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x4e, 0x47, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x08, + 0x0a, 0x04, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, + 0x03, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x41, 0x50, 0x10, 0x04, 0x22, 0x8e, 0x05, 0x0a, 0x08, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x4c, 0x0a, 0x12, 0x76, 0x61, 0x72, 0x69, 0x61, 0x64, + 0x69, 0x63, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x52, 0x11, 0x76, 0x61, 0x72, 0x69, 0x61, 0x64, 0x69, 0x63, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, + 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x52, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x2f, 0x0a, 0x13, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x12, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0xf3, 0x01, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, + 0x10, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x75, + 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x55, 0x6e, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x10, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x36, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0f, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x1a, 0x1c, 0x0a, + 0x06, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xa8, 0x01, 0x0a, 0x12, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x72, + 0x6f, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x6c, 0x61, 0x6e, 0x44, 0x65, + 0x73, 0x74, 0x72, 0x6f, 0x79, 0x12, 0x3f, 0x0a, 0x1c, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x67, 0x65, 0x74, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x11, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x96, 0x04, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0xef, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, + 0x0a, 0x13, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, + 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x12, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, - 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0x90, 0x02, 0x0a, 0x14, 0x55, 0x70, 0x67, 0x72, - 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x1a, 0x72, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, - 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x09, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x36, 0x2e, 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x72, 0x61, 0x77, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x1a, 0x83, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x3e, 0x0a, 0x0e, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x0d, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x4c, 0x0a, 0x0c, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x09, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x1a, 0x26, 0x0a, 0x10, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x31, 0x0a, 0x12, 0x44, + 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x2f, + 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, + 0xc7, 0x06, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x1a, 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0xa6, 0x06, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, + 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x65, 0x0a, 0x10, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x73, 0x12, 0x6c, 0x0a, 0x13, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x3c, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, + 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, - 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xb6, 0x01, 0x0a, 0x16, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x57, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, - 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, - 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, - 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, - 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, - 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, - 0x69, 0x63, 0x73, 0x22, 0xba, 0x01, 0x0a, 0x1a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x1a, 0x57, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, - 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, - 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, - 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, - 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, - 0x22, 0xc1, 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x1a, 0x67, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x65, - 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, - 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, - 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, - 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, - 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, - 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, - 0x74, 0x69, 0x63, 0x73, 0x22, 0xe3, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0xbc, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3c, - 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, - 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, - 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, - 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, - 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x93, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x34, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, - 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6e, - 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, - 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, - 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, - 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, - 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0xf2, 0x04, 0x0a, 0x12, 0x50, - 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x1a, 0xbb, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, - 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x72, - 0x69, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, + 0x74, 0x61, 0x12, 0x4e, 0x0a, 0x13, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x70, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x12, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x12, 0x52, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x36, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x55, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x57, 0x0a, + 0x16, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x51, 0x0a, 0x0e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x99, 0x01, 0x0a, 0x16, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x3a, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, - 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x45, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, - 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, - 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x70, 0x6f, - 0x73, 0x65, 0x64, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, + 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, + 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, + 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, + 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0x90, 0x02, 0x0a, 0x14, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, + 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x72, + 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, + 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x30, 0x0a, 0x09, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, + 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x72, 0x61, 0x77, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x1a, 0x83, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3e, 0x0a, 0x0e, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x0d, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, + 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, + 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xb6, 0x01, 0x0a, 0x16, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x1a, 0x57, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, - 0x70, 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, - 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, - 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, - 0x9d, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0d, - 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, - 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x6c, - 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x72, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, - 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x0f, - 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, - 0x27, 0x0a, 0x0f, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, - 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, - 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, + 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, - 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, - 0x65, 0x67, 0x61, 0x63, 0x79, 0x54, 0x79, 0x70, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, - 0x92, 0x04, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x1a, 0xb6, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, - 0x70, 0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x6c, - 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, - 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x6e, - 0x6e, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x73, 0x22, 0xba, 0x01, 0x0a, 0x1a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, + 0x74, 0x61, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x1a, 0x57, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, + 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x6c, 0x61, - 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, - 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, + 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xc1, + 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x1a, 0x67, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x2b, 0x0a, 0x11, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x65, 0x72, 0x72, + 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x06, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, + 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, + 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, + 0x63, 0x73, 0x22, 0xe3, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x1a, 0xbc, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0d, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, + 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, + 0x74, 0x61, 0x1a, 0x93, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x34, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6e, 0x65, 0x77, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, + 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x18, + 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0xf2, 0x04, 0x0a, 0x12, 0x50, 0x6c, 0x61, + 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x1a, + 0xbb, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, + 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x6f, + 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, + 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x45, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x6e, + 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, + 0x64, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, - 0x1a, 0xc1, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, - 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, - 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, - 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, - 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, - 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x10, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x54, 0x79, 0x70, 0x65, 0x53, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x22, 0xed, 0x02, 0x0a, 0x13, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x36, 0x0a, 0x07, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x1a, 0x78, 0x0a, 0x10, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, - 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x1a, 0xa3, - 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x12, 0x69, - 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x36, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x11, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x64, - 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, + 0x69, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0c, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, + 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x9d, 0x02, + 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x6c, + 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, + 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x6e, + 0x6e, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x0f, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, + 0x0f, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x50, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, + 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, + 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, + 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, 0x65, 0x67, + 0x61, 0x63, 0x79, 0x54, 0x79, 0x70, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x92, 0x04, + 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x1a, 0xb6, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, + 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, + 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x70, 0x72, + 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x6e, + 0x6e, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, + 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, + 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x6c, 0x61, 0x6e, 0x6e, + 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0xc1, + 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x6e, + 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, + 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, - 0x74, 0x69, 0x63, 0x73, 0x22, 0x9c, 0x02, 0x0a, 0x0e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, - 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x95, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, - 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, - 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x74, 0x69, 0x63, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x10, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x54, 0x79, 0x70, 0x65, 0x53, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x22, 0xed, 0x02, 0x0a, 0x13, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x36, 0x0a, 0x07, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x1a, 0x78, 0x0a, 0x10, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x1a, 0xa3, 0x01, 0x0a, + 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x12, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x36, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x11, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, + 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, + 0x63, 0x73, 0x22, 0xe7, 0x03, 0x0a, 0x11, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0xa8, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x17, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x28, 0x0a, 0x10, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x0c, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, 0x61, 0x77, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x1a, 0xa6, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3a, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, + 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, + 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, + 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, + 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0x9c, 0x02, 0x0a, + 0x0e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, + 0x95, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, + 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, - 0x72, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, - 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, - 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, - 0x69, 0x63, 0x73, 0x2a, 0x25, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, + 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, + 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x72, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, + 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0x81, 0x02, 0x0a, 0x0c, + 0x47, 0x65, 0x74, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x09, 0x0a, 0x07, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0xe5, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, + 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, + 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x1a, 0x51, 0x0a, 0x0e, + 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x46, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0xd1, 0x01, 0x0a, 0x0c, 0x43, 0x61, 0x6c, 0x6c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x1a, 0x54, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x35, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x6b, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x2a, 0x25, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, - 0x4d, 0x41, 0x52, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x32, 0xcc, 0x09, 0x0a, 0x08, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x60, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, + 0x4d, 0x41, 0x52, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x32, 0xa4, 0x0c, 0x0a, 0x08, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x24, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, @@ -3487,23 +4772,40 @@ var file_tfplugin6_proto_rawDesc = []byte{ 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, - 0x0e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, - 0x21, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, 0x65, 0x61, 0x64, - 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, - 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x47, 0x5a, 0x45, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2f, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x74, 0x66, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x76, 0x36, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x36, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, + 0x11, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x24, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x4d, + 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x57, 0x0a, 0x0e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x21, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, 0x65, + 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, + 0x2e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0c, 0x43, + 0x61, 0x6c, 0x6c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x46, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, + 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x1f, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x20, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x6f, 0x70, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x42, 0x47, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x74, 0x66, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x76, 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2f, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -3519,7 +4821,7 @@ func file_tfplugin6_proto_rawDescGZIP() []byte { } var file_tfplugin6_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_tfplugin6_proto_msgTypes = make([]protoimpl.MessageInfo, 51) +var file_tfplugin6_proto_msgTypes = make([]protoimpl.MessageInfo, 72) var file_tfplugin6_proto_goTypes = []interface{}{ (StringKind)(0), // 0: tfplugin6.StringKind (Diagnostic_Severity)(0), // 1: tfplugin6.Diagnostic.Severity @@ -3527,143 +4829,193 @@ var file_tfplugin6_proto_goTypes = []interface{}{ (Schema_Object_NestingMode)(0), // 3: tfplugin6.Schema.Object.NestingMode (*DynamicValue)(nil), // 4: tfplugin6.DynamicValue (*Diagnostic)(nil), // 5: tfplugin6.Diagnostic - (*AttributePath)(nil), // 6: tfplugin6.AttributePath - (*StopProvider)(nil), // 7: tfplugin6.StopProvider - (*RawState)(nil), // 8: tfplugin6.RawState - (*Schema)(nil), // 9: tfplugin6.Schema - (*GetProviderSchema)(nil), // 10: tfplugin6.GetProviderSchema - (*ValidateProviderConfig)(nil), // 11: tfplugin6.ValidateProviderConfig - (*UpgradeResourceState)(nil), // 12: tfplugin6.UpgradeResourceState - (*ValidateResourceConfig)(nil), // 13: tfplugin6.ValidateResourceConfig - (*ValidateDataResourceConfig)(nil), // 14: tfplugin6.ValidateDataResourceConfig - (*ConfigureProvider)(nil), // 15: tfplugin6.ConfigureProvider - (*ReadResource)(nil), // 16: tfplugin6.ReadResource - (*PlanResourceChange)(nil), // 17: tfplugin6.PlanResourceChange - (*ApplyResourceChange)(nil), // 18: tfplugin6.ApplyResourceChange - (*ImportResourceState)(nil), // 19: tfplugin6.ImportResourceState - (*ReadDataSource)(nil), // 20: tfplugin6.ReadDataSource - (*AttributePath_Step)(nil), // 21: tfplugin6.AttributePath.Step - (*StopProvider_Request)(nil), // 22: tfplugin6.StopProvider.Request - (*StopProvider_Response)(nil), // 23: tfplugin6.StopProvider.Response - nil, // 24: tfplugin6.RawState.FlatmapEntry - (*Schema_Block)(nil), // 25: tfplugin6.Schema.Block - (*Schema_Attribute)(nil), // 26: tfplugin6.Schema.Attribute - (*Schema_NestedBlock)(nil), // 27: tfplugin6.Schema.NestedBlock - (*Schema_Object)(nil), // 28: tfplugin6.Schema.Object - (*GetProviderSchema_Request)(nil), // 29: tfplugin6.GetProviderSchema.Request - (*GetProviderSchema_Response)(nil), // 30: tfplugin6.GetProviderSchema.Response - (*GetProviderSchema_ServerCapabilities)(nil), // 31: tfplugin6.GetProviderSchema.ServerCapabilities - nil, // 32: tfplugin6.GetProviderSchema.Response.ResourceSchemasEntry - nil, // 33: tfplugin6.GetProviderSchema.Response.DataSourceSchemasEntry - (*ValidateProviderConfig_Request)(nil), // 34: tfplugin6.ValidateProviderConfig.Request - (*ValidateProviderConfig_Response)(nil), // 35: tfplugin6.ValidateProviderConfig.Response - (*UpgradeResourceState_Request)(nil), // 36: tfplugin6.UpgradeResourceState.Request - (*UpgradeResourceState_Response)(nil), // 37: tfplugin6.UpgradeResourceState.Response - (*ValidateResourceConfig_Request)(nil), // 38: tfplugin6.ValidateResourceConfig.Request - (*ValidateResourceConfig_Response)(nil), // 39: tfplugin6.ValidateResourceConfig.Response - (*ValidateDataResourceConfig_Request)(nil), // 40: tfplugin6.ValidateDataResourceConfig.Request - (*ValidateDataResourceConfig_Response)(nil), // 41: tfplugin6.ValidateDataResourceConfig.Response - (*ConfigureProvider_Request)(nil), // 42: tfplugin6.ConfigureProvider.Request - (*ConfigureProvider_Response)(nil), // 43: tfplugin6.ConfigureProvider.Response - (*ReadResource_Request)(nil), // 44: tfplugin6.ReadResource.Request - (*ReadResource_Response)(nil), // 45: tfplugin6.ReadResource.Response - (*PlanResourceChange_Request)(nil), // 46: tfplugin6.PlanResourceChange.Request - (*PlanResourceChange_Response)(nil), // 47: tfplugin6.PlanResourceChange.Response - (*ApplyResourceChange_Request)(nil), // 48: tfplugin6.ApplyResourceChange.Request - (*ApplyResourceChange_Response)(nil), // 49: tfplugin6.ApplyResourceChange.Response - (*ImportResourceState_Request)(nil), // 50: tfplugin6.ImportResourceState.Request - (*ImportResourceState_ImportedResource)(nil), // 51: tfplugin6.ImportResourceState.ImportedResource - (*ImportResourceState_Response)(nil), // 52: tfplugin6.ImportResourceState.Response - (*ReadDataSource_Request)(nil), // 53: tfplugin6.ReadDataSource.Request - (*ReadDataSource_Response)(nil), // 54: tfplugin6.ReadDataSource.Response + (*FunctionError)(nil), // 6: tfplugin6.FunctionError + (*AttributePath)(nil), // 7: tfplugin6.AttributePath + (*StopProvider)(nil), // 8: tfplugin6.StopProvider + (*RawState)(nil), // 9: tfplugin6.RawState + (*Schema)(nil), // 10: tfplugin6.Schema + (*Function)(nil), // 11: tfplugin6.Function + (*ServerCapabilities)(nil), // 12: tfplugin6.ServerCapabilities + (*GetMetadata)(nil), // 13: tfplugin6.GetMetadata + (*GetProviderSchema)(nil), // 14: tfplugin6.GetProviderSchema + (*ValidateProviderConfig)(nil), // 15: tfplugin6.ValidateProviderConfig + (*UpgradeResourceState)(nil), // 16: tfplugin6.UpgradeResourceState + (*ValidateResourceConfig)(nil), // 17: tfplugin6.ValidateResourceConfig + (*ValidateDataResourceConfig)(nil), // 18: tfplugin6.ValidateDataResourceConfig + (*ConfigureProvider)(nil), // 19: tfplugin6.ConfigureProvider + (*ReadResource)(nil), // 20: tfplugin6.ReadResource + (*PlanResourceChange)(nil), // 21: tfplugin6.PlanResourceChange + (*ApplyResourceChange)(nil), // 22: tfplugin6.ApplyResourceChange + (*ImportResourceState)(nil), // 23: tfplugin6.ImportResourceState + (*MoveResourceState)(nil), // 24: tfplugin6.MoveResourceState + (*ReadDataSource)(nil), // 25: tfplugin6.ReadDataSource + (*GetFunctions)(nil), // 26: tfplugin6.GetFunctions + (*CallFunction)(nil), // 27: tfplugin6.CallFunction + (*AttributePath_Step)(nil), // 28: tfplugin6.AttributePath.Step + (*StopProvider_Request)(nil), // 29: tfplugin6.StopProvider.Request + (*StopProvider_Response)(nil), // 30: tfplugin6.StopProvider.Response + nil, // 31: tfplugin6.RawState.FlatmapEntry + (*Schema_Block)(nil), // 32: tfplugin6.Schema.Block + (*Schema_Attribute)(nil), // 33: tfplugin6.Schema.Attribute + (*Schema_NestedBlock)(nil), // 34: tfplugin6.Schema.NestedBlock + (*Schema_Object)(nil), // 35: tfplugin6.Schema.Object + (*Function_Parameter)(nil), // 36: tfplugin6.Function.Parameter + (*Function_Return)(nil), // 37: tfplugin6.Function.Return + (*GetMetadata_Request)(nil), // 38: tfplugin6.GetMetadata.Request + (*GetMetadata_Response)(nil), // 39: tfplugin6.GetMetadata.Response + (*GetMetadata_FunctionMetadata)(nil), // 40: tfplugin6.GetMetadata.FunctionMetadata + (*GetMetadata_DataSourceMetadata)(nil), // 41: tfplugin6.GetMetadata.DataSourceMetadata + (*GetMetadata_ResourceMetadata)(nil), // 42: tfplugin6.GetMetadata.ResourceMetadata + (*GetProviderSchema_Request)(nil), // 43: tfplugin6.GetProviderSchema.Request + (*GetProviderSchema_Response)(nil), // 44: tfplugin6.GetProviderSchema.Response + nil, // 45: tfplugin6.GetProviderSchema.Response.ResourceSchemasEntry + nil, // 46: tfplugin6.GetProviderSchema.Response.DataSourceSchemasEntry + nil, // 47: tfplugin6.GetProviderSchema.Response.FunctionsEntry + (*ValidateProviderConfig_Request)(nil), // 48: tfplugin6.ValidateProviderConfig.Request + (*ValidateProviderConfig_Response)(nil), // 49: tfplugin6.ValidateProviderConfig.Response + (*UpgradeResourceState_Request)(nil), // 50: tfplugin6.UpgradeResourceState.Request + (*UpgradeResourceState_Response)(nil), // 51: tfplugin6.UpgradeResourceState.Response + (*ValidateResourceConfig_Request)(nil), // 52: tfplugin6.ValidateResourceConfig.Request + (*ValidateResourceConfig_Response)(nil), // 53: tfplugin6.ValidateResourceConfig.Response + (*ValidateDataResourceConfig_Request)(nil), // 54: tfplugin6.ValidateDataResourceConfig.Request + (*ValidateDataResourceConfig_Response)(nil), // 55: tfplugin6.ValidateDataResourceConfig.Response + (*ConfigureProvider_Request)(nil), // 56: tfplugin6.ConfigureProvider.Request + (*ConfigureProvider_Response)(nil), // 57: tfplugin6.ConfigureProvider.Response + (*ReadResource_Request)(nil), // 58: tfplugin6.ReadResource.Request + (*ReadResource_Response)(nil), // 59: tfplugin6.ReadResource.Response + (*PlanResourceChange_Request)(nil), // 60: tfplugin6.PlanResourceChange.Request + (*PlanResourceChange_Response)(nil), // 61: tfplugin6.PlanResourceChange.Response + (*ApplyResourceChange_Request)(nil), // 62: tfplugin6.ApplyResourceChange.Request + (*ApplyResourceChange_Response)(nil), // 63: tfplugin6.ApplyResourceChange.Response + (*ImportResourceState_Request)(nil), // 64: tfplugin6.ImportResourceState.Request + (*ImportResourceState_ImportedResource)(nil), // 65: tfplugin6.ImportResourceState.ImportedResource + (*ImportResourceState_Response)(nil), // 66: tfplugin6.ImportResourceState.Response + (*MoveResourceState_Request)(nil), // 67: tfplugin6.MoveResourceState.Request + (*MoveResourceState_Response)(nil), // 68: tfplugin6.MoveResourceState.Response + (*ReadDataSource_Request)(nil), // 69: tfplugin6.ReadDataSource.Request + (*ReadDataSource_Response)(nil), // 70: tfplugin6.ReadDataSource.Response + (*GetFunctions_Request)(nil), // 71: tfplugin6.GetFunctions.Request + (*GetFunctions_Response)(nil), // 72: tfplugin6.GetFunctions.Response + nil, // 73: tfplugin6.GetFunctions.Response.FunctionsEntry + (*CallFunction_Request)(nil), // 74: tfplugin6.CallFunction.Request + (*CallFunction_Response)(nil), // 75: tfplugin6.CallFunction.Response } var file_tfplugin6_proto_depIdxs = []int32{ 1, // 0: tfplugin6.Diagnostic.severity:type_name -> tfplugin6.Diagnostic.Severity - 6, // 1: tfplugin6.Diagnostic.attribute:type_name -> tfplugin6.AttributePath - 21, // 2: tfplugin6.AttributePath.steps:type_name -> tfplugin6.AttributePath.Step - 24, // 3: tfplugin6.RawState.flatmap:type_name -> tfplugin6.RawState.FlatmapEntry - 25, // 4: tfplugin6.Schema.block:type_name -> tfplugin6.Schema.Block - 26, // 5: tfplugin6.Schema.Block.attributes:type_name -> tfplugin6.Schema.Attribute - 27, // 6: tfplugin6.Schema.Block.block_types:type_name -> tfplugin6.Schema.NestedBlock - 0, // 7: tfplugin6.Schema.Block.description_kind:type_name -> tfplugin6.StringKind - 28, // 8: tfplugin6.Schema.Attribute.nested_type:type_name -> tfplugin6.Schema.Object - 0, // 9: tfplugin6.Schema.Attribute.description_kind:type_name -> tfplugin6.StringKind - 25, // 10: tfplugin6.Schema.NestedBlock.block:type_name -> tfplugin6.Schema.Block - 2, // 11: tfplugin6.Schema.NestedBlock.nesting:type_name -> tfplugin6.Schema.NestedBlock.NestingMode - 26, // 12: tfplugin6.Schema.Object.attributes:type_name -> tfplugin6.Schema.Attribute - 3, // 13: tfplugin6.Schema.Object.nesting:type_name -> tfplugin6.Schema.Object.NestingMode - 9, // 14: tfplugin6.GetProviderSchema.Response.provider:type_name -> tfplugin6.Schema - 32, // 15: tfplugin6.GetProviderSchema.Response.resource_schemas:type_name -> tfplugin6.GetProviderSchema.Response.ResourceSchemasEntry - 33, // 16: tfplugin6.GetProviderSchema.Response.data_source_schemas:type_name -> tfplugin6.GetProviderSchema.Response.DataSourceSchemasEntry - 5, // 17: tfplugin6.GetProviderSchema.Response.diagnostics:type_name -> tfplugin6.Diagnostic - 9, // 18: tfplugin6.GetProviderSchema.Response.provider_meta:type_name -> tfplugin6.Schema - 31, // 19: tfplugin6.GetProviderSchema.Response.server_capabilities:type_name -> tfplugin6.GetProviderSchema.ServerCapabilities - 9, // 20: tfplugin6.GetProviderSchema.Response.ResourceSchemasEntry.value:type_name -> tfplugin6.Schema - 9, // 21: tfplugin6.GetProviderSchema.Response.DataSourceSchemasEntry.value:type_name -> tfplugin6.Schema - 4, // 22: tfplugin6.ValidateProviderConfig.Request.config:type_name -> tfplugin6.DynamicValue - 5, // 23: tfplugin6.ValidateProviderConfig.Response.diagnostics:type_name -> tfplugin6.Diagnostic - 8, // 24: tfplugin6.UpgradeResourceState.Request.raw_state:type_name -> tfplugin6.RawState - 4, // 25: tfplugin6.UpgradeResourceState.Response.upgraded_state:type_name -> tfplugin6.DynamicValue - 5, // 26: tfplugin6.UpgradeResourceState.Response.diagnostics:type_name -> tfplugin6.Diagnostic - 4, // 27: tfplugin6.ValidateResourceConfig.Request.config:type_name -> tfplugin6.DynamicValue - 5, // 28: tfplugin6.ValidateResourceConfig.Response.diagnostics:type_name -> tfplugin6.Diagnostic - 4, // 29: tfplugin6.ValidateDataResourceConfig.Request.config:type_name -> tfplugin6.DynamicValue - 5, // 30: tfplugin6.ValidateDataResourceConfig.Response.diagnostics:type_name -> tfplugin6.Diagnostic - 4, // 31: tfplugin6.ConfigureProvider.Request.config:type_name -> tfplugin6.DynamicValue - 5, // 32: tfplugin6.ConfigureProvider.Response.diagnostics:type_name -> tfplugin6.Diagnostic - 4, // 33: tfplugin6.ReadResource.Request.current_state:type_name -> tfplugin6.DynamicValue - 4, // 34: tfplugin6.ReadResource.Request.provider_meta:type_name -> tfplugin6.DynamicValue - 4, // 35: tfplugin6.ReadResource.Response.new_state:type_name -> tfplugin6.DynamicValue - 5, // 36: tfplugin6.ReadResource.Response.diagnostics:type_name -> tfplugin6.Diagnostic - 4, // 37: tfplugin6.PlanResourceChange.Request.prior_state:type_name -> tfplugin6.DynamicValue - 4, // 38: tfplugin6.PlanResourceChange.Request.proposed_new_state:type_name -> tfplugin6.DynamicValue - 4, // 39: tfplugin6.PlanResourceChange.Request.config:type_name -> tfplugin6.DynamicValue - 4, // 40: tfplugin6.PlanResourceChange.Request.provider_meta:type_name -> tfplugin6.DynamicValue - 4, // 41: tfplugin6.PlanResourceChange.Response.planned_state:type_name -> tfplugin6.DynamicValue - 6, // 42: tfplugin6.PlanResourceChange.Response.requires_replace:type_name -> tfplugin6.AttributePath - 5, // 43: tfplugin6.PlanResourceChange.Response.diagnostics:type_name -> tfplugin6.Diagnostic - 4, // 44: tfplugin6.ApplyResourceChange.Request.prior_state:type_name -> tfplugin6.DynamicValue - 4, // 45: tfplugin6.ApplyResourceChange.Request.planned_state:type_name -> tfplugin6.DynamicValue - 4, // 46: tfplugin6.ApplyResourceChange.Request.config:type_name -> tfplugin6.DynamicValue - 4, // 47: tfplugin6.ApplyResourceChange.Request.provider_meta:type_name -> tfplugin6.DynamicValue - 4, // 48: tfplugin6.ApplyResourceChange.Response.new_state:type_name -> tfplugin6.DynamicValue - 5, // 49: tfplugin6.ApplyResourceChange.Response.diagnostics:type_name -> tfplugin6.Diagnostic - 4, // 50: tfplugin6.ImportResourceState.ImportedResource.state:type_name -> tfplugin6.DynamicValue - 51, // 51: tfplugin6.ImportResourceState.Response.imported_resources:type_name -> tfplugin6.ImportResourceState.ImportedResource - 5, // 52: tfplugin6.ImportResourceState.Response.diagnostics:type_name -> tfplugin6.Diagnostic - 4, // 53: tfplugin6.ReadDataSource.Request.config:type_name -> tfplugin6.DynamicValue - 4, // 54: tfplugin6.ReadDataSource.Request.provider_meta:type_name -> tfplugin6.DynamicValue - 4, // 55: tfplugin6.ReadDataSource.Response.state:type_name -> tfplugin6.DynamicValue - 5, // 56: tfplugin6.ReadDataSource.Response.diagnostics:type_name -> tfplugin6.Diagnostic - 29, // 57: tfplugin6.Provider.GetProviderSchema:input_type -> tfplugin6.GetProviderSchema.Request - 34, // 58: tfplugin6.Provider.ValidateProviderConfig:input_type -> tfplugin6.ValidateProviderConfig.Request - 38, // 59: tfplugin6.Provider.ValidateResourceConfig:input_type -> tfplugin6.ValidateResourceConfig.Request - 40, // 60: tfplugin6.Provider.ValidateDataResourceConfig:input_type -> tfplugin6.ValidateDataResourceConfig.Request - 36, // 61: tfplugin6.Provider.UpgradeResourceState:input_type -> tfplugin6.UpgradeResourceState.Request - 42, // 62: tfplugin6.Provider.ConfigureProvider:input_type -> tfplugin6.ConfigureProvider.Request - 44, // 63: tfplugin6.Provider.ReadResource:input_type -> tfplugin6.ReadResource.Request - 46, // 64: tfplugin6.Provider.PlanResourceChange:input_type -> tfplugin6.PlanResourceChange.Request - 48, // 65: tfplugin6.Provider.ApplyResourceChange:input_type -> tfplugin6.ApplyResourceChange.Request - 50, // 66: tfplugin6.Provider.ImportResourceState:input_type -> tfplugin6.ImportResourceState.Request - 53, // 67: tfplugin6.Provider.ReadDataSource:input_type -> tfplugin6.ReadDataSource.Request - 22, // 68: tfplugin6.Provider.StopProvider:input_type -> tfplugin6.StopProvider.Request - 30, // 69: tfplugin6.Provider.GetProviderSchema:output_type -> tfplugin6.GetProviderSchema.Response - 35, // 70: tfplugin6.Provider.ValidateProviderConfig:output_type -> tfplugin6.ValidateProviderConfig.Response - 39, // 71: tfplugin6.Provider.ValidateResourceConfig:output_type -> tfplugin6.ValidateResourceConfig.Response - 41, // 72: tfplugin6.Provider.ValidateDataResourceConfig:output_type -> tfplugin6.ValidateDataResourceConfig.Response - 37, // 73: tfplugin6.Provider.UpgradeResourceState:output_type -> tfplugin6.UpgradeResourceState.Response - 43, // 74: tfplugin6.Provider.ConfigureProvider:output_type -> tfplugin6.ConfigureProvider.Response - 45, // 75: tfplugin6.Provider.ReadResource:output_type -> tfplugin6.ReadResource.Response - 47, // 76: tfplugin6.Provider.PlanResourceChange:output_type -> tfplugin6.PlanResourceChange.Response - 49, // 77: tfplugin6.Provider.ApplyResourceChange:output_type -> tfplugin6.ApplyResourceChange.Response - 52, // 78: tfplugin6.Provider.ImportResourceState:output_type -> tfplugin6.ImportResourceState.Response - 54, // 79: tfplugin6.Provider.ReadDataSource:output_type -> tfplugin6.ReadDataSource.Response - 23, // 80: tfplugin6.Provider.StopProvider:output_type -> tfplugin6.StopProvider.Response - 69, // [69:81] is the sub-list for method output_type - 57, // [57:69] is the sub-list for method input_type - 57, // [57:57] is the sub-list for extension type_name - 57, // [57:57] is the sub-list for extension extendee - 0, // [0:57] is the sub-list for field type_name + 7, // 1: tfplugin6.Diagnostic.attribute:type_name -> tfplugin6.AttributePath + 28, // 2: tfplugin6.AttributePath.steps:type_name -> tfplugin6.AttributePath.Step + 31, // 3: tfplugin6.RawState.flatmap:type_name -> tfplugin6.RawState.FlatmapEntry + 32, // 4: tfplugin6.Schema.block:type_name -> tfplugin6.Schema.Block + 36, // 5: tfplugin6.Function.parameters:type_name -> tfplugin6.Function.Parameter + 36, // 6: tfplugin6.Function.variadic_parameter:type_name -> tfplugin6.Function.Parameter + 37, // 7: tfplugin6.Function.return:type_name -> tfplugin6.Function.Return + 0, // 8: tfplugin6.Function.description_kind:type_name -> tfplugin6.StringKind + 33, // 9: tfplugin6.Schema.Block.attributes:type_name -> tfplugin6.Schema.Attribute + 34, // 10: tfplugin6.Schema.Block.block_types:type_name -> tfplugin6.Schema.NestedBlock + 0, // 11: tfplugin6.Schema.Block.description_kind:type_name -> tfplugin6.StringKind + 35, // 12: tfplugin6.Schema.Attribute.nested_type:type_name -> tfplugin6.Schema.Object + 0, // 13: tfplugin6.Schema.Attribute.description_kind:type_name -> tfplugin6.StringKind + 32, // 14: tfplugin6.Schema.NestedBlock.block:type_name -> tfplugin6.Schema.Block + 2, // 15: tfplugin6.Schema.NestedBlock.nesting:type_name -> tfplugin6.Schema.NestedBlock.NestingMode + 33, // 16: tfplugin6.Schema.Object.attributes:type_name -> tfplugin6.Schema.Attribute + 3, // 17: tfplugin6.Schema.Object.nesting:type_name -> tfplugin6.Schema.Object.NestingMode + 0, // 18: tfplugin6.Function.Parameter.description_kind:type_name -> tfplugin6.StringKind + 12, // 19: tfplugin6.GetMetadata.Response.server_capabilities:type_name -> tfplugin6.ServerCapabilities + 5, // 20: tfplugin6.GetMetadata.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 41, // 21: tfplugin6.GetMetadata.Response.data_sources:type_name -> tfplugin6.GetMetadata.DataSourceMetadata + 42, // 22: tfplugin6.GetMetadata.Response.resources:type_name -> tfplugin6.GetMetadata.ResourceMetadata + 40, // 23: tfplugin6.GetMetadata.Response.functions:type_name -> tfplugin6.GetMetadata.FunctionMetadata + 10, // 24: tfplugin6.GetProviderSchema.Response.provider:type_name -> tfplugin6.Schema + 45, // 25: tfplugin6.GetProviderSchema.Response.resource_schemas:type_name -> tfplugin6.GetProviderSchema.Response.ResourceSchemasEntry + 46, // 26: tfplugin6.GetProviderSchema.Response.data_source_schemas:type_name -> tfplugin6.GetProviderSchema.Response.DataSourceSchemasEntry + 5, // 27: tfplugin6.GetProviderSchema.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 10, // 28: tfplugin6.GetProviderSchema.Response.provider_meta:type_name -> tfplugin6.Schema + 12, // 29: tfplugin6.GetProviderSchema.Response.server_capabilities:type_name -> tfplugin6.ServerCapabilities + 47, // 30: tfplugin6.GetProviderSchema.Response.functions:type_name -> tfplugin6.GetProviderSchema.Response.FunctionsEntry + 10, // 31: tfplugin6.GetProviderSchema.Response.ResourceSchemasEntry.value:type_name -> tfplugin6.Schema + 10, // 32: tfplugin6.GetProviderSchema.Response.DataSourceSchemasEntry.value:type_name -> tfplugin6.Schema + 11, // 33: tfplugin6.GetProviderSchema.Response.FunctionsEntry.value:type_name -> tfplugin6.Function + 4, // 34: tfplugin6.ValidateProviderConfig.Request.config:type_name -> tfplugin6.DynamicValue + 5, // 35: tfplugin6.ValidateProviderConfig.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 9, // 36: tfplugin6.UpgradeResourceState.Request.raw_state:type_name -> tfplugin6.RawState + 4, // 37: tfplugin6.UpgradeResourceState.Response.upgraded_state:type_name -> tfplugin6.DynamicValue + 5, // 38: tfplugin6.UpgradeResourceState.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 39: tfplugin6.ValidateResourceConfig.Request.config:type_name -> tfplugin6.DynamicValue + 5, // 40: tfplugin6.ValidateResourceConfig.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 41: tfplugin6.ValidateDataResourceConfig.Request.config:type_name -> tfplugin6.DynamicValue + 5, // 42: tfplugin6.ValidateDataResourceConfig.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 43: tfplugin6.ConfigureProvider.Request.config:type_name -> tfplugin6.DynamicValue + 5, // 44: tfplugin6.ConfigureProvider.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 45: tfplugin6.ReadResource.Request.current_state:type_name -> tfplugin6.DynamicValue + 4, // 46: tfplugin6.ReadResource.Request.provider_meta:type_name -> tfplugin6.DynamicValue + 4, // 47: tfplugin6.ReadResource.Response.new_state:type_name -> tfplugin6.DynamicValue + 5, // 48: tfplugin6.ReadResource.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 49: tfplugin6.PlanResourceChange.Request.prior_state:type_name -> tfplugin6.DynamicValue + 4, // 50: tfplugin6.PlanResourceChange.Request.proposed_new_state:type_name -> tfplugin6.DynamicValue + 4, // 51: tfplugin6.PlanResourceChange.Request.config:type_name -> tfplugin6.DynamicValue + 4, // 52: tfplugin6.PlanResourceChange.Request.provider_meta:type_name -> tfplugin6.DynamicValue + 4, // 53: tfplugin6.PlanResourceChange.Response.planned_state:type_name -> tfplugin6.DynamicValue + 7, // 54: tfplugin6.PlanResourceChange.Response.requires_replace:type_name -> tfplugin6.AttributePath + 5, // 55: tfplugin6.PlanResourceChange.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 56: tfplugin6.ApplyResourceChange.Request.prior_state:type_name -> tfplugin6.DynamicValue + 4, // 57: tfplugin6.ApplyResourceChange.Request.planned_state:type_name -> tfplugin6.DynamicValue + 4, // 58: tfplugin6.ApplyResourceChange.Request.config:type_name -> tfplugin6.DynamicValue + 4, // 59: tfplugin6.ApplyResourceChange.Request.provider_meta:type_name -> tfplugin6.DynamicValue + 4, // 60: tfplugin6.ApplyResourceChange.Response.new_state:type_name -> tfplugin6.DynamicValue + 5, // 61: tfplugin6.ApplyResourceChange.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 62: tfplugin6.ImportResourceState.ImportedResource.state:type_name -> tfplugin6.DynamicValue + 65, // 63: tfplugin6.ImportResourceState.Response.imported_resources:type_name -> tfplugin6.ImportResourceState.ImportedResource + 5, // 64: tfplugin6.ImportResourceState.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 9, // 65: tfplugin6.MoveResourceState.Request.source_state:type_name -> tfplugin6.RawState + 4, // 66: tfplugin6.MoveResourceState.Response.target_state:type_name -> tfplugin6.DynamicValue + 5, // 67: tfplugin6.MoveResourceState.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 68: tfplugin6.ReadDataSource.Request.config:type_name -> tfplugin6.DynamicValue + 4, // 69: tfplugin6.ReadDataSource.Request.provider_meta:type_name -> tfplugin6.DynamicValue + 4, // 70: tfplugin6.ReadDataSource.Response.state:type_name -> tfplugin6.DynamicValue + 5, // 71: tfplugin6.ReadDataSource.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 73, // 72: tfplugin6.GetFunctions.Response.functions:type_name -> tfplugin6.GetFunctions.Response.FunctionsEntry + 5, // 73: tfplugin6.GetFunctions.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 11, // 74: tfplugin6.GetFunctions.Response.FunctionsEntry.value:type_name -> tfplugin6.Function + 4, // 75: tfplugin6.CallFunction.Request.arguments:type_name -> tfplugin6.DynamicValue + 4, // 76: tfplugin6.CallFunction.Response.result:type_name -> tfplugin6.DynamicValue + 6, // 77: tfplugin6.CallFunction.Response.error:type_name -> tfplugin6.FunctionError + 38, // 78: tfplugin6.Provider.GetMetadata:input_type -> tfplugin6.GetMetadata.Request + 43, // 79: tfplugin6.Provider.GetProviderSchema:input_type -> tfplugin6.GetProviderSchema.Request + 48, // 80: tfplugin6.Provider.ValidateProviderConfig:input_type -> tfplugin6.ValidateProviderConfig.Request + 52, // 81: tfplugin6.Provider.ValidateResourceConfig:input_type -> tfplugin6.ValidateResourceConfig.Request + 54, // 82: tfplugin6.Provider.ValidateDataResourceConfig:input_type -> tfplugin6.ValidateDataResourceConfig.Request + 50, // 83: tfplugin6.Provider.UpgradeResourceState:input_type -> tfplugin6.UpgradeResourceState.Request + 56, // 84: tfplugin6.Provider.ConfigureProvider:input_type -> tfplugin6.ConfigureProvider.Request + 58, // 85: tfplugin6.Provider.ReadResource:input_type -> tfplugin6.ReadResource.Request + 60, // 86: tfplugin6.Provider.PlanResourceChange:input_type -> tfplugin6.PlanResourceChange.Request + 62, // 87: tfplugin6.Provider.ApplyResourceChange:input_type -> tfplugin6.ApplyResourceChange.Request + 64, // 88: tfplugin6.Provider.ImportResourceState:input_type -> tfplugin6.ImportResourceState.Request + 67, // 89: tfplugin6.Provider.MoveResourceState:input_type -> tfplugin6.MoveResourceState.Request + 69, // 90: tfplugin6.Provider.ReadDataSource:input_type -> tfplugin6.ReadDataSource.Request + 71, // 91: tfplugin6.Provider.GetFunctions:input_type -> tfplugin6.GetFunctions.Request + 74, // 92: tfplugin6.Provider.CallFunction:input_type -> tfplugin6.CallFunction.Request + 29, // 93: tfplugin6.Provider.StopProvider:input_type -> tfplugin6.StopProvider.Request + 39, // 94: tfplugin6.Provider.GetMetadata:output_type -> tfplugin6.GetMetadata.Response + 44, // 95: tfplugin6.Provider.GetProviderSchema:output_type -> tfplugin6.GetProviderSchema.Response + 49, // 96: tfplugin6.Provider.ValidateProviderConfig:output_type -> tfplugin6.ValidateProviderConfig.Response + 53, // 97: tfplugin6.Provider.ValidateResourceConfig:output_type -> tfplugin6.ValidateResourceConfig.Response + 55, // 98: tfplugin6.Provider.ValidateDataResourceConfig:output_type -> tfplugin6.ValidateDataResourceConfig.Response + 51, // 99: tfplugin6.Provider.UpgradeResourceState:output_type -> tfplugin6.UpgradeResourceState.Response + 57, // 100: tfplugin6.Provider.ConfigureProvider:output_type -> tfplugin6.ConfigureProvider.Response + 59, // 101: tfplugin6.Provider.ReadResource:output_type -> tfplugin6.ReadResource.Response + 61, // 102: tfplugin6.Provider.PlanResourceChange:output_type -> tfplugin6.PlanResourceChange.Response + 63, // 103: tfplugin6.Provider.ApplyResourceChange:output_type -> tfplugin6.ApplyResourceChange.Response + 66, // 104: tfplugin6.Provider.ImportResourceState:output_type -> tfplugin6.ImportResourceState.Response + 68, // 105: tfplugin6.Provider.MoveResourceState:output_type -> tfplugin6.MoveResourceState.Response + 70, // 106: tfplugin6.Provider.ReadDataSource:output_type -> tfplugin6.ReadDataSource.Response + 72, // 107: tfplugin6.Provider.GetFunctions:output_type -> tfplugin6.GetFunctions.Response + 75, // 108: tfplugin6.Provider.CallFunction:output_type -> tfplugin6.CallFunction.Response + 30, // 109: tfplugin6.Provider.StopProvider:output_type -> tfplugin6.StopProvider.Response + 94, // [94:110] is the sub-list for method output_type + 78, // [78:94] is the sub-list for method input_type + 78, // [78:78] is the sub-list for extension type_name + 78, // [78:78] is the sub-list for extension extendee + 0, // [0:78] is the sub-list for field type_name } func init() { file_tfplugin6_proto_init() } @@ -3684,8 +5036,44 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Diagnostic); i { + file_tfplugin6_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Diagnostic); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FunctionError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AttributePath); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StopProvider); i { case 0: return &v.state case 1: @@ -3696,8 +5084,8 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AttributePath); i { + file_tfplugin6_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RawState); i { case 0: return &v.state case 1: @@ -3708,8 +5096,8 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StopProvider); i { + file_tfplugin6_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Schema); i { case 0: return &v.state case 1: @@ -3720,8 +5108,8 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RawState); i { + file_tfplugin6_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Function); i { case 0: return &v.state case 1: @@ -3732,8 +5120,8 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Schema); i { + file_tfplugin6_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerCapabilities); i { case 0: return &v.state case 1: @@ -3744,7 +5132,19 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetProviderSchema); i { case 0: return &v.state @@ -3756,7 +5156,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateProviderConfig); i { case 0: return &v.state @@ -3768,7 +5168,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpgradeResourceState); i { case 0: return &v.state @@ -3780,7 +5180,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateResourceConfig); i { case 0: return &v.state @@ -3792,7 +5192,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateDataResourceConfig); i { case 0: return &v.state @@ -3804,7 +5204,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ConfigureProvider); i { case 0: return &v.state @@ -3816,7 +5216,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadResource); i { case 0: return &v.state @@ -3828,7 +5228,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlanResourceChange); i { case 0: return &v.state @@ -3840,7 +5240,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyResourceChange); i { case 0: return &v.state @@ -3852,7 +5252,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ImportResourceState); i { case 0: return &v.state @@ -3864,7 +5264,19 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MoveResourceState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadDataSource); i { case 0: return &v.state @@ -3876,7 +5288,31 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFunctions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CallFunction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AttributePath_Step); i { case 0: return &v.state @@ -3888,7 +5324,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StopProvider_Request); i { case 0: return &v.state @@ -3900,7 +5336,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StopProvider_Response); i { case 0: return &v.state @@ -3912,7 +5348,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Schema_Block); i { case 0: return &v.state @@ -3924,7 +5360,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Schema_Attribute); i { case 0: return &v.state @@ -3936,7 +5372,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Schema_NestedBlock); i { case 0: return &v.state @@ -3948,7 +5384,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Schema_Object); i { case 0: return &v.state @@ -3960,8 +5396,8 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProviderSchema_Request); i { + file_tfplugin6_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Function_Parameter); i { case 0: return &v.state case 1: @@ -3972,8 +5408,8 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProviderSchema_Response); i { + file_tfplugin6_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Function_Return); i { case 0: return &v.state case 1: @@ -3984,8 +5420,8 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProviderSchema_ServerCapabilities); i { + file_tfplugin6_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata_Request); i { case 0: return &v.state case 1: @@ -3996,7 +5432,79 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata_FunctionMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata_DataSourceMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadata_ResourceMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProviderSchema_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProviderSchema_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateProviderConfig_Request); i { case 0: return &v.state @@ -4008,7 +5516,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateProviderConfig_Response); i { case 0: return &v.state @@ -4020,7 +5528,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpgradeResourceState_Request); i { case 0: return &v.state @@ -4032,7 +5540,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpgradeResourceState_Response); i { case 0: return &v.state @@ -4044,7 +5552,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateResourceConfig_Request); i { case 0: return &v.state @@ -4056,7 +5564,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateResourceConfig_Response); i { case 0: return &v.state @@ -4068,7 +5576,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateDataResourceConfig_Request); i { case 0: return &v.state @@ -4080,7 +5588,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateDataResourceConfig_Response); i { case 0: return &v.state @@ -4092,7 +5600,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ConfigureProvider_Request); i { case 0: return &v.state @@ -4104,7 +5612,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ConfigureProvider_Response); i { case 0: return &v.state @@ -4116,7 +5624,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadResource_Request); i { case 0: return &v.state @@ -4128,7 +5636,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadResource_Response); i { case 0: return &v.state @@ -4140,7 +5648,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlanResourceChange_Request); i { case 0: return &v.state @@ -4152,7 +5660,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlanResourceChange_Response); i { case 0: return &v.state @@ -4164,7 +5672,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyResourceChange_Request); i { case 0: return &v.state @@ -4176,7 +5684,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyResourceChange_Response); i { case 0: return &v.state @@ -4188,7 +5696,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ImportResourceState_Request); i { case 0: return &v.state @@ -4200,7 +5708,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ImportResourceState_ImportedResource); i { case 0: return &v.state @@ -4212,7 +5720,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ImportResourceState_Response); i { case 0: return &v.state @@ -4224,7 +5732,31 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MoveResourceState_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MoveResourceState_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadDataSource_Request); i { case 0: return &v.state @@ -4236,7 +5768,7 @@ func file_tfplugin6_proto_init() { return nil } } - file_tfplugin6_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { + file_tfplugin6_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadDataSource_Response); i { case 0: return &v.state @@ -4248,8 +5780,57 @@ func file_tfplugin6_proto_init() { return nil } } + file_tfplugin6_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFunctions_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFunctions_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CallFunction_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CallFunction_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } - file_tfplugin6_proto_msgTypes[17].OneofWrappers = []interface{}{ + file_tfplugin6_proto_msgTypes[2].OneofWrappers = []interface{}{} + file_tfplugin6_proto_msgTypes[24].OneofWrappers = []interface{}{ (*AttributePath_Step_AttributeName)(nil), (*AttributePath_Step_ElementKeyString)(nil), (*AttributePath_Step_ElementKeyInt)(nil), @@ -4260,7 +5841,7 @@ func file_tfplugin6_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tfplugin6_proto_rawDesc, NumEnums: 4, - NumMessages: 51, + NumMessages: 72, NumExtensions: 0, NumServices: 1, }, diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6.proto b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6.proto index 01a72fd9..097abf0c 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6.proto +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6.proto @@ -1,9 +1,9 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -// Terraform Plugin RPC protocol version 6.3 +// Terraform Plugin RPC protocol version 6.5 // -// This file defines version 6.3 of the RPC protocol. To implement a plugin +// This file defines version 6.5 of the RPC protocol. To implement a plugin // against this protocol, copy this definition into your own codebase and // use protoc to generate stubs for your target language. // @@ -43,6 +43,13 @@ message Diagnostic { AttributePath attribute = 4; } +message FunctionError { + string text = 1; + // The optional function_argument records the index position of the + // argument which caused the error. + optional int64 function_argument = 2; +} + message AttributePath { message Step { oneof selector { @@ -147,8 +154,94 @@ message Schema { Block block = 2; } +message Function { + // parameters is the ordered list of positional function parameters. + repeated Parameter parameters = 1; + + // variadic_parameter is an optional final parameter which accepts + // zero or more argument values, in which Terraform will send an + // ordered list of the parameter type. + Parameter variadic_parameter = 2; + + // return is the function result. + Return return = 3; + + // summary is the human-readable shortened documentation for the function. + string summary = 4; + + // description is human-readable documentation for the function. + string description = 5; + + // description_kind is the formatting of the description. + StringKind description_kind = 6; + + // deprecation_message is human-readable documentation if the + // function is deprecated. + string deprecation_message = 7; + + message Parameter { + // name is the human-readable display name for the parameter. + string name = 1; + + // type is the type constraint for the parameter. + bytes type = 2; + + // allow_null_value when enabled denotes that a null argument value can + // be passed to the provider. When disabled, Terraform returns an error + // if the argument value is null. + bool allow_null_value = 3; + + // allow_unknown_values when enabled denotes that only wholly known + // argument values will be passed to the provider. When disabled, + // Terraform skips the function call entirely and assumes an unknown + // value result from the function. + bool allow_unknown_values = 4; + + // description is human-readable documentation for the parameter. + string description = 5; + + // description_kind is the formatting of the description. + StringKind description_kind = 6; + } + + message Return { + // type is the type constraint for the function result. + bytes type = 1; + } +} + +// ServerCapabilities allows providers to communicate extra information +// regarding supported protocol features. This is used to indicate +// availability of certain forward-compatible changes which may be optional +// in a major protocol version, but cannot be tested for directly. +message ServerCapabilities { + // The plan_destroy capability signals that a provider expects a call + // to PlanResourceChange when a resource is going to be destroyed. + bool plan_destroy = 1; + + // The get_provider_schema_optional capability indicates that this + // provider does not require calling GetProviderSchema to operate + // normally, and the caller can used a cached copy of the provider's + // schema. + bool get_provider_schema_optional = 2; + + // The move_resource_state capability signals that a provider supports the + // MoveResourceState RPC. + bool move_resource_state = 3; +} + service Provider { //////// Information about what a provider supports/expects + + // GetMetadata returns upfront information about server capabilities and + // supported resource types without requiring the server to instantiate all + // schema information, which may be memory intensive. This RPC is optional, + // where clients may receive an unimplemented RPC error. Clients should + // ignore the error and call the GetProviderSchema RPC as a fallback. + rpc GetMetadata(GetMetadata.Request) returns (GetMetadata.Response); + + // GetSchema returns schema information for the provider, data resources, + // and managed resources. rpc GetProviderSchema(GetProviderSchema.Request) returns (GetProviderSchema.Response); rpc ValidateProviderConfig(ValidateProviderConfig.Request) returns (ValidateProviderConfig.Response); rpc ValidateResourceConfig(ValidateResourceConfig.Request) returns (ValidateResourceConfig.Response); @@ -163,13 +256,50 @@ service Provider { rpc PlanResourceChange(PlanResourceChange.Request) returns (PlanResourceChange.Response); rpc ApplyResourceChange(ApplyResourceChange.Request) returns (ApplyResourceChange.Response); rpc ImportResourceState(ImportResourceState.Request) returns (ImportResourceState.Response); - + rpc MoveResourceState(MoveResourceState.Request) returns (MoveResourceState.Response); rpc ReadDataSource(ReadDataSource.Request) returns (ReadDataSource.Response); + // Functions + + // GetFunctions returns the definitions of all functions. + rpc GetFunctions(GetFunctions.Request) returns (GetFunctions.Response); + + // CallFunction runs the provider-defined function logic and returns + // the result with any diagnostics. + rpc CallFunction(CallFunction.Request) returns (CallFunction.Response); + //////// Graceful Shutdown rpc StopProvider(StopProvider.Request) returns (StopProvider.Response); } +message GetMetadata { + message Request { + } + + message Response { + ServerCapabilities server_capabilities = 1; + repeated Diagnostic diagnostics = 2; + repeated DataSourceMetadata data_sources = 3; + repeated ResourceMetadata resources = 4; + + // functions returns metadata for any functions. + repeated FunctionMetadata functions = 5; + } + + message FunctionMetadata { + // name is the function name. + string name = 1; + } + + message DataSourceMetadata { + string type_name = 1; + } + + message ResourceMetadata { + string type_name = 1; + } +} + message GetProviderSchema { message Request { } @@ -180,17 +310,9 @@ message GetProviderSchema { repeated Diagnostic diagnostics = 4; Schema provider_meta = 5; ServerCapabilities server_capabilities = 6; - } - - // ServerCapabilities allows providers to communicate extra information - // regarding supported protocol features. This is used to indicate - // availability of certain forward-compatible changes which may be optional - // in a major protocol version, but cannot be tested for directly. - message ServerCapabilities { - // The plan_destroy capability signals that a provider expects a call - // to PlanResourceChange when a resource is going to be destroyed. - bool plan_destroy = 1; + // functions is a mapping of function names to definitions. + map functions = 7; } } @@ -369,6 +491,42 @@ message ImportResourceState { } } +message MoveResourceState { + message Request { + // The address of the provider the resource is being moved from. + string source_provider_address = 1; + + // The resource type that the resource is being moved from. + string source_type_name = 2; + + // The schema version of the resource type that the resource is being + // moved from. + int64 source_schema_version = 3; + + // The raw state of the resource being moved. Only the json field is + // populated, as there should be no legacy providers using the flatmap + // format that support newly introduced RPCs. + RawState source_state = 4; + + // The resource type that the resource is being moved to. + string target_type_name = 5; + + // The private state of the resource being moved. + bytes source_private = 6; + } + + message Response { + // The state of the resource after it has been moved. + DynamicValue target_state = 1; + + // Any diagnostics that occurred during the move. + repeated Diagnostic diagnostics = 2; + + // The private state of the resource after it has been moved. + bytes target_private = 3; + } +} + message ReadDataSource { message Request { string type_name = 1; @@ -380,3 +538,33 @@ message ReadDataSource { repeated Diagnostic diagnostics = 2; } } + +message GetFunctions { + message Request {} + + message Response { + // functions is a mapping of function names to definitions. + map functions = 1; + + // diagnostics is any warnings or errors. + repeated Diagnostic diagnostics = 2; + } +} + +message CallFunction { + message Request { + // name is the name of the function being called. + string name = 1; + + // arguments is the data of each function argument value. + repeated DynamicValue arguments = 2; + } + + message Response { + // result is result value after running the function logic. + DynamicValue result = 1; + + // error is any errors from the function logic. + FunctionError error = 2; + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6_grpc.pb.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6_grpc.pb.go index 01e8f162..3ae64b46 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6_grpc.pb.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6/tfplugin6_grpc.pb.go @@ -1,9 +1,9 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -// Terraform Plugin RPC protocol version 6.3 +// Terraform Plugin RPC protocol version 6.5 // -// This file defines version 6.3 of the RPC protocol. To implement a plugin +// This file defines version 6.5 of the RPC protocol. To implement a plugin // against this protocol, copy this definition into your own codebase and // use protoc to generate stubs for your target language. // @@ -23,7 +23,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v4.23.2 +// - protoc v4.25.1 // source: tfplugin6.proto package tfplugin6 @@ -41,6 +41,7 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( + Provider_GetMetadata_FullMethodName = "/tfplugin6.Provider/GetMetadata" Provider_GetProviderSchema_FullMethodName = "/tfplugin6.Provider/GetProviderSchema" Provider_ValidateProviderConfig_FullMethodName = "/tfplugin6.Provider/ValidateProviderConfig" Provider_ValidateResourceConfig_FullMethodName = "/tfplugin6.Provider/ValidateResourceConfig" @@ -51,7 +52,10 @@ const ( Provider_PlanResourceChange_FullMethodName = "/tfplugin6.Provider/PlanResourceChange" Provider_ApplyResourceChange_FullMethodName = "/tfplugin6.Provider/ApplyResourceChange" Provider_ImportResourceState_FullMethodName = "/tfplugin6.Provider/ImportResourceState" + Provider_MoveResourceState_FullMethodName = "/tfplugin6.Provider/MoveResourceState" Provider_ReadDataSource_FullMethodName = "/tfplugin6.Provider/ReadDataSource" + Provider_GetFunctions_FullMethodName = "/tfplugin6.Provider/GetFunctions" + Provider_CallFunction_FullMethodName = "/tfplugin6.Provider/CallFunction" Provider_StopProvider_FullMethodName = "/tfplugin6.Provider/StopProvider" ) @@ -59,7 +63,14 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ProviderClient interface { - // ////// Information about what a provider supports/expects + // GetMetadata returns upfront information about server capabilities and + // supported resource types without requiring the server to instantiate all + // schema information, which may be memory intensive. This RPC is optional, + // where clients may receive an unimplemented RPC error. Clients should + // ignore the error and call the GetProviderSchema RPC as a fallback. + GetMetadata(ctx context.Context, in *GetMetadata_Request, opts ...grpc.CallOption) (*GetMetadata_Response, error) + // GetSchema returns schema information for the provider, data resources, + // and managed resources. GetProviderSchema(ctx context.Context, in *GetProviderSchema_Request, opts ...grpc.CallOption) (*GetProviderSchema_Response, error) ValidateProviderConfig(ctx context.Context, in *ValidateProviderConfig_Request, opts ...grpc.CallOption) (*ValidateProviderConfig_Response, error) ValidateResourceConfig(ctx context.Context, in *ValidateResourceConfig_Request, opts ...grpc.CallOption) (*ValidateResourceConfig_Response, error) @@ -72,7 +83,13 @@ type ProviderClient interface { PlanResourceChange(ctx context.Context, in *PlanResourceChange_Request, opts ...grpc.CallOption) (*PlanResourceChange_Response, error) ApplyResourceChange(ctx context.Context, in *ApplyResourceChange_Request, opts ...grpc.CallOption) (*ApplyResourceChange_Response, error) ImportResourceState(ctx context.Context, in *ImportResourceState_Request, opts ...grpc.CallOption) (*ImportResourceState_Response, error) + MoveResourceState(ctx context.Context, in *MoveResourceState_Request, opts ...grpc.CallOption) (*MoveResourceState_Response, error) ReadDataSource(ctx context.Context, in *ReadDataSource_Request, opts ...grpc.CallOption) (*ReadDataSource_Response, error) + // GetFunctions returns the definitions of all functions. + GetFunctions(ctx context.Context, in *GetFunctions_Request, opts ...grpc.CallOption) (*GetFunctions_Response, error) + // CallFunction runs the provider-defined function logic and returns + // the result with any diagnostics. + CallFunction(ctx context.Context, in *CallFunction_Request, opts ...grpc.CallOption) (*CallFunction_Response, error) // ////// Graceful Shutdown StopProvider(ctx context.Context, in *StopProvider_Request, opts ...grpc.CallOption) (*StopProvider_Response, error) } @@ -85,6 +102,15 @@ func NewProviderClient(cc grpc.ClientConnInterface) ProviderClient { return &providerClient{cc} } +func (c *providerClient) GetMetadata(ctx context.Context, in *GetMetadata_Request, opts ...grpc.CallOption) (*GetMetadata_Response, error) { + out := new(GetMetadata_Response) + err := c.cc.Invoke(ctx, Provider_GetMetadata_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *providerClient) GetProviderSchema(ctx context.Context, in *GetProviderSchema_Request, opts ...grpc.CallOption) (*GetProviderSchema_Response, error) { out := new(GetProviderSchema_Response) err := c.cc.Invoke(ctx, Provider_GetProviderSchema_FullMethodName, in, out, opts...) @@ -175,6 +201,15 @@ func (c *providerClient) ImportResourceState(ctx context.Context, in *ImportReso return out, nil } +func (c *providerClient) MoveResourceState(ctx context.Context, in *MoveResourceState_Request, opts ...grpc.CallOption) (*MoveResourceState_Response, error) { + out := new(MoveResourceState_Response) + err := c.cc.Invoke(ctx, Provider_MoveResourceState_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *providerClient) ReadDataSource(ctx context.Context, in *ReadDataSource_Request, opts ...grpc.CallOption) (*ReadDataSource_Response, error) { out := new(ReadDataSource_Response) err := c.cc.Invoke(ctx, Provider_ReadDataSource_FullMethodName, in, out, opts...) @@ -184,6 +219,24 @@ func (c *providerClient) ReadDataSource(ctx context.Context, in *ReadDataSource_ return out, nil } +func (c *providerClient) GetFunctions(ctx context.Context, in *GetFunctions_Request, opts ...grpc.CallOption) (*GetFunctions_Response, error) { + out := new(GetFunctions_Response) + err := c.cc.Invoke(ctx, Provider_GetFunctions_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) CallFunction(ctx context.Context, in *CallFunction_Request, opts ...grpc.CallOption) (*CallFunction_Response, error) { + out := new(CallFunction_Response) + err := c.cc.Invoke(ctx, Provider_CallFunction_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *providerClient) StopProvider(ctx context.Context, in *StopProvider_Request, opts ...grpc.CallOption) (*StopProvider_Response, error) { out := new(StopProvider_Response) err := c.cc.Invoke(ctx, Provider_StopProvider_FullMethodName, in, out, opts...) @@ -197,7 +250,14 @@ func (c *providerClient) StopProvider(ctx context.Context, in *StopProvider_Requ // All implementations must embed UnimplementedProviderServer // for forward compatibility type ProviderServer interface { - // ////// Information about what a provider supports/expects + // GetMetadata returns upfront information about server capabilities and + // supported resource types without requiring the server to instantiate all + // schema information, which may be memory intensive. This RPC is optional, + // where clients may receive an unimplemented RPC error. Clients should + // ignore the error and call the GetProviderSchema RPC as a fallback. + GetMetadata(context.Context, *GetMetadata_Request) (*GetMetadata_Response, error) + // GetSchema returns schema information for the provider, data resources, + // and managed resources. GetProviderSchema(context.Context, *GetProviderSchema_Request) (*GetProviderSchema_Response, error) ValidateProviderConfig(context.Context, *ValidateProviderConfig_Request) (*ValidateProviderConfig_Response, error) ValidateResourceConfig(context.Context, *ValidateResourceConfig_Request) (*ValidateResourceConfig_Response, error) @@ -210,7 +270,13 @@ type ProviderServer interface { PlanResourceChange(context.Context, *PlanResourceChange_Request) (*PlanResourceChange_Response, error) ApplyResourceChange(context.Context, *ApplyResourceChange_Request) (*ApplyResourceChange_Response, error) ImportResourceState(context.Context, *ImportResourceState_Request) (*ImportResourceState_Response, error) + MoveResourceState(context.Context, *MoveResourceState_Request) (*MoveResourceState_Response, error) ReadDataSource(context.Context, *ReadDataSource_Request) (*ReadDataSource_Response, error) + // GetFunctions returns the definitions of all functions. + GetFunctions(context.Context, *GetFunctions_Request) (*GetFunctions_Response, error) + // CallFunction runs the provider-defined function logic and returns + // the result with any diagnostics. + CallFunction(context.Context, *CallFunction_Request) (*CallFunction_Response, error) // ////// Graceful Shutdown StopProvider(context.Context, *StopProvider_Request) (*StopProvider_Response, error) mustEmbedUnimplementedProviderServer() @@ -220,6 +286,9 @@ type ProviderServer interface { type UnimplementedProviderServer struct { } +func (UnimplementedProviderServer) GetMetadata(context.Context, *GetMetadata_Request) (*GetMetadata_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMetadata not implemented") +} func (UnimplementedProviderServer) GetProviderSchema(context.Context, *GetProviderSchema_Request) (*GetProviderSchema_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method GetProviderSchema not implemented") } @@ -250,9 +319,18 @@ func (UnimplementedProviderServer) ApplyResourceChange(context.Context, *ApplyRe func (UnimplementedProviderServer) ImportResourceState(context.Context, *ImportResourceState_Request) (*ImportResourceState_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method ImportResourceState not implemented") } +func (UnimplementedProviderServer) MoveResourceState(context.Context, *MoveResourceState_Request) (*MoveResourceState_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method MoveResourceState not implemented") +} func (UnimplementedProviderServer) ReadDataSource(context.Context, *ReadDataSource_Request) (*ReadDataSource_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method ReadDataSource not implemented") } +func (UnimplementedProviderServer) GetFunctions(context.Context, *GetFunctions_Request) (*GetFunctions_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetFunctions not implemented") +} +func (UnimplementedProviderServer) CallFunction(context.Context, *CallFunction_Request) (*CallFunction_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method CallFunction not implemented") +} func (UnimplementedProviderServer) StopProvider(context.Context, *StopProvider_Request) (*StopProvider_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method StopProvider not implemented") } @@ -269,6 +347,24 @@ func RegisterProviderServer(s grpc.ServiceRegistrar, srv ProviderServer) { s.RegisterService(&Provider_ServiceDesc, srv) } +func _Provider_GetMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetMetadata_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).GetMetadata(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Provider_GetMetadata_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).GetMetadata(ctx, req.(*GetMetadata_Request)) + } + return interceptor(ctx, in, info, handler) +} + func _Provider_GetProviderSchema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetProviderSchema_Request) if err := dec(in); err != nil { @@ -449,6 +545,24 @@ func _Provider_ImportResourceState_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _Provider_MoveResourceState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MoveResourceState_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).MoveResourceState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Provider_MoveResourceState_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).MoveResourceState(ctx, req.(*MoveResourceState_Request)) + } + return interceptor(ctx, in, info, handler) +} + func _Provider_ReadDataSource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ReadDataSource_Request) if err := dec(in); err != nil { @@ -467,6 +581,42 @@ func _Provider_ReadDataSource_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Provider_GetFunctions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetFunctions_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).GetFunctions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Provider_GetFunctions_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).GetFunctions(ctx, req.(*GetFunctions_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_CallFunction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CallFunction_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).CallFunction(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Provider_CallFunction_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).CallFunction(ctx, req.(*CallFunction_Request)) + } + return interceptor(ctx, in, info, handler) +} + func _Provider_StopProvider_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(StopProvider_Request) if err := dec(in); err != nil { @@ -492,6 +642,10 @@ var Provider_ServiceDesc = grpc.ServiceDesc{ ServiceName: "tfplugin6.Provider", HandlerType: (*ProviderServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "GetMetadata", + Handler: _Provider_GetMetadata_Handler, + }, { MethodName: "GetProviderSchema", Handler: _Provider_GetProviderSchema_Handler, @@ -532,10 +686,22 @@ var Provider_ServiceDesc = grpc.ServiceDesc{ MethodName: "ImportResourceState", Handler: _Provider_ImportResourceState_Handler, }, + { + MethodName: "MoveResourceState", + Handler: _Provider_MoveResourceState_Handler, + }, { MethodName: "ReadDataSource", Handler: _Provider_ReadDataSource_Handler, }, + { + MethodName: "GetFunctions", + Handler: _Provider_GetFunctions_Handler, + }, + { + MethodName: "CallFunction", + Handler: _Provider_CallFunction_Handler, + }, { MethodName: "StopProvider", Handler: _Provider_StopProvider_Handler, diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/attribute_path.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/attribute_path.go index 0cf4daac..18897336 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/attribute_path.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/attribute_path.go @@ -1,98 +1,92 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( - "errors" + "fmt" "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" "github.com/hashicorp/terraform-plugin-go/tftypes" ) -var ErrUnknownAttributePathStepType = errors.New("unknown type of AttributePath_Step") - -func AttributePath(in *tftypes.AttributePath) (*tfplugin6.AttributePath, error) { +func AttributePath(in *tftypes.AttributePath) *tfplugin6.AttributePath { if in == nil { - return nil, nil + return nil } - steps, err := AttributePath_Steps(in.Steps()) - if err != nil { - return nil, err + + resp := &tfplugin6.AttributePath{ + Steps: AttributePath_Steps(in.Steps()), } - return &tfplugin6.AttributePath{ - Steps: steps, - }, nil + + return resp } -func AttributePaths(in []*tftypes.AttributePath) ([]*tfplugin6.AttributePath, error) { +func AttributePaths(in []*tftypes.AttributePath) []*tfplugin6.AttributePath { resp := make([]*tfplugin6.AttributePath, 0, len(in)) + for _, a := range in { - if a == nil { - resp = append(resp, nil) - continue - } - attr, err := AttributePath(a) - if err != nil { - return resp, err - } - resp = append(resp, attr) + resp = append(resp, AttributePath(a)) } - return resp, nil + + return resp } -func AttributePath_Step(step tftypes.AttributePathStep) (*tfplugin6.AttributePath_Step, error) { - var resp tfplugin6.AttributePath_Step - if name, ok := step.(tftypes.AttributeName); ok { - resp.Selector = &tfplugin6.AttributePath_Step_AttributeName{ - AttributeName: string(name), - } - return &resp, nil +func AttributePath_Step(step tftypes.AttributePathStep) *tfplugin6.AttributePath_Step { + if step == nil { + return nil } - if key, ok := step.(tftypes.ElementKeyString); ok { - resp.Selector = &tfplugin6.AttributePath_Step_ElementKeyString{ - ElementKeyString: string(key), + + switch step := step.(type) { + case tftypes.AttributeName: + return &tfplugin6.AttributePath_Step{ + Selector: &tfplugin6.AttributePath_Step_AttributeName{ + AttributeName: string(step), + }, } - return &resp, nil - } - if key, ok := step.(tftypes.ElementKeyInt); ok { - resp.Selector = &tfplugin6.AttributePath_Step_ElementKeyInt{ - ElementKeyInt: int64(key), + case tftypes.ElementKeyInt: + return &tfplugin6.AttributePath_Step{ + Selector: &tfplugin6.AttributePath_Step_ElementKeyInt{ + ElementKeyInt: int64(step), + }, } - return &resp, nil - } - if _, ok := step.(tftypes.ElementKeyValue); ok { - // the protocol has no equivalent of an ElementKeyValue, so we - // return nil for both the step and the error here, to signal - // that we've hit a step we can't convey back to Terraform - return nil, nil + case tftypes.ElementKeyString: + return &tfplugin6.AttributePath_Step{ + Selector: &tfplugin6.AttributePath_Step_ElementKeyString{ + ElementKeyString: string(step), + }, + } + case tftypes.ElementKeyValue: + // The protocol has no equivalent of an ElementKeyValue, so this + // returns nil for the step to signal a step we cannot convey back + // to Terraform. + return nil } - return nil, ErrUnknownAttributePathStepType + + // It is not currently possible to create tftypes.AttributePathStep + // implementations outside the tftypes package and these implementations + // should rarely change, if ever, since they are critical to how + // Terraform understands attribute paths. If this panic was reached, it + // implies that a new step type was introduced and needs to be + // implemented as a new case above or that this logic needs to be + // otherwise changed to handle some new attribute path system. + panic(fmt.Sprintf("unimplemented tftypes.AttributePathStep type: %T", step)) } -func AttributePath_Steps(in []tftypes.AttributePathStep) ([]*tfplugin6.AttributePath_Step, error) { +func AttributePath_Steps(in []tftypes.AttributePathStep) []*tfplugin6.AttributePath_Step { resp := make([]*tfplugin6.AttributePath_Step, 0, len(in)) + for _, step := range in { - if step == nil { - resp = append(resp, nil) - continue - } - s, err := AttributePath_Step(step) - if err != nil { - return resp, err - } - // in the face of a set, the protocol has no way to represent - // the index, so we just bail and return the prefix we can - // return. + s := AttributePath_Step(step) + + // In the face of a ElementKeyValue or missing step, Terraform has no + // way to represent the attribute path, so only return the prefix. if s == nil { - return resp, nil + return resp } + resp = append(resp, s) } - return resp, nil -} -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/data_source.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/data_source.go index 624a3bb1..954272ab 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/data_source.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/data_source.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( @@ -5,57 +8,37 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" ) -func ValidateDataResourceConfig_Request(in *tfprotov6.ValidateDataResourceConfigRequest) (*tfplugin6.ValidateDataResourceConfig_Request, error) { - resp := &tfplugin6.ValidateDataResourceConfig_Request{ - TypeName: in.TypeName, +func GetMetadata_DataSourceMetadata(in *tfprotov6.DataSourceMetadata) *tfplugin6.GetMetadata_DataSourceMetadata { + if in == nil { + return nil } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - return resp, nil -} -func ValidateDataResourceConfig_Response(in *tfprotov6.ValidateDataResourceConfigResponse) (*tfplugin6.ValidateDataResourceConfig_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err + return &tfplugin6.GetMetadata_DataSourceMetadata{ + TypeName: in.TypeName, } - return &tfplugin6.ValidateDataResourceConfig_Response{ - Diagnostics: diags, - }, nil } -func ReadDataSource_Request(in *tfprotov6.ReadDataSourceRequest) (*tfplugin6.ReadDataSource_Request, error) { - resp := &tfplugin6.ReadDataSource_Request{ - TypeName: in.TypeName, - } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) +func ValidateDataResourceConfig_Response(in *tfprotov6.ValidateDataResourceConfigResponse) *tfplugin6.ValidateDataResourceConfig_Response { + if in == nil { + return nil } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) + + resp := &tfplugin6.ValidateDataResourceConfig_Response{ + Diagnostics: Diagnostics(in.Diagnostics), } - return resp, nil + + return resp } -func ReadDataSource_Response(in *tfprotov6.ReadDataSourceResponse) (*tfplugin6.ReadDataSource_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func ReadDataSource_Response(in *tfprotov6.ReadDataSourceResponse) *tfplugin6.ReadDataSource_Response { + if in == nil { + return nil } + resp := &tfplugin6.ReadDataSource_Response{ - Diagnostics: diags, + Diagnostics: Diagnostics(in.Diagnostics), + State: DynamicValue(in.State), } - if in.State != nil { - resp.State = DynamicValue(in.State) - } - return resp, nil -} -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/diagnostic.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/diagnostic.go index 4144222c..fa3ea736 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/diagnostic.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/diagnostic.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( @@ -7,43 +10,36 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" ) -func Diagnostic(in *tfprotov6.Diagnostic) (*tfplugin6.Diagnostic, error) { - diag := &tfplugin6.Diagnostic{ - Severity: Diagnostic_Severity(in.Severity), - Summary: forceValidUTF8(in.Summary), - Detail: forceValidUTF8(in.Detail), +func Diagnostic(in *tfprotov6.Diagnostic) *tfplugin6.Diagnostic { + if in == nil { + return nil } - if in.Attribute != nil { - attr, err := AttributePath(in.Attribute) - if err != nil { - return diag, err - } - diag.Attribute = attr + + resp := &tfplugin6.Diagnostic{ + Attribute: AttributePath(in.Attribute), + Detail: ForceValidUTF8(in.Detail), + Severity: Diagnostic_Severity(in.Severity), + Summary: ForceValidUTF8(in.Summary), } - return diag, nil + + return resp } func Diagnostic_Severity(in tfprotov6.DiagnosticSeverity) tfplugin6.Diagnostic_Severity { return tfplugin6.Diagnostic_Severity(in) } -func Diagnostics(in []*tfprotov6.Diagnostic) ([]*tfplugin6.Diagnostic, error) { - diagnostics := make([]*tfplugin6.Diagnostic, 0, len(in)) +func Diagnostics(in []*tfprotov6.Diagnostic) []*tfplugin6.Diagnostic { + resp := make([]*tfplugin6.Diagnostic, 0, len(in)) + for _, diag := range in { - if diag == nil { - diagnostics = append(diagnostics, nil) - continue - } - d, err := Diagnostic(diag) - if err != nil { - return diagnostics, err - } - diagnostics = append(diagnostics, d) + resp = append(resp, Diagnostic(diag)) } - return diagnostics, nil + + return resp } -// forceValidUTF8 returns a string guaranteed to be valid UTF-8 even if the +// ForceValidUTF8 returns a string guaranteed to be valid UTF-8 even if the // input isn't, by replacing any invalid bytes with a valid UTF-8 encoding of // the Unicode Replacement Character (\uFFFD). // @@ -62,7 +58,7 @@ func Diagnostics(in []*tfprotov6.Diagnostic) ([]*tfplugin6.Diagnostic, error) { // it's ultimately up to the user and their terminal or web browser to // interpret the result. Don't use this for strings that have machine-readable // meaning. -func forceValidUTF8(s string) string { +func ForceValidUTF8(s string) string { // Most strings that pass through here will already be valid UTF-8 and // utf8.ValidString has a fast path which will beat our rune-by-rune // analysis below, so it's worth the cost of walking the string twice @@ -95,11 +91,3 @@ func forceValidUTF8(s string) string { } return string(ret) } - -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/doc.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/doc.go new file mode 100644 index 00000000..2f60cc42 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package toproto converts terraform-plugin-go tfprotov6 types to Protocol +// Buffers generated tfplugin6 types. +package toproto diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/dynamic_value.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/dynamic_value.go index ef1693da..881be181 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/dynamic_value.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/dynamic_value.go @@ -1,35 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( - "fmt" - "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" "github.com/hashicorp/terraform-plugin-go/tftypes" ) func DynamicValue(in *tfprotov6.DynamicValue) *tfplugin6.DynamicValue { - return &tfplugin6.DynamicValue{ + if in == nil { + return nil + } + + resp := &tfplugin6.DynamicValue{ Msgpack: in.MsgPack, Json: in.JSON, } + + return resp } -func CtyType(in tftypes.Type) ([]byte, error) { - switch { - case in.Is(tftypes.String), in.Is(tftypes.Bool), in.Is(tftypes.Number), - in.Is(tftypes.List{}), in.Is(tftypes.Map{}), - in.Is(tftypes.Set{}), in.Is(tftypes.Object{}), - in.Is(tftypes.Tuple{}), in.Is(tftypes.DynamicPseudoType): - return in.MarshalJSON() //nolint:staticcheck +func CtyType(in tftypes.Type) []byte { + if in == nil { + return nil } - return nil, fmt.Errorf("unknown type %s", in) -} -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. + // MarshalJSON is always error safe. + // nolint:staticcheck // Intended first-party usage + resp, _ := in.MarshalJSON() + + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/function.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/function.go new file mode 100644 index 00000000..8c4d73eb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/function.go @@ -0,0 +1,100 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto + +import ( + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" +) + +func CallFunction_Response(in *tfprotov6.CallFunctionResponse) *tfplugin6.CallFunction_Response { + if in == nil { + return nil + } + + resp := &tfplugin6.CallFunction_Response{ + Error: FunctionError(in.Error), + Result: DynamicValue(in.Result), + } + + return resp +} + +func Function(in *tfprotov6.Function) *tfplugin6.Function { + if in == nil { + return nil + } + + resp := &tfplugin6.Function{ + Description: in.Description, + DescriptionKind: StringKind(in.DescriptionKind), + DeprecationMessage: in.DeprecationMessage, + Parameters: make([]*tfplugin6.Function_Parameter, 0, len(in.Parameters)), + Return: Function_Return(in.Return), + Summary: in.Summary, + VariadicParameter: Function_Parameter(in.VariadicParameter), + } + + for _, parameter := range in.Parameters { + resp.Parameters = append(resp.Parameters, Function_Parameter(parameter)) + } + + return resp +} + +func Function_Parameter(in *tfprotov6.FunctionParameter) *tfplugin6.Function_Parameter { + if in == nil { + return nil + } + + resp := &tfplugin6.Function_Parameter{ + AllowNullValue: in.AllowNullValue, + AllowUnknownValues: in.AllowUnknownValues, + Description: in.Description, + DescriptionKind: StringKind(in.DescriptionKind), + Name: in.Name, + Type: CtyType(in.Type), + } + + return resp +} + +func Function_Return(in *tfprotov6.FunctionReturn) *tfplugin6.Function_Return { + if in == nil { + return nil + } + + resp := &tfplugin6.Function_Return{ + Type: CtyType(in.Type), + } + + return resp +} + +func GetFunctions_Response(in *tfprotov6.GetFunctionsResponse) *tfplugin6.GetFunctions_Response { + if in == nil { + return nil + } + + resp := &tfplugin6.GetFunctions_Response{ + Diagnostics: Diagnostics(in.Diagnostics), + Functions: make(map[string]*tfplugin6.Function, len(in.Functions)), + } + + for name, function := range in.Functions { + resp.Functions[name] = Function(function) + } + + return resp +} + +func GetMetadata_FunctionMetadata(in *tfprotov6.FunctionMetadata) *tfplugin6.GetMetadata_FunctionMetadata { + if in == nil { + return nil + } + + return &tfplugin6.GetMetadata_FunctionMetadata{ + Name: in.Name, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/function_error.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/function_error.go new file mode 100644 index 00000000..33f3a223 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/function_error.go @@ -0,0 +1,22 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto + +import ( + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" +) + +func FunctionError(in *tfprotov6.FunctionError) *tfplugin6.FunctionError { + if in == nil { + return nil + } + + resp := &tfplugin6.FunctionError{ + FunctionArgument: in.FunctionArgument, + Text: ForceValidUTF8(in.Text), + } + + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/provider.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/provider.go index ce37207f..7b283c9d 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/provider.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/provider.go @@ -1,122 +1,103 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( - "fmt" - "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" ) -func GetProviderSchema_Request(in *tfprotov6.GetProviderSchemaRequest) (*tfplugin6.GetProviderSchema_Request, error) { - return &tfplugin6.GetProviderSchema_Request{}, nil +func GetMetadata_Response(in *tfprotov6.GetMetadataResponse) *tfplugin6.GetMetadata_Response { + if in == nil { + return nil + } + + resp := &tfplugin6.GetMetadata_Response{ + DataSources: make([]*tfplugin6.GetMetadata_DataSourceMetadata, 0, len(in.DataSources)), + Diagnostics: Diagnostics(in.Diagnostics), + Functions: make([]*tfplugin6.GetMetadata_FunctionMetadata, 0, len(in.Functions)), + Resources: make([]*tfplugin6.GetMetadata_ResourceMetadata, 0, len(in.Resources)), + ServerCapabilities: ServerCapabilities(in.ServerCapabilities), + } + + for _, datasource := range in.DataSources { + resp.DataSources = append(resp.DataSources, GetMetadata_DataSourceMetadata(&datasource)) + } + + for _, function := range in.Functions { + resp.Functions = append(resp.Functions, GetMetadata_FunctionMetadata(&function)) + } + + for _, resource := range in.Resources { + resp.Resources = append(resp.Resources, GetMetadata_ResourceMetadata(&resource)) + } + + return resp } -func GetProviderSchema_Response(in *tfprotov6.GetProviderSchemaResponse) (*tfplugin6.GetProviderSchema_Response, error) { +func GetProviderSchema_Response(in *tfprotov6.GetProviderSchemaResponse) *tfplugin6.GetProviderSchema_Response { if in == nil { - return nil, nil - } - resp := tfplugin6.GetProviderSchema_Response{ - ServerCapabilities: GetProviderSchema_ServerCapabilities(in.ServerCapabilities), - } - if in.Provider != nil { - schema, err := Schema(in.Provider) - if err != nil { - return &resp, fmt.Errorf("error marshaling provider schema: %w", err) - } - resp.Provider = schema - } - if in.ProviderMeta != nil { - schema, err := Schema(in.ProviderMeta) - if err != nil { - return &resp, fmt.Errorf("error marshaling provider_meta schema: %w", err) - } - resp.ProviderMeta = schema - } - resp.ResourceSchemas = make(map[string]*tfplugin6.Schema, len(in.ResourceSchemas)) - for k, v := range in.ResourceSchemas { - if v == nil { - resp.ResourceSchemas[k] = nil - continue - } - schema, err := Schema(v) - if err != nil { - return &resp, fmt.Errorf("error marshaling resource schema for %q: %w", k, err) - } - resp.ResourceSchemas[k] = schema - } - resp.DataSourceSchemas = make(map[string]*tfplugin6.Schema, len(in.DataSourceSchemas)) - for k, v := range in.DataSourceSchemas { - if v == nil { - resp.DataSourceSchemas[k] = nil - continue - } - schema, err := Schema(v) - if err != nil { - return &resp, fmt.Errorf("error marshaling data source schema for %q: %w", k, err) - } - resp.DataSourceSchemas[k] = schema - } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return &resp, err - } - resp.Diagnostics = diags - return &resp, nil -} + return nil + } -func ValidateProviderConfig_Request(in *tfprotov6.ValidateProviderConfigRequest) (*tfplugin6.ValidateProviderConfig_Request, error) { - resp := &tfplugin6.ValidateProviderConfig_Request{} - if in.Config != nil { - resp.Config = DynamicValue(in.Config) + resp := &tfplugin6.GetProviderSchema_Response{ + DataSourceSchemas: make(map[string]*tfplugin6.Schema, len(in.DataSourceSchemas)), + Diagnostics: Diagnostics(in.Diagnostics), + Functions: make(map[string]*tfplugin6.Function, len(in.Functions)), + Provider: Schema(in.Provider), + ProviderMeta: Schema(in.ProviderMeta), + ResourceSchemas: make(map[string]*tfplugin6.Schema, len(in.ResourceSchemas)), + ServerCapabilities: ServerCapabilities(in.ServerCapabilities), } - return resp, nil -} -func ValidateProviderConfig_Response(in *tfprotov6.ValidateProviderConfigResponse) (*tfplugin6.ValidateProviderConfig_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err + for name, schema := range in.ResourceSchemas { + resp.ResourceSchemas[name] = Schema(schema) } - resp := &tfplugin6.ValidateProviderConfig_Response{ - Diagnostics: diags, + + for name, schema := range in.DataSourceSchemas { + resp.DataSourceSchemas[name] = Schema(schema) } - return resp, nil + + for name, function := range in.Functions { + resp.Functions[name] = Function(function) + } + + return resp } -func Configure_Request(in *tfprotov6.ConfigureProviderRequest) (*tfplugin6.ConfigureProvider_Request, error) { - resp := &tfplugin6.ConfigureProvider_Request{ - TerraformVersion: in.TerraformVersion, +func ValidateProviderConfig_Response(in *tfprotov6.ValidateProviderConfigResponse) *tfplugin6.ValidateProviderConfig_Response { + if in == nil { + return nil } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) + + resp := &tfplugin6.ValidateProviderConfig_Response{ + Diagnostics: Diagnostics(in.Diagnostics), } - return resp, nil + + return resp } -func Configure_Response(in *tfprotov6.ConfigureProviderResponse) (*tfplugin6.ConfigureProvider_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func ConfigureProvider_Response(in *tfprotov6.ConfigureProviderResponse) *tfplugin6.ConfigureProvider_Response { + if in == nil { + return nil } - return &tfplugin6.ConfigureProvider_Response{ - Diagnostics: diags, - }, nil -} -func Stop_Request(in *tfprotov6.StopProviderRequest) (*tfplugin6.StopProvider_Request, error) { - return &tfplugin6.StopProvider_Request{}, nil + resp := &tfplugin6.ConfigureProvider_Response{ + Diagnostics: Diagnostics(in.Diagnostics), + } + + return resp } -func Stop_Response(in *tfprotov6.StopProviderResponse) (*tfplugin6.StopProvider_Response, error) { - return &tfplugin6.StopProvider_Response{ +func StopProvider_Response(in *tfprotov6.StopProviderResponse) *tfplugin6.StopProvider_Response { + if in == nil { + return nil + } + + resp := &tfplugin6.StopProvider_Response{ Error: in.Error, - }, nil -} + } -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/resource.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/resource.go index bb096818..638504d7 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/resource.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/resource.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( @@ -5,210 +8,135 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" ) -func ValidateResourceConfig_Request(in *tfprotov6.ValidateResourceConfigRequest) (*tfplugin6.ValidateResourceConfig_Request, error) { - resp := &tfplugin6.ValidateResourceConfig_Request{ - TypeName: in.TypeName, +func GetMetadata_ResourceMetadata(in *tfprotov6.ResourceMetadata) *tfplugin6.GetMetadata_ResourceMetadata { + if in == nil { + return nil } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - return resp, nil -} -func ValidateResourceConfig_Response(in *tfprotov6.ValidateResourceConfigResponse) (*tfplugin6.ValidateResourceConfig_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err + resp := &tfplugin6.GetMetadata_ResourceMetadata{ + TypeName: in.TypeName, } - return &tfplugin6.ValidateResourceConfig_Response{ - Diagnostics: diags, - }, nil + + return resp } -func UpgradeResourceState_Request(in *tfprotov6.UpgradeResourceStateRequest) (*tfplugin6.UpgradeResourceState_Request, error) { - resp := &tfplugin6.UpgradeResourceState_Request{ - TypeName: in.TypeName, - Version: in.Version, +func ValidateResourceConfig_Response(in *tfprotov6.ValidateResourceConfigResponse) *tfplugin6.ValidateResourceConfig_Response { + if in == nil { + return nil } - if in.RawState != nil { - resp.RawState = RawState(in.RawState) + + resp := &tfplugin6.ValidateResourceConfig_Response{ + Diagnostics: Diagnostics(in.Diagnostics), } - return resp, nil + + return resp } -func UpgradeResourceState_Response(in *tfprotov6.UpgradeResourceStateResponse) (*tfplugin6.UpgradeResourceState_Response, error) { - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err +func UpgradeResourceState_Response(in *tfprotov6.UpgradeResourceStateResponse) *tfplugin6.UpgradeResourceState_Response { + if in == nil { + return nil } + resp := &tfplugin6.UpgradeResourceState_Response{ - Diagnostics: diags, + Diagnostics: Diagnostics(in.Diagnostics), + UpgradedState: DynamicValue(in.UpgradedState), } - if in.UpgradedState != nil { - resp.UpgradedState = DynamicValue(in.UpgradedState) - } - return resp, nil + + return resp } -func ReadResource_Request(in *tfprotov6.ReadResourceRequest) (*tfplugin6.ReadResource_Request, error) { - resp := &tfplugin6.ReadResource_Request{ - TypeName: in.TypeName, - Private: in.Private, - } - if in.CurrentState != nil { - resp.CurrentState = DynamicValue(in.CurrentState) +func ReadResource_Response(in *tfprotov6.ReadResourceResponse) *tfplugin6.ReadResource_Response { + if in == nil { + return nil } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) - } - return resp, nil -} -func ReadResource_Response(in *tfprotov6.ReadResourceResponse) (*tfplugin6.ReadResource_Response, error) { resp := &tfplugin6.ReadResource_Response{ - Private: in.Private, - } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err - } - resp.Diagnostics = diags - if in.NewState != nil { - resp.NewState = DynamicValue(in.NewState) + Diagnostics: Diagnostics(in.Diagnostics), + NewState: DynamicValue(in.NewState), + Private: in.Private, } - return resp, nil + + return resp } -func PlanResourceChange_Request(in *tfprotov6.PlanResourceChangeRequest) (*tfplugin6.PlanResourceChange_Request, error) { - resp := &tfplugin6.PlanResourceChange_Request{ - TypeName: in.TypeName, - PriorPrivate: in.PriorPrivate, - } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - if in.PriorState != nil { - resp.PriorState = DynamicValue(in.PriorState) +func PlanResourceChange_Response(in *tfprotov6.PlanResourceChangeResponse) *tfplugin6.PlanResourceChange_Response { + if in == nil { + return nil } - if in.ProposedNewState != nil { - resp.ProposedNewState = DynamicValue(in.ProposedNewState) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) - } - return resp, nil -} -func PlanResourceChange_Response(in *tfprotov6.PlanResourceChangeResponse) (*tfplugin6.PlanResourceChange_Response, error) { resp := &tfplugin6.PlanResourceChange_Response{ - PlannedPrivate: in.PlannedPrivate, + Diagnostics: Diagnostics(in.Diagnostics), LegacyTypeSystem: in.UnsafeToUseLegacyTypeSystem, //nolint:staticcheck + PlannedPrivate: in.PlannedPrivate, + PlannedState: DynamicValue(in.PlannedState), + RequiresReplace: AttributePaths(in.RequiresReplace), } - requiresReplace, err := AttributePaths(in.RequiresReplace) - if err != nil { - return resp, err - } - resp.RequiresReplace = requiresReplace - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err - } - resp.Diagnostics = diags - if in.PlannedState != nil { - resp.PlannedState = DynamicValue(in.PlannedState) - } - return resp, nil + + return resp } -func ApplyResourceChange_Request(in *tfprotov6.ApplyResourceChangeRequest) (*tfplugin6.ApplyResourceChange_Request, error) { - resp := &tfplugin6.ApplyResourceChange_Request{ - TypeName: in.TypeName, - PlannedPrivate: in.PlannedPrivate, - } - if in.Config != nil { - resp.Config = DynamicValue(in.Config) - } - if in.PriorState != nil { - resp.PriorState = DynamicValue(in.PriorState) +func ApplyResourceChange_Response(in *tfprotov6.ApplyResourceChangeResponse) *tfplugin6.ApplyResourceChange_Response { + if in == nil { + return nil } - if in.PlannedState != nil { - resp.PlannedState = DynamicValue(in.PlannedState) - } - if in.ProviderMeta != nil { - resp.ProviderMeta = DynamicValue(in.ProviderMeta) - } - return resp, nil -} -func ApplyResourceChange_Response(in *tfprotov6.ApplyResourceChangeResponse) (*tfplugin6.ApplyResourceChange_Response, error) { resp := &tfplugin6.ApplyResourceChange_Response{ - Private: in.Private, + Diagnostics: Diagnostics(in.Diagnostics), LegacyTypeSystem: in.UnsafeToUseLegacyTypeSystem, //nolint:staticcheck + NewState: DynamicValue(in.NewState), + Private: in.Private, } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return resp, err - } - resp.Diagnostics = diags - if in.NewState != nil { - resp.NewState = DynamicValue(in.NewState) - } - return resp, nil -} -func ImportResourceState_Request(in *tfprotov6.ImportResourceStateRequest) (*tfplugin6.ImportResourceState_Request, error) { - return &tfplugin6.ImportResourceState_Request{ - TypeName: in.TypeName, - Id: in.ID, - }, nil + return resp } -func ImportResourceState_Response(in *tfprotov6.ImportResourceStateResponse) (*tfplugin6.ImportResourceState_Response, error) { - importedResources, err := ImportResourceState_ImportedResources(in.ImportedResources) - if err != nil { - return nil, err +func ImportResourceState_Response(in *tfprotov6.ImportResourceStateResponse) *tfplugin6.ImportResourceState_Response { + if in == nil { + return nil } - diags, err := Diagnostics(in.Diagnostics) - if err != nil { - return nil, err + + resp := &tfplugin6.ImportResourceState_Response{ + Diagnostics: Diagnostics(in.Diagnostics), + ImportedResources: ImportResourceState_ImportedResources(in.ImportedResources), } - return &tfplugin6.ImportResourceState_Response{ - ImportedResources: importedResources, - Diagnostics: diags, - }, nil + + return resp } -func ImportResourceState_ImportedResource(in *tfprotov6.ImportedResource) (*tfplugin6.ImportResourceState_ImportedResource, error) { +func ImportResourceState_ImportedResource(in *tfprotov6.ImportedResource) *tfplugin6.ImportResourceState_ImportedResource { + if in == nil { + return nil + } + resp := &tfplugin6.ImportResourceState_ImportedResource{ - TypeName: in.TypeName, Private: in.Private, + State: DynamicValue(in.State), + TypeName: in.TypeName, } - if in.State != nil { - resp.State = DynamicValue(in.State) - } - return resp, nil + + return resp } -func ImportResourceState_ImportedResources(in []*tfprotov6.ImportedResource) ([]*tfplugin6.ImportResourceState_ImportedResource, error) { +func ImportResourceState_ImportedResources(in []*tfprotov6.ImportedResource) []*tfplugin6.ImportResourceState_ImportedResource { resp := make([]*tfplugin6.ImportResourceState_ImportedResource, 0, len(in)) + for _, i := range in { - if i == nil { - resp = append(resp, nil) - continue - } - r, err := ImportResourceState_ImportedResource(i) - if err != nil { - return resp, err - } - resp = append(resp, r) - } - return resp, nil + resp = append(resp, ImportResourceState_ImportedResource(i)) + } + + return resp } -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. +func MoveResourceState_Response(in *tfprotov6.MoveResourceStateResponse) *tfplugin6.MoveResourceState_Response { + if in == nil { + return nil + } + + resp := &tfplugin6.MoveResourceState_Response{ + Diagnostics: Diagnostics(in.Diagnostics), + TargetPrivate: in.TargetPrivate, + TargetState: DynamicValue(in.TargetState), + } + + return resp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/schema.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/schema.go index f3dfcb97..fb46bd67 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/schema.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/schema.go @@ -1,120 +1,98 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( - "fmt" - "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" ) -func Schema(in *tfprotov6.Schema) (*tfplugin6.Schema, error) { - var resp tfplugin6.Schema - resp.Version = in.Version - if in.Block != nil { - block, err := Schema_Block(in.Block) - if err != nil { - return &resp, fmt.Errorf("error marshalling block: %w", err) - } - resp.Block = block +func Schema(in *tfprotov6.Schema) *tfplugin6.Schema { + if in == nil { + return nil + } + + resp := &tfplugin6.Schema{ + Block: Schema_Block(in.Block), + Version: in.Version, } - return &resp, nil + + return resp } -func Schema_Block(in *tfprotov6.SchemaBlock) (*tfplugin6.Schema_Block, error) { +func Schema_Block(in *tfprotov6.SchemaBlock) *tfplugin6.Schema_Block { + if in == nil { + return nil + } + resp := &tfplugin6.Schema_Block{ - Version: in.Version, + Attributes: Schema_Attributes(in.Attributes), + BlockTypes: Schema_NestedBlocks(in.BlockTypes), + Deprecated: in.Deprecated, Description: in.Description, DescriptionKind: StringKind(in.DescriptionKind), - Deprecated: in.Deprecated, - } - attrs, err := Schema_Attributes(in.Attributes) - if err != nil { - return resp, err - } - resp.Attributes = attrs - blocks, err := Schema_NestedBlocks(in.BlockTypes) - if err != nil { - return resp, err + Version: in.Version, } - resp.BlockTypes = blocks - return resp, nil + + return resp } -func Schema_Attribute(in *tfprotov6.SchemaAttribute) (*tfplugin6.Schema_Attribute, error) { +func Schema_Attribute(in *tfprotov6.SchemaAttribute) *tfplugin6.Schema_Attribute { + if in == nil { + return nil + } + resp := &tfplugin6.Schema_Attribute{ - Name: in.Name, + Computed: in.Computed, + Deprecated: in.Deprecated, Description: in.Description, - Required: in.Required, + DescriptionKind: StringKind(in.DescriptionKind), + Name: in.Name, + NestedType: Schema_Object(in.NestedType), Optional: in.Optional, - Computed: in.Computed, + Required: in.Required, Sensitive: in.Sensitive, - DescriptionKind: StringKind(in.DescriptionKind), - Deprecated: in.Deprecated, - } - if in.Type != nil { - t, err := CtyType(in.Type) - if err != nil { - return resp, fmt.Errorf("error marshaling type to JSON: %w", err) - } - resp.Type = t + Type: CtyType(in.Type), } - if in.NestedType != nil { - nb, err := Schema_Object(in.NestedType) - if err != nil { - return resp, err - } - resp.NestedType = nb - } - return resp, nil + + return resp } -func Schema_Attributes(in []*tfprotov6.SchemaAttribute) ([]*tfplugin6.Schema_Attribute, error) { +func Schema_Attributes(in []*tfprotov6.SchemaAttribute) []*tfplugin6.Schema_Attribute { resp := make([]*tfplugin6.Schema_Attribute, 0, len(in)) + for _, a := range in { - if a == nil { - resp = append(resp, nil) - continue - } - attr, err := Schema_Attribute(a) - if err != nil { - return nil, err - } - resp = append(resp, attr) + resp = append(resp, Schema_Attribute(a)) } - return resp, nil + + return resp } -func Schema_NestedBlock(in *tfprotov6.SchemaNestedBlock) (*tfplugin6.Schema_NestedBlock, error) { +func Schema_NestedBlock(in *tfprotov6.SchemaNestedBlock) *tfplugin6.Schema_NestedBlock { + if in == nil { + return nil + } + resp := &tfplugin6.Schema_NestedBlock{ - TypeName: in.TypeName, - Nesting: Schema_NestedBlock_NestingMode(in.Nesting), - MinItems: in.MinItems, + Block: Schema_Block(in.Block), MaxItems: in.MaxItems, + MinItems: in.MinItems, + Nesting: Schema_NestedBlock_NestingMode(in.Nesting), + TypeName: in.TypeName, } - if in.Block != nil { - block, err := Schema_Block(in.Block) - if err != nil { - return resp, fmt.Errorf("error marshaling nested block: %w", err) - } - resp.Block = block - } - return resp, nil + + return resp } -func Schema_NestedBlocks(in []*tfprotov6.SchemaNestedBlock) ([]*tfplugin6.Schema_NestedBlock, error) { +func Schema_NestedBlocks(in []*tfprotov6.SchemaNestedBlock) []*tfplugin6.Schema_NestedBlock { resp := make([]*tfplugin6.Schema_NestedBlock, 0, len(in)) + for _, b := range in { - if b == nil { - resp = append(resp, nil) - continue - } - block, err := Schema_NestedBlock(b) - if err != nil { - return nil, err - } - resp = append(resp, block) + resp = append(resp, Schema_NestedBlock(b)) } - return resp, nil + + return resp } func Schema_NestedBlock_NestingMode(in tfprotov6.SchemaNestedBlockNestingMode) tfplugin6.Schema_NestedBlock_NestingMode { @@ -125,23 +103,15 @@ func Schema_Object_NestingMode(in tfprotov6.SchemaObjectNestingMode) tfplugin6.S return tfplugin6.Schema_Object_NestingMode(in) } -func Schema_Object(in *tfprotov6.SchemaObject) (*tfplugin6.Schema_Object, error) { - resp := &tfplugin6.Schema_Object{ - Nesting: Schema_Object_NestingMode(in.Nesting), +func Schema_Object(in *tfprotov6.SchemaObject) *tfplugin6.Schema_Object { + if in == nil { + return nil } - attrs, err := Schema_Attributes(in.Attributes) - if err != nil { - return nil, err + + resp := &tfplugin6.Schema_Object{ + Attributes: Schema_Attributes(in.Attributes), + Nesting: Schema_Object_NestingMode(in.Nesting), } - resp.Attributes = attrs - return resp, nil + return resp } - -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/server_capabilities.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/server_capabilities.go index 26a16417..82d21b2e 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/server_capabilities.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/server_capabilities.go @@ -8,12 +8,16 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" ) -func GetProviderSchema_ServerCapabilities(in *tfprotov6.ServerCapabilities) *tfplugin6.GetProviderSchema_ServerCapabilities { +func ServerCapabilities(in *tfprotov6.ServerCapabilities) *tfplugin6.ServerCapabilities { if in == nil { return nil } - return &tfplugin6.GetProviderSchema_ServerCapabilities{ - PlanDestroy: in.PlanDestroy, + resp := &tfplugin6.ServerCapabilities{ + GetProviderSchemaOptional: in.GetProviderSchemaOptional, + MoveResourceState: in.MoveResourceState, + PlanDestroy: in.PlanDestroy, } + + return resp } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/state.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/state.go deleted file mode 100644 index b6a69fcc..00000000 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/state.go +++ /dev/null @@ -1,21 +0,0 @@ -package toproto - -import ( - "github.com/hashicorp/terraform-plugin-go/tfprotov6" - "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" -) - -func RawState(in *tfprotov6.RawState) *tfplugin6.RawState { - return &tfplugin6.RawState{ - Json: in.JSON, - Flatmap: in.Flatmap, - } -} - -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/string_kind.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/string_kind.go index 10f1727e..8e5036ee 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/string_kind.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto/string_kind.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package toproto import ( @@ -8,11 +11,3 @@ import ( func StringKind(in tfprotov6.StringKind) tfplugin6.StringKind { return tfplugin6.StringKind(in) } - -// we have to say this next thing to get golint to stop yelling at us about the -// underscores in the function names. We want the function names to match -// actually-generated code, so it feels like fair play. It's just a shame we -// lose golint for the entire file. -// -// This file is not actually generated. You can edit it. Ignore this next line. -// Code generated by hand ignore this next bit DO NOT EDIT. diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/provider.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/provider.go index 0681cfe1..e1ea384d 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/provider.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/provider.go @@ -10,6 +10,13 @@ import ( // ProviderServer is an interface that reflects that Terraform protocol. // Providers must implement this interface. type ProviderServer interface { + // GetMetadata returns upfront information about server capabilities and + // supported resource types without requiring the server to instantiate all + // schema information, which may be memory intensive. This RPC is optional, + // where clients may receive an unimplemented RPC error. Clients should + // ignore the error and call the GetProviderSchema RPC as a fallback. + GetMetadata(context.Context, *GetMetadataRequest) (*GetMetadataResponse, error) + // GetProviderSchema is called when Terraform needs to know what the // provider's schema is, along with the schemas of all its resources // and data sources. @@ -40,6 +47,40 @@ type ProviderServer interface { // data source is to terraform-plugin-go, so they're their own // interface that is composed into ProviderServer. DataSourceServer + + // FunctionServer is an interface encapsulating all the function-related RPC + // requests. ProviderServer implementations must implement them, but they + // are a handy interface for defining what a function is to + // terraform-plugin-go, so they are their own interface that is composed + // into ProviderServer. + // + // This will be required in an upcoming release. + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353 + // FunctionServer +} + +// GetMetadataRequest represents a GetMetadata RPC request. +type GetMetadataRequest struct{} + +// GetMetadataResponse represents a GetMetadata RPC response. +type GetMetadataResponse struct { + // ServerCapabilities defines optionally supported protocol features, + // such as forward-compatible Terraform behavior changes. + ServerCapabilities *ServerCapabilities + + // Diagnostics report errors or warnings related to returning the + // provider's schemas. Returning an empty slice indicates success, with + // no errors or warnings generated. + Diagnostics []*Diagnostic + + // DataSources returns metadata for all data resources. + DataSources []DataSourceMetadata + + // Functions returns metadata for all functions. + Functions []FunctionMetadata + + // Resources returns metadata for all managed resources. + Resources []ResourceMetadata } // GetProviderSchemaRequest represents a Terraform RPC request for the @@ -78,6 +119,14 @@ type GetProviderSchemaResponse struct { // `data` in a user's configuration. DataSourceSchemas map[string]*Schema + // Functions is a map of function names to their definition. + // + // Unlike data resources and managed resources, the name should NOT be + // prefixed with the provider name and an underscore. Configuration + // references to functions use a separate namespacing syntax that already + // includes the provider name. + Functions map[string]*Function + // Diagnostics report errors or warnings related to returning the // provider's schemas. Returning an empty slice indicates success, with // no errors or warnings generated. diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/resource.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/resource.go index d2e213f2..9344f8db 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/resource.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/resource.go @@ -9,6 +9,13 @@ import ( "github.com/hashicorp/terraform-plugin-go/tftypes" ) +// ResourceMetadata describes metadata for a managed resource in the GetMetadata +// RPC. +type ResourceMetadata struct { + // TypeName is the name of the managed resource. + TypeName string +} + // ResourceServer is an interface containing the methods a resource // implementation needs to fill. type ResourceServer interface { @@ -47,6 +54,27 @@ type ResourceServer interface { ImportResourceState(context.Context, *ImportResourceStateRequest) (*ImportResourceStateResponse, error) } +// ResourceServerWithMoveResourceState is a temporary interface for servers +// to implement MoveResourceState RPC handling. +// +// Deprecated: The MoveResourceState method will be moved into the +// ResourceServer interface and this interface will be removed in a future +// version. +type ResourceServerWithMoveResourceState interface { + ResourceServer + + // MoveResourceState is called when Terraform is asked to change a resource + // type for an existing resource. The provider must accept the change as + // valid by ensuring the source resource type, schema version, and provider + // address are compatible to convert the source state into the target + // resource type and latest state version. + // + // This functionality is only supported in Terraform 1.8 and later. The + // provider must have enabled the MoveResourceState server capability to + // enable these requests. + MoveResourceState(context.Context, *MoveResourceStateRequest) (*MoveResourceStateResponse, error) +} + // ValidateResourceConfigRequest is the request Terraform sends when it // wants to validate a resource's configuration. type ValidateResourceConfigRequest struct { @@ -469,3 +497,47 @@ type ImportedResource struct { // the resource, but will not be considered when calculating diffs. Private []byte } + +// MoveResourceStateRequest is the request Terraform sends when it requests a +// provider to move the state of a source resource into the target resource. +// Target resource types generally must opt into accepting each source resource +// type since any transformation logic requires knowledge of the source state. +// +// This functionality is only supported in Terraform 1.8 and later. The provider +// must have enabled the MoveResourceState server capability to enable these +// requests. +type MoveResourceStateRequest struct { + // SourcePrivate is the private state of the source resource. + SourcePrivate []byte + + // SourceProviderAddress is the address of the provider for the source + // resource type. + SourceProviderAddress string + + // SourceSchemaVersion is the version of the source resource state. + SourceSchemaVersion int64 + + // SourceState is the raw state of the source resource. + // + // Only the underlying JSON field is populated. + SourceState *RawState + + // SourceTypeName is the source resource type for the move request. + SourceTypeName string + + // TargetTypeName is the target resource type for the move request. + TargetTypeName string +} + +// MoveResourceStateResponse is the response from the provider containing +// the moved state for the given resource. +type MoveResourceStateResponse struct { + // TargetPrivate is the target resource private state after the move. + TargetPrivate []byte + + // TargetState is the target resource state after the move. + TargetState *DynamicValue + + // Diagnostics report any warnings or errors related to moving the state. + Diagnostics []*Diagnostic +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/server_capabilities.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/server_capabilities.go index 153ea46d..959899ce 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/server_capabilities.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/server_capabilities.go @@ -9,6 +9,15 @@ package tfprotov6 // This information is used in GetProviderSchemaResponse as capabilities are // static features which must be known upfront in the provider server. type ServerCapabilities struct { + // GetProviderSchemaOptional signals that this provider does not require + // having the GetProviderSchema RPC called first to operate normally. This + // means the caller can use a cached copy of the provider's schema instead. + GetProviderSchemaOptional bool + + // MoveResourceState signals that a provider supports the MoveResourceState + // RPC. + MoveResourceState bool + // PlanDestroy signals that a provider expects a call to // PlanResourceChange when a resource is going to be destroyed. This is // opt-in to prevent unexpected errors or panics since the diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server/server.go b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server/server.go index a639e82d..e8b5eb4d 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server/server.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server/server.go @@ -16,19 +16,20 @@ import ( "sync" "time" + "google.golang.org/grpc" + "github.com/hashicorp/terraform-plugin-go/internal/logging" "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto" "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tf6serverlogging" "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6" "github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto" - "google.golang.org/grpc" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-plugin" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-log/tfsdklog" - testing "github.com/mitchellh/go-testing-interface" + "github.com/mitchellh/go-testing-interface" ) const ( @@ -48,7 +49,7 @@ const ( // // In the future, it may be possible to include this information directly // in the protocol buffers rather than recreating a constant here. - protocolVersionMinor uint = 3 + protocolVersionMinor uint = 4 ) // protocolVersion represents the combined major and minor version numbers of @@ -486,86 +487,113 @@ func New(name string, serve tfprotov6.ProviderServer, opts ...ServeOpt) tfplugin } } -func (s *server) GetProviderSchema(ctx context.Context, req *tfplugin6.GetProviderSchema_Request) (*tfplugin6.GetProviderSchema_Response, error) { - rpc := "GetProviderSchema" +func (s *server) GetMetadata(ctx context.Context, protoReq *tfplugin6.GetMetadata_Request) (*tfplugin6.GetMetadata_Response, error) { + rpc := "GetMetadata" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.GetProviderSchemaRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } + + req := fromproto.GetMetadataRequest(protoReq) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.GetProviderSchema(ctx, r) + + resp, err := s.downstream.GetMetadata(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) - ret, err := toproto.GetProviderSchema_Response(resp) + tf6serverlogging.ServerCapabilities(ctx, resp.ServerCapabilities) + + protoResp := toproto.GetMetadata_Response(resp) + + return protoResp, nil +} + +func (s *server) GetProviderSchema(ctx context.Context, protoReq *tfplugin6.GetProviderSchema_Request) (*tfplugin6.GetProviderSchema_Response, error) { + rpc := "GetProviderSchema" + ctx = s.loggingContext(ctx) + ctx = logging.RpcContext(ctx, rpc) + ctx = s.stoppableContext(ctx) + logging.ProtocolTrace(ctx, "Received request") + defer logging.ProtocolTrace(ctx, "Served request") + + req := fromproto.GetProviderSchemaRequest(protoReq) + + ctx = tf6serverlogging.DownstreamRequest(ctx) + + resp, err := s.downstream.GetProviderSchema(ctx, req) + if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) + logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } - return ret, nil + + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) + tf6serverlogging.ServerCapabilities(ctx, resp.ServerCapabilities) + + protoResp := toproto.GetProviderSchema_Response(resp) + + return protoResp, nil } -func (s *server) ConfigureProvider(ctx context.Context, req *tfplugin6.ConfigureProvider_Request) (*tfplugin6.ConfigureProvider_Response, error) { +func (s *server) ConfigureProvider(ctx context.Context, protoReq *tfplugin6.ConfigureProvider_Request) (*tfplugin6.ConfigureProvider_Response, error) { rpc := "ConfigureProvider" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ConfigureProviderRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) + + req := fromproto.ConfigureProviderRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ConfigureProvider(ctx, r) + + resp, err := s.downstream.ConfigureProvider(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) - ret, err := toproto.Configure_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ConfigureProvider_Response(resp) + + return protoResp, nil } -func (s *server) ValidateProviderConfig(ctx context.Context, req *tfplugin6.ValidateProviderConfig_Request) (*tfplugin6.ValidateProviderConfig_Response, error) { +func (s *server) ValidateProviderConfig(ctx context.Context, protoReq *tfplugin6.ValidateProviderConfig_Request) (*tfplugin6.ValidateProviderConfig_Response, error) { rpc := "ValidateProviderConfig" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ValidateProviderConfigRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) + + req := fromproto.ValidateProviderConfigRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ValidateProviderConfig(ctx, r) + + resp, err := s.downstream.ValidateProviderConfig(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) - ret, err := toproto.ValidateProviderConfig_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ValidateProviderConfig_Response(resp) + + return protoResp, nil } // stop closes the stopCh associated with the server and replaces it with a new @@ -581,285 +609,435 @@ func (s *server) stop() { s.stopCh = make(chan struct{}) } -func (s *server) StopProvider(ctx context.Context, req *tfplugin6.StopProvider_Request) (*tfplugin6.StopProvider_Response, error) { +func (s *server) StopProvider(ctx context.Context, protoReq *tfplugin6.StopProvider_Request) (*tfplugin6.StopProvider_Response, error) { rpc := "StopProvider" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.StopProviderRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } + + req := fromproto.StopProviderRequest(protoReq) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.StopProvider(ctx, r) + + resp, err := s.downstream.StopProvider(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, nil) logging.ProtocolTrace(ctx, "Closing all our contexts") s.stop() logging.ProtocolTrace(ctx, "Closed all our contexts") - ret, err := toproto.Stop_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.StopProvider_Response(resp) + + return protoResp, nil } -func (s *server) ValidateDataResourceConfig(ctx context.Context, req *tfplugin6.ValidateDataResourceConfig_Request) (*tfplugin6.ValidateDataResourceConfig_Response, error) { +func (s *server) ValidateDataResourceConfig(ctx context.Context, protoReq *tfplugin6.ValidateDataResourceConfig_Request) (*tfplugin6.ValidateDataResourceConfig_Response, error) { rpc := "ValidateDataResourceConfig" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.DataSourceContext(ctx, req.TypeName) + ctx = logging.DataSourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ValidateDataResourceConfigRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) + + req := fromproto.ValidateDataResourceConfigRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ValidateDataResourceConfig(ctx, r) + + resp, err := s.downstream.ValidateDataResourceConfig(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) - ret, err := toproto.ValidateDataResourceConfig_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ValidateDataResourceConfig_Response(resp) + + return protoResp, nil } -func (s *server) ReadDataSource(ctx context.Context, req *tfplugin6.ReadDataSource_Request) (*tfplugin6.ReadDataSource_Response, error) { +func (s *server) ReadDataSource(ctx context.Context, protoReq *tfplugin6.ReadDataSource_Request) (*tfplugin6.ReadDataSource_Response, error) { rpc := "ReadDataSource" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.DataSourceContext(ctx, req.TypeName) + ctx = logging.DataSourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ReadDataSourceRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", r.ProviderMeta) + + req := fromproto.ReadDataSourceRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", req.ProviderMeta) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ReadDataSource(ctx, r) + + resp, err := s.downstream.ReadDataSource(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "State", resp.State) - ret, err := toproto.ReadDataSource_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ReadDataSource_Response(resp) + + return protoResp, nil } -func (s *server) ValidateResourceConfig(ctx context.Context, req *tfplugin6.ValidateResourceConfig_Request) (*tfplugin6.ValidateResourceConfig_Response, error) { +func (s *server) ValidateResourceConfig(ctx context.Context, protoReq *tfplugin6.ValidateResourceConfig_Request) (*tfplugin6.ValidateResourceConfig_Response, error) { rpc := "ValidateResourceConfig" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ValidateResourceConfigRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) + + req := fromproto.ValidateResourceConfigRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ValidateResourceConfig(ctx, r) + + resp, err := s.downstream.ValidateResourceConfig(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) - ret, err := toproto.ValidateResourceConfig_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ValidateResourceConfig_Response(resp) + + return protoResp, nil } -func (s *server) UpgradeResourceState(ctx context.Context, req *tfplugin6.UpgradeResourceState_Request) (*tfplugin6.UpgradeResourceState_Response, error) { +func (s *server) UpgradeResourceState(ctx context.Context, protoReq *tfplugin6.UpgradeResourceState_Request) (*tfplugin6.UpgradeResourceState_Response, error) { rpc := "UpgradeResourceState" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.UpgradeResourceStateRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } + + req := fromproto.UpgradeResourceStateRequest(protoReq) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.UpgradeResourceState(ctx, r) + + resp, err := s.downstream.UpgradeResourceState(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "UpgradedState", resp.UpgradedState) - ret, err := toproto.UpgradeResourceState_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.UpgradeResourceState_Response(resp) + + return protoResp, nil } -func (s *server) ReadResource(ctx context.Context, req *tfplugin6.ReadResource_Request) (*tfplugin6.ReadResource_Response, error) { +func (s *server) ReadResource(ctx context.Context, protoReq *tfplugin6.ReadResource_Request) (*tfplugin6.ReadResource_Response, error) { rpc := "ReadResource" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ReadResourceRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "CurrentState", r.CurrentState) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", r.ProviderMeta) - logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "Private", r.Private) + + req := fromproto.ReadResourceRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "CurrentState", req.CurrentState) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", req.ProviderMeta) + logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "Private", req.Private) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ReadResource(ctx, r) + + resp, err := s.downstream.ReadResource(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "NewState", resp.NewState) logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Response", "Private", resp.Private) - ret, err := toproto.ReadResource_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ReadResource_Response(resp) + + return protoResp, nil } -func (s *server) PlanResourceChange(ctx context.Context, req *tfplugin6.PlanResourceChange_Request) (*tfplugin6.PlanResourceChange_Response, error) { +func (s *server) PlanResourceChange(ctx context.Context, protoReq *tfplugin6.PlanResourceChange_Request) (*tfplugin6.PlanResourceChange_Response, error) { rpc := "PlanResourceChange" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.PlanResourceChangeRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PriorState", r.PriorState) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProposedNewState", r.ProposedNewState) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", r.ProviderMeta) - logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "PriorPrivate", r.PriorPrivate) + + req := fromproto.PlanResourceChangeRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PriorState", req.PriorState) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProposedNewState", req.ProposedNewState) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", req.ProviderMeta) + logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "PriorPrivate", req.PriorPrivate) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.PlanResourceChange(ctx, r) + + resp, err := s.downstream.PlanResourceChange(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "PlannedState", resp.PlannedState) logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Response", "PlannedPrivate", resp.PlannedPrivate) - ret, err := toproto.PlanResourceChange_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.PlanResourceChange_Response(resp) + + return protoResp, nil } -func (s *server) ApplyResourceChange(ctx context.Context, req *tfplugin6.ApplyResourceChange_Request) (*tfplugin6.ApplyResourceChange_Response, error) { +func (s *server) ApplyResourceChange(ctx context.Context, protoReq *tfplugin6.ApplyResourceChange_Request) (*tfplugin6.ApplyResourceChange_Response, error) { rpc := "ApplyResourceChange" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ApplyResourceChangeRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", r.Config) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PlannedState", r.PlannedState) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PriorState", r.PriorState) - logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", r.ProviderMeta) - logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "PlannedPrivate", r.PlannedPrivate) + + req := fromproto.ApplyResourceChangeRequest(protoReq) + + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PlannedState", req.PlannedState) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "PriorState", req.PriorState) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "ProviderMeta", req.ProviderMeta) + logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Request", "PlannedPrivate", req.PlannedPrivate) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ApplyResourceChange(ctx, r) + + resp, err := s.downstream.ApplyResourceChange(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "NewState", resp.NewState) logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Response", "Private", resp.Private) - ret, err := toproto.ApplyResourceChange_Response(resp) - if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } - return ret, nil + + protoResp := toproto.ApplyResourceChange_Response(resp) + + return protoResp, nil } -func (s *server) ImportResourceState(ctx context.Context, req *tfplugin6.ImportResourceState_Request) (*tfplugin6.ImportResourceState_Response, error) { +func (s *server) ImportResourceState(ctx context.Context, protoReq *tfplugin6.ImportResourceState_Request) (*tfplugin6.ImportResourceState_Response, error) { rpc := "ImportResourceState" ctx = s.loggingContext(ctx) ctx = logging.RpcContext(ctx, rpc) - ctx = logging.ResourceContext(ctx, req.TypeName) + ctx = logging.ResourceContext(ctx, protoReq.TypeName) ctx = s.stoppableContext(ctx) logging.ProtocolTrace(ctx, "Received request") defer logging.ProtocolTrace(ctx, "Served request") - r, err := fromproto.ImportResourceStateRequest(req) - if err != nil { - logging.ProtocolError(ctx, "Error converting request from protobuf", map[string]interface{}{logging.KeyError: err}) - return nil, err - } + + req := fromproto.ImportResourceStateRequest(protoReq) + ctx = tf6serverlogging.DownstreamRequest(ctx) - resp, err := s.downstream.ImportResourceState(ctx, r) + + resp, err := s.downstream.ImportResourceState(ctx, req) + if err != nil { logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) return nil, err } + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) + for _, importedResource := range resp.ImportedResources { logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response_ImportedResource", "State", importedResource.State) logging.ProtocolPrivateData(ctx, s.protocolDataDir, rpc, "Response_ImportedResource", "Private", importedResource.Private) } - ret, err := toproto.ImportResourceState_Response(resp) + + protoResp := toproto.ImportResourceState_Response(resp) + + return protoResp, nil +} + +func (s *server) MoveResourceState(ctx context.Context, protoReq *tfplugin6.MoveResourceState_Request) (*tfplugin6.MoveResourceState_Response, error) { + rpc := "MoveResourceState" + ctx = s.loggingContext(ctx) + ctx = logging.RpcContext(ctx, rpc) + ctx = logging.ResourceContext(ctx, protoReq.TargetTypeName) + ctx = s.stoppableContext(ctx) + logging.ProtocolTrace(ctx, "Received request") + defer logging.ProtocolTrace(ctx, "Served request") + + // Remove this check and error in preference of + // s.downstream.MoveResourceState below once ResourceServer interface + // implements the MoveResourceState method. + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/363 + // nolint:staticcheck + resourceServerWMRS, ok := s.downstream.(tfprotov6.ResourceServerWithMoveResourceState) + + if !ok { + logging.ProtocolError(ctx, "ProviderServer does not implement ResourceServerWithMoveResourceState") + + protoResp := &tfplugin6.MoveResourceState_Response{ + Diagnostics: []*tfplugin6.Diagnostic{ + { + Severity: tfplugin6.Diagnostic_ERROR, + Summary: "Provider Move Resource State Not Implemented", + Detail: "A MoveResourceState call was received by the provider, however the provider does not implement the call. " + + "Either upgrade the provider to a version that implements move resource state support or this is a bug in Terraform that should be reported to the Terraform maintainers.", + }, + }, + } + + return protoResp, nil + } + + req := fromproto.MoveResourceStateRequest(protoReq) + + ctx = tf6serverlogging.DownstreamRequest(ctx) + + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/363 + // resp, err := s.downstream.MoveResourceState(ctx, req) + resp, err := resourceServerWMRS.MoveResourceState(ctx, req) + + if err != nil { + logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err}) + + return nil, err + } + + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "TargetState", resp.TargetState) + + protoResp := toproto.MoveResourceState_Response(resp) + + return protoResp, nil +} + +func (s *server) CallFunction(ctx context.Context, protoReq *tfplugin6.CallFunction_Request) (*tfplugin6.CallFunction_Response, error) { + rpc := "CallFunction" + ctx = s.loggingContext(ctx) + ctx = logging.RpcContext(ctx, rpc) + ctx = s.stoppableContext(ctx) + logging.ProtocolTrace(ctx, "Received request") + defer logging.ProtocolTrace(ctx, "Served request") + + // Remove this check and error in preference of s.downstream.CallFunction + // below once ProviderServer interface requires FunctionServer. + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353 + functionServer, ok := s.downstream.(tfprotov6.FunctionServer) + + if !ok { + logging.ProtocolError(ctx, "ProviderServer does not implement FunctionServer") + + text := "Provider Functions Not Implemented: A provider-defined function call was received by the provider, however the provider does not implement functions. " + + "Either upgrade the provider to a version that implements provider-defined functions or this is a bug in Terraform that should be reported to the Terraform maintainers." + + protoResp := &tfplugin6.CallFunction_Response{ + Error: &tfplugin6.FunctionError{ + Text: text, + }, + } + + return protoResp, nil + } + + req := fromproto.CallFunctionRequest(protoReq) + + for position, argument := range req.Arguments { + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", fmt.Sprintf("Arguments_%d", position), argument) + } + + ctx = tf6serverlogging.DownstreamRequest(ctx) + + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353 + // resp, err := s.downstream.CallFunction(ctx, req) + resp, err := functionServer.CallFunction(ctx, req) + + if err != nil { + logging.ProtocolError(ctx, "Error from downstream", map[string]any{logging.KeyError: err}) + return nil, err + } + + tf6serverlogging.DownstreamResponseWithError(ctx, resp.Error) + logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Response", "Result", resp.Result) + + protoResp := toproto.CallFunction_Response(resp) + + return protoResp, nil +} + +func (s *server) GetFunctions(ctx context.Context, protoReq *tfplugin6.GetFunctions_Request) (*tfplugin6.GetFunctions_Response, error) { + rpc := "GetFunctions" + ctx = s.loggingContext(ctx) + ctx = logging.RpcContext(ctx, rpc) + ctx = s.stoppableContext(ctx) + logging.ProtocolTrace(ctx, "Received request") + defer logging.ProtocolTrace(ctx, "Served request") + + // Remove this check and response in preference of s.downstream.GetFunctions + // below once ProviderServer interface requires FunctionServer. + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353 + functionServer, ok := s.downstream.(tfprotov6.FunctionServer) + + if !ok { + logging.ProtocolWarn(ctx, "ProviderServer does not implement FunctionServer") + + protoResp := &tfplugin6.GetFunctions_Response{ + Functions: map[string]*tfplugin6.Function{}, + } + + return protoResp, nil + } + + req := fromproto.GetFunctionsRequest(protoReq) + + ctx = tf6serverlogging.DownstreamRequest(ctx) + + // Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353 + // resp, err := s.downstream.GetFunctions(ctx, req) + resp, err := functionServer.GetFunctions(ctx, req) + if err != nil { - logging.ProtocolError(ctx, "Error converting response to protobuf", map[string]interface{}{logging.KeyError: err}) + logging.ProtocolError(ctx, "Error from downstream", map[string]any{logging.KeyError: err}) return nil, err } - return ret, nil + + tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics) + + protoResp := toproto.GetFunctions_Response(resp) + + return protoResp, nil } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/list.go b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/list.go index 512c7c90..fdf9b1db 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/list.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/list.go @@ -4,6 +4,7 @@ package tftypes import ( + "bytes" "fmt" ) @@ -114,9 +115,15 @@ func valueFromList(typ Type, in interface{}) (Value, error) { // // Deprecated: this is not meant to be called by third-party code. func (l List) MarshalJSON() ([]byte, error) { - elementType, err := l.ElementType.MarshalJSON() - if err != nil { - return nil, fmt.Errorf("error marshaling tftypes.List's element type %T to JSON: %w", l.ElementType, err) - } - return []byte(`["list",` + string(elementType) + `]`), nil + var buf bytes.Buffer + + buf.WriteString(`["list",`) + + // MarshalJSON is always error safe + elementTypeBytes, _ := l.ElementType.MarshalJSON() + + buf.Write(elementTypeBytes) + buf.WriteString(`]`) + + return buf.Bytes(), nil } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/map.go b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/map.go index 0d299dcb..cfcab04f 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/map.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/map.go @@ -4,6 +4,7 @@ package tftypes import ( + "bytes" "fmt" "sort" ) @@ -87,11 +88,17 @@ func (m Map) supportedGoTypes() []string { // // Deprecated: this is not meant to be called by third-party code. func (m Map) MarshalJSON() ([]byte, error) { - attributeType, err := m.ElementType.MarshalJSON() - if err != nil { - return nil, fmt.Errorf("error marshaling tftypes.Map's attribute type %T to JSON: %w", m.ElementType, err) - } - return []byte(`["map",` + string(attributeType) + `]`), nil + var buf bytes.Buffer + + buf.WriteString(`["map",`) + + // MarshalJSON is always error safe + elementTypeBytes, _ := m.ElementType.MarshalJSON() + + buf.Write(elementTypeBytes) + buf.WriteString(`]`) + + return buf.Bytes(), nil } func valueFromMap(typ Type, in interface{}) (Value, error) { diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/object.go b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/object.go index b901c99e..0e340bee 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/object.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/object.go @@ -4,6 +4,7 @@ package tftypes import ( + "bytes" "encoding/json" "fmt" "sort" @@ -230,27 +231,89 @@ func valueFromObject(types map[string]Type, optionalAttrs map[string]struct{}, i } // MarshalJSON returns a JSON representation of the full type signature of `o`, -// including the AttributeTypes. +// including the AttributeTypes and, if present, OptionalAttributes. // // Deprecated: this is not meant to be called by third-party code. func (o Object) MarshalJSON() ([]byte, error) { - attrs, err := json.Marshal(o.AttributeTypes) - if err != nil { - return nil, err + var buf bytes.Buffer + + buf.WriteString(`["object",{`) + + attributeTypeNames := make([]string, 0, len(o.AttributeTypes)) + + for attributeTypeName := range o.AttributeTypes { + attributeTypeNames = append(attributeTypeNames, attributeTypeName) } - var optionalAttrs []byte + + // Ensure consistent ordering for human readability and unit testing. + // The slices package was introduced in Go 1.21, so it is not usable until + // this Go module is updated to Go 1.21 minimum. + sort.Strings(attributeTypeNames) + + for index, attributeTypeName := range attributeTypeNames { + if index > 0 { + buf.WriteString(`,`) + } + + buf.Write(marshalJSONObjectAttributeName(attributeTypeName)) + buf.WriteString(`:`) + + // MarshalJSON is always error safe + attributeTypeBytes, _ := o.AttributeTypes[attributeTypeName].MarshalJSON() + + buf.Write(attributeTypeBytes) + } + + buf.WriteString(`}`) + if len(o.OptionalAttributes) > 0 { - optionalAttrs = append(optionalAttrs, []byte(",")...) - names := make([]string, 0, len(o.OptionalAttributes)) - for k := range o.OptionalAttributes { - names = append(names, k) + buf.WriteString(`,[`) + + optionalAttributeNames := make([]string, 0, len(o.OptionalAttributes)) + + for optionalAttributeName := range o.OptionalAttributes { + optionalAttributeNames = append(optionalAttributeNames, optionalAttributeName) } - sort.Strings(names) - optionalsJSON, err := json.Marshal(names) - if err != nil { - return nil, err + + // Ensure consistent ordering for human readability and unit testing. + // The slices package was introduced in Go 1.21, so it is not usable + // until this Go module is updated to Go 1.21 minimum. + sort.Strings(optionalAttributeNames) + + for index, optionalAttributeName := range optionalAttributeNames { + if index > 0 { + buf.WriteString(`,`) + } + + buf.Write(marshalJSONObjectAttributeName(optionalAttributeName)) } - optionalAttrs = append(optionalAttrs, optionalsJSON...) + + buf.WriteString(`]`) } - return []byte(`["object",` + string(attrs) + string(optionalAttrs) + `]`), nil + + buf.WriteString(`]`) + + return buf.Bytes(), nil +} + +// marshalJSONObjectAttributeName an object attribute name string into JSON or +// panics. +// +// JSON encoding a string has some non-trivial rules and go-cty already depends +// on the Go standard library for this, so for now this logic also offloads this +// effort the same way to handle user input. As of Go 1.21, it is not possible +// for a caller to input something that would trigger an encoding error. There +// is FuzzMarshalJSONObjectAttributeName to verify this assertion. +// +// If a panic can be induced, a Type Validate() method or requiring the use of +// Type construction functions that require validation are better solutions than +// handling validation errors at this point. +func marshalJSONObjectAttributeName(name string) []byte { + result, err := json.Marshal(name) + + if err != nil { + panic(fmt.Sprintf("unable to JSON encode object attribute name: %s", name)) + } + + return result } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/primitive.go b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/primitive.go index 5a631bae..1a604281 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/primitive.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/primitive.go @@ -86,7 +86,10 @@ func (p primitive) MarshalJSON() ([]byte, error) { case DynamicPseudoType.name: return []byte(`"dynamic"`), nil } - return nil, fmt.Errorf("unknown primitive type %q", p) + + // MarshalJSON should always be error safe and reaching this panic implies + // a new primitive type was added that needs to be handled above. + panic(fmt.Sprintf("unimplemented tftypes.primitive type: %+v", p)) } func (p primitive) supportedGoTypes() []string { diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/set.go b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/set.go index e4549b59..1865c1fa 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/set.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/set.go @@ -4,6 +4,7 @@ package tftypes import ( + "bytes" "fmt" ) @@ -110,9 +111,15 @@ func valueFromSet(typ Type, in interface{}) (Value, error) { // // Deprecated: this is not meant to be called by third-party code. func (s Set) MarshalJSON() ([]byte, error) { - elementType, err := s.ElementType.MarshalJSON() - if err != nil { - return nil, fmt.Errorf("error marshaling tftypes.Set's element type %T to JSON: %w", s.ElementType, err) - } - return []byte(`["set",` + string(elementType) + `]`), nil + var buf bytes.Buffer + + buf.WriteString(`["set",`) + + // MarshalJSON is always error safe + elementTypeBytes, _ := s.ElementType.MarshalJSON() + + buf.Write(elementTypeBytes) + buf.WriteString(`]`) + + return buf.Bytes(), nil } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/tuple.go b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/tuple.go index a5c5e523..9e735dce 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/tuple.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/tuple.go @@ -4,7 +4,7 @@ package tftypes import ( - "encoding/json" + "bytes" "fmt" "strings" ) @@ -148,9 +148,22 @@ func valueFromTuple(types []Type, in interface{}) (Value, error) { // // Deprecated: this is not meant to be called by third-party code. func (tu Tuple) MarshalJSON() ([]byte, error) { - elements, err := json.Marshal(tu.ElementTypes) - if err != nil { - return nil, err + var buf bytes.Buffer + + buf.WriteString(`["tuple",[`) + + for index, elementType := range tu.ElementTypes { + if index > 0 { + buf.WriteString(",") + } + + // MarshalJSON is always error safe + elementTypeBytes, _ := elementType.MarshalJSON() + + buf.Write(elementTypeBytes) } - return []byte(`["tuple",` + string(elements) + `]`), nil + + buf.WriteString(`]]`) + + return buf.Bytes(), nil } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/type.go b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/type.go index c5965992..be0749dc 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/type.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/type.go @@ -43,7 +43,7 @@ type Type interface { // MarshalJSON returns a JSON representation of the Type's signature. // It is modeled based on Terraform's requirements for type signature // JSON representations, and may change over time to match Terraform's - // formatting. + // formatting. The error return should always be nil. // // Deprecated: this is not meant to be called by third-party code. MarshalJSON() ([]byte, error) diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/value.go b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/value.go index b8450783..63570211 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/value.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/value.go @@ -223,7 +223,7 @@ func (val Value) Equal(o Value) bool { } deepEqual, err := val.deepEqual(o) if err != nil { - panic(err) + return false } return deepEqual } diff --git a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/value_msgpack.go b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/value_msgpack.go index ed03ef98..08fb1520 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/value_msgpack.go +++ b/vendor/github.com/hashicorp/terraform-plugin-go/tftypes/value_msgpack.go @@ -446,7 +446,7 @@ func marshalMsgPackNumber(val Value, typ Type, p *AttributePath, enc *msgpack.En if err != nil { return p.NewErrorf("error encoding int value: %w", err) } - } else if fv, acc := n.Float64(); acc == big.Exact { + } else if fv, acc := n.Float64(); acc == big.Exact && !n.IsInt() { err := enc.EncodeFloat64(fv) if err != nil { return p.NewErrorf("error encoding float value: %w", err) diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/grpc_provider.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/grpc_provider.go index 831d7877..70477da4 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/grpc_provider.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/grpc_provider.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov5" "github.com/hashicorp/terraform-plugin-go/tftypes" + "github.com/hashicorp/terraform-plugin-sdk/v2/internal/configs/configschema" "github.com/hashicorp/terraform-plugin-sdk/v2/internal/configs/hcl2shim" "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" @@ -28,6 +29,9 @@ const ( newExtraKey = "_new_extra_shim" ) +// Verify provider server interface implementation. +var _ tfprotov5.ProviderServer = (*GRPCProviderServer)(nil) + func NewGRPCProviderServer(p *Provider) *GRPCProviderServer { return &GRPCProviderServer{ provider: p, @@ -67,14 +71,49 @@ func (s *GRPCProviderServer) StopContext(ctx context.Context) context.Context { return stoppable } +func (s *GRPCProviderServer) serverCapabilities() *tfprotov5.ServerCapabilities { + return &tfprotov5.ServerCapabilities{ + GetProviderSchemaOptional: true, + } +} + +func (s *GRPCProviderServer) GetMetadata(ctx context.Context, req *tfprotov5.GetMetadataRequest) (*tfprotov5.GetMetadataResponse, error) { + ctx = logging.InitContext(ctx) + + logging.HelperSchemaTrace(ctx, "Getting provider metadata") + + resp := &tfprotov5.GetMetadataResponse{ + DataSources: make([]tfprotov5.DataSourceMetadata, 0, len(s.provider.DataSourcesMap)), + Functions: make([]tfprotov5.FunctionMetadata, 0), + Resources: make([]tfprotov5.ResourceMetadata, 0, len(s.provider.ResourcesMap)), + ServerCapabilities: s.serverCapabilities(), + } + + for typeName := range s.provider.DataSourcesMap { + resp.DataSources = append(resp.DataSources, tfprotov5.DataSourceMetadata{ + TypeName: typeName, + }) + } + + for typeName := range s.provider.ResourcesMap { + resp.Resources = append(resp.Resources, tfprotov5.ResourceMetadata{ + TypeName: typeName, + }) + } + + return resp, nil +} + func (s *GRPCProviderServer) GetProviderSchema(ctx context.Context, req *tfprotov5.GetProviderSchemaRequest) (*tfprotov5.GetProviderSchemaResponse, error) { ctx = logging.InitContext(ctx) logging.HelperSchemaTrace(ctx, "Getting provider schema") resp := &tfprotov5.GetProviderSchemaResponse{ - ResourceSchemas: make(map[string]*tfprotov5.Schema), - DataSourceSchemas: make(map[string]*tfprotov5.Schema), + DataSourceSchemas: make(map[string]*tfprotov5.Schema, len(s.provider.DataSourcesMap)), + Functions: make(map[string]*tfprotov5.Function, 0), + ResourceSchemas: make(map[string]*tfprotov5.Schema, len(s.provider.ResourcesMap)), + ServerCapabilities: s.serverCapabilities(), } resp.Provider = &tfprotov5.Schema{ @@ -549,6 +588,18 @@ func (s *GRPCProviderServer) ConfigureProvider(ctx context.Context, req *tfproto } config := terraform.NewResourceConfigShimmed(configVal, schemaBlock) + + // CtyValue is the raw protocol configuration data from newer APIs. + // + // This field was only added as a targeted fix for passing raw protocol data + // through the existing (helper/schema.Provider).Configure() exported method + // and is only populated in that situation. The data could theoretically be + // set in the NewResourceConfigShimmed() function, however the consequences + // of doing this were not investigated at the time the fix was introduced. + // + // Reference: https://github.com/hashicorp/terraform-plugin-sdk/issues/1270 + config.CtyValue = configVal + // TODO: remove global stop context hack // This attaches a global stop synchro'd context onto the provider.Configure // request scoped context. This provides a substitute for the removed provider.StopContext() @@ -662,20 +713,23 @@ func (s *GRPCProviderServer) PlanResourceChange(ctx context.Context, req *tfprot ctx = logging.InitContext(ctx) resp := &tfprotov5.PlanResourceChangeResponse{} + res, ok := s.provider.ResourcesMap[req.TypeName] + if !ok { + resp.Diagnostics = convert.AppendProtoDiag(ctx, resp.Diagnostics, fmt.Errorf("unknown resource type: %s", req.TypeName)) + return resp, nil + } + schemaBlock := s.getResourceSchemaBlock(req.TypeName) + // This is a signal to Terraform Core that we're doing the best we can to // shim the legacy type system of the SDK onto the Terraform type system // but we need it to cut us some slack. This setting should not be taken // forward to any new SDK implementations, since setting it prevents us // from catching certain classes of provider bug that can lead to // confusing downstream errors. - resp.UnsafeToUseLegacyTypeSystem = true //nolint:staticcheck - - res, ok := s.provider.ResourcesMap[req.TypeName] - if !ok { - resp.Diagnostics = convert.AppendProtoDiag(ctx, resp.Diagnostics, fmt.Errorf("unknown resource type: %s", req.TypeName)) - return resp, nil + if !res.EnableLegacyTypeSystemPlanErrors { + //nolint:staticcheck // explicitly for this SDK + resp.UnsafeToUseLegacyTypeSystem = true } - schemaBlock := s.getResourceSchemaBlock(req.TypeName) priorStateVal, err := msgpack.Unmarshal(req.PriorState.MsgPack, schemaBlock.ImpliedType()) if err != nil { @@ -1075,7 +1129,10 @@ func (s *GRPCProviderServer) ApplyResourceChange(ctx context.Context, req *tfpro // forward to any new SDK implementations, since setting it prevents us // from catching certain classes of provider bug that can lead to // confusing downstream errors. - resp.UnsafeToUseLegacyTypeSystem = true //nolint:staticcheck + if !res.EnableLegacyTypeSystemApplyErrors { + //nolint:staticcheck // explicitly for this SDK + resp.UnsafeToUseLegacyTypeSystem = true + } return resp, nil } @@ -1155,6 +1212,42 @@ func (s *GRPCProviderServer) ImportResourceState(ctx context.Context, req *tfpro return resp, nil } +func (s *GRPCProviderServer) MoveResourceState(ctx context.Context, req *tfprotov5.MoveResourceStateRequest) (*tfprotov5.MoveResourceStateResponse, error) { + if req == nil { + return nil, fmt.Errorf("MoveResourceState request is nil") + } + + ctx = logging.InitContext(ctx) + + logging.HelperSchemaTrace(ctx, "Returning error for MoveResourceState") + + resp := &tfprotov5.MoveResourceStateResponse{} + + _, ok := s.provider.ResourcesMap[req.TargetTypeName] + + if !ok { + resp.Diagnostics = []*tfprotov5.Diagnostic{ + { + Severity: tfprotov5.DiagnosticSeverityError, + Summary: "Unknown Resource Type", + Detail: fmt.Sprintf("The %q resource type is not supported by this provider.", req.TargetTypeName), + }, + } + + return resp, nil + } + + resp.Diagnostics = []*tfprotov5.Diagnostic{ + { + Severity: tfprotov5.DiagnosticSeverityError, + Summary: "Move Resource State Not Supported", + Detail: fmt.Sprintf("The %q resource type does not support moving resource state across resource types.", req.TargetTypeName), + }, + } + + return resp, nil +} + func (s *GRPCProviderServer) ReadDataSource(ctx context.Context, req *tfprotov5.ReadDataSourceRequest) (*tfprotov5.ReadDataSourceResponse, error) { ctx = logging.InitContext(ctx) resp := &tfprotov5.ReadDataSourceResponse{} @@ -1220,6 +1313,32 @@ func (s *GRPCProviderServer) ReadDataSource(ctx context.Context, req *tfprotov5. return resp, nil } +func (s *GRPCProviderServer) CallFunction(ctx context.Context, req *tfprotov5.CallFunctionRequest) (*tfprotov5.CallFunctionResponse, error) { + ctx = logging.InitContext(ctx) + + logging.HelperSchemaTrace(ctx, "Returning error for provider function call") + + resp := &tfprotov5.CallFunctionResponse{ + Error: &tfprotov5.FunctionError{ + Text: fmt.Sprintf("Function Not Found: No function named %q was found in the provider.", req.Name), + }, + } + + return resp, nil +} + +func (s *GRPCProviderServer) GetFunctions(ctx context.Context, req *tfprotov5.GetFunctionsRequest) (*tfprotov5.GetFunctionsResponse, error) { + ctx = logging.InitContext(ctx) + + logging.HelperSchemaTrace(ctx, "Getting provider functions") + + resp := &tfprotov5.GetFunctionsResponse{ + Functions: make(map[string]*tfprotov5.Function, 0), + } + + return resp, nil +} + func pathToAttributePath(path cty.Path) *tftypes.AttributePath { var steps []tftypes.AttributePathStep diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/provider.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/provider.go index 75e1a7c4..55ba6e2c 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/provider.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/provider.go @@ -12,8 +12,6 @@ import ( "sort" "strings" - "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform-plugin-go/tfprotov5" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/internal/configs/configschema" @@ -130,10 +128,10 @@ func (p *Provider) InternalValidate() error { return errors.New("ConfigureFunc and ConfigureContextFunc must not both be set") } - var validationErrors error + var validationErrors []error sm := schemaMap(p.Schema) if err := sm.InternalValidate(sm); err != nil { - validationErrors = multierror.Append(validationErrors, err) + validationErrors = append(validationErrors, err) } // Provider-specific checks @@ -145,17 +143,17 @@ func (p *Provider) InternalValidate() error { for k, r := range p.ResourcesMap { if err := r.InternalValidate(nil, true); err != nil { - validationErrors = multierror.Append(validationErrors, fmt.Errorf("resource %s: %s", k, err)) + validationErrors = append(validationErrors, fmt.Errorf("resource %s: %s", k, err)) } } for k, r := range p.DataSourcesMap { if err := r.InternalValidate(nil, false); err != nil { - validationErrors = multierror.Append(validationErrors, fmt.Errorf("data source %s: %s", k, err)) + validationErrors = append(validationErrors, fmt.Errorf("data source %s: %s", k, err)) } } - return validationErrors + return errors.Join(validationErrors...) } func isReservedProviderFieldName(name string) bool { @@ -286,6 +284,14 @@ func (p *Provider) Configure(ctx context.Context, c *terraform.ResourceConfig) d return diag.FromErr(err) } + // Modify the ResourceData to contain the original ResourceConfig to support + // GetOkExists() and GetRawConfig(). + // + // Reference: https://github.com/hashicorp/terraform-plugin-sdk/issues/1270 + if data != nil { + data.config = c + } + if p.ConfigureFunc != nil { meta, err := p.ConfigureFunc(data) if err != nil { @@ -487,6 +493,7 @@ func (p *Provider) DataSources() []terraform.DataSource { // If TF_APPEND_USER_AGENT is set, its value will be appended to the returned // string. func (p *Provider) UserAgent(name, version string) string { + //nolint:staticcheck // best effort usage ua := fmt.Sprintf("Terraform/%s (+https://www.terraform.io) Terraform-Plugin-SDK/%s", p.TerraformVersion, meta.SDKVersionString()) if name != "" { ua += " " + name diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/resource.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/resource.go index 8a1472e4..7564a0af 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/resource.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/resource.go @@ -595,6 +595,51 @@ type Resource struct { // See github.com/hashicorp/terraform-plugin-sdk/issues/655 for more // details. UseJSONNumber bool + + // EnableLegacyTypeSystemApplyErrors when enabled will prevent the SDK from + // setting the legacy type system flag in the protocol during + // ApplyResourceChange (Create, Update, and Delete) operations. Before + // enabling this setting in a production release for a resource, the + // resource should be exhaustively acceptance tested with the setting + // enabled in an environment where it is easy to clean up resources, + // potentially outside of Terraform, since these errors may be unavoidable + // in certain cases. + // + // Disabling the legacy type system protocol flag is an unsafe operation + // when using this SDK as there are certain unavoidable behaviors imposed + // by the SDK, however this option is surfaced to allow provider developers + // to try to discover fixable data inconsistency errors more easily. + // Terraform, when encountering an enabled legacy type system protocol flag, + // will demote certain schema and data consistency errors into warning logs + // containing the text "legacy plugin SDK". Some errors for errant schema + // definitions, such as when an attribute is not marked as Computed as + // expected by Terraform, can only be resolved by migrating to + // terraform-plugin-framework since that SDK does not impose behavior + // changes with it enabled. However, data-based errors typically require + // logic fixes that should be applicable for both SDKs to be resolved. + EnableLegacyTypeSystemApplyErrors bool + + // EnableLegacyTypeSystemPlanErrors when enabled will prevent the SDK from + // setting the legacy type system flag in the protocol during + // PlanResourceChange operations. Before enabling this setting in a + // production release for a resource, the resource should be exhaustively + // acceptance tested with the setting enabled in an environment where it is + // easy to clean up resources, potentially outside of Terraform, since these + // errors may be unavoidable in certain cases. + // + // Disabling the legacy type system protocol flag is an unsafe operation + // when using this SDK as there are certain unavoidable behaviors imposed + // by the SDK, however this option is surfaced to allow provider developers + // to try to discover fixable data inconsistency errors more easily. + // Terraform, when encountering an enabled legacy type system protocol flag, + // will demote certain schema and data consistency errors into warning logs + // containing the text "legacy plugin SDK". Some errors for errant schema + // definitions, such as when an attribute is not marked as Computed as + // expected by Terraform, can only be resolved by migrating to + // terraform-plugin-framework since that SDK does not impose behavior + // changes with it enabled. However, data-based errors typically require + // logic fixes that should be applicable for both SDKs to be resolved. + EnableLegacyTypeSystemPlanErrors bool } // SchemaMap returns the schema information for this Resource whether it is diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/resource_data.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/resource_data.go index b7eb7d27..4380db7e 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/resource_data.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema/resource_data.go @@ -591,9 +591,13 @@ func (d *ResourceData) GetProviderMeta(dst interface{}) error { // GetRawConfig is considered experimental and advanced functionality, and // familiarity with the Terraform protocol is suggested when using it. func (d *ResourceData) GetRawConfig() cty.Value { + // These methods follow the field readers preference order. if d.diff != nil && !d.diff.RawConfig.IsNull() { return d.diff.RawConfig } + if d.config != nil && !d.config.CtyValue.IsNull() { + return d.config.CtyValue + } if d.state != nil && !d.state.RawConfig.IsNull() { return d.state.RawConfig } @@ -607,6 +611,7 @@ func (d *ResourceData) GetRawConfig() cty.Value { // GetRawState is considered experimental and advanced functionality, and // familiarity with the Terraform protocol is suggested when using it. func (d *ResourceData) GetRawState() cty.Value { + // These methods follow the field readers preference order. if d.diff != nil && !d.diff.RawState.IsNull() { return d.diff.RawState } @@ -623,6 +628,7 @@ func (d *ResourceData) GetRawState() cty.Value { // GetRawPlan is considered experimental and advanced functionality, and // familiarity with the Terraform protocol is suggested when using it. func (d *ResourceData) GetRawPlan() cty.Value { + // These methods follow the field readers preference order. if d.diff != nil && !d.diff.RawPlan.IsNull() { return d.diff.RawPlan } diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/meta.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/meta.go index f24f7fa2..94147642 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/meta.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/meta.go @@ -45,6 +45,18 @@ func All(validators ...schema.SchemaValidateFunc) schema.SchemaValidateFunc { } } +// AllDiag returns a SchemaValidateDiagFunc which tests if the provided value +// passes all provided SchemaValidateDiagFunc +func AllDiag(validators ...schema.SchemaValidateDiagFunc) schema.SchemaValidateDiagFunc { + return func(i interface{}, k cty.Path) diag.Diagnostics { + var diags diag.Diagnostics + for _, validator := range validators { + diags = append(diags, validator(i, k)...) + } + return diags + } +} + // Any returns a SchemaValidateFunc which tests if the provided value // passes any of the provided SchemaValidateFunc func Any(validators ...schema.SchemaValidateFunc) schema.SchemaValidateFunc { @@ -63,6 +75,22 @@ func Any(validators ...schema.SchemaValidateFunc) schema.SchemaValidateFunc { } } +// AnyDiag returns a SchemaValidateDiagFunc which tests if the provided value +// passes any of the provided SchemaValidateDiagFunc +func AnyDiag(validators ...schema.SchemaValidateDiagFunc) schema.SchemaValidateDiagFunc { + return func(i interface{}, k cty.Path) diag.Diagnostics { + var diags diag.Diagnostics + for _, validator := range validators { + validatorDiags := validator(i, k) + if len(validatorDiags) == 0 { + return diag.Diagnostics{} + } + diags = append(diags, validatorDiags...) + } + return diags + } +} + // ToDiagFunc is a wrapper for legacy schema.SchemaValidateFunc // converting it to schema.SchemaValidateDiagFunc func ToDiagFunc(validator schema.SchemaValidateFunc) schema.SchemaValidateDiagFunc { diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/strings.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/strings.go index 19c9055f..375a698f 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/strings.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/strings.go @@ -146,7 +146,7 @@ func StringInSlice(valid []string, ignoreCase bool) schema.SchemaValidateFunc { } } - errors = append(errors, fmt.Errorf("expected %s to be one of %v, got %s", k, valid, v)) + errors = append(errors, fmt.Errorf("expected %s to be one of %q, got %s", k, valid, v)) return warnings, errors } } diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/testing.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/testing.go index 8dadd66f..a5aa6e04 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/testing.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation/testing.go @@ -4,9 +4,11 @@ package validation import ( + "fmt" "regexp" + "testing" - testing "github.com/mitchellh/go-testing-interface" + "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -18,23 +20,53 @@ type testCase struct { expectedErr *regexp.Regexp } -func runTestCases(t testing.T, cases []testCase) { +func runTestCases(t *testing.T, cases []testCase) { t.Helper() for i, tc := range cases { - _, errs := tc.f(tc.val, "test_property") + t.Run(fmt.Sprintf("TestCase_%d", i), func(t *testing.T) { + _, errs := tc.f(tc.val, "test_property") - if len(errs) == 0 && tc.expectedErr == nil { - continue - } + if len(errs) == 0 && tc.expectedErr == nil { + return + } - if len(errs) != 0 && tc.expectedErr == nil { - t.Fatalf("expected test case %d to produce no errors, got %v", i, errs) - } + if len(errs) != 0 && tc.expectedErr == nil { + t.Fatalf("expected test case %d to produce no errors, got %v", i, errs) + } - if !matchAnyError(errs, tc.expectedErr) { - t.Fatalf("expected test case %d to produce error matching \"%s\", got %v", i, tc.expectedErr, errs) - } + if !matchAnyError(errs, tc.expectedErr) { + t.Fatalf("expected test case %d to produce error matching \"%s\", got %v", i, tc.expectedErr, errs) + } + }) + } +} + +type diagTestCase struct { + val interface{} + f schema.SchemaValidateDiagFunc + expectedDiagSummary *regexp.Regexp +} + +func runDiagTestCases(t *testing.T, cases []diagTestCase) { + t.Helper() + + for i, tc := range cases { + t.Run(fmt.Sprintf("TestCase_%d", i), func(t *testing.T) { + diags := tc.f(tc.val, cty.GetAttrPath("test_property")) + + if len(diags) == 0 && tc.expectedDiagSummary == nil { + return + } + + if len(diags) != 0 && tc.expectedDiagSummary == nil { + t.Fatalf("expected test case %d to produce no diagnostics, got %v", i, diags) + } + + if !matchAnyDiagSummary(diags, tc.expectedDiagSummary) { + t.Fatalf("expected test case %d to produce diagnostic summary matching \"%s\", got %v", i, tc.expectedDiagSummary, diags) + } + }) } } diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/meta/meta.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/meta/meta.go index 494f61ce..7c62ee70 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/meta/meta.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/meta/meta.go @@ -14,11 +14,17 @@ import ( ) // The main version number that is being run at the moment. -var SDKVersion = "2.10.1" +// +// Deprecated: Use Go standard library [runtime/debug] package build information +// instead. +var SDKVersion = "2.33.0" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. +// +// Deprecated: Use Go standard library [runtime/debug] package build information +// instead. var SDKPrerelease = "" // SemVer is an instance of version.Version. This has the secondary @@ -31,6 +37,9 @@ func init() { } // VersionString returns the complete version string, including prerelease +// +// Deprecated: Use Go standard library [runtime/debug] package build information +// instead. func SDKVersionString() string { if SDKPrerelease != "" { return fmt.Sprintf("%s-%s", SDKVersion, SDKPrerelease) diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/terraform/resource.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/terraform/resource.go index 0da59371..2c1fa4ec 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/terraform/resource.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/terraform/resource.go @@ -40,6 +40,21 @@ type ResourceConfig struct { ComputedKeys []string Raw map[string]interface{} Config map[string]interface{} + + // CtyValue is the raw protocol configuration data from newer APIs. + // + // This field was only added as a targeted fix for passing raw protocol data + // through the existing (helper/schema.Provider).Configure() exported method + // and is only populated in that situation. The data could theoretically be + // set in the NewResourceConfigShimmed() function, however the consequences + // of doing this were not investigated at the time the fix was introduced. + // + // This field is ignored in the Equal() method to prevent a breaking + // behavior change since the entirety of the terraform package and this type + // are unintentionally exported in v2. + // + // Reference: https://github.com/hashicorp/terraform-plugin-sdk/issues/1270 + CtyValue cty.Value } // NewResourceConfigRaw constructs a ResourceConfig whose content is exactly @@ -169,6 +184,10 @@ func (c *ResourceConfig) DeepCopy() *ResourceConfig { } // Equal checks the equality of two resource configs. +// +// This method intentionally ignores the CtyValue field as a major version +// compatibility concern, as this exported field was later added to the type. +// Reference: https://github.com/hashicorp/terraform-plugin-sdk/issues/1270 func (c *ResourceConfig) Equal(c2 *ResourceConfig) bool { // If either are nil, then they're only equal if they're both nil if c == nil || c2 == nil { diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/terraform/state.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/terraform/state.go index 9357070b..7d217935 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/terraform/state.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/terraform/state.go @@ -7,6 +7,7 @@ import ( "bufio" "bytes" "encoding/json" + "errors" "fmt" "log" "os" @@ -17,7 +18,6 @@ import ( "sync" "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/go-multierror" "github.com/hashicorp/go-uuid" "github.com/mitchellh/copystructure" @@ -287,7 +287,7 @@ func (s *State) Validate() error { s.Lock() defer s.Unlock() - var result error + var result []error // !!!! FOR DEVELOPERS !!!! // @@ -309,7 +309,7 @@ func (s *State) Validate() error { key := strings.Join(ms.Path, ".") if _, ok := found[key]; ok { - result = multierror.Append(result, fmt.Errorf( + result = append(result, fmt.Errorf( strings.TrimSpace(stateValidateErrMultiModule), key)) continue } @@ -318,7 +318,7 @@ func (s *State) Validate() error { } } - return result + return errors.Join(result...) } // Remove removes the item in the state at the given address, returning diff --git a/vendor/github.com/huandu/xstrings/.travis.yml b/vendor/github.com/huandu/xstrings/.travis.yml deleted file mode 100644 index d6460be4..00000000 --- a/vendor/github.com/huandu/xstrings/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go -install: - - go get golang.org/x/tools/cmd/cover - - go get github.com/mattn/goveralls -script: - - go test -v -covermode=count -coverprofile=coverage.out - - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ ! -z "$COVERALLS_TOKEN" ]; then $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN; fi' diff --git a/vendor/github.com/huandu/xstrings/README.md b/vendor/github.com/huandu/xstrings/README.md index 292bf2f3..750c3c7e 100644 --- a/vendor/github.com/huandu/xstrings/README.md +++ b/vendor/github.com/huandu/xstrings/README.md @@ -1,7 +1,7 @@ -# xstrings # +# xstrings -[![Build Status](https://travis-ci.org/huandu/xstrings.svg?branch=master)](https://travis-ci.org/huandu/xstrings) -[![GoDoc](https://godoc.org/github.com/huandu/xstrings?status.svg)](https://godoc.org/github.com/huandu/xstrings) +[![Build Status](https://github.com/huandu/xstrings/workflows/Go/badge.svg)](https://github.com/huandu/xstrings/actions) +[![Go Doc](https://godoc.org/github.com/huandu/xstrings?status.svg)](https://pkg.go.dev/github.com/huandu/xstrings) [![Go Report](https://goreportcard.com/badge/github.com/huandu/xstrings)](https://goreportcard.com/report/github.com/huandu/xstrings) [![Coverage Status](https://coveralls.io/repos/github/huandu/xstrings/badge.svg?branch=master)](https://coveralls.io/github/huandu/xstrings?branch=master) @@ -9,109 +9,109 @@ Go package [xstrings](https://godoc.org/github.com/huandu/xstrings) is a collect All functions are well tested and carefully tuned for performance. -## Propose a new function ## +## Propose a new function Please review [contributing guideline](CONTRIBUTING.md) and [create new issue](https://github.com/huandu/xstrings/issues) to state why it should be included. -## Install ## +## Install Use `go get` to install this library. go get github.com/huandu/xstrings -## API document ## +## API document See [GoDoc](https://godoc.org/github.com/huandu/xstrings) for full document. -## Function list ## +## Function list Go functions have a unique naming style. One, who has experience in other language but new in Go, may have difficulties to find out right string function to use. Here is a list of functions in [strings](http://golang.org/pkg/strings) and [xstrings](https://godoc.org/github.com/huandu/xstrings) with enough extra information about how to map these functions to their friends in other languages. Hope this list could be helpful for fresh gophers. -### Package `xstrings` functions ### - -*Keep this table sorted by Function in ascending order.* - -| Function | Friends | # | -| -------- | ------- | --- | -| [Center](https://godoc.org/github.com/huandu/xstrings#Center) | `str.center` in Python; `String#center` in Ruby | [#30](https://github.com/huandu/xstrings/issues/30) | -| [Count](https://godoc.org/github.com/huandu/xstrings#Count) | `String#count` in Ruby | [#16](https://github.com/huandu/xstrings/issues/16) | -| [Delete](https://godoc.org/github.com/huandu/xstrings#Delete) | `String#delete` in Ruby | [#17](https://github.com/huandu/xstrings/issues/17) | -| [ExpandTabs](https://godoc.org/github.com/huandu/xstrings#ExpandTabs) | `str.expandtabs` in Python | [#27](https://github.com/huandu/xstrings/issues/27) | -| [FirstRuneToLower](https://godoc.org/github.com/huandu/xstrings#FirstRuneToLower) | `lcfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) | -| [FirstRuneToUpper](https://godoc.org/github.com/huandu/xstrings#FirstRuneToUpper) | `String#capitalize` in Ruby; `ucfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) | -| [Insert](https://godoc.org/github.com/huandu/xstrings#Insert) | `String#insert` in Ruby | [#18](https://github.com/huandu/xstrings/issues/18) | -| [LastPartition](https://godoc.org/github.com/huandu/xstrings#LastPartition) | `str.rpartition` in Python; `String#rpartition` in Ruby | [#19](https://github.com/huandu/xstrings/issues/19) | -| [LeftJustify](https://godoc.org/github.com/huandu/xstrings#LeftJustify) | `str.ljust` in Python; `String#ljust` in Ruby | [#28](https://github.com/huandu/xstrings/issues/28) | -| [Len](https://godoc.org/github.com/huandu/xstrings#Len) | `mb_strlen` in PHP | [#23](https://github.com/huandu/xstrings/issues/23) | -| [Partition](https://godoc.org/github.com/huandu/xstrings#Partition) | `str.partition` in Python; `String#partition` in Ruby | [#10](https://github.com/huandu/xstrings/issues/10) | -| [Reverse](https://godoc.org/github.com/huandu/xstrings#Reverse) | `String#reverse` in Ruby; `strrev` in PHP; `reverse` in Perl | [#7](https://github.com/huandu/xstrings/issues/7) | -| [RightJustify](https://godoc.org/github.com/huandu/xstrings#RightJustify) | `str.rjust` in Python; `String#rjust` in Ruby | [#29](https://github.com/huandu/xstrings/issues/29) | -| [RuneWidth](https://godoc.org/github.com/huandu/xstrings#RuneWidth) | - | [#27](https://github.com/huandu/xstrings/issues/27) | -| [Scrub](https://godoc.org/github.com/huandu/xstrings#Scrub) | `String#scrub` in Ruby | [#20](https://github.com/huandu/xstrings/issues/20) | -| [Shuffle](https://godoc.org/github.com/huandu/xstrings#Shuffle) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) | -| [ShuffleSource](https://godoc.org/github.com/huandu/xstrings#ShuffleSource) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) | -| [Slice](https://godoc.org/github.com/huandu/xstrings#Slice) | `mb_substr` in PHP | [#9](https://github.com/huandu/xstrings/issues/9) | -| [Squeeze](https://godoc.org/github.com/huandu/xstrings#Squeeze) | `String#squeeze` in Ruby | [#11](https://github.com/huandu/xstrings/issues/11) | -| [Successor](https://godoc.org/github.com/huandu/xstrings#Successor) | `String#succ` or `String#next` in Ruby | [#22](https://github.com/huandu/xstrings/issues/22) | -| [SwapCase](https://godoc.org/github.com/huandu/xstrings#SwapCase) | `str.swapcase` in Python; `String#swapcase` in Ruby | [#12](https://github.com/huandu/xstrings/issues/12) | -| [ToCamelCase](https://godoc.org/github.com/huandu/xstrings#ToCamelCase) | `String#camelize` in RoR | [#1](https://github.com/huandu/xstrings/issues/1) | -| [ToKebab](https://godoc.org/github.com/huandu/xstrings#ToKebabCase) | - | [#41](https://github.com/huandu/xstrings/issues/41) | -| [ToSnakeCase](https://godoc.org/github.com/huandu/xstrings#ToSnakeCase) | `String#underscore` in RoR | [#1](https://github.com/huandu/xstrings/issues/1) | -| [Translate](https://godoc.org/github.com/huandu/xstrings#Translate) | `str.translate` in Python; `String#tr` in Ruby; `strtr` in PHP; `tr///` in Perl | [#21](https://github.com/huandu/xstrings/issues/21) | -| [Width](https://godoc.org/github.com/huandu/xstrings#Width) | `mb_strwidth` in PHP | [#26](https://github.com/huandu/xstrings/issues/26) | -| [WordCount](https://godoc.org/github.com/huandu/xstrings#WordCount) | `str_word_count` in PHP | [#14](https://github.com/huandu/xstrings/issues/14) | -| [WordSplit](https://godoc.org/github.com/huandu/xstrings#WordSplit) | - | [#14](https://github.com/huandu/xstrings/issues/14) | - -### Package `strings` functions ### - -*Keep this table sorted by Function in ascending order.* - -| Function | Friends | -| -------- | ------- | -| [Contains](http://golang.org/pkg/strings/#Contains) | `String#include?` in Ruby | -| [ContainsAny](http://golang.org/pkg/strings/#ContainsAny) | - | -| [ContainsRune](http://golang.org/pkg/strings/#ContainsRune) | - | -| [Count](http://golang.org/pkg/strings/#Count) | `str.count` in Python; `substr_count` in PHP | -| [EqualFold](http://golang.org/pkg/strings/#EqualFold) | `stricmp` in PHP; `String#casecmp` in Ruby | -| [Fields](http://golang.org/pkg/strings/#Fields) | `str.split` in Python; `split` in Perl; `String#split` in Ruby | -| [FieldsFunc](http://golang.org/pkg/strings/#FieldsFunc) | - | -| [HasPrefix](http://golang.org/pkg/strings/#HasPrefix) | `str.startswith` in Python; `String#start_with?` in Ruby | -| [HasSuffix](http://golang.org/pkg/strings/#HasSuffix) | `str.endswith` in Python; `String#end_with?` in Ruby | -| [Index](http://golang.org/pkg/strings/#Index) | `str.index` in Python; `String#index` in Ruby; `strpos` in PHP; `index` in Perl | -| [IndexAny](http://golang.org/pkg/strings/#IndexAny) | - | -| [IndexByte](http://golang.org/pkg/strings/#IndexByte) | - | -| [IndexFunc](http://golang.org/pkg/strings/#IndexFunc) | - | -| [IndexRune](http://golang.org/pkg/strings/#IndexRune) | - | -| [Join](http://golang.org/pkg/strings/#Join) | `str.join` in Python; `Array#join` in Ruby; `implode` in PHP; `join` in Perl | -| [LastIndex](http://golang.org/pkg/strings/#LastIndex) | `str.rindex` in Python; `String#rindex`; `strrpos` in PHP; `rindex` in Perl | -| [LastIndexAny](http://golang.org/pkg/strings/#LastIndexAny) | - | -| [LastIndexFunc](http://golang.org/pkg/strings/#LastIndexFunc) | - | -| [Map](http://golang.org/pkg/strings/#Map) | `String#each_codepoint` in Ruby | -| [Repeat](http://golang.org/pkg/strings/#Repeat) | operator `*` in Python and Ruby; `str_repeat` in PHP | -| [Replace](http://golang.org/pkg/strings/#Replace) | `str.replace` in Python; `String#sub` in Ruby; `str_replace` in PHP | -| [Split](http://golang.org/pkg/strings/#Split) | `str.split` in Python; `String#split` in Ruby; `explode` in PHP; `split` in Perl | -| [SplitAfter](http://golang.org/pkg/strings/#SplitAfter) | - | -| [SplitAfterN](http://golang.org/pkg/strings/#SplitAfterN) | - | -| [SplitN](http://golang.org/pkg/strings/#SplitN) | `str.split` in Python; `String#split` in Ruby; `explode` in PHP; `split` in Perl | -| [Title](http://golang.org/pkg/strings/#Title) | `str.title` in Python | -| [ToLower](http://golang.org/pkg/strings/#ToLower) | `str.lower` in Python; `String#downcase` in Ruby; `strtolower` in PHP; `lc` in Perl | -| [ToLowerSpecial](http://golang.org/pkg/strings/#ToLowerSpecial) | - | -| [ToTitle](http://golang.org/pkg/strings/#ToTitle) | - | -| [ToTitleSpecial](http://golang.org/pkg/strings/#ToTitleSpecial) | - | -| [ToUpper](http://golang.org/pkg/strings/#ToUpper) | `str.upper` in Python; `String#upcase` in Ruby; `strtoupper` in PHP; `uc` in Perl | -| [ToUpperSpecial](http://golang.org/pkg/strings/#ToUpperSpecial) | - | -| [Trim](http://golang.org/pkg/strings/#Trim) | `str.strip` in Python; `String#strip` in Ruby; `trim` in PHP | -| [TrimFunc](http://golang.org/pkg/strings/#TrimFunc) | - | -| [TrimLeft](http://golang.org/pkg/strings/#TrimLeft) | `str.lstrip` in Python; `String#lstrip` in Ruby; `ltrim` in PHP | -| [TrimLeftFunc](http://golang.org/pkg/strings/#TrimLeftFunc) | - | -| [TrimPrefix](http://golang.org/pkg/strings/#TrimPrefix) | - | -| [TrimRight](http://golang.org/pkg/strings/#TrimRight) | `str.rstrip` in Python; `String#rstrip` in Ruby; `rtrim` in PHP | -| [TrimRightFunc](http://golang.org/pkg/strings/#TrimRightFunc) | - | -| [TrimSpace](http://golang.org/pkg/strings/#TrimSpace) | `str.strip` in Python; `String#strip` in Ruby; `trim` in PHP | -| [TrimSuffix](http://golang.org/pkg/strings/#TrimSuffix) | `String#chomp` in Ruby; `chomp` in Perl | - -## License ## +### Package `xstrings` functions + +_Keep this table sorted by Function in ascending order._ + +| Function | Friends | # | +| --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | --------------------------------------------------- | +| [Center](https://godoc.org/github.com/huandu/xstrings#Center) | `str.center` in Python; `String#center` in Ruby | [#30](https://github.com/huandu/xstrings/issues/30) | +| [Count](https://godoc.org/github.com/huandu/xstrings#Count) | `String#count` in Ruby | [#16](https://github.com/huandu/xstrings/issues/16) | +| [Delete](https://godoc.org/github.com/huandu/xstrings#Delete) | `String#delete` in Ruby | [#17](https://github.com/huandu/xstrings/issues/17) | +| [ExpandTabs](https://godoc.org/github.com/huandu/xstrings#ExpandTabs) | `str.expandtabs` in Python | [#27](https://github.com/huandu/xstrings/issues/27) | +| [FirstRuneToLower](https://godoc.org/github.com/huandu/xstrings#FirstRuneToLower) | `lcfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) | +| [FirstRuneToUpper](https://godoc.org/github.com/huandu/xstrings#FirstRuneToUpper) | `String#capitalize` in Ruby; `ucfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) | +| [Insert](https://godoc.org/github.com/huandu/xstrings#Insert) | `String#insert` in Ruby | [#18](https://github.com/huandu/xstrings/issues/18) | +| [LastPartition](https://godoc.org/github.com/huandu/xstrings#LastPartition) | `str.rpartition` in Python; `String#rpartition` in Ruby | [#19](https://github.com/huandu/xstrings/issues/19) | +| [LeftJustify](https://godoc.org/github.com/huandu/xstrings#LeftJustify) | `str.ljust` in Python; `String#ljust` in Ruby | [#28](https://github.com/huandu/xstrings/issues/28) | +| [Len](https://godoc.org/github.com/huandu/xstrings#Len) | `mb_strlen` in PHP | [#23](https://github.com/huandu/xstrings/issues/23) | +| [Partition](https://godoc.org/github.com/huandu/xstrings#Partition) | `str.partition` in Python; `String#partition` in Ruby | [#10](https://github.com/huandu/xstrings/issues/10) | +| [Reverse](https://godoc.org/github.com/huandu/xstrings#Reverse) | `String#reverse` in Ruby; `strrev` in PHP; `reverse` in Perl | [#7](https://github.com/huandu/xstrings/issues/7) | +| [RightJustify](https://godoc.org/github.com/huandu/xstrings#RightJustify) | `str.rjust` in Python; `String#rjust` in Ruby | [#29](https://github.com/huandu/xstrings/issues/29) | +| [RuneWidth](https://godoc.org/github.com/huandu/xstrings#RuneWidth) | - | [#27](https://github.com/huandu/xstrings/issues/27) | +| [Scrub](https://godoc.org/github.com/huandu/xstrings#Scrub) | `String#scrub` in Ruby | [#20](https://github.com/huandu/xstrings/issues/20) | +| [Shuffle](https://godoc.org/github.com/huandu/xstrings#Shuffle) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) | +| [ShuffleSource](https://godoc.org/github.com/huandu/xstrings#ShuffleSource) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) | +| [Slice](https://godoc.org/github.com/huandu/xstrings#Slice) | `mb_substr` in PHP | [#9](https://github.com/huandu/xstrings/issues/9) | +| [Squeeze](https://godoc.org/github.com/huandu/xstrings#Squeeze) | `String#squeeze` in Ruby | [#11](https://github.com/huandu/xstrings/issues/11) | +| [Successor](https://godoc.org/github.com/huandu/xstrings#Successor) | `String#succ` or `String#next` in Ruby | [#22](https://github.com/huandu/xstrings/issues/22) | +| [SwapCase](https://godoc.org/github.com/huandu/xstrings#SwapCase) | `str.swapcase` in Python; `String#swapcase` in Ruby | [#12](https://github.com/huandu/xstrings/issues/12) | +| [ToCamelCase](https://godoc.org/github.com/huandu/xstrings#ToCamelCase) | `String#camelize` in RoR | [#1](https://github.com/huandu/xstrings/issues/1) | +| [ToKebab](https://godoc.org/github.com/huandu/xstrings#ToKebabCase) | - | [#41](https://github.com/huandu/xstrings/issues/41) | +| [ToSnakeCase](https://godoc.org/github.com/huandu/xstrings#ToSnakeCase) | `String#underscore` in RoR | [#1](https://github.com/huandu/xstrings/issues/1) | +| [Translate](https://godoc.org/github.com/huandu/xstrings#Translate) | `str.translate` in Python; `String#tr` in Ruby; `strtr` in PHP; `tr///` in Perl | [#21](https://github.com/huandu/xstrings/issues/21) | +| [Width](https://godoc.org/github.com/huandu/xstrings#Width) | `mb_strwidth` in PHP | [#26](https://github.com/huandu/xstrings/issues/26) | +| [WordCount](https://godoc.org/github.com/huandu/xstrings#WordCount) | `str_word_count` in PHP | [#14](https://github.com/huandu/xstrings/issues/14) | +| [WordSplit](https://godoc.org/github.com/huandu/xstrings#WordSplit) | - | [#14](https://github.com/huandu/xstrings/issues/14) | + +### Package `strings` functions + +_Keep this table sorted by Function in ascending order._ + +| Function | Friends | +| --------------------------------------------------------------- | ----------------------------------------------------------------------------------- | +| [Contains](http://golang.org/pkg/strings/#Contains) | `String#include?` in Ruby | +| [ContainsAny](http://golang.org/pkg/strings/#ContainsAny) | - | +| [ContainsRune](http://golang.org/pkg/strings/#ContainsRune) | - | +| [Count](http://golang.org/pkg/strings/#Count) | `str.count` in Python; `substr_count` in PHP | +| [EqualFold](http://golang.org/pkg/strings/#EqualFold) | `stricmp` in PHP; `String#casecmp` in Ruby | +| [Fields](http://golang.org/pkg/strings/#Fields) | `str.split` in Python; `split` in Perl; `String#split` in Ruby | +| [FieldsFunc](http://golang.org/pkg/strings/#FieldsFunc) | - | +| [HasPrefix](http://golang.org/pkg/strings/#HasPrefix) | `str.startswith` in Python; `String#start_with?` in Ruby | +| [HasSuffix](http://golang.org/pkg/strings/#HasSuffix) | `str.endswith` in Python; `String#end_with?` in Ruby | +| [Index](http://golang.org/pkg/strings/#Index) | `str.index` in Python; `String#index` in Ruby; `strpos` in PHP; `index` in Perl | +| [IndexAny](http://golang.org/pkg/strings/#IndexAny) | - | +| [IndexByte](http://golang.org/pkg/strings/#IndexByte) | - | +| [IndexFunc](http://golang.org/pkg/strings/#IndexFunc) | - | +| [IndexRune](http://golang.org/pkg/strings/#IndexRune) | - | +| [Join](http://golang.org/pkg/strings/#Join) | `str.join` in Python; `Array#join` in Ruby; `implode` in PHP; `join` in Perl | +| [LastIndex](http://golang.org/pkg/strings/#LastIndex) | `str.rindex` in Python; `String#rindex`; `strrpos` in PHP; `rindex` in Perl | +| [LastIndexAny](http://golang.org/pkg/strings/#LastIndexAny) | - | +| [LastIndexFunc](http://golang.org/pkg/strings/#LastIndexFunc) | - | +| [Map](http://golang.org/pkg/strings/#Map) | `String#each_codepoint` in Ruby | +| [Repeat](http://golang.org/pkg/strings/#Repeat) | operator `*` in Python and Ruby; `str_repeat` in PHP | +| [Replace](http://golang.org/pkg/strings/#Replace) | `str.replace` in Python; `String#sub` in Ruby; `str_replace` in PHP | +| [Split](http://golang.org/pkg/strings/#Split) | `str.split` in Python; `String#split` in Ruby; `explode` in PHP; `split` in Perl | +| [SplitAfter](http://golang.org/pkg/strings/#SplitAfter) | - | +| [SplitAfterN](http://golang.org/pkg/strings/#SplitAfterN) | - | +| [SplitN](http://golang.org/pkg/strings/#SplitN) | `str.split` in Python; `String#split` in Ruby; `explode` in PHP; `split` in Perl | +| [Title](http://golang.org/pkg/strings/#Title) | `str.title` in Python | +| [ToLower](http://golang.org/pkg/strings/#ToLower) | `str.lower` in Python; `String#downcase` in Ruby; `strtolower` in PHP; `lc` in Perl | +| [ToLowerSpecial](http://golang.org/pkg/strings/#ToLowerSpecial) | - | +| [ToTitle](http://golang.org/pkg/strings/#ToTitle) | - | +| [ToTitleSpecial](http://golang.org/pkg/strings/#ToTitleSpecial) | - | +| [ToUpper](http://golang.org/pkg/strings/#ToUpper) | `str.upper` in Python; `String#upcase` in Ruby; `strtoupper` in PHP; `uc` in Perl | +| [ToUpperSpecial](http://golang.org/pkg/strings/#ToUpperSpecial) | - | +| [Trim](http://golang.org/pkg/strings/#Trim) | `str.strip` in Python; `String#strip` in Ruby; `trim` in PHP | +| [TrimFunc](http://golang.org/pkg/strings/#TrimFunc) | - | +| [TrimLeft](http://golang.org/pkg/strings/#TrimLeft) | `str.lstrip` in Python; `String#lstrip` in Ruby; `ltrim` in PHP | +| [TrimLeftFunc](http://golang.org/pkg/strings/#TrimLeftFunc) | - | +| [TrimPrefix](http://golang.org/pkg/strings/#TrimPrefix) | - | +| [TrimRight](http://golang.org/pkg/strings/#TrimRight) | `str.rstrip` in Python; `String#rstrip` in Ruby; `rtrim` in PHP | +| [TrimRightFunc](http://golang.org/pkg/strings/#TrimRightFunc) | - | +| [TrimSpace](http://golang.org/pkg/strings/#TrimSpace) | `str.strip` in Python; `String#strip` in Ruby; `trim` in PHP | +| [TrimSuffix](http://golang.org/pkg/strings/#TrimSuffix) | `String#chomp` in Ruby; `chomp` in Perl | + +## License This library is licensed under MIT license. See LICENSE for details. diff --git a/vendor/github.com/huandu/xstrings/convert.go b/vendor/github.com/huandu/xstrings/convert.go index 3d5a3495..151c3151 100644 --- a/vendor/github.com/huandu/xstrings/convert.go +++ b/vendor/github.com/huandu/xstrings/convert.go @@ -130,7 +130,7 @@ func camelCaseToLowerCase(str string, connector rune) string { wt, word, remaining = nextWord(remaining) } - if wt != invalidWord && wt != punctWord { + if wt != invalidWord && wt != punctWord && wt != connectorWord { buf.WriteRune(connector) } diff --git a/vendor/github.com/imdario/mergo/CONTRIBUTING.md b/vendor/github.com/imdario/mergo/CONTRIBUTING.md new file mode 100644 index 00000000..0a1ff9f9 --- /dev/null +++ b/vendor/github.com/imdario/mergo/CONTRIBUTING.md @@ -0,0 +1,112 @@ + +# Contributing to mergo + +First off, thanks for taking the time to contribute! ❤️ + +All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉 + +> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about: +> - Star the project +> - Tweet about it +> - Refer this project in your project's readme +> - Mention the project at local meetups and tell your friends/colleagues + + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [I Have a Question](#i-have-a-question) +- [I Want To Contribute](#i-want-to-contribute) +- [Reporting Bugs](#reporting-bugs) +- [Suggesting Enhancements](#suggesting-enhancements) + +## Code of Conduct + +This project and everyone participating in it is governed by the +[mergo Code of Conduct](https://github.com/imdario/mergoblob/master/CODE_OF_CONDUCT.md). +By participating, you are expected to uphold this code. Please report unacceptable behavior +to <>. + + +## I Have a Question + +> If you want to ask a question, we assume that you have read the available [Documentation](https://pkg.go.dev/github.com/imdario/mergo). + +Before you ask a question, it is best to search for existing [Issues](https://github.com/imdario/mergo/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. + +If you then still feel the need to ask a question and need clarification, we recommend the following: + +- Open an [Issue](https://github.com/imdario/mergo/issues/new). +- Provide as much context as you can about what you're running into. +- Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant. + +We will then take care of the issue as soon as possible. + +## I Want To Contribute + +> ### Legal Notice +> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license. + +### Reporting Bugs + + +#### Before Submitting a Bug Report + +A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible. + +- Make sure that you are using the latest version. +- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](). If you are looking for support, you might want to check [this section](#i-have-a-question)). +- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/imdario/mergoissues?q=label%3Abug). +- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue. +- Collect information about the bug: +- Stack trace (Traceback) +- OS, Platform and Version (Windows, Linux, macOS, x86, ARM) +- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant. +- Possibly your input and the output +- Can you reliably reproduce the issue? And can you also reproduce it with older versions? + + +#### How Do I Submit a Good Bug Report? + +> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to . + + +We use GitHub issues to track bugs and errors. If you run into an issue with the project: + +- Open an [Issue](https://github.com/imdario/mergo/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.) +- Explain the behavior you would expect and the actual behavior. +- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case. +- Provide the information you collected in the previous section. + +Once it's filed: + +- The project team will label the issue accordingly. +- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced. +- If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be implemented by someone. + +### Suggesting Enhancements + +This section guides you through submitting an enhancement suggestion for mergo, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. + + +#### Before Submitting an Enhancement + +- Make sure that you are using the latest version. +- Read the [documentation]() carefully and find out if the functionality is already covered, maybe by an individual configuration. +- Perform a [search](https://github.com/imdario/mergo/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. +- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library. + + +#### How Do I Submit a Good Enhancement Suggestion? + +Enhancement suggestions are tracked as [GitHub issues](https://github.com/imdario/mergo/issues). + +- Use a **clear and descriptive title** for the issue to identify the suggestion. +- Provide a **step-by-step description of the suggested enhancement** in as many details as possible. +- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you. +- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. +- **Explain why this enhancement would be useful** to most mergo users. You may also want to point out the other projects that solved it better and which could serve as inspiration. + + +## Attribution +This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)! diff --git a/vendor/github.com/imdario/mergo/README.md b/vendor/github.com/imdario/mergo/README.md index 7e6f7aee..4f028749 100644 --- a/vendor/github.com/imdario/mergo/README.md +++ b/vendor/github.com/imdario/mergo/README.md @@ -1,6 +1,5 @@ # Mergo - [![GoDoc][3]][4] [![GitHub release][5]][6] [![GoCard][7]][8] @@ -9,6 +8,7 @@ [![Sourcegraph][11]][12] [![FOSSA Status][13]][14] [![Become my sponsor][15]][16] +[![Tidelift][17]][18] [1]: https://travis-ci.org/imdario/mergo.png [2]: https://travis-ci.org/imdario/mergo @@ -26,6 +26,8 @@ [14]: https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield [15]: https://img.shields.io/github/sponsors/imdario [16]: https://github.com/sponsors/imdario +[17]: https://tidelift.com/badges/package/go/github.com%2Fimdario%2Fmergo +[18]: https://tidelift.com/subscription/pkg/go-github.com-imdario-mergo A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements. @@ -55,7 +57,6 @@ If Mergo is useful to you, consider buying me a coffee, a beer, or making a mont ### Mergo in the wild -- [cli/cli](https://github.com/cli/cli) - [moby/moby](https://github.com/moby/moby) - [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) - [vmware/dispatch](https://github.com/vmware/dispatch) diff --git a/vendor/github.com/imdario/mergo/SECURITY.md b/vendor/github.com/imdario/mergo/SECURITY.md new file mode 100644 index 00000000..a5de61f7 --- /dev/null +++ b/vendor/github.com/imdario/mergo/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 0.3.x | :white_check_mark: | +| < 0.3 | :x: | + +## Security contact information + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. diff --git a/vendor/github.com/imdario/mergo/map.go b/vendor/github.com/imdario/mergo/map.go index a13a7ee4..b50d5c2a 100644 --- a/vendor/github.com/imdario/mergo/map.go +++ b/vendor/github.com/imdario/mergo/map.go @@ -44,7 +44,7 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, conf } } // Remember, remember... - visited[h] = &visit{addr, typ, seen} + visited[h] = &visit{typ, seen, addr} } zeroValue := reflect.Value{} switch dst.Kind() { @@ -58,7 +58,7 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, conf } fieldName := field.Name fieldName = changeInitialCase(fieldName, unicode.ToLower) - if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v)) || overwrite) { + if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v), !config.ShouldNotDereference) || overwrite) { dstMap[fieldName] = src.Field(i).Interface() } } @@ -142,7 +142,7 @@ func MapWithOverwrite(dst, src interface{}, opts ...func(*Config)) error { func _map(dst, src interface{}, opts ...func(*Config)) error { if dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr { - return ErrNonPointerAgument + return ErrNonPointerArgument } var ( vDst, vSrc reflect.Value diff --git a/vendor/github.com/imdario/mergo/merge.go b/vendor/github.com/imdario/mergo/merge.go index 8b4e2f47..0ef9b213 100644 --- a/vendor/github.com/imdario/mergo/merge.go +++ b/vendor/github.com/imdario/mergo/merge.go @@ -38,10 +38,11 @@ func isExportedComponent(field *reflect.StructField) bool { } type Config struct { + Transformers Transformers Overwrite bool + ShouldNotDereference bool AppendSlice bool TypeCheck bool - Transformers Transformers overwriteWithEmptyValue bool overwriteSliceWithEmptyValue bool sliceDeepCopy bool @@ -76,7 +77,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co } } // Remember, remember... - visited[h] = &visit{addr, typ, seen} + visited[h] = &visit{typ, seen, addr} } if config.Transformers != nil && !isReflectNil(dst) && dst.IsValid() { @@ -95,7 +96,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co } } } else { - if dst.CanSet() && (isReflectNil(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) { + if dst.CanSet() && (isReflectNil(dst) || overwrite) && (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc) { dst.Set(src) } } @@ -110,7 +111,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co } if src.Kind() != reflect.Map { - if overwrite { + if overwrite && dst.CanSet() { dst.Set(src) } return @@ -162,7 +163,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co dstSlice = reflect.ValueOf(dstElement.Interface()) } - if (!isEmptyValue(src) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice && !sliceDeepCopy { + if (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) && !config.AppendSlice && !sliceDeepCopy { if typeCheck && srcSlice.Type() != dstSlice.Type() { return fmt.Errorf("cannot override two slices with different type (%s, %s)", srcSlice.Type(), dstSlice.Type()) } @@ -194,22 +195,38 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co dst.SetMapIndex(key, dstSlice) } } - if dstElement.IsValid() && !isEmptyValue(dstElement) && (reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map || reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice) { - continue + + if dstElement.IsValid() && !isEmptyValue(dstElement, !config.ShouldNotDereference) { + if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice { + continue + } + if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map && reflect.TypeOf(dstElement.Interface()).Kind() == reflect.Map { + continue + } } - if srcElement.IsValid() && ((srcElement.Kind() != reflect.Ptr && overwrite) || !dstElement.IsValid() || isEmptyValue(dstElement)) { + if srcElement.IsValid() && ((srcElement.Kind() != reflect.Ptr && overwrite) || !dstElement.IsValid() || isEmptyValue(dstElement, !config.ShouldNotDereference)) { if dst.IsNil() { dst.Set(reflect.MakeMap(dst.Type())) } dst.SetMapIndex(key, srcElement) } } + + // Ensure that all keys in dst are deleted if they are not in src. + if overwriteWithEmptySrc { + for _, key := range dst.MapKeys() { + srcElement := src.MapIndex(key) + if !srcElement.IsValid() { + dst.SetMapIndex(key, reflect.Value{}) + } + } + } case reflect.Slice: if !dst.CanSet() { break } - if (!isEmptyValue(src) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice && !sliceDeepCopy { + if (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) && !config.AppendSlice && !sliceDeepCopy { dst.Set(src) } else if config.AppendSlice { if src.Type() != dst.Type() { @@ -244,12 +261,18 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co if src.Kind() != reflect.Interface { if dst.IsNil() || (src.Kind() != reflect.Ptr && overwrite) { - if dst.CanSet() && (overwrite || isEmptyValue(dst)) { + if dst.CanSet() && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) { dst.Set(src) } } else if src.Kind() == reflect.Ptr { - if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil { - return + if !config.ShouldNotDereference { + if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil { + return + } + } else { + if overwriteWithEmptySrc || (overwrite && !src.IsNil()) || dst.IsNil() { + dst.Set(src) + } } } else if dst.Elem().Type() == src.Type() { if err = deepMerge(dst.Elem(), src, visited, depth+1, config); err != nil { @@ -262,7 +285,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co } if dst.IsNil() || overwrite { - if dst.CanSet() && (overwrite || isEmptyValue(dst)) { + if dst.CanSet() && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) { dst.Set(src) } break @@ -275,7 +298,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co break } default: - mustSet := (isEmptyValue(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) + mustSet := (isEmptyValue(dst, !config.ShouldNotDereference) || overwrite) && (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc) if mustSet { if dst.CanSet() { dst.Set(src) @@ -326,6 +349,12 @@ func WithOverrideEmptySlice(config *Config) { config.overwriteSliceWithEmptyValue = true } +// WithoutDereference prevents dereferencing pointers when evaluating whether they are empty +// (i.e. a non-nil pointer is never considered empty). +func WithoutDereference(config *Config) { + config.ShouldNotDereference = true +} + // WithAppendSlice will make merge append slices instead of overwriting it. func WithAppendSlice(config *Config) { config.AppendSlice = true @@ -344,7 +373,7 @@ func WithSliceDeepCopy(config *Config) { func merge(dst, src interface{}, opts ...func(*Config)) error { if dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr { - return ErrNonPointerAgument + return ErrNonPointerArgument } var ( vDst, vSrc reflect.Value diff --git a/vendor/github.com/imdario/mergo/mergo.go b/vendor/github.com/imdario/mergo/mergo.go index 9fe362d4..0a721e2d 100644 --- a/vendor/github.com/imdario/mergo/mergo.go +++ b/vendor/github.com/imdario/mergo/mergo.go @@ -20,7 +20,7 @@ var ( ErrNotSupported = errors.New("only structs, maps, and slices are supported") ErrExpectedMapAsDestination = errors.New("dst was expected to be a map") ErrExpectedStructAsDestination = errors.New("dst was expected to be a struct") - ErrNonPointerAgument = errors.New("dst must be a pointer") + ErrNonPointerArgument = errors.New("dst must be a pointer") ) // During deepMerge, must keep track of checks that are @@ -28,13 +28,13 @@ var ( // checks in progress are true when it reencounters them. // Visited are stored in a map indexed by 17 * a1 + a2; type visit struct { - ptr uintptr typ reflect.Type next *visit + ptr uintptr } // From src/pkg/encoding/json/encode.go. -func isEmptyValue(v reflect.Value) bool { +func isEmptyValue(v reflect.Value, shouldDereference bool) bool { switch v.Kind() { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: return v.Len() == 0 @@ -50,7 +50,10 @@ func isEmptyValue(v reflect.Value) bool { if v.IsNil() { return true } - return isEmptyValue(v.Elem()) + if shouldDereference { + return isEmptyValue(v.Elem(), shouldDereference) + } + return false case reflect.Func: return v.IsNil() case reflect.Invalid: diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go index d569c0c9..d0ea68f4 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go +++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go @@ -1,6 +1,7 @@ -//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine +//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine && !tinygo // +build darwin freebsd openbsd netbsd dragonfly hurd // +build !appengine +// +build !tinygo package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go index 31503226..7402e061 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_others.go +++ b/vendor/github.com/mattn/go-isatty/isatty_others.go @@ -1,5 +1,6 @@ -//go:build appengine || js || nacl || wasm -// +build appengine js nacl wasm +//go:build (appengine || js || nacl || tinygo || wasm) && !windows +// +build appengine js nacl tinygo wasm +// +build !windows package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go index 67787657..0337d8cf 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go +++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go @@ -1,6 +1,7 @@ -//go:build (linux || aix || zos) && !appengine +//go:build (linux || aix || zos) && !appengine && !tinygo // +build linux aix zos // +build !appengine +// +build !tinygo package isatty diff --git a/vendor/github.com/vmihailenco/msgpack/v5/CHANGELOG.md b/vendor/github.com/vmihailenco/msgpack/v5/CHANGELOG.md index f6b19d5b..d45441e6 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/CHANGELOG.md +++ b/vendor/github.com/vmihailenco/msgpack/v5/CHANGELOG.md @@ -1,6 +1,30 @@ -## [5.3.5](https://github.com/vmihailenco/msgpack/compare/v5.3.4...v5.3.5) (2021-10-22) +## [5.4.1](https://github.com/vmihailenco/msgpack/compare/v5.4.0...v5.4.1) (2023-10-26) + + +### Bug Fixes + +* **reflect:** not assignable to type ([edeaedd](https://github.com/vmihailenco/msgpack/commit/edeaeddb2d51868df8c6ff2d8a218b527aeaf5fd)) + + + +# [5.4.0](https://github.com/vmihailenco/msgpack/compare/v5.3.6...v5.4.0) (2023-10-01) + +## [5.3.6](https://github.com/vmihailenco/msgpack/compare/v5.3.5...v5.3.6) (2023-10-01) + + +### Features + +* allow overwriting time.Time parsing from extID 13 (for NodeJS Date) ([9a6b73b](https://github.com/vmihailenco/msgpack/commit/9a6b73b3588fd962d568715f4375e24b089f7066)) +* apply omitEmptyFlag to empty structs ([e5f8d03](https://github.com/vmihailenco/msgpack/commit/e5f8d03c0a1dd9cc571d648cd610305139078de5)) +* support sorted keys for map[string]bool ([690c1fa](https://github.com/vmihailenco/msgpack/commit/690c1fab9814fab4842295ea986111f49850d9a4)) + + + +## [5.3.5](https://github.com/vmihailenco/msgpack/compare/v5.3.4...v5.3.5) (2021-10-22) + +- Allow decoding `nil` code as boolean false. ## v5 diff --git a/vendor/github.com/vmihailenco/msgpack/v5/README.md b/vendor/github.com/vmihailenco/msgpack/v5/README.md index 66ad98b9..038464f1 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/README.md +++ b/vendor/github.com/vmihailenco/msgpack/v5/README.md @@ -5,19 +5,18 @@ [![Documentation](https://img.shields.io/badge/msgpack-documentation-informational)](https://msgpack.uptrace.dev/) [![Chat](https://discordapp.com/api/guilds/752070105847955518/widget.png)](https://discord.gg/rWtp5Aj) -> :heart: -> [**Uptrace.dev** - All-in-one tool to optimize performance and monitor errors & logs](https://uptrace.dev/?utm_source=gh-msgpack&utm_campaign=gh-msgpack-var2) +> msgpack is brought to you by :star: [**uptrace/uptrace**](https://github.com/uptrace/uptrace). +> Uptrace is an [open source APM](https://uptrace.dev/get/open-source-apm.html) and blazingly fast +> [distributed tracing tool](https://get.uptrace.dev/compare/distributed-tracing-tools.html) powered +> by OpenTelemetry and ClickHouse. Give it a star as well! + +## Resources -- Join [Discord](https://discord.gg/rWtp5Aj) to ask questions. - [Documentation](https://msgpack.uptrace.dev) +- [Chat](https://discord.gg/rWtp5Aj) - [Reference](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5) - [Examples](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#pkg-examples) -Other projects you may like: - -- [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, MySQL, and SQLite. -- [BunRouter](https://bunrouter.uptrace.dev/) - fast and flexible HTTP router for Go. - ## Features - Primitives, arrays, maps, structs, time.Time and interface{}. @@ -84,3 +83,18 @@ func ExampleMarshal() { // Output: bar } ``` + +## See also + +- [Golang ORM](https://github.com/uptrace/bun) for PostgreSQL, MySQL, MSSQL, and SQLite +- [Golang PostgreSQL](https://bun.uptrace.dev/postgres/) +- [Golang HTTP router](https://github.com/uptrace/bunrouter) +- [Golang ClickHouse ORM](https://github.com/uptrace/go-clickhouse) + +## Contributors + +Thanks to all the people who already contributed! + + + + diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode.go b/vendor/github.com/vmihailenco/msgpack/v5/decode.go index 5df40e5d..ea645aad 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/decode.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode.go @@ -14,14 +14,16 @@ import ( ) const ( - looseInterfaceDecodingFlag uint32 = 1 << iota - disallowUnknownFieldsFlag + bytesAllocLimit = 1 << 20 // 1mb + sliceAllocLimit = 1e6 // 1m elements + maxMapSize = 1e6 // 1m elements ) const ( - bytesAllocLimit = 1e6 // 1mb - sliceAllocLimit = 1e4 - maxMapSize = 1e6 + looseInterfaceDecodingFlag uint32 = 1 << iota + disallowUnknownFieldsFlag + usePreallocateValues + disableAllocLimitFlag ) type bufReader interface { @@ -53,7 +55,7 @@ func PutDecoder(dec *Decoder) { // in the value pointed to by v. func Unmarshal(data []byte, v interface{}) error { dec := GetDecoder() - + dec.UsePreallocateValues(true) dec.Reset(bytes.NewReader(data)) err := dec.Decode(v) @@ -64,16 +66,14 @@ func Unmarshal(data []byte, v interface{}) error { // A Decoder reads and decodes MessagePack values from an input stream. type Decoder struct { - r io.Reader - s io.ByteScanner - buf []byte - - rec []byte // accumulates read data if not nil - + r io.Reader + s io.ByteScanner + mapDecoder func(*Decoder) (interface{}, error) + structTag string + buf []byte + rec []byte dict []string flags uint32 - structTag string - mapDecoder func(*Decoder) (interface{}, error) } // NewDecoder returns a new decoder that reads from r. @@ -95,10 +95,9 @@ func (d *Decoder) Reset(r io.Reader) { // ResetDict is like Reset, but also resets the dict. func (d *Decoder) ResetDict(r io.Reader, dict []string) { - d.resetReader(r) + d.ResetReader(r) d.flags = 0 d.structTag = "" - d.mapDecoder = nil d.dict = dict } @@ -110,10 +109,16 @@ func (d *Decoder) WithDict(dict []string, fn func(*Decoder) error) error { return err } -func (d *Decoder) resetReader(r io.Reader) { +func (d *Decoder) ResetReader(r io.Reader) { + d.mapDecoder = nil + d.dict = nil + if br, ok := r.(bufReader); ok { d.r = br d.s = br + } else if r == nil { + d.r = nil + d.s = nil } else { br := bufio.NewReader(r) d.r = br @@ -161,6 +166,24 @@ func (d *Decoder) UseInternedStrings(on bool) { } } +// UsePreallocateValues enables preallocating values in chunks +func (d *Decoder) UsePreallocateValues(on bool) { + if on { + d.flags |= usePreallocateValues + } else { + d.flags &= ^usePreallocateValues + } +} + +// DisableAllocLimit enables fully allocating slices/maps when the size is known +func (d *Decoder) DisableAllocLimit(on bool) { + if on { + d.flags |= disableAllocLimitFlag + } else { + d.flags &= ^disableAllocLimitFlag + } +} + // Buffered returns a reader of the data remaining in the Decoder's buffer. // The reader is valid until the next call to Decode. func (d *Decoder) Buffered() io.Reader { @@ -603,7 +626,11 @@ func (d *Decoder) readFull(b []byte) error { func (d *Decoder) readN(n int) ([]byte, error) { var err error - d.buf, err = readN(d.r, d.buf, n) + if d.flags&disableAllocLimitFlag != 0 { + d.buf, err = readN(d.r, d.buf, n) + } else { + d.buf, err = readNGrow(d.r, d.buf, n) + } if err != nil { return nil, err } @@ -615,6 +642,24 @@ func (d *Decoder) readN(n int) ([]byte, error) { } func readN(r io.Reader, b []byte, n int) ([]byte, error) { + if b == nil { + if n == 0 { + return make([]byte, 0), nil + } + b = make([]byte, 0, n) + } + + if n > cap(b) { + b = append(b, make([]byte, n-len(b))...) + } else if n <= cap(b) { + b = b[:n] + } + + _, err := io.ReadFull(r, b) + return b, err +} + +func readNGrow(r io.Reader, b []byte, n int) ([]byte, error) { if b == nil { if n == 0 { return make([]byte, 0), nil diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode_map.go b/vendor/github.com/vmihailenco/msgpack/v5/decode_map.go index 52e0526c..c54dae37 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/decode_map.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode_map.go @@ -13,6 +13,8 @@ var errArrayStruct = errors.New("msgpack: number of fields in array-encoded stru var ( mapStringStringPtrType = reflect.TypeOf((*map[string]string)(nil)) mapStringStringType = mapStringStringPtrType.Elem() + mapStringBoolPtrType = reflect.TypeOf((*map[string]bool)(nil)) + mapStringBoolType = mapStringBoolPtrType.Elem() ) var ( @@ -33,7 +35,11 @@ func decodeMapValue(d *Decoder, v reflect.Value) error { } if v.IsNil() { - v.Set(reflect.MakeMap(typ)) + ln := n + if d.flags&disableAllocLimitFlag == 0 { + ln = min(ln, maxMapSize) + } + v.Set(reflect.MakeMapWithSize(typ, ln)) } if n == 0 { return nil @@ -104,7 +110,11 @@ func (d *Decoder) decodeMapStringStringPtr(ptr *map[string]string) error { m := *ptr if m == nil { - *ptr = make(map[string]string, min(size, maxMapSize)) + ln := size + if d.flags&disableAllocLimitFlag == 0 { + ln = min(size, maxMapSize) + } + *ptr = make(map[string]string, ln) m = *ptr } @@ -147,7 +157,7 @@ func (d *Decoder) DecodeMap() (map[string]interface{}, error) { return nil, nil } - m := make(map[string]interface{}, min(n, maxMapSize)) + m := make(map[string]interface{}, n) for i := 0; i < n; i++ { mk, err := d.DecodeString() @@ -174,7 +184,7 @@ func (d *Decoder) DecodeUntypedMap() (map[interface{}]interface{}, error) { return nil, nil } - m := make(map[interface{}]interface{}, min(n, maxMapSize)) + m := make(map[interface{}]interface{}, n) for i := 0; i < n; i++ { mk, err := d.decodeInterfaceCond() @@ -222,7 +232,13 @@ func (d *Decoder) DecodeTypedMap() (interface{}, error) { } mapType := reflect.MapOf(keyType, valueType) - mapValue := reflect.MakeMap(mapType) + + ln := n + if d.flags&disableAllocLimitFlag == 0 { + ln = min(ln, maxMapSize) + } + + mapValue := reflect.MakeMapWithSize(mapType, ln) mapValue.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(value)) n-- @@ -234,17 +250,18 @@ func (d *Decoder) DecodeTypedMap() (interface{}, error) { } func (d *Decoder) decodeTypedMapValue(v reflect.Value, n int) error { - typ := v.Type() - keyType := typ.Key() - valueType := typ.Elem() - + var ( + typ = v.Type() + keyType = typ.Key() + valueType = typ.Elem() + ) for i := 0; i < n; i++ { - mk := reflect.New(keyType).Elem() + mk := d.newValue(keyType).Elem() if err := d.DecodeValue(mk); err != nil { return err } - mv := reflect.New(valueType).Elem() + mv := d.newValue(valueType).Elem() if err := d.DecodeValue(mv); err != nil { return err } diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode_query.go b/vendor/github.com/vmihailenco/msgpack/v5/decode_query.go index c302ed1f..4dce0fe5 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/decode_query.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode_query.go @@ -11,9 +11,8 @@ import ( type queryResult struct { query string key string + values []interface{} hasAsterisk bool - - values []interface{} } func (q *queryResult) nextKey() { diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode_slice.go b/vendor/github.com/vmihailenco/msgpack/v5/decode_slice.go index db6f7c54..9c155f2b 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/decode_slice.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode_slice.go @@ -49,7 +49,7 @@ func (d *Decoder) decodeStringSlicePtr(ptr *[]string) error { return nil } - ss := makeStrings(*ptr, n) + ss := makeStrings(*ptr, n, d.flags&disableAllocLimitFlag != 0) for i := 0; i < n; i++ { s, err := d.DecodeString() if err != nil { @@ -62,8 +62,8 @@ func (d *Decoder) decodeStringSlicePtr(ptr *[]string) error { return nil } -func makeStrings(s []string, n int) []string { - if n > sliceAllocLimit { +func makeStrings(s []string, n int, noLimit bool) []string { + if !noLimit && n > sliceAllocLimit { n = sliceAllocLimit } @@ -101,10 +101,17 @@ func decodeSliceValue(d *Decoder, v reflect.Value) error { v.Set(v.Slice(0, v.Cap())) } + noLimit := d.flags&disableAllocLimitFlag != 1 + + if noLimit && n > v.Len() { + v.Set(growSliceValue(v, n, noLimit)) + } + for i := 0; i < n; i++ { - if i >= v.Len() { - v.Set(growSliceValue(v, n)) + if !noLimit && i >= v.Len() { + v.Set(growSliceValue(v, n, noLimit)) } + elem := v.Index(i) if err := d.DecodeValue(elem); err != nil { return err @@ -114,9 +121,9 @@ func decodeSliceValue(d *Decoder, v reflect.Value) error { return nil } -func growSliceValue(v reflect.Value, n int) reflect.Value { +func growSliceValue(v reflect.Value, n int, noLimit bool) reflect.Value { diff := n - v.Len() - if diff > sliceAllocLimit { + if !noLimit && diff > sliceAllocLimit { diff = sliceAllocLimit } v = reflect.AppendSlice(v, reflect.MakeSlice(v.Type(), diff, diff)) @@ -163,7 +170,7 @@ func (d *Decoder) decodeSlice(c byte) ([]interface{}, error) { return nil, nil } - s := make([]interface{}, 0, min(n, sliceAllocLimit)) + s := make([]interface{}, 0, n) for i := 0; i < n; i++ { v, err := d.decodeInterfaceCond() if err != nil { diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode_typgen.go b/vendor/github.com/vmihailenco/msgpack/v5/decode_typgen.go new file mode 100644 index 00000000..0b4c1d04 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode_typgen.go @@ -0,0 +1,46 @@ +package msgpack + +import ( + "reflect" + "sync" +) + +var cachedValues struct { + m map[reflect.Type]chan reflect.Value + sync.RWMutex +} + +func cachedValue(t reflect.Type) reflect.Value { + cachedValues.RLock() + ch := cachedValues.m[t] + cachedValues.RUnlock() + if ch != nil { + return <-ch + } + + cachedValues.Lock() + defer cachedValues.Unlock() + if ch = cachedValues.m[t]; ch != nil { + return <-ch + } + + ch = make(chan reflect.Value, 256) + go func() { + for { + ch <- reflect.New(t) + } + }() + if cachedValues.m == nil { + cachedValues.m = make(map[reflect.Type]chan reflect.Value, 8) + } + cachedValues.m[t] = ch + return <-ch +} + +func (d *Decoder) newValue(t reflect.Type) reflect.Value { + if d.flags&usePreallocateValues == 0 { + return reflect.New(t) + } + + return cachedValue(t) +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode_value.go b/vendor/github.com/vmihailenco/msgpack/v5/decode_value.go index d2ff2aea..c44a674e 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/decode_value.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode_value.go @@ -10,6 +10,7 @@ import ( var ( interfaceType = reflect.TypeOf((*interface{})(nil)).Elem() stringType = reflect.TypeOf((*string)(nil)).Elem() + boolType = reflect.TypeOf((*bool)(nil)).Elem() ) var valueDecoders []decoderFunc @@ -127,12 +128,12 @@ func ptrValueDecoder(typ reflect.Type) decoderFunc { return func(d *Decoder, v reflect.Value) error { if d.hasNilCode() { if !v.IsNil() { - v.Set(reflect.Zero(v.Type())) + v.Set(d.newValue(typ).Elem()) } return d.DecodeNil() } if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) + v.Set(d.newValue(typ.Elem())) } return decoder(d, v.Elem()) } @@ -154,7 +155,7 @@ func nilAwareDecoder(typ reflect.Type, fn decoderFunc) decoderFunc { return d.decodeNilValue(v) } if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) + v.Set(d.newValue(typ.Elem())) } return fn(d, v) } diff --git a/vendor/github.com/vmihailenco/msgpack/v5/encode.go b/vendor/github.com/vmihailenco/msgpack/v5/encode.go index 0ef6212e..135adc8f 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/encode.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/encode.go @@ -75,15 +75,12 @@ func Marshal(v interface{}) ([]byte, error) { } type Encoder struct { - w writer - - buf []byte - timeBuf []byte - - dict map[string]int - - flags uint32 + w writer + dict map[string]int structTag string + buf []byte + timeBuf []byte + flags uint32 } // NewEncoder returns a new encoder that writes to w. @@ -107,7 +104,7 @@ func (e *Encoder) Reset(w io.Writer) { // ResetDict is like Reset, but also resets the dict. func (e *Encoder) ResetDict(w io.Writer, dict map[string]int) { - e.resetWriter(w) + e.ResetWriter(w) e.flags = 0 e.structTag = "" e.dict = dict @@ -121,9 +118,12 @@ func (e *Encoder) WithDict(dict map[string]int, fn func(*Encoder) error) error { return err } -func (e *Encoder) resetWriter(w io.Writer) { +func (e *Encoder) ResetWriter(w io.Writer) { + e.dict = nil if bw, ok := w.(writer); ok { e.w = bw + } else if w == nil { + e.w = nil } else { e.w = newByteWriter(w) } @@ -132,6 +132,7 @@ func (e *Encoder) resetWriter(w io.Writer) { // SetSortMapKeys causes the Encoder to encode map keys in increasing order. // Supported map types are: // - map[string]string +// - map[string]bool // - map[string]interface{} func (e *Encoder) SetSortMapKeys(on bool) *Encoder { if on { diff --git a/vendor/github.com/vmihailenco/msgpack/v5/encode_map.go b/vendor/github.com/vmihailenco/msgpack/v5/encode_map.go index ba4c61be..a5aa31bb 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/encode_map.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/encode_map.go @@ -30,6 +30,32 @@ func encodeMapValue(e *Encoder, v reflect.Value) error { return nil } +func encodeMapStringBoolValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + + if err := e.EncodeMapLen(v.Len()); err != nil { + return err + } + + m := v.Convert(mapStringBoolType).Interface().(map[string]bool) + if e.flags&sortMapKeysFlag != 0 { + return e.encodeSortedMapStringBool(m) + } + + for mk, mv := range m { + if err := e.EncodeString(mk); err != nil { + return err + } + if err := e.EncodeBool(mv); err != nil { + return err + } + } + + return nil +} + func encodeMapStringStringValue(e *Encoder, v reflect.Value) error { if v.IsNil() { return e.EncodeNil() @@ -113,6 +139,26 @@ func (e *Encoder) EncodeMapSorted(m map[string]interface{}) error { return nil } +func (e *Encoder) encodeSortedMapStringBool(m map[string]bool) error { + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, k := range keys { + err := e.EncodeString(k) + if err != nil { + return err + } + if err = e.EncodeBool(m[k]); err != nil { + return err + } + } + + return nil +} + func (e *Encoder) encodeSortedMapStringString(m map[string]string) error { keys := make([]string, 0, len(m)) for k := range m { @@ -148,7 +194,7 @@ func encodeStructValue(e *Encoder, strct reflect.Value) error { if e.flags&arrayEncodedStructsFlag != 0 || structFields.AsArray { return encodeStructValueAsArray(e, strct, structFields.List) } - fields := structFields.OmitEmpty(strct, e.flags&omitEmptyFlag != 0) + fields := structFields.OmitEmpty(e, strct) if err := e.EncodeMapLen(len(fields)); err != nil { return err diff --git a/vendor/github.com/vmihailenco/msgpack/v5/encode_value.go b/vendor/github.com/vmihailenco/msgpack/v5/encode_value.go index 48cf489f..1d6303a2 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/encode_value.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/encode_value.go @@ -111,6 +111,8 @@ func _getEncoder(typ reflect.Type) encoderFunc { switch typ.Elem() { case stringType: return encodeMapStringStringValue + case boolType: + return encodeMapStringBoolValue case interfaceType: return encodeMapStringInterfaceValue } @@ -198,6 +200,13 @@ func nilable(kind reflect.Kind) bool { return false } +func nilableType(t reflect.Type) bool { + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return nilable(t.Kind()) +} + //------------------------------------------------------------------------------ func marshalBinaryValueAddr(e *Encoder, v reflect.Value) error { diff --git a/vendor/github.com/vmihailenco/msgpack/v5/ext.go b/vendor/github.com/vmihailenco/msgpack/v5/ext.go index 76e11603..354b9d92 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/ext.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/ext.go @@ -96,7 +96,7 @@ func makeExtEncoder( func makeExtEncoderAddr(extEncoder encoderFunc) encoderFunc { return func(e *Encoder, v reflect.Value) error { if !v.CanAddr() { - return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface()) + return fmt.Errorf("msgpack: EncodeExt(nonaddressable %T)", v.Interface()) } return extEncoder(e, v.Addr()) } @@ -157,7 +157,7 @@ func makeExtDecoder( func makeExtDecoderAddr(extDecoder decoderFunc) decoderFunc { return func(d *Decoder, v reflect.Value) error { if !v.CanAddr() { - return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface()) + return fmt.Errorf("msgpack: DecodeExt(nonaddressable %T)", v.Interface()) } return extDecoder(d, v.Addr()) } @@ -254,9 +254,9 @@ func (d *Decoder) decodeInterfaceExt(c byte) (interface{}, error) { return nil, fmt.Errorf("msgpack: unknown ext id=%d", extID) } - v := reflect.New(info.Type).Elem() + v := d.newValue(info.Type).Elem() if nilable(v.Kind()) && v.IsNil() { - v.Set(reflect.New(info.Type.Elem())) + v.Set(d.newValue(info.Type.Elem())) } if err := info.Decoder(d, v, extLen); err != nil { diff --git a/vendor/github.com/vmihailenco/msgpack/v5/intern.go b/vendor/github.com/vmihailenco/msgpack/v5/intern.go index be0316a8..7f019aaa 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/intern.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/intern.go @@ -57,18 +57,16 @@ func encodeInternedStringValue(e *Encoder, v reflect.Value) error { func (e *Encoder) encodeInternedString(s string, intern bool) error { // Interned string takes at least 3 bytes. Plain string 1 byte + string len. - if len(s) >= minInternedStringLen { - if idx, ok := e.dict[s]; ok { - return e.encodeInternedStringIndex(idx) - } + if idx, ok := e.dict[s]; ok { + return e.encodeInternedStringIndex(idx) + } - if intern && len(e.dict) < maxDictLen { - if e.dict == nil { - e.dict = make(map[string]int) - } - idx := len(e.dict) - e.dict[s] = idx + if intern && len(s) >= minInternedStringLen && len(e.dict) < maxDictLen { + if e.dict == nil { + e.dict = make(map[string]int) } + idx := len(e.dict) + e.dict[s] = idx } return e.encodeNormalString(s) diff --git a/vendor/github.com/vmihailenco/msgpack/v5/msgpack.go b/vendor/github.com/vmihailenco/msgpack/v5/msgpack.go index 4db2fa2c..4fa000b8 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/msgpack.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/msgpack.go @@ -43,8 +43,8 @@ func (m *RawMessage) DecodeMsgpack(dec *Decoder) error { //------------------------------------------------------------------------------ type unexpectedCodeError struct { - code byte hint string + code byte } func (err unexpectedCodeError) Error() string { diff --git a/vendor/github.com/vmihailenco/msgpack/v5/package.json b/vendor/github.com/vmihailenco/msgpack/v5/package.json index 298910d4..921f8eab 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/package.json +++ b/vendor/github.com/vmihailenco/msgpack/v5/package.json @@ -1,4 +1,4 @@ { "name": "msgpack", - "version": "5.3.5" + "version": "5.4.1" } diff --git a/vendor/github.com/vmihailenco/msgpack/v5/time.go b/vendor/github.com/vmihailenco/msgpack/v5/time.go index 44566ec0..1a4ba126 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/time.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/time.go @@ -26,6 +26,11 @@ func timeDecoder(d *Decoder, v reflect.Value, extLen int) error { return err } + if tm.IsZero() { + // Zero time does not have timezone information. + tm = tm.UTC() + } + ptr := v.Addr().Interface().(*time.Time) *ptr = tm @@ -103,7 +108,8 @@ func (d *Decoder) DecodeTime() (time.Time, error) { return time.Time{}, err } - if extID != timeExtID { + // NodeJS seems to use extID 13. + if extID != timeExtID && extID != 13 { return time.Time{}, fmt.Errorf("msgpack: invalid time ext id=%d", extID) } diff --git a/vendor/github.com/vmihailenco/msgpack/v5/types.go b/vendor/github.com/vmihailenco/msgpack/v5/types.go index 69aca611..d212e098 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/types.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/types.go @@ -66,8 +66,8 @@ type structCache struct { } type structCacheKey struct { - tag string typ reflect.Type + tag string } func newStructCache() *structCache { @@ -90,19 +90,20 @@ func (m *structCache) Fields(typ reflect.Type, tag string) *fields { //------------------------------------------------------------------------------ type field struct { + encoder encoderFunc + decoder decoderFunc name string index []int omitEmpty bool - encoder encoderFunc - decoder decoderFunc } -func (f *field) Omit(strct reflect.Value, forced bool) bool { +func (f *field) Omit(e *Encoder, strct reflect.Value) bool { v, ok := fieldByIndex(strct, f.index) if !ok { return true } - return (f.omitEmpty || forced) && isEmptyValue(v) + forced := e.flags&omitEmptyFlag != 0 + return (f.omitEmpty || forced) && e.isEmptyValue(v) } func (f *field) EncodeValue(e *Encoder, strct reflect.Value) error { @@ -152,7 +153,8 @@ func (fs *fields) warnIfFieldExists(name string) { } } -func (fs *fields) OmitEmpty(strct reflect.Value, forced bool) []*field { +func (fs *fields) OmitEmpty(e *Encoder, strct reflect.Value) []*field { + forced := e.flags&omitEmptyFlag != 0 if !fs.hasOmitEmpty && !forced { return fs.List } @@ -160,7 +162,7 @@ func (fs *fields) OmitEmpty(strct reflect.Value, forced bool) []*field { fields := make([]*field, 0, len(fs.List)) for _, f := range fs.List { - if !f.Omit(strct, forced) { + if !f.Omit(e, strct) { fields = append(fields, f) } } @@ -317,7 +319,7 @@ type isZeroer interface { IsZero() bool } -func isEmptyValue(v reflect.Value) bool { +func (e *Encoder) isEmptyValue(v reflect.Value) bool { kind := v.Kind() for kind == reflect.Interface { @@ -335,6 +337,10 @@ func isEmptyValue(v reflect.Value) bool { switch kind { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: return v.Len() == 0 + case reflect.Struct: + structFields := structs.Fields(v.Type(), e.structTag) + fields := structFields.OmitEmpty(e, v) + return len(fields) == 0 case reflect.Bool: return !v.Bool() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: @@ -399,7 +405,7 @@ func indirectNil(v reflect.Value) (reflect.Value, bool) { if elemType.Kind() != reflect.Struct { return v, false } - v.Set(reflect.New(elemType)) + v.Set(cachedValue(elemType)) } v = v.Elem() } diff --git a/vendor/github.com/vmihailenco/msgpack/v5/version.go b/vendor/github.com/vmihailenco/msgpack/v5/version.go index 1d49337c..ca10205f 100644 --- a/vendor/github.com/vmihailenco/msgpack/v5/version.go +++ b/vendor/github.com/vmihailenco/msgpack/v5/version.go @@ -2,5 +2,5 @@ package msgpack // Version is the current release version. func Version() string { - return "5.3.5" + return "5.4.1" } diff --git a/vendor/github.com/zclconf/go-cty/cty/convert/conversion_dynamic.go b/vendor/github.com/zclconf/go-cty/cty/convert/conversion_dynamic.go index 3b554e01..95f3925b 100644 --- a/vendor/github.com/zclconf/go-cty/cty/convert/conversion_dynamic.go +++ b/vendor/github.com/zclconf/go-cty/cty/convert/conversion_dynamic.go @@ -40,6 +40,11 @@ func dynamicPassthrough(in cty.Value, path cty.Path) (cty.Value, error) { // perspective, and will panic if it finds that they are not. For example if // in is an object and out is a map, this function will still attempt to iterate // through both as if they were the same. +// While the outermost in and out types may be compatible from a Convert +// perspective, inner types may not match when converting between maps and +// objects with optional attributes when the optional attributes don't match +// the map element type. Therefor in the case of a non-primitive type mismatch, +// we have to assume conversion was possible and pass the out type through. func dynamicReplace(in, out cty.Type) cty.Type { if in == cty.DynamicPseudoType || in == cty.NilType { // Short circuit this case, there's no point worrying about this if in @@ -56,11 +61,9 @@ func dynamicReplace(in, out cty.Type) cty.Type { // return it unchanged. return out case out.IsMapType(): - var elemType cty.Type - // Maps are compatible with other maps or objects. if in.IsMapType() { - elemType = dynamicReplace(in.ElementType(), out.ElementType()) + return cty.Map(dynamicReplace(in.ElementType(), out.ElementType())) } if in.IsObjectType() { @@ -69,10 +72,10 @@ func dynamicReplace(in, out cty.Type) cty.Type { types = append(types, t) } unifiedType, _ := unify(types, true) - elemType = dynamicReplace(unifiedType, out.ElementType()) + return cty.Map(dynamicReplace(unifiedType, out.ElementType())) } - return cty.Map(elemType) + return out case out.IsObjectType(): // Objects are compatible with other objects and maps. outTypes := map[string]cty.Type{} @@ -97,33 +100,29 @@ func dynamicReplace(in, out cty.Type) cty.Type { return cty.Object(outTypes) case out.IsSetType(): - var elemType cty.Type - // Sets are compatible with other sets, lists, tuples. if in.IsSetType() || in.IsListType() { - elemType = dynamicReplace(in.ElementType(), out.ElementType()) + return cty.Set(dynamicReplace(in.ElementType(), out.ElementType())) } if in.IsTupleType() { unifiedType, _ := unify(in.TupleElementTypes(), true) - elemType = dynamicReplace(unifiedType, out.ElementType()) + return cty.Set(dynamicReplace(unifiedType, out.ElementType())) } - return cty.Set(elemType) + return out case out.IsListType(): - var elemType cty.Type - // Lists are compatible with other lists, sets, and tuples. if in.IsSetType() || in.IsListType() { - elemType = dynamicReplace(in.ElementType(), out.ElementType()) + return cty.List(dynamicReplace(in.ElementType(), out.ElementType())) } if in.IsTupleType() { unifiedType, _ := unify(in.TupleElementTypes(), true) - elemType = dynamicReplace(unifiedType, out.ElementType()) + return cty.List(dynamicReplace(unifiedType, out.ElementType())) } - return cty.List(elemType) + return out case out.IsTupleType(): // Tuples are only compatible with other tuples var types []cty.Type diff --git a/vendor/github.com/zclconf/go-cty/cty/ctystrings/prefix.go b/vendor/github.com/zclconf/go-cty/cty/ctystrings/prefix.go index 1d9f5c5a..bbf04523 100644 --- a/vendor/github.com/zclconf/go-cty/cty/ctystrings/prefix.go +++ b/vendor/github.com/zclconf/go-cty/cty/ctystrings/prefix.go @@ -4,7 +4,7 @@ import ( "fmt" "unicode/utf8" - "github.com/apparentlymart/go-textseg/v13/textseg" + "github.com/apparentlymart/go-textseg/v15/textseg" "golang.org/x/text/unicode/norm" ) @@ -26,10 +26,6 @@ import ( // application can guarantee that the remainder of the string will not begin // with combining marks then it is safe to instead just normalize the prefix // string with [Normalize]. -// -// Note that this function only takes into account normalization boundaries -// and does _not_ take into account grapheme cluster boundaries as defined -// by Unicode Standard Annex #29. func SafeKnownPrefix(prefix string) string { prefix = Normalize(prefix) diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go index 1816bb9c..25df19b0 100644 --- a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go +++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go @@ -1506,8 +1506,8 @@ func Keys(inputMap cty.Value) (cty.Value, error) { } // Lookup performs a dynamic lookup into a map. -// There are two required arguments, map and key, plus an optional default, -// which is a value to return if no key is found in map. +// There are three required arguments, inputMap and key, plus a defaultValue, +// which is a value to return if the given key is not found in the inputMap. func Lookup(inputMap, key, defaultValue cty.Value) (cty.Value, error) { return LookupFunc.Call([]cty.Value{inputMap, key, defaultValue}) } diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/conversion.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/conversion.go index 5d06a451..406dea23 100644 --- a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/conversion.go +++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/conversion.go @@ -30,8 +30,9 @@ func MakeToFunc(wantTy cty.Type) function.Function { // messages to be more appropriate for an explicit type // conversion, whereas the cty function system produces // messages aimed at _implicit_ type conversions. - Type: cty.DynamicPseudoType, - AllowNull: true, + Type: cty.DynamicPseudoType, + AllowNull: true, + AllowDynamicType: true, }, }, Type: func(args []cty.Value) (cty.Type, error) { diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format.go index d04a5eec..2339cc33 100644 --- a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format.go +++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format.go @@ -6,7 +6,7 @@ import ( "math/big" "strings" - "github.com/apparentlymart/go-textseg/v13/textseg" + "github.com/apparentlymart/go-textseg/v15/textseg" "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/convert" diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/string.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/string.go index 57ebce1b..f79bf98d 100644 --- a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/string.go +++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/string.go @@ -6,7 +6,7 @@ import ( "sort" "strings" - "github.com/apparentlymart/go-textseg/v13/textseg" + "github.com/apparentlymart/go-textseg/v15/textseg" "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/function" diff --git a/vendor/github.com/zclconf/go-cty/cty/json/marshal.go b/vendor/github.com/zclconf/go-cty/cty/json/marshal.go index 7a14ce81..07d9f331 100644 --- a/vendor/github.com/zclconf/go-cty/cty/json/marshal.go +++ b/vendor/github.com/zclconf/go-cty/cty/json/marshal.go @@ -12,6 +12,9 @@ func marshal(val cty.Value, t cty.Type, path cty.Path, b *bytes.Buffer) error { if val.IsMarked() { return path.NewErrorf("value has marks, so it cannot be serialized as JSON") } + if !val.IsKnown() { + return path.NewErrorf("value is not known") + } // If we're going to decode as DynamicPseudoType then we need to save // dynamic type information to recover the real type. @@ -24,10 +27,6 @@ func marshal(val cty.Value, t cty.Type, path cty.Path, b *bytes.Buffer) error { return nil } - if !val.IsKnown() { - return path.NewErrorf("value is not known") - } - // The caller should've guaranteed that the given val is conformant with // the given type t, so we'll proceed under that assumption here. @@ -185,7 +184,10 @@ func marshalDynamic(val cty.Value, path cty.Path, b *bytes.Buffer) error { return path.NewErrorf("failed to serialize type: %s", err) } b.WriteString(`{"value":`) - marshal(val, val.Type(), path, b) + err = marshal(val, val.Type(), path, b) + if err != nil { + return path.NewErrorf("failed to serialize value: %s", err) + } b.WriteString(`,"type":`) b.Write(typeJSON) b.WriteRune('}') diff --git a/vendor/github.com/zclconf/go-cty/cty/primitive_type.go b/vendor/github.com/zclconf/go-cty/cty/primitive_type.go index 3ce2540b..2beea652 100644 --- a/vendor/github.com/zclconf/go-cty/cty/primitive_type.go +++ b/vendor/github.com/zclconf/go-cty/cty/primitive_type.go @@ -1,6 +1,8 @@ package cty -import "math/big" +import ( + "math/big" +) // primitiveType is the hidden implementation of the various primitive types // that are exposed as variables in this package. @@ -77,6 +79,18 @@ func rawNumberEqual(a, b *big.Float) bool { case a.Sign() != b.Sign(): return false default: + // First check if these are integers, and compare them directly. Floats + // need a more nuanced approach. + aInt, aAcc := a.Int(nil) + bInt, bAcc := b.Int(nil) + if aAcc != bAcc { + // only one is an exact integer value, so they can't be equal + return false + } + if aAcc == big.Exact { + return aInt.Cmp(bInt) == 0 + } + // This format and precision matches that used by cty/json.Marshal, // and thus achieves our definition of "two numbers are equal if // we'd use the same JSON serialization for both of them". diff --git a/vendor/github.com/zclconf/go-cty/cty/unknown_refinement.go b/vendor/github.com/zclconf/go-cty/cty/unknown_refinement.go index d90bcbc3..85fb28d6 100644 --- a/vendor/github.com/zclconf/go-cty/cty/unknown_refinement.go +++ b/vendor/github.com/zclconf/go-cty/cty/unknown_refinement.go @@ -44,7 +44,17 @@ func (v Value) Refine() *RefinementBuilder { var wip unknownValRefinement switch { case ty == DynamicPseudoType && !v.IsKnown(): - panic("cannot refine an unknown value of an unknown type") + // This case specifically matches DynamicVal, which is constrained + // by backward compatibility to be a singleton and so we cannot allow + // any refinements to it. + // To preserve the typical assumption that DynamicVal is a safe + // placeholder to use when no value is known at all, we silently + // ignore all attempts to refine this particular value and just + // always echo back a totally-unrefined DynamicVal. + return &RefinementBuilder{ + orig: DynamicVal, + marks: marks, + } case ty == String: wip = &refinementString{} case ty == Number: @@ -136,10 +146,27 @@ type RefinementBuilder struct { wip unknownValRefinement } -func (b *RefinementBuilder) assertRefineable() { +// refineable is an internal detail to help with two special situations +// related to refinements: +// - If the refinement is to a value of a type that doesn't support any +// refinements at all, this function will immediately panic with a +// message reporting that, because it's a caller bug to try to refine +// a value in a way that's inappropriate for its known type. +// - If the refinement is to an unknown value of an unknown type +// (i.e. cty.DynamicVal) then it returns false, indicating that the +// caller should just silently ignore whatever refinement was requested. +// - In all other cases this function returns true, which means the direct +// caller should attempt to apply the requested refinement, and then +// panic itself if the requested refinement doesn't make sense for the +// specific value being refined. +func (b *RefinementBuilder) refineable() bool { + if b.orig == DynamicVal { + return false + } if b.wip == nil { panic(fmt.Sprintf("cannot refine a %#v value", b.orig.Type())) } + return true } // NotNull constrains the value as definitely not being null. @@ -157,7 +184,9 @@ func (b *RefinementBuilder) assertRefineable() { // -- a value whose type is `cty.DynamicPseudoType` -- as being non-null. // An unknown value of an unknown type is always completely unconstrained. func (b *RefinementBuilder) NotNull() *RefinementBuilder { - b.assertRefineable() + if !b.refineable() { + return b + } if b.orig.IsKnown() && b.orig.IsNull() { panic("refining null value as non-null") @@ -181,7 +210,9 @@ func (b *RefinementBuilder) NotNull() *RefinementBuilder { // value for each type constraint -- but this is here for symmetry with the // fact that a [ValueRange] can also represent that a value is definitely null. func (b *RefinementBuilder) Null() *RefinementBuilder { - b.assertRefineable() + if !b.refineable() { + return b + } if b.orig.IsKnown() && !b.orig.IsNull() { panic("refining non-null value as null") @@ -209,7 +240,9 @@ func (b *RefinementBuilder) NumberRangeInclusive(min, max Value) *RefinementBuil // NumberRangeLowerBound constraints the lower bound of a number value, or // panics if this builder is not refining a number value. func (b *RefinementBuilder) NumberRangeLowerBound(min Value, inclusive bool) *RefinementBuilder { - b.assertRefineable() + if !b.refineable() { + return b + } wip, ok := b.wip.(*refinementNumber) if !ok { @@ -258,7 +291,9 @@ func (b *RefinementBuilder) NumberRangeLowerBound(min Value, inclusive bool) *Re // NumberRangeUpperBound constraints the upper bound of a number value, or // panics if this builder is not refining a number value. func (b *RefinementBuilder) NumberRangeUpperBound(max Value, inclusive bool) *RefinementBuilder { - b.assertRefineable() + if !b.refineable() { + return b + } wip, ok := b.wip.(*refinementNumber) if !ok { @@ -308,7 +343,9 @@ func (b *RefinementBuilder) NumberRangeUpperBound(max Value, inclusive bool) *Re // collection value, or panics if this builder is not refining a collection // value. func (b *RefinementBuilder) CollectionLengthLowerBound(min int) *RefinementBuilder { - b.assertRefineable() + if !b.refineable() { + return b + } wip, ok := b.wip.(*refinementCollection) if !ok { @@ -340,7 +377,9 @@ func (b *RefinementBuilder) CollectionLengthLowerBound(min int) *RefinementBuild // The upper bound must be a known, non-null number or this function will // panic. func (b *RefinementBuilder) CollectionLengthUpperBound(max int) *RefinementBuilder { - b.assertRefineable() + if !b.refineable() { + return b + } wip, ok := b.wip.(*refinementCollection) if !ok { @@ -419,7 +458,9 @@ func (b *RefinementBuilder) StringPrefix(prefix string) *RefinementBuilder { // Use [RefinementBuilder.StringPrefix] instead if an application cannot fully // control the final result to avoid violating this rule. func (b *RefinementBuilder) StringPrefixFull(prefix string) *RefinementBuilder { - b.assertRefineable() + if !b.refineable() { + return b + } wip, ok := b.wip.(*refinementString) if !ok { @@ -487,7 +528,7 @@ func (b *RefinementBuilder) NewValue() (ret Value) { ret = ret.WithMarks(b.marks) }() - if b.orig.IsKnown() { + if b.orig.IsKnown() || b.orig == DynamicVal { return b.orig } diff --git a/vendor/github.com/zclconf/go-cty/cty/value_range.go b/vendor/github.com/zclconf/go-cty/cty/value_range.go index 36f21946..d7d15353 100644 --- a/vendor/github.com/zclconf/go-cty/cty/value_range.go +++ b/vendor/github.com/zclconf/go-cty/cty/value_range.go @@ -21,6 +21,10 @@ import ( // offered by ranges and so can share code between both known and unknown // values. func (v Value) Range() ValueRange { + if v.IsMarked() { + panic("Value.Range on marked value; must be unmarked first") + } + // For an unknown value we just use its own refinements. if unk, isUnk := v.v.(*unknownType); isUnk { refinement := unk.refinement diff --git a/vendor/golang.org/x/crypto/argon2/argon2.go b/vendor/golang.org/x/crypto/argon2/argon2.go new file mode 100644 index 00000000..29f0a2de --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/argon2.go @@ -0,0 +1,283 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package argon2 implements the key derivation function Argon2. +// Argon2 was selected as the winner of the Password Hashing Competition and can +// be used to derive cryptographic keys from passwords. +// +// For a detailed specification of Argon2 see [1]. +// +// If you aren't sure which function you need, use Argon2id (IDKey) and +// the parameter recommendations for your scenario. +// +// # Argon2i +// +// Argon2i (implemented by Key) is the side-channel resistant version of Argon2. +// It uses data-independent memory access, which is preferred for password +// hashing and password-based key derivation. Argon2i requires more passes over +// memory than Argon2id to protect from trade-off attacks. The recommended +// parameters (taken from [2]) for non-interactive operations are time=3 and to +// use the maximum available memory. +// +// # Argon2id +// +// Argon2id (implemented by IDKey) is a hybrid version of Argon2 combining +// Argon2i and Argon2d. It uses data-independent memory access for the first +// half of the first iteration over the memory and data-dependent memory access +// for the rest. Argon2id is side-channel resistant and provides better brute- +// force cost savings due to time-memory tradeoffs than Argon2i. The recommended +// parameters for non-interactive operations (taken from [2]) are time=1 and to +// use the maximum available memory. +// +// [1] https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf +// [2] https://tools.ietf.org/html/draft-irtf-cfrg-argon2-03#section-9.3 +package argon2 + +import ( + "encoding/binary" + "sync" + + "golang.org/x/crypto/blake2b" +) + +// The Argon2 version implemented by this package. +const Version = 0x13 + +const ( + argon2d = iota + argon2i + argon2id +) + +// Key derives a key from the password, salt, and cost parameters using Argon2i +// returning a byte slice of length keyLen that can be used as cryptographic +// key. The CPU cost and parallelism degree must be greater than zero. +// +// For example, you can get a derived key for e.g. AES-256 (which needs a +// 32-byte key) by doing: +// +// key := argon2.Key([]byte("some password"), salt, 3, 32*1024, 4, 32) +// +// The draft RFC recommends[2] time=3, and memory=32*1024 is a sensible number. +// If using that amount of memory (32 MB) is not possible in some contexts then +// the time parameter can be increased to compensate. +// +// The time parameter specifies the number of passes over the memory and the +// memory parameter specifies the size of the memory in KiB. For example +// memory=32*1024 sets the memory cost to ~32 MB. The number of threads can be +// adjusted to the number of available CPUs. The cost parameters should be +// increased as memory latency and CPU parallelism increases. Remember to get a +// good random salt. +func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte { + return deriveKey(argon2i, password, salt, nil, nil, time, memory, threads, keyLen) +} + +// IDKey derives a key from the password, salt, and cost parameters using +// Argon2id returning a byte slice of length keyLen that can be used as +// cryptographic key. The CPU cost and parallelism degree must be greater than +// zero. +// +// For example, you can get a derived key for e.g. AES-256 (which needs a +// 32-byte key) by doing: +// +// key := argon2.IDKey([]byte("some password"), salt, 1, 64*1024, 4, 32) +// +// The draft RFC recommends[2] time=1, and memory=64*1024 is a sensible number. +// If using that amount of memory (64 MB) is not possible in some contexts then +// the time parameter can be increased to compensate. +// +// The time parameter specifies the number of passes over the memory and the +// memory parameter specifies the size of the memory in KiB. For example +// memory=64*1024 sets the memory cost to ~64 MB. The number of threads can be +// adjusted to the numbers of available CPUs. The cost parameters should be +// increased as memory latency and CPU parallelism increases. Remember to get a +// good random salt. +func IDKey(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte { + return deriveKey(argon2id, password, salt, nil, nil, time, memory, threads, keyLen) +} + +func deriveKey(mode int, password, salt, secret, data []byte, time, memory uint32, threads uint8, keyLen uint32) []byte { + if time < 1 { + panic("argon2: number of rounds too small") + } + if threads < 1 { + panic("argon2: parallelism degree too low") + } + h0 := initHash(password, salt, secret, data, time, memory, uint32(threads), keyLen, mode) + + memory = memory / (syncPoints * uint32(threads)) * (syncPoints * uint32(threads)) + if memory < 2*syncPoints*uint32(threads) { + memory = 2 * syncPoints * uint32(threads) + } + B := initBlocks(&h0, memory, uint32(threads)) + processBlocks(B, time, memory, uint32(threads), mode) + return extractKey(B, memory, uint32(threads), keyLen) +} + +const ( + blockLength = 128 + syncPoints = 4 +) + +type block [blockLength]uint64 + +func initHash(password, salt, key, data []byte, time, memory, threads, keyLen uint32, mode int) [blake2b.Size + 8]byte { + var ( + h0 [blake2b.Size + 8]byte + params [24]byte + tmp [4]byte + ) + + b2, _ := blake2b.New512(nil) + binary.LittleEndian.PutUint32(params[0:4], threads) + binary.LittleEndian.PutUint32(params[4:8], keyLen) + binary.LittleEndian.PutUint32(params[8:12], memory) + binary.LittleEndian.PutUint32(params[12:16], time) + binary.LittleEndian.PutUint32(params[16:20], uint32(Version)) + binary.LittleEndian.PutUint32(params[20:24], uint32(mode)) + b2.Write(params[:]) + binary.LittleEndian.PutUint32(tmp[:], uint32(len(password))) + b2.Write(tmp[:]) + b2.Write(password) + binary.LittleEndian.PutUint32(tmp[:], uint32(len(salt))) + b2.Write(tmp[:]) + b2.Write(salt) + binary.LittleEndian.PutUint32(tmp[:], uint32(len(key))) + b2.Write(tmp[:]) + b2.Write(key) + binary.LittleEndian.PutUint32(tmp[:], uint32(len(data))) + b2.Write(tmp[:]) + b2.Write(data) + b2.Sum(h0[:0]) + return h0 +} + +func initBlocks(h0 *[blake2b.Size + 8]byte, memory, threads uint32) []block { + var block0 [1024]byte + B := make([]block, memory) + for lane := uint32(0); lane < threads; lane++ { + j := lane * (memory / threads) + binary.LittleEndian.PutUint32(h0[blake2b.Size+4:], lane) + + binary.LittleEndian.PutUint32(h0[blake2b.Size:], 0) + blake2bHash(block0[:], h0[:]) + for i := range B[j+0] { + B[j+0][i] = binary.LittleEndian.Uint64(block0[i*8:]) + } + + binary.LittleEndian.PutUint32(h0[blake2b.Size:], 1) + blake2bHash(block0[:], h0[:]) + for i := range B[j+1] { + B[j+1][i] = binary.LittleEndian.Uint64(block0[i*8:]) + } + } + return B +} + +func processBlocks(B []block, time, memory, threads uint32, mode int) { + lanes := memory / threads + segments := lanes / syncPoints + + processSegment := func(n, slice, lane uint32, wg *sync.WaitGroup) { + var addresses, in, zero block + if mode == argon2i || (mode == argon2id && n == 0 && slice < syncPoints/2) { + in[0] = uint64(n) + in[1] = uint64(lane) + in[2] = uint64(slice) + in[3] = uint64(memory) + in[4] = uint64(time) + in[5] = uint64(mode) + } + + index := uint32(0) + if n == 0 && slice == 0 { + index = 2 // we have already generated the first two blocks + if mode == argon2i || mode == argon2id { + in[6]++ + processBlock(&addresses, &in, &zero) + processBlock(&addresses, &addresses, &zero) + } + } + + offset := lane*lanes + slice*segments + index + var random uint64 + for index < segments { + prev := offset - 1 + if index == 0 && slice == 0 { + prev += lanes // last block in lane + } + if mode == argon2i || (mode == argon2id && n == 0 && slice < syncPoints/2) { + if index%blockLength == 0 { + in[6]++ + processBlock(&addresses, &in, &zero) + processBlock(&addresses, &addresses, &zero) + } + random = addresses[index%blockLength] + } else { + random = B[prev][0] + } + newOffset := indexAlpha(random, lanes, segments, threads, n, slice, lane, index) + processBlockXOR(&B[offset], &B[prev], &B[newOffset]) + index, offset = index+1, offset+1 + } + wg.Done() + } + + for n := uint32(0); n < time; n++ { + for slice := uint32(0); slice < syncPoints; slice++ { + var wg sync.WaitGroup + for lane := uint32(0); lane < threads; lane++ { + wg.Add(1) + go processSegment(n, slice, lane, &wg) + } + wg.Wait() + } + } + +} + +func extractKey(B []block, memory, threads, keyLen uint32) []byte { + lanes := memory / threads + for lane := uint32(0); lane < threads-1; lane++ { + for i, v := range B[(lane*lanes)+lanes-1] { + B[memory-1][i] ^= v + } + } + + var block [1024]byte + for i, v := range B[memory-1] { + binary.LittleEndian.PutUint64(block[i*8:], v) + } + key := make([]byte, keyLen) + blake2bHash(key, block[:]) + return key +} + +func indexAlpha(rand uint64, lanes, segments, threads, n, slice, lane, index uint32) uint32 { + refLane := uint32(rand>>32) % threads + if n == 0 && slice == 0 { + refLane = lane + } + m, s := 3*segments, ((slice+1)%syncPoints)*segments + if lane == refLane { + m += index + } + if n == 0 { + m, s = slice*segments, 0 + if slice == 0 || lane == refLane { + m += index + } + } + if index == 0 || lane == refLane { + m-- + } + return phi(rand, uint64(m), uint64(s), refLane, lanes) +} + +func phi(rand, m, s uint64, lane, lanes uint32) uint32 { + p := rand & 0xFFFFFFFF + p = (p * p) >> 32 + p = (p * m) >> 32 + return lane*lanes + uint32((s+m-(p+1))%uint64(lanes)) +} diff --git a/vendor/golang.org/x/crypto/argon2/blake2b.go b/vendor/golang.org/x/crypto/argon2/blake2b.go new file mode 100644 index 00000000..10f46948 --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/blake2b.go @@ -0,0 +1,53 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package argon2 + +import ( + "encoding/binary" + "hash" + + "golang.org/x/crypto/blake2b" +) + +// blake2bHash computes an arbitrary long hash value of in +// and writes the hash to out. +func blake2bHash(out []byte, in []byte) { + var b2 hash.Hash + if n := len(out); n < blake2b.Size { + b2, _ = blake2b.New(n, nil) + } else { + b2, _ = blake2b.New512(nil) + } + + var buffer [blake2b.Size]byte + binary.LittleEndian.PutUint32(buffer[:4], uint32(len(out))) + b2.Write(buffer[:4]) + b2.Write(in) + + if len(out) <= blake2b.Size { + b2.Sum(out[:0]) + return + } + + outLen := len(out) + b2.Sum(buffer[:0]) + b2.Reset() + copy(out, buffer[:32]) + out = out[32:] + for len(out) > blake2b.Size { + b2.Write(buffer[:]) + b2.Sum(buffer[:0]) + copy(out, buffer[:32]) + out = out[32:] + b2.Reset() + } + + if outLen%blake2b.Size > 0 { // outLen > 64 + r := ((outLen + 31) / 32) - 2 // ⌈τ /32⌉-2 + b2, _ = blake2b.New(outLen-32*r, nil) + } + b2.Write(buffer[:]) + b2.Sum(out[:0]) +} diff --git a/vendor/golang.org/x/crypto/argon2/blamka_amd64.go b/vendor/golang.org/x/crypto/argon2/blamka_amd64.go new file mode 100644 index 00000000..063e7784 --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/blamka_amd64.go @@ -0,0 +1,60 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build amd64 && gc && !purego + +package argon2 + +import "golang.org/x/sys/cpu" + +func init() { + useSSE4 = cpu.X86.HasSSE41 +} + +//go:noescape +func mixBlocksSSE2(out, a, b, c *block) + +//go:noescape +func xorBlocksSSE2(out, a, b, c *block) + +//go:noescape +func blamkaSSE4(b *block) + +func processBlockSSE(out, in1, in2 *block, xor bool) { + var t block + mixBlocksSSE2(&t, in1, in2, &t) + if useSSE4 { + blamkaSSE4(&t) + } else { + for i := 0; i < blockLength; i += 16 { + blamkaGeneric( + &t[i+0], &t[i+1], &t[i+2], &t[i+3], + &t[i+4], &t[i+5], &t[i+6], &t[i+7], + &t[i+8], &t[i+9], &t[i+10], &t[i+11], + &t[i+12], &t[i+13], &t[i+14], &t[i+15], + ) + } + for i := 0; i < blockLength/8; i += 2 { + blamkaGeneric( + &t[i], &t[i+1], &t[16+i], &t[16+i+1], + &t[32+i], &t[32+i+1], &t[48+i], &t[48+i+1], + &t[64+i], &t[64+i+1], &t[80+i], &t[80+i+1], + &t[96+i], &t[96+i+1], &t[112+i], &t[112+i+1], + ) + } + } + if xor { + xorBlocksSSE2(out, in1, in2, &t) + } else { + mixBlocksSSE2(out, in1, in2, &t) + } +} + +func processBlock(out, in1, in2 *block) { + processBlockSSE(out, in1, in2, false) +} + +func processBlockXOR(out, in1, in2 *block) { + processBlockSSE(out, in1, in2, true) +} diff --git a/vendor/golang.org/x/crypto/argon2/blamka_amd64.s b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s new file mode 100644 index 00000000..6713acca --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s @@ -0,0 +1,243 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build amd64 && gc && !purego + +#include "textflag.h" + +DATA ·c40<>+0x00(SB)/8, $0x0201000706050403 +DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b +GLOBL ·c40<>(SB), (NOPTR+RODATA), $16 + +DATA ·c48<>+0x00(SB)/8, $0x0100070605040302 +DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a +GLOBL ·c48<>(SB), (NOPTR+RODATA), $16 + +#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \ + MOVO v4, t1; \ + MOVO v5, v4; \ + MOVO t1, v5; \ + MOVO v6, t1; \ + PUNPCKLQDQ v6, t2; \ + PUNPCKHQDQ v7, v6; \ + PUNPCKHQDQ t2, v6; \ + PUNPCKLQDQ v7, t2; \ + MOVO t1, v7; \ + MOVO v2, t1; \ + PUNPCKHQDQ t2, v7; \ + PUNPCKLQDQ v3, t2; \ + PUNPCKHQDQ t2, v2; \ + PUNPCKLQDQ t1, t2; \ + PUNPCKHQDQ t2, v3 + +#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \ + MOVO v4, t1; \ + MOVO v5, v4; \ + MOVO t1, v5; \ + MOVO v2, t1; \ + PUNPCKLQDQ v2, t2; \ + PUNPCKHQDQ v3, v2; \ + PUNPCKHQDQ t2, v2; \ + PUNPCKLQDQ v3, t2; \ + MOVO t1, v3; \ + MOVO v6, t1; \ + PUNPCKHQDQ t2, v3; \ + PUNPCKLQDQ v7, t2; \ + PUNPCKHQDQ t2, v6; \ + PUNPCKLQDQ t1, t2; \ + PUNPCKHQDQ t2, v7 + +#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, t0, c40, c48) \ + MOVO v0, t0; \ + PMULULQ v2, t0; \ + PADDQ v2, v0; \ + PADDQ t0, v0; \ + PADDQ t0, v0; \ + PXOR v0, v6; \ + PSHUFD $0xB1, v6, v6; \ + MOVO v4, t0; \ + PMULULQ v6, t0; \ + PADDQ v6, v4; \ + PADDQ t0, v4; \ + PADDQ t0, v4; \ + PXOR v4, v2; \ + PSHUFB c40, v2; \ + MOVO v0, t0; \ + PMULULQ v2, t0; \ + PADDQ v2, v0; \ + PADDQ t0, v0; \ + PADDQ t0, v0; \ + PXOR v0, v6; \ + PSHUFB c48, v6; \ + MOVO v4, t0; \ + PMULULQ v6, t0; \ + PADDQ v6, v4; \ + PADDQ t0, v4; \ + PADDQ t0, v4; \ + PXOR v4, v2; \ + MOVO v2, t0; \ + PADDQ v2, t0; \ + PSRLQ $63, v2; \ + PXOR t0, v2; \ + MOVO v1, t0; \ + PMULULQ v3, t0; \ + PADDQ v3, v1; \ + PADDQ t0, v1; \ + PADDQ t0, v1; \ + PXOR v1, v7; \ + PSHUFD $0xB1, v7, v7; \ + MOVO v5, t0; \ + PMULULQ v7, t0; \ + PADDQ v7, v5; \ + PADDQ t0, v5; \ + PADDQ t0, v5; \ + PXOR v5, v3; \ + PSHUFB c40, v3; \ + MOVO v1, t0; \ + PMULULQ v3, t0; \ + PADDQ v3, v1; \ + PADDQ t0, v1; \ + PADDQ t0, v1; \ + PXOR v1, v7; \ + PSHUFB c48, v7; \ + MOVO v5, t0; \ + PMULULQ v7, t0; \ + PADDQ v7, v5; \ + PADDQ t0, v5; \ + PADDQ t0, v5; \ + PXOR v5, v3; \ + MOVO v3, t0; \ + PADDQ v3, t0; \ + PSRLQ $63, v3; \ + PXOR t0, v3 + +#define LOAD_MSG_0(block, off) \ + MOVOU 8*(off+0)(block), X0; \ + MOVOU 8*(off+2)(block), X1; \ + MOVOU 8*(off+4)(block), X2; \ + MOVOU 8*(off+6)(block), X3; \ + MOVOU 8*(off+8)(block), X4; \ + MOVOU 8*(off+10)(block), X5; \ + MOVOU 8*(off+12)(block), X6; \ + MOVOU 8*(off+14)(block), X7 + +#define STORE_MSG_0(block, off) \ + MOVOU X0, 8*(off+0)(block); \ + MOVOU X1, 8*(off+2)(block); \ + MOVOU X2, 8*(off+4)(block); \ + MOVOU X3, 8*(off+6)(block); \ + MOVOU X4, 8*(off+8)(block); \ + MOVOU X5, 8*(off+10)(block); \ + MOVOU X6, 8*(off+12)(block); \ + MOVOU X7, 8*(off+14)(block) + +#define LOAD_MSG_1(block, off) \ + MOVOU 8*off+0*8(block), X0; \ + MOVOU 8*off+16*8(block), X1; \ + MOVOU 8*off+32*8(block), X2; \ + MOVOU 8*off+48*8(block), X3; \ + MOVOU 8*off+64*8(block), X4; \ + MOVOU 8*off+80*8(block), X5; \ + MOVOU 8*off+96*8(block), X6; \ + MOVOU 8*off+112*8(block), X7 + +#define STORE_MSG_1(block, off) \ + MOVOU X0, 8*off+0*8(block); \ + MOVOU X1, 8*off+16*8(block); \ + MOVOU X2, 8*off+32*8(block); \ + MOVOU X3, 8*off+48*8(block); \ + MOVOU X4, 8*off+64*8(block); \ + MOVOU X5, 8*off+80*8(block); \ + MOVOU X6, 8*off+96*8(block); \ + MOVOU X7, 8*off+112*8(block) + +#define BLAMKA_ROUND_0(block, off, t0, t1, c40, c48) \ + LOAD_MSG_0(block, off); \ + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ + SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1); \ + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1); \ + STORE_MSG_0(block, off) + +#define BLAMKA_ROUND_1(block, off, t0, t1, c40, c48) \ + LOAD_MSG_1(block, off); \ + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ + SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1); \ + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1); \ + STORE_MSG_1(block, off) + +// func blamkaSSE4(b *block) +TEXT ·blamkaSSE4(SB), 4, $0-8 + MOVQ b+0(FP), AX + + MOVOU ·c40<>(SB), X10 + MOVOU ·c48<>(SB), X11 + + BLAMKA_ROUND_0(AX, 0, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 16, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 32, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 48, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 64, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 80, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 96, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 112, X8, X9, X10, X11) + + BLAMKA_ROUND_1(AX, 0, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 2, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 4, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 6, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 8, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 10, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 12, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 14, X8, X9, X10, X11) + RET + +// func mixBlocksSSE2(out, a, b, c *block) +TEXT ·mixBlocksSSE2(SB), 4, $0-32 + MOVQ out+0(FP), DX + MOVQ a+8(FP), AX + MOVQ b+16(FP), BX + MOVQ c+24(FP), CX + MOVQ $128, DI + +loop: + MOVOU 0(AX), X0 + MOVOU 0(BX), X1 + MOVOU 0(CX), X2 + PXOR X1, X0 + PXOR X2, X0 + MOVOU X0, 0(DX) + ADDQ $16, AX + ADDQ $16, BX + ADDQ $16, CX + ADDQ $16, DX + SUBQ $2, DI + JA loop + RET + +// func xorBlocksSSE2(out, a, b, c *block) +TEXT ·xorBlocksSSE2(SB), 4, $0-32 + MOVQ out+0(FP), DX + MOVQ a+8(FP), AX + MOVQ b+16(FP), BX + MOVQ c+24(FP), CX + MOVQ $128, DI + +loop: + MOVOU 0(AX), X0 + MOVOU 0(BX), X1 + MOVOU 0(CX), X2 + MOVOU 0(DX), X3 + PXOR X1, X0 + PXOR X2, X0 + PXOR X3, X0 + MOVOU X0, 0(DX) + ADDQ $16, AX + ADDQ $16, BX + ADDQ $16, CX + ADDQ $16, DX + SUBQ $2, DI + JA loop + RET diff --git a/vendor/golang.org/x/crypto/argon2/blamka_generic.go b/vendor/golang.org/x/crypto/argon2/blamka_generic.go new file mode 100644 index 00000000..a481b224 --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/blamka_generic.go @@ -0,0 +1,163 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package argon2 + +var useSSE4 bool + +func processBlockGeneric(out, in1, in2 *block, xor bool) { + var t block + for i := range t { + t[i] = in1[i] ^ in2[i] + } + for i := 0; i < blockLength; i += 16 { + blamkaGeneric( + &t[i+0], &t[i+1], &t[i+2], &t[i+3], + &t[i+4], &t[i+5], &t[i+6], &t[i+7], + &t[i+8], &t[i+9], &t[i+10], &t[i+11], + &t[i+12], &t[i+13], &t[i+14], &t[i+15], + ) + } + for i := 0; i < blockLength/8; i += 2 { + blamkaGeneric( + &t[i], &t[i+1], &t[16+i], &t[16+i+1], + &t[32+i], &t[32+i+1], &t[48+i], &t[48+i+1], + &t[64+i], &t[64+i+1], &t[80+i], &t[80+i+1], + &t[96+i], &t[96+i+1], &t[112+i], &t[112+i+1], + ) + } + if xor { + for i := range t { + out[i] ^= in1[i] ^ in2[i] ^ t[i] + } + } else { + for i := range t { + out[i] = in1[i] ^ in2[i] ^ t[i] + } + } +} + +func blamkaGeneric(t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15 *uint64) { + v00, v01, v02, v03 := *t00, *t01, *t02, *t03 + v04, v05, v06, v07 := *t04, *t05, *t06, *t07 + v08, v09, v10, v11 := *t08, *t09, *t10, *t11 + v12, v13, v14, v15 := *t12, *t13, *t14, *t15 + + v00 += v04 + 2*uint64(uint32(v00))*uint64(uint32(v04)) + v12 ^= v00 + v12 = v12>>32 | v12<<32 + v08 += v12 + 2*uint64(uint32(v08))*uint64(uint32(v12)) + v04 ^= v08 + v04 = v04>>24 | v04<<40 + + v00 += v04 + 2*uint64(uint32(v00))*uint64(uint32(v04)) + v12 ^= v00 + v12 = v12>>16 | v12<<48 + v08 += v12 + 2*uint64(uint32(v08))*uint64(uint32(v12)) + v04 ^= v08 + v04 = v04>>63 | v04<<1 + + v01 += v05 + 2*uint64(uint32(v01))*uint64(uint32(v05)) + v13 ^= v01 + v13 = v13>>32 | v13<<32 + v09 += v13 + 2*uint64(uint32(v09))*uint64(uint32(v13)) + v05 ^= v09 + v05 = v05>>24 | v05<<40 + + v01 += v05 + 2*uint64(uint32(v01))*uint64(uint32(v05)) + v13 ^= v01 + v13 = v13>>16 | v13<<48 + v09 += v13 + 2*uint64(uint32(v09))*uint64(uint32(v13)) + v05 ^= v09 + v05 = v05>>63 | v05<<1 + + v02 += v06 + 2*uint64(uint32(v02))*uint64(uint32(v06)) + v14 ^= v02 + v14 = v14>>32 | v14<<32 + v10 += v14 + 2*uint64(uint32(v10))*uint64(uint32(v14)) + v06 ^= v10 + v06 = v06>>24 | v06<<40 + + v02 += v06 + 2*uint64(uint32(v02))*uint64(uint32(v06)) + v14 ^= v02 + v14 = v14>>16 | v14<<48 + v10 += v14 + 2*uint64(uint32(v10))*uint64(uint32(v14)) + v06 ^= v10 + v06 = v06>>63 | v06<<1 + + v03 += v07 + 2*uint64(uint32(v03))*uint64(uint32(v07)) + v15 ^= v03 + v15 = v15>>32 | v15<<32 + v11 += v15 + 2*uint64(uint32(v11))*uint64(uint32(v15)) + v07 ^= v11 + v07 = v07>>24 | v07<<40 + + v03 += v07 + 2*uint64(uint32(v03))*uint64(uint32(v07)) + v15 ^= v03 + v15 = v15>>16 | v15<<48 + v11 += v15 + 2*uint64(uint32(v11))*uint64(uint32(v15)) + v07 ^= v11 + v07 = v07>>63 | v07<<1 + + v00 += v05 + 2*uint64(uint32(v00))*uint64(uint32(v05)) + v15 ^= v00 + v15 = v15>>32 | v15<<32 + v10 += v15 + 2*uint64(uint32(v10))*uint64(uint32(v15)) + v05 ^= v10 + v05 = v05>>24 | v05<<40 + + v00 += v05 + 2*uint64(uint32(v00))*uint64(uint32(v05)) + v15 ^= v00 + v15 = v15>>16 | v15<<48 + v10 += v15 + 2*uint64(uint32(v10))*uint64(uint32(v15)) + v05 ^= v10 + v05 = v05>>63 | v05<<1 + + v01 += v06 + 2*uint64(uint32(v01))*uint64(uint32(v06)) + v12 ^= v01 + v12 = v12>>32 | v12<<32 + v11 += v12 + 2*uint64(uint32(v11))*uint64(uint32(v12)) + v06 ^= v11 + v06 = v06>>24 | v06<<40 + + v01 += v06 + 2*uint64(uint32(v01))*uint64(uint32(v06)) + v12 ^= v01 + v12 = v12>>16 | v12<<48 + v11 += v12 + 2*uint64(uint32(v11))*uint64(uint32(v12)) + v06 ^= v11 + v06 = v06>>63 | v06<<1 + + v02 += v07 + 2*uint64(uint32(v02))*uint64(uint32(v07)) + v13 ^= v02 + v13 = v13>>32 | v13<<32 + v08 += v13 + 2*uint64(uint32(v08))*uint64(uint32(v13)) + v07 ^= v08 + v07 = v07>>24 | v07<<40 + + v02 += v07 + 2*uint64(uint32(v02))*uint64(uint32(v07)) + v13 ^= v02 + v13 = v13>>16 | v13<<48 + v08 += v13 + 2*uint64(uint32(v08))*uint64(uint32(v13)) + v07 ^= v08 + v07 = v07>>63 | v07<<1 + + v03 += v04 + 2*uint64(uint32(v03))*uint64(uint32(v04)) + v14 ^= v03 + v14 = v14>>32 | v14<<32 + v09 += v14 + 2*uint64(uint32(v09))*uint64(uint32(v14)) + v04 ^= v09 + v04 = v04>>24 | v04<<40 + + v03 += v04 + 2*uint64(uint32(v03))*uint64(uint32(v04)) + v14 ^= v03 + v14 = v14>>16 | v14<<48 + v09 += v14 + 2*uint64(uint32(v09))*uint64(uint32(v14)) + v04 ^= v09 + v04 = v04>>63 | v04<<1 + + *t00, *t01, *t02, *t03 = v00, v01, v02, v03 + *t04, *t05, *t06, *t07 = v04, v05, v06, v07 + *t08, *t09, *t10, *t11 = v08, v09, v10, v11 + *t12, *t13, *t14, *t15 = v12, v13, v14, v15 +} diff --git a/vendor/golang.org/x/crypto/argon2/blamka_ref.go b/vendor/golang.org/x/crypto/argon2/blamka_ref.go new file mode 100644 index 00000000..16d58c65 --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/blamka_ref.go @@ -0,0 +1,15 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !amd64 || purego || !gc + +package argon2 + +func processBlock(out, in1, in2 *block) { + processBlockGeneric(out, in1, in2, false) +} + +func processBlockXOR(out, in1, in2 *block) { + processBlockGeneric(out, in1, in2, true) +} diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b.go b/vendor/golang.org/x/crypto/blake2b/blake2b.go new file mode 100644 index 00000000..d2e98d42 --- /dev/null +++ b/vendor/golang.org/x/crypto/blake2b/blake2b.go @@ -0,0 +1,291 @@ +// Copyright 2016 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 blake2b implements the BLAKE2b hash algorithm defined by RFC 7693 +// and the extendable output function (XOF) BLAKE2Xb. +// +// BLAKE2b is optimized for 64-bit platforms—including NEON-enabled ARMs—and +// produces digests of any size between 1 and 64 bytes. +// For a detailed specification of BLAKE2b see https://blake2.net/blake2.pdf +// and for BLAKE2Xb see https://blake2.net/blake2x.pdf +// +// If you aren't sure which function you need, use BLAKE2b (Sum512 or New512). +// If you need a secret-key MAC (message authentication code), use the New512 +// function with a non-nil key. +// +// BLAKE2X is a construction to compute hash values larger than 64 bytes. It +// can produce hash values between 0 and 4 GiB. +package blake2b + +import ( + "encoding/binary" + "errors" + "hash" +) + +const ( + // The blocksize of BLAKE2b in bytes. + BlockSize = 128 + // The hash size of BLAKE2b-512 in bytes. + Size = 64 + // The hash size of BLAKE2b-384 in bytes. + Size384 = 48 + // The hash size of BLAKE2b-256 in bytes. + Size256 = 32 +) + +var ( + useAVX2 bool + useAVX bool + useSSE4 bool +) + +var ( + errKeySize = errors.New("blake2b: invalid key size") + errHashSize = errors.New("blake2b: invalid hash size") +) + +var iv = [8]uint64{ + 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, +} + +// Sum512 returns the BLAKE2b-512 checksum of the data. +func Sum512(data []byte) [Size]byte { + var sum [Size]byte + checkSum(&sum, Size, data) + return sum +} + +// Sum384 returns the BLAKE2b-384 checksum of the data. +func Sum384(data []byte) [Size384]byte { + var sum [Size]byte + var sum384 [Size384]byte + checkSum(&sum, Size384, data) + copy(sum384[:], sum[:Size384]) + return sum384 +} + +// Sum256 returns the BLAKE2b-256 checksum of the data. +func Sum256(data []byte) [Size256]byte { + var sum [Size]byte + var sum256 [Size256]byte + checkSum(&sum, Size256, data) + copy(sum256[:], sum[:Size256]) + return sum256 +} + +// New512 returns a new hash.Hash computing the BLAKE2b-512 checksum. A non-nil +// key turns the hash into a MAC. The key must be between zero and 64 bytes long. +func New512(key []byte) (hash.Hash, error) { return newDigest(Size, key) } + +// New384 returns a new hash.Hash computing the BLAKE2b-384 checksum. A non-nil +// key turns the hash into a MAC. The key must be between zero and 64 bytes long. +func New384(key []byte) (hash.Hash, error) { return newDigest(Size384, key) } + +// New256 returns a new hash.Hash computing the BLAKE2b-256 checksum. A non-nil +// key turns the hash into a MAC. The key must be between zero and 64 bytes long. +func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) } + +// New returns a new hash.Hash computing the BLAKE2b checksum with a custom length. +// A non-nil key turns the hash into a MAC. The key must be between zero and 64 bytes long. +// The hash size can be a value between 1 and 64 but it is highly recommended to use +// values equal or greater than: +// - 32 if BLAKE2b is used as a hash function (The key is zero bytes long). +// - 16 if BLAKE2b is used as a MAC function (The key is at least 16 bytes long). +// When the key is nil, the returned hash.Hash implements BinaryMarshaler +// and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash. +func New(size int, key []byte) (hash.Hash, error) { return newDigest(size, key) } + +func newDigest(hashSize int, key []byte) (*digest, error) { + if hashSize < 1 || hashSize > Size { + return nil, errHashSize + } + if len(key) > Size { + return nil, errKeySize + } + d := &digest{ + size: hashSize, + keyLen: len(key), + } + copy(d.key[:], key) + d.Reset() + return d, nil +} + +func checkSum(sum *[Size]byte, hashSize int, data []byte) { + h := iv + h[0] ^= uint64(hashSize) | (1 << 16) | (1 << 24) + var c [2]uint64 + + if length := len(data); length > BlockSize { + n := length &^ (BlockSize - 1) + if length == n { + n -= BlockSize + } + hashBlocks(&h, &c, 0, data[:n]) + data = data[n:] + } + + var block [BlockSize]byte + offset := copy(block[:], data) + remaining := uint64(BlockSize - offset) + if c[0] < remaining { + c[1]-- + } + c[0] -= remaining + + hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:]) + + for i, v := range h[:(hashSize+7)/8] { + binary.LittleEndian.PutUint64(sum[8*i:], v) + } +} + +type digest struct { + h [8]uint64 + c [2]uint64 + size int + block [BlockSize]byte + offset int + + key [BlockSize]byte + keyLen int +} + +const ( + magic = "b2b" + marshaledSize = len(magic) + 8*8 + 2*8 + 1 + BlockSize + 1 +) + +func (d *digest) MarshalBinary() ([]byte, error) { + if d.keyLen != 0 { + return nil, errors.New("crypto/blake2b: cannot marshal MACs") + } + b := make([]byte, 0, marshaledSize) + b = append(b, magic...) + for i := 0; i < 8; i++ { + b = appendUint64(b, d.h[i]) + } + b = appendUint64(b, d.c[0]) + b = appendUint64(b, d.c[1]) + // Maximum value for size is 64 + b = append(b, byte(d.size)) + b = append(b, d.block[:]...) + b = append(b, byte(d.offset)) + return b, nil +} + +func (d *digest) UnmarshalBinary(b []byte) error { + if len(b) < len(magic) || string(b[:len(magic)]) != magic { + return errors.New("crypto/blake2b: invalid hash state identifier") + } + if len(b) != marshaledSize { + return errors.New("crypto/blake2b: invalid hash state size") + } + b = b[len(magic):] + for i := 0; i < 8; i++ { + b, d.h[i] = consumeUint64(b) + } + b, d.c[0] = consumeUint64(b) + b, d.c[1] = consumeUint64(b) + d.size = int(b[0]) + b = b[1:] + copy(d.block[:], b[:BlockSize]) + b = b[BlockSize:] + d.offset = int(b[0]) + return nil +} + +func (d *digest) BlockSize() int { return BlockSize } + +func (d *digest) Size() int { return d.size } + +func (d *digest) Reset() { + d.h = iv + d.h[0] ^= uint64(d.size) | (uint64(d.keyLen) << 8) | (1 << 16) | (1 << 24) + d.offset, d.c[0], d.c[1] = 0, 0, 0 + if d.keyLen > 0 { + d.block = d.key + d.offset = BlockSize + } +} + +func (d *digest) Write(p []byte) (n int, err error) { + n = len(p) + + if d.offset > 0 { + remaining := BlockSize - d.offset + if n <= remaining { + d.offset += copy(d.block[d.offset:], p) + return + } + copy(d.block[d.offset:], p[:remaining]) + hashBlocks(&d.h, &d.c, 0, d.block[:]) + d.offset = 0 + p = p[remaining:] + } + + if length := len(p); length > BlockSize { + nn := length &^ (BlockSize - 1) + if length == nn { + nn -= BlockSize + } + hashBlocks(&d.h, &d.c, 0, p[:nn]) + p = p[nn:] + } + + if len(p) > 0 { + d.offset += copy(d.block[:], p) + } + + return +} + +func (d *digest) Sum(sum []byte) []byte { + var hash [Size]byte + d.finalize(&hash) + return append(sum, hash[:d.size]...) +} + +func (d *digest) finalize(hash *[Size]byte) { + var block [BlockSize]byte + copy(block[:], d.block[:d.offset]) + remaining := uint64(BlockSize - d.offset) + + c := d.c + if c[0] < remaining { + c[1]-- + } + c[0] -= remaining + + h := d.h + hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:]) + + for i, v := range h { + binary.LittleEndian.PutUint64(hash[8*i:], v) + } +} + +func appendUint64(b []byte, x uint64) []byte { + var a [8]byte + binary.BigEndian.PutUint64(a[:], x) + return append(b, a[:]...) +} + +func appendUint32(b []byte, x uint32) []byte { + var a [4]byte + binary.BigEndian.PutUint32(a[:], x) + return append(b, a[:]...) +} + +func consumeUint64(b []byte) ([]byte, uint64) { + x := binary.BigEndian.Uint64(b) + return b[8:], x +} + +func consumeUint32(b []byte) ([]byte, uint32) { + x := binary.BigEndian.Uint32(b) + return b[4:], x +} diff --git a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go new file mode 100644 index 00000000..199c21d2 --- /dev/null +++ b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go @@ -0,0 +1,37 @@ +// Copyright 2016 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. + +//go:build amd64 && gc && !purego + +package blake2b + +import "golang.org/x/sys/cpu" + +func init() { + useAVX2 = cpu.X86.HasAVX2 + useAVX = cpu.X86.HasAVX + useSSE4 = cpu.X86.HasSSE41 +} + +//go:noescape +func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) + +//go:noescape +func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) + +//go:noescape +func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) + +func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) { + switch { + case useAVX2: + hashBlocksAVX2(h, c, flag, blocks) + case useAVX: + hashBlocksAVX(h, c, flag, blocks) + case useSSE4: + hashBlocksSSE4(h, c, flag, blocks) + default: + hashBlocksGeneric(h, c, flag, blocks) + } +} diff --git a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s new file mode 100644 index 00000000..9ae8206c --- /dev/null +++ b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s @@ -0,0 +1,744 @@ +// Copyright 2016 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. + +//go:build amd64 && gc && !purego + +#include "textflag.h" + +DATA ·AVX2_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908 +DATA ·AVX2_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b +DATA ·AVX2_iv0<>+0x10(SB)/8, $0x3c6ef372fe94f82b +DATA ·AVX2_iv0<>+0x18(SB)/8, $0xa54ff53a5f1d36f1 +GLOBL ·AVX2_iv0<>(SB), (NOPTR+RODATA), $32 + +DATA ·AVX2_iv1<>+0x00(SB)/8, $0x510e527fade682d1 +DATA ·AVX2_iv1<>+0x08(SB)/8, $0x9b05688c2b3e6c1f +DATA ·AVX2_iv1<>+0x10(SB)/8, $0x1f83d9abfb41bd6b +DATA ·AVX2_iv1<>+0x18(SB)/8, $0x5be0cd19137e2179 +GLOBL ·AVX2_iv1<>(SB), (NOPTR+RODATA), $32 + +DATA ·AVX2_c40<>+0x00(SB)/8, $0x0201000706050403 +DATA ·AVX2_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b +DATA ·AVX2_c40<>+0x10(SB)/8, $0x0201000706050403 +DATA ·AVX2_c40<>+0x18(SB)/8, $0x0a09080f0e0d0c0b +GLOBL ·AVX2_c40<>(SB), (NOPTR+RODATA), $32 + +DATA ·AVX2_c48<>+0x00(SB)/8, $0x0100070605040302 +DATA ·AVX2_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a +DATA ·AVX2_c48<>+0x10(SB)/8, $0x0100070605040302 +DATA ·AVX2_c48<>+0x18(SB)/8, $0x09080f0e0d0c0b0a +GLOBL ·AVX2_c48<>(SB), (NOPTR+RODATA), $32 + +DATA ·AVX_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908 +DATA ·AVX_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b +GLOBL ·AVX_iv0<>(SB), (NOPTR+RODATA), $16 + +DATA ·AVX_iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b +DATA ·AVX_iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1 +GLOBL ·AVX_iv1<>(SB), (NOPTR+RODATA), $16 + +DATA ·AVX_iv2<>+0x00(SB)/8, $0x510e527fade682d1 +DATA ·AVX_iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f +GLOBL ·AVX_iv2<>(SB), (NOPTR+RODATA), $16 + +DATA ·AVX_iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b +DATA ·AVX_iv3<>+0x08(SB)/8, $0x5be0cd19137e2179 +GLOBL ·AVX_iv3<>(SB), (NOPTR+RODATA), $16 + +DATA ·AVX_c40<>+0x00(SB)/8, $0x0201000706050403 +DATA ·AVX_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b +GLOBL ·AVX_c40<>(SB), (NOPTR+RODATA), $16 + +DATA ·AVX_c48<>+0x00(SB)/8, $0x0100070605040302 +DATA ·AVX_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a +GLOBL ·AVX_c48<>(SB), (NOPTR+RODATA), $16 + +#define VPERMQ_0x39_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x39 +#define VPERMQ_0x93_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x93 +#define VPERMQ_0x4E_Y2_Y2 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2; BYTE $0x4e +#define VPERMQ_0x93_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x93 +#define VPERMQ_0x39_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x39 + +#define ROUND_AVX2(m0, m1, m2, m3, t, c40, c48) \ + VPADDQ m0, Y0, Y0; \ + VPADDQ Y1, Y0, Y0; \ + VPXOR Y0, Y3, Y3; \ + VPSHUFD $-79, Y3, Y3; \ + VPADDQ Y3, Y2, Y2; \ + VPXOR Y2, Y1, Y1; \ + VPSHUFB c40, Y1, Y1; \ + VPADDQ m1, Y0, Y0; \ + VPADDQ Y1, Y0, Y0; \ + VPXOR Y0, Y3, Y3; \ + VPSHUFB c48, Y3, Y3; \ + VPADDQ Y3, Y2, Y2; \ + VPXOR Y2, Y1, Y1; \ + VPADDQ Y1, Y1, t; \ + VPSRLQ $63, Y1, Y1; \ + VPXOR t, Y1, Y1; \ + VPERMQ_0x39_Y1_Y1; \ + VPERMQ_0x4E_Y2_Y2; \ + VPERMQ_0x93_Y3_Y3; \ + VPADDQ m2, Y0, Y0; \ + VPADDQ Y1, Y0, Y0; \ + VPXOR Y0, Y3, Y3; \ + VPSHUFD $-79, Y3, Y3; \ + VPADDQ Y3, Y2, Y2; \ + VPXOR Y2, Y1, Y1; \ + VPSHUFB c40, Y1, Y1; \ + VPADDQ m3, Y0, Y0; \ + VPADDQ Y1, Y0, Y0; \ + VPXOR Y0, Y3, Y3; \ + VPSHUFB c48, Y3, Y3; \ + VPADDQ Y3, Y2, Y2; \ + VPXOR Y2, Y1, Y1; \ + VPADDQ Y1, Y1, t; \ + VPSRLQ $63, Y1, Y1; \ + VPXOR t, Y1, Y1; \ + VPERMQ_0x39_Y3_Y3; \ + VPERMQ_0x4E_Y2_Y2; \ + VPERMQ_0x93_Y1_Y1 + +#define VMOVQ_SI_X11_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x1E +#define VMOVQ_SI_X12_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x26 +#define VMOVQ_SI_X13_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x2E +#define VMOVQ_SI_X14_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x36 +#define VMOVQ_SI_X15_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x3E + +#define VMOVQ_SI_X11(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x5E; BYTE $n +#define VMOVQ_SI_X12(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x66; BYTE $n +#define VMOVQ_SI_X13(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x6E; BYTE $n +#define VMOVQ_SI_X14(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x76; BYTE $n +#define VMOVQ_SI_X15(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x7E; BYTE $n + +#define VPINSRQ_1_SI_X11_0 BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x1E; BYTE $0x01 +#define VPINSRQ_1_SI_X12_0 BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x26; BYTE $0x01 +#define VPINSRQ_1_SI_X13_0 BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x2E; BYTE $0x01 +#define VPINSRQ_1_SI_X14_0 BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x36; BYTE $0x01 +#define VPINSRQ_1_SI_X15_0 BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x3E; BYTE $0x01 + +#define VPINSRQ_1_SI_X11(n) BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x5E; BYTE $n; BYTE $0x01 +#define VPINSRQ_1_SI_X12(n) BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x66; BYTE $n; BYTE $0x01 +#define VPINSRQ_1_SI_X13(n) BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x6E; BYTE $n; BYTE $0x01 +#define VPINSRQ_1_SI_X14(n) BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x76; BYTE $n; BYTE $0x01 +#define VPINSRQ_1_SI_X15(n) BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x7E; BYTE $n; BYTE $0x01 + +#define VMOVQ_R8_X15 BYTE $0xC4; BYTE $0x41; BYTE $0xF9; BYTE $0x6E; BYTE $0xF8 +#define VPINSRQ_1_R9_X15 BYTE $0xC4; BYTE $0x43; BYTE $0x81; BYTE $0x22; BYTE $0xF9; BYTE $0x01 + +// load msg: Y12 = (i0, i1, i2, i3) +// i0, i1, i2, i3 must not be 0 +#define LOAD_MSG_AVX2_Y12(i0, i1, i2, i3) \ + VMOVQ_SI_X12(i0*8); \ + VMOVQ_SI_X11(i2*8); \ + VPINSRQ_1_SI_X12(i1*8); \ + VPINSRQ_1_SI_X11(i3*8); \ + VINSERTI128 $1, X11, Y12, Y12 + +// load msg: Y13 = (i0, i1, i2, i3) +// i0, i1, i2, i3 must not be 0 +#define LOAD_MSG_AVX2_Y13(i0, i1, i2, i3) \ + VMOVQ_SI_X13(i0*8); \ + VMOVQ_SI_X11(i2*8); \ + VPINSRQ_1_SI_X13(i1*8); \ + VPINSRQ_1_SI_X11(i3*8); \ + VINSERTI128 $1, X11, Y13, Y13 + +// load msg: Y14 = (i0, i1, i2, i3) +// i0, i1, i2, i3 must not be 0 +#define LOAD_MSG_AVX2_Y14(i0, i1, i2, i3) \ + VMOVQ_SI_X14(i0*8); \ + VMOVQ_SI_X11(i2*8); \ + VPINSRQ_1_SI_X14(i1*8); \ + VPINSRQ_1_SI_X11(i3*8); \ + VINSERTI128 $1, X11, Y14, Y14 + +// load msg: Y15 = (i0, i1, i2, i3) +// i0, i1, i2, i3 must not be 0 +#define LOAD_MSG_AVX2_Y15(i0, i1, i2, i3) \ + VMOVQ_SI_X15(i0*8); \ + VMOVQ_SI_X11(i2*8); \ + VPINSRQ_1_SI_X15(i1*8); \ + VPINSRQ_1_SI_X11(i3*8); \ + VINSERTI128 $1, X11, Y15, Y15 + +#define LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15() \ + VMOVQ_SI_X12_0; \ + VMOVQ_SI_X11(4*8); \ + VPINSRQ_1_SI_X12(2*8); \ + VPINSRQ_1_SI_X11(6*8); \ + VINSERTI128 $1, X11, Y12, Y12; \ + LOAD_MSG_AVX2_Y13(1, 3, 5, 7); \ + LOAD_MSG_AVX2_Y14(8, 10, 12, 14); \ + LOAD_MSG_AVX2_Y15(9, 11, 13, 15) + +#define LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3() \ + LOAD_MSG_AVX2_Y12(14, 4, 9, 13); \ + LOAD_MSG_AVX2_Y13(10, 8, 15, 6); \ + VMOVQ_SI_X11(11*8); \ + VPSHUFD $0x4E, 0*8(SI), X14; \ + VPINSRQ_1_SI_X11(5*8); \ + VINSERTI128 $1, X11, Y14, Y14; \ + LOAD_MSG_AVX2_Y15(12, 2, 7, 3) + +#define LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4() \ + VMOVQ_SI_X11(5*8); \ + VMOVDQU 11*8(SI), X12; \ + VPINSRQ_1_SI_X11(15*8); \ + VINSERTI128 $1, X11, Y12, Y12; \ + VMOVQ_SI_X13(8*8); \ + VMOVQ_SI_X11(2*8); \ + VPINSRQ_1_SI_X13_0; \ + VPINSRQ_1_SI_X11(13*8); \ + VINSERTI128 $1, X11, Y13, Y13; \ + LOAD_MSG_AVX2_Y14(10, 3, 7, 9); \ + LOAD_MSG_AVX2_Y15(14, 6, 1, 4) + +#define LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8() \ + LOAD_MSG_AVX2_Y12(7, 3, 13, 11); \ + LOAD_MSG_AVX2_Y13(9, 1, 12, 14); \ + LOAD_MSG_AVX2_Y14(2, 5, 4, 15); \ + VMOVQ_SI_X15(6*8); \ + VMOVQ_SI_X11_0; \ + VPINSRQ_1_SI_X15(10*8); \ + VPINSRQ_1_SI_X11(8*8); \ + VINSERTI128 $1, X11, Y15, Y15 + +#define LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13() \ + LOAD_MSG_AVX2_Y12(9, 5, 2, 10); \ + VMOVQ_SI_X13_0; \ + VMOVQ_SI_X11(4*8); \ + VPINSRQ_1_SI_X13(7*8); \ + VPINSRQ_1_SI_X11(15*8); \ + VINSERTI128 $1, X11, Y13, Y13; \ + LOAD_MSG_AVX2_Y14(14, 11, 6, 3); \ + LOAD_MSG_AVX2_Y15(1, 12, 8, 13) + +#define LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9() \ + VMOVQ_SI_X12(2*8); \ + VMOVQ_SI_X11_0; \ + VPINSRQ_1_SI_X12(6*8); \ + VPINSRQ_1_SI_X11(8*8); \ + VINSERTI128 $1, X11, Y12, Y12; \ + LOAD_MSG_AVX2_Y13(12, 10, 11, 3); \ + LOAD_MSG_AVX2_Y14(4, 7, 15, 1); \ + LOAD_MSG_AVX2_Y15(13, 5, 14, 9) + +#define LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11() \ + LOAD_MSG_AVX2_Y12(12, 1, 14, 4); \ + LOAD_MSG_AVX2_Y13(5, 15, 13, 10); \ + VMOVQ_SI_X14_0; \ + VPSHUFD $0x4E, 8*8(SI), X11; \ + VPINSRQ_1_SI_X14(6*8); \ + VINSERTI128 $1, X11, Y14, Y14; \ + LOAD_MSG_AVX2_Y15(7, 3, 2, 11) + +#define LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10() \ + LOAD_MSG_AVX2_Y12(13, 7, 12, 3); \ + LOAD_MSG_AVX2_Y13(11, 14, 1, 9); \ + LOAD_MSG_AVX2_Y14(5, 15, 8, 2); \ + VMOVQ_SI_X15_0; \ + VMOVQ_SI_X11(6*8); \ + VPINSRQ_1_SI_X15(4*8); \ + VPINSRQ_1_SI_X11(10*8); \ + VINSERTI128 $1, X11, Y15, Y15 + +#define LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5() \ + VMOVQ_SI_X12(6*8); \ + VMOVQ_SI_X11(11*8); \ + VPINSRQ_1_SI_X12(14*8); \ + VPINSRQ_1_SI_X11_0; \ + VINSERTI128 $1, X11, Y12, Y12; \ + LOAD_MSG_AVX2_Y13(15, 9, 3, 8); \ + VMOVQ_SI_X11(1*8); \ + VMOVDQU 12*8(SI), X14; \ + VPINSRQ_1_SI_X11(10*8); \ + VINSERTI128 $1, X11, Y14, Y14; \ + VMOVQ_SI_X15(2*8); \ + VMOVDQU 4*8(SI), X11; \ + VPINSRQ_1_SI_X15(7*8); \ + VINSERTI128 $1, X11, Y15, Y15 + +#define LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0() \ + LOAD_MSG_AVX2_Y12(10, 8, 7, 1); \ + VMOVQ_SI_X13(2*8); \ + VPSHUFD $0x4E, 5*8(SI), X11; \ + VPINSRQ_1_SI_X13(4*8); \ + VINSERTI128 $1, X11, Y13, Y13; \ + LOAD_MSG_AVX2_Y14(15, 9, 3, 13); \ + VMOVQ_SI_X15(11*8); \ + VMOVQ_SI_X11(12*8); \ + VPINSRQ_1_SI_X15(14*8); \ + VPINSRQ_1_SI_X11_0; \ + VINSERTI128 $1, X11, Y15, Y15 + +// func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) +TEXT ·hashBlocksAVX2(SB), 4, $320-48 // frame size = 288 + 32 byte alignment + MOVQ h+0(FP), AX + MOVQ c+8(FP), BX + MOVQ flag+16(FP), CX + MOVQ blocks_base+24(FP), SI + MOVQ blocks_len+32(FP), DI + + MOVQ SP, DX + ADDQ $31, DX + ANDQ $~31, DX + + MOVQ CX, 16(DX) + XORQ CX, CX + MOVQ CX, 24(DX) + + VMOVDQU ·AVX2_c40<>(SB), Y4 + VMOVDQU ·AVX2_c48<>(SB), Y5 + + VMOVDQU 0(AX), Y8 + VMOVDQU 32(AX), Y9 + VMOVDQU ·AVX2_iv0<>(SB), Y6 + VMOVDQU ·AVX2_iv1<>(SB), Y7 + + MOVQ 0(BX), R8 + MOVQ 8(BX), R9 + MOVQ R9, 8(DX) + +loop: + ADDQ $128, R8 + MOVQ R8, 0(DX) + CMPQ R8, $128 + JGE noinc + INCQ R9 + MOVQ R9, 8(DX) + +noinc: + VMOVDQA Y8, Y0 + VMOVDQA Y9, Y1 + VMOVDQA Y6, Y2 + VPXOR 0(DX), Y7, Y3 + + LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15() + VMOVDQA Y12, 32(DX) + VMOVDQA Y13, 64(DX) + VMOVDQA Y14, 96(DX) + VMOVDQA Y15, 128(DX) + ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) + LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3() + VMOVDQA Y12, 160(DX) + VMOVDQA Y13, 192(DX) + VMOVDQA Y14, 224(DX) + VMOVDQA Y15, 256(DX) + + ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) + LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4() + ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) + LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8() + ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) + LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13() + ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) + LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9() + ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) + LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11() + ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) + LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10() + ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) + LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5() + ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) + LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0() + ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5) + + ROUND_AVX2(32(DX), 64(DX), 96(DX), 128(DX), Y10, Y4, Y5) + ROUND_AVX2(160(DX), 192(DX), 224(DX), 256(DX), Y10, Y4, Y5) + + VPXOR Y0, Y8, Y8 + VPXOR Y1, Y9, Y9 + VPXOR Y2, Y8, Y8 + VPXOR Y3, Y9, Y9 + + LEAQ 128(SI), SI + SUBQ $128, DI + JNE loop + + MOVQ R8, 0(BX) + MOVQ R9, 8(BX) + + VMOVDQU Y8, 0(AX) + VMOVDQU Y9, 32(AX) + VZEROUPPER + + RET + +#define VPUNPCKLQDQ_X2_X2_X15 BYTE $0xC5; BYTE $0x69; BYTE $0x6C; BYTE $0xFA +#define VPUNPCKLQDQ_X3_X3_X15 BYTE $0xC5; BYTE $0x61; BYTE $0x6C; BYTE $0xFB +#define VPUNPCKLQDQ_X7_X7_X15 BYTE $0xC5; BYTE $0x41; BYTE $0x6C; BYTE $0xFF +#define VPUNPCKLQDQ_X13_X13_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x11; BYTE $0x6C; BYTE $0xFD +#define VPUNPCKLQDQ_X14_X14_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x09; BYTE $0x6C; BYTE $0xFE + +#define VPUNPCKHQDQ_X15_X2_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x69; BYTE $0x6D; BYTE $0xD7 +#define VPUNPCKHQDQ_X15_X3_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xDF +#define VPUNPCKHQDQ_X15_X6_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x49; BYTE $0x6D; BYTE $0xF7 +#define VPUNPCKHQDQ_X15_X7_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xFF +#define VPUNPCKHQDQ_X15_X3_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xD7 +#define VPUNPCKHQDQ_X15_X7_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xF7 +#define VPUNPCKHQDQ_X15_X13_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xDF +#define VPUNPCKHQDQ_X15_X13_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xFF + +#define SHUFFLE_AVX() \ + VMOVDQA X6, X13; \ + VMOVDQA X2, X14; \ + VMOVDQA X4, X6; \ + VPUNPCKLQDQ_X13_X13_X15; \ + VMOVDQA X5, X4; \ + VMOVDQA X6, X5; \ + VPUNPCKHQDQ_X15_X7_X6; \ + VPUNPCKLQDQ_X7_X7_X15; \ + VPUNPCKHQDQ_X15_X13_X7; \ + VPUNPCKLQDQ_X3_X3_X15; \ + VPUNPCKHQDQ_X15_X2_X2; \ + VPUNPCKLQDQ_X14_X14_X15; \ + VPUNPCKHQDQ_X15_X3_X3; \ + +#define SHUFFLE_AVX_INV() \ + VMOVDQA X2, X13; \ + VMOVDQA X4, X14; \ + VPUNPCKLQDQ_X2_X2_X15; \ + VMOVDQA X5, X4; \ + VPUNPCKHQDQ_X15_X3_X2; \ + VMOVDQA X14, X5; \ + VPUNPCKLQDQ_X3_X3_X15; \ + VMOVDQA X6, X14; \ + VPUNPCKHQDQ_X15_X13_X3; \ + VPUNPCKLQDQ_X7_X7_X15; \ + VPUNPCKHQDQ_X15_X6_X6; \ + VPUNPCKLQDQ_X14_X14_X15; \ + VPUNPCKHQDQ_X15_X7_X7; \ + +#define HALF_ROUND_AVX(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \ + VPADDQ m0, v0, v0; \ + VPADDQ v2, v0, v0; \ + VPADDQ m1, v1, v1; \ + VPADDQ v3, v1, v1; \ + VPXOR v0, v6, v6; \ + VPXOR v1, v7, v7; \ + VPSHUFD $-79, v6, v6; \ + VPSHUFD $-79, v7, v7; \ + VPADDQ v6, v4, v4; \ + VPADDQ v7, v5, v5; \ + VPXOR v4, v2, v2; \ + VPXOR v5, v3, v3; \ + VPSHUFB c40, v2, v2; \ + VPSHUFB c40, v3, v3; \ + VPADDQ m2, v0, v0; \ + VPADDQ v2, v0, v0; \ + VPADDQ m3, v1, v1; \ + VPADDQ v3, v1, v1; \ + VPXOR v0, v6, v6; \ + VPXOR v1, v7, v7; \ + VPSHUFB c48, v6, v6; \ + VPSHUFB c48, v7, v7; \ + VPADDQ v6, v4, v4; \ + VPADDQ v7, v5, v5; \ + VPXOR v4, v2, v2; \ + VPXOR v5, v3, v3; \ + VPADDQ v2, v2, t0; \ + VPSRLQ $63, v2, v2; \ + VPXOR t0, v2, v2; \ + VPADDQ v3, v3, t0; \ + VPSRLQ $63, v3, v3; \ + VPXOR t0, v3, v3 + +// load msg: X12 = (i0, i1), X13 = (i2, i3), X14 = (i4, i5), X15 = (i6, i7) +// i0, i1, i2, i3, i4, i5, i6, i7 must not be 0 +#define LOAD_MSG_AVX(i0, i1, i2, i3, i4, i5, i6, i7) \ + VMOVQ_SI_X12(i0*8); \ + VMOVQ_SI_X13(i2*8); \ + VMOVQ_SI_X14(i4*8); \ + VMOVQ_SI_X15(i6*8); \ + VPINSRQ_1_SI_X12(i1*8); \ + VPINSRQ_1_SI_X13(i3*8); \ + VPINSRQ_1_SI_X14(i5*8); \ + VPINSRQ_1_SI_X15(i7*8) + +// load msg: X12 = (0, 2), X13 = (4, 6), X14 = (1, 3), X15 = (5, 7) +#define LOAD_MSG_AVX_0_2_4_6_1_3_5_7() \ + VMOVQ_SI_X12_0; \ + VMOVQ_SI_X13(4*8); \ + VMOVQ_SI_X14(1*8); \ + VMOVQ_SI_X15(5*8); \ + VPINSRQ_1_SI_X12(2*8); \ + VPINSRQ_1_SI_X13(6*8); \ + VPINSRQ_1_SI_X14(3*8); \ + VPINSRQ_1_SI_X15(7*8) + +// load msg: X12 = (1, 0), X13 = (11, 5), X14 = (12, 2), X15 = (7, 3) +#define LOAD_MSG_AVX_1_0_11_5_12_2_7_3() \ + VPSHUFD $0x4E, 0*8(SI), X12; \ + VMOVQ_SI_X13(11*8); \ + VMOVQ_SI_X14(12*8); \ + VMOVQ_SI_X15(7*8); \ + VPINSRQ_1_SI_X13(5*8); \ + VPINSRQ_1_SI_X14(2*8); \ + VPINSRQ_1_SI_X15(3*8) + +// load msg: X12 = (11, 12), X13 = (5, 15), X14 = (8, 0), X15 = (2, 13) +#define LOAD_MSG_AVX_11_12_5_15_8_0_2_13() \ + VMOVDQU 11*8(SI), X12; \ + VMOVQ_SI_X13(5*8); \ + VMOVQ_SI_X14(8*8); \ + VMOVQ_SI_X15(2*8); \ + VPINSRQ_1_SI_X13(15*8); \ + VPINSRQ_1_SI_X14_0; \ + VPINSRQ_1_SI_X15(13*8) + +// load msg: X12 = (2, 5), X13 = (4, 15), X14 = (6, 10), X15 = (0, 8) +#define LOAD_MSG_AVX_2_5_4_15_6_10_0_8() \ + VMOVQ_SI_X12(2*8); \ + VMOVQ_SI_X13(4*8); \ + VMOVQ_SI_X14(6*8); \ + VMOVQ_SI_X15_0; \ + VPINSRQ_1_SI_X12(5*8); \ + VPINSRQ_1_SI_X13(15*8); \ + VPINSRQ_1_SI_X14(10*8); \ + VPINSRQ_1_SI_X15(8*8) + +// load msg: X12 = (9, 5), X13 = (2, 10), X14 = (0, 7), X15 = (4, 15) +#define LOAD_MSG_AVX_9_5_2_10_0_7_4_15() \ + VMOVQ_SI_X12(9*8); \ + VMOVQ_SI_X13(2*8); \ + VMOVQ_SI_X14_0; \ + VMOVQ_SI_X15(4*8); \ + VPINSRQ_1_SI_X12(5*8); \ + VPINSRQ_1_SI_X13(10*8); \ + VPINSRQ_1_SI_X14(7*8); \ + VPINSRQ_1_SI_X15(15*8) + +// load msg: X12 = (2, 6), X13 = (0, 8), X14 = (12, 10), X15 = (11, 3) +#define LOAD_MSG_AVX_2_6_0_8_12_10_11_3() \ + VMOVQ_SI_X12(2*8); \ + VMOVQ_SI_X13_0; \ + VMOVQ_SI_X14(12*8); \ + VMOVQ_SI_X15(11*8); \ + VPINSRQ_1_SI_X12(6*8); \ + VPINSRQ_1_SI_X13(8*8); \ + VPINSRQ_1_SI_X14(10*8); \ + VPINSRQ_1_SI_X15(3*8) + +// load msg: X12 = (0, 6), X13 = (9, 8), X14 = (7, 3), X15 = (2, 11) +#define LOAD_MSG_AVX_0_6_9_8_7_3_2_11() \ + MOVQ 0*8(SI), X12; \ + VPSHUFD $0x4E, 8*8(SI), X13; \ + MOVQ 7*8(SI), X14; \ + MOVQ 2*8(SI), X15; \ + VPINSRQ_1_SI_X12(6*8); \ + VPINSRQ_1_SI_X14(3*8); \ + VPINSRQ_1_SI_X15(11*8) + +// load msg: X12 = (6, 14), X13 = (11, 0), X14 = (15, 9), X15 = (3, 8) +#define LOAD_MSG_AVX_6_14_11_0_15_9_3_8() \ + MOVQ 6*8(SI), X12; \ + MOVQ 11*8(SI), X13; \ + MOVQ 15*8(SI), X14; \ + MOVQ 3*8(SI), X15; \ + VPINSRQ_1_SI_X12(14*8); \ + VPINSRQ_1_SI_X13_0; \ + VPINSRQ_1_SI_X14(9*8); \ + VPINSRQ_1_SI_X15(8*8) + +// load msg: X12 = (5, 15), X13 = (8, 2), X14 = (0, 4), X15 = (6, 10) +#define LOAD_MSG_AVX_5_15_8_2_0_4_6_10() \ + MOVQ 5*8(SI), X12; \ + MOVQ 8*8(SI), X13; \ + MOVQ 0*8(SI), X14; \ + MOVQ 6*8(SI), X15; \ + VPINSRQ_1_SI_X12(15*8); \ + VPINSRQ_1_SI_X13(2*8); \ + VPINSRQ_1_SI_X14(4*8); \ + VPINSRQ_1_SI_X15(10*8) + +// load msg: X12 = (12, 13), X13 = (1, 10), X14 = (2, 7), X15 = (4, 5) +#define LOAD_MSG_AVX_12_13_1_10_2_7_4_5() \ + VMOVDQU 12*8(SI), X12; \ + MOVQ 1*8(SI), X13; \ + MOVQ 2*8(SI), X14; \ + VPINSRQ_1_SI_X13(10*8); \ + VPINSRQ_1_SI_X14(7*8); \ + VMOVDQU 4*8(SI), X15 + +// load msg: X12 = (15, 9), X13 = (3, 13), X14 = (11, 14), X15 = (12, 0) +#define LOAD_MSG_AVX_15_9_3_13_11_14_12_0() \ + MOVQ 15*8(SI), X12; \ + MOVQ 3*8(SI), X13; \ + MOVQ 11*8(SI), X14; \ + MOVQ 12*8(SI), X15; \ + VPINSRQ_1_SI_X12(9*8); \ + VPINSRQ_1_SI_X13(13*8); \ + VPINSRQ_1_SI_X14(14*8); \ + VPINSRQ_1_SI_X15_0 + +// func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) +TEXT ·hashBlocksAVX(SB), 4, $288-48 // frame size = 272 + 16 byte alignment + MOVQ h+0(FP), AX + MOVQ c+8(FP), BX + MOVQ flag+16(FP), CX + MOVQ blocks_base+24(FP), SI + MOVQ blocks_len+32(FP), DI + + MOVQ SP, R10 + ADDQ $15, R10 + ANDQ $~15, R10 + + VMOVDQU ·AVX_c40<>(SB), X0 + VMOVDQU ·AVX_c48<>(SB), X1 + VMOVDQA X0, X8 + VMOVDQA X1, X9 + + VMOVDQU ·AVX_iv3<>(SB), X0 + VMOVDQA X0, 0(R10) + XORQ CX, 0(R10) // 0(R10) = ·AVX_iv3 ^ (CX || 0) + + VMOVDQU 0(AX), X10 + VMOVDQU 16(AX), X11 + VMOVDQU 32(AX), X2 + VMOVDQU 48(AX), X3 + + MOVQ 0(BX), R8 + MOVQ 8(BX), R9 + +loop: + ADDQ $128, R8 + CMPQ R8, $128 + JGE noinc + INCQ R9 + +noinc: + VMOVQ_R8_X15 + VPINSRQ_1_R9_X15 + + VMOVDQA X10, X0 + VMOVDQA X11, X1 + VMOVDQU ·AVX_iv0<>(SB), X4 + VMOVDQU ·AVX_iv1<>(SB), X5 + VMOVDQU ·AVX_iv2<>(SB), X6 + + VPXOR X15, X6, X6 + VMOVDQA 0(R10), X7 + + LOAD_MSG_AVX_0_2_4_6_1_3_5_7() + VMOVDQA X12, 16(R10) + VMOVDQA X13, 32(R10) + VMOVDQA X14, 48(R10) + VMOVDQA X15, 64(R10) + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX() + LOAD_MSG_AVX(8, 10, 12, 14, 9, 11, 13, 15) + VMOVDQA X12, 80(R10) + VMOVDQA X13, 96(R10) + VMOVDQA X14, 112(R10) + VMOVDQA X15, 128(R10) + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX_INV() + + LOAD_MSG_AVX(14, 4, 9, 13, 10, 8, 15, 6) + VMOVDQA X12, 144(R10) + VMOVDQA X13, 160(R10) + VMOVDQA X14, 176(R10) + VMOVDQA X15, 192(R10) + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX() + LOAD_MSG_AVX_1_0_11_5_12_2_7_3() + VMOVDQA X12, 208(R10) + VMOVDQA X13, 224(R10) + VMOVDQA X14, 240(R10) + VMOVDQA X15, 256(R10) + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX_INV() + + LOAD_MSG_AVX_11_12_5_15_8_0_2_13() + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX() + LOAD_MSG_AVX(10, 3, 7, 9, 14, 6, 1, 4) + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX_INV() + + LOAD_MSG_AVX(7, 3, 13, 11, 9, 1, 12, 14) + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX() + LOAD_MSG_AVX_2_5_4_15_6_10_0_8() + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX_INV() + + LOAD_MSG_AVX_9_5_2_10_0_7_4_15() + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX() + LOAD_MSG_AVX(14, 11, 6, 3, 1, 12, 8, 13) + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX_INV() + + LOAD_MSG_AVX_2_6_0_8_12_10_11_3() + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX() + LOAD_MSG_AVX(4, 7, 15, 1, 13, 5, 14, 9) + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX_INV() + + LOAD_MSG_AVX(12, 1, 14, 4, 5, 15, 13, 10) + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX() + LOAD_MSG_AVX_0_6_9_8_7_3_2_11() + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX_INV() + + LOAD_MSG_AVX(13, 7, 12, 3, 11, 14, 1, 9) + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX() + LOAD_MSG_AVX_5_15_8_2_0_4_6_10() + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX_INV() + + LOAD_MSG_AVX_6_14_11_0_15_9_3_8() + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX() + LOAD_MSG_AVX_12_13_1_10_2_7_4_5() + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX_INV() + + LOAD_MSG_AVX(10, 8, 7, 1, 2, 4, 6, 5) + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX() + LOAD_MSG_AVX_15_9_3_13_11_14_12_0() + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9) + SHUFFLE_AVX_INV() + + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 16(R10), 32(R10), 48(R10), 64(R10), X15, X8, X9) + SHUFFLE_AVX() + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 80(R10), 96(R10), 112(R10), 128(R10), X15, X8, X9) + SHUFFLE_AVX_INV() + + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 144(R10), 160(R10), 176(R10), 192(R10), X15, X8, X9) + SHUFFLE_AVX() + HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 208(R10), 224(R10), 240(R10), 256(R10), X15, X8, X9) + SHUFFLE_AVX_INV() + + VMOVDQU 32(AX), X14 + VMOVDQU 48(AX), X15 + VPXOR X0, X10, X10 + VPXOR X1, X11, X11 + VPXOR X2, X14, X14 + VPXOR X3, X15, X15 + VPXOR X4, X10, X10 + VPXOR X5, X11, X11 + VPXOR X6, X14, X2 + VPXOR X7, X15, X3 + VMOVDQU X2, 32(AX) + VMOVDQU X3, 48(AX) + + LEAQ 128(SI), SI + SUBQ $128, DI + JNE loop + + VMOVDQU X10, 0(AX) + VMOVDQU X11, 16(AX) + + MOVQ R8, 0(BX) + MOVQ R9, 8(BX) + VZEROUPPER + + RET diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s b/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s new file mode 100644 index 00000000..adfac00c --- /dev/null +++ b/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s @@ -0,0 +1,278 @@ +// Copyright 2016 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. + +//go:build amd64 && gc && !purego + +#include "textflag.h" + +DATA ·iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908 +DATA ·iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b +GLOBL ·iv0<>(SB), (NOPTR+RODATA), $16 + +DATA ·iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b +DATA ·iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1 +GLOBL ·iv1<>(SB), (NOPTR+RODATA), $16 + +DATA ·iv2<>+0x00(SB)/8, $0x510e527fade682d1 +DATA ·iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f +GLOBL ·iv2<>(SB), (NOPTR+RODATA), $16 + +DATA ·iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b +DATA ·iv3<>+0x08(SB)/8, $0x5be0cd19137e2179 +GLOBL ·iv3<>(SB), (NOPTR+RODATA), $16 + +DATA ·c40<>+0x00(SB)/8, $0x0201000706050403 +DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b +GLOBL ·c40<>(SB), (NOPTR+RODATA), $16 + +DATA ·c48<>+0x00(SB)/8, $0x0100070605040302 +DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a +GLOBL ·c48<>(SB), (NOPTR+RODATA), $16 + +#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \ + MOVO v4, t1; \ + MOVO v5, v4; \ + MOVO t1, v5; \ + MOVO v6, t1; \ + PUNPCKLQDQ v6, t2; \ + PUNPCKHQDQ v7, v6; \ + PUNPCKHQDQ t2, v6; \ + PUNPCKLQDQ v7, t2; \ + MOVO t1, v7; \ + MOVO v2, t1; \ + PUNPCKHQDQ t2, v7; \ + PUNPCKLQDQ v3, t2; \ + PUNPCKHQDQ t2, v2; \ + PUNPCKLQDQ t1, t2; \ + PUNPCKHQDQ t2, v3 + +#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \ + MOVO v4, t1; \ + MOVO v5, v4; \ + MOVO t1, v5; \ + MOVO v2, t1; \ + PUNPCKLQDQ v2, t2; \ + PUNPCKHQDQ v3, v2; \ + PUNPCKHQDQ t2, v2; \ + PUNPCKLQDQ v3, t2; \ + MOVO t1, v3; \ + MOVO v6, t1; \ + PUNPCKHQDQ t2, v3; \ + PUNPCKLQDQ v7, t2; \ + PUNPCKHQDQ t2, v6; \ + PUNPCKLQDQ t1, t2; \ + PUNPCKHQDQ t2, v7 + +#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \ + PADDQ m0, v0; \ + PADDQ m1, v1; \ + PADDQ v2, v0; \ + PADDQ v3, v1; \ + PXOR v0, v6; \ + PXOR v1, v7; \ + PSHUFD $0xB1, v6, v6; \ + PSHUFD $0xB1, v7, v7; \ + PADDQ v6, v4; \ + PADDQ v7, v5; \ + PXOR v4, v2; \ + PXOR v5, v3; \ + PSHUFB c40, v2; \ + PSHUFB c40, v3; \ + PADDQ m2, v0; \ + PADDQ m3, v1; \ + PADDQ v2, v0; \ + PADDQ v3, v1; \ + PXOR v0, v6; \ + PXOR v1, v7; \ + PSHUFB c48, v6; \ + PSHUFB c48, v7; \ + PADDQ v6, v4; \ + PADDQ v7, v5; \ + PXOR v4, v2; \ + PXOR v5, v3; \ + MOVOU v2, t0; \ + PADDQ v2, t0; \ + PSRLQ $63, v2; \ + PXOR t0, v2; \ + MOVOU v3, t0; \ + PADDQ v3, t0; \ + PSRLQ $63, v3; \ + PXOR t0, v3 + +#define LOAD_MSG(m0, m1, m2, m3, src, i0, i1, i2, i3, i4, i5, i6, i7) \ + MOVQ i0*8(src), m0; \ + PINSRQ $1, i1*8(src), m0; \ + MOVQ i2*8(src), m1; \ + PINSRQ $1, i3*8(src), m1; \ + MOVQ i4*8(src), m2; \ + PINSRQ $1, i5*8(src), m2; \ + MOVQ i6*8(src), m3; \ + PINSRQ $1, i7*8(src), m3 + +// func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) +TEXT ·hashBlocksSSE4(SB), 4, $288-48 // frame size = 272 + 16 byte alignment + MOVQ h+0(FP), AX + MOVQ c+8(FP), BX + MOVQ flag+16(FP), CX + MOVQ blocks_base+24(FP), SI + MOVQ blocks_len+32(FP), DI + + MOVQ SP, R10 + ADDQ $15, R10 + ANDQ $~15, R10 + + MOVOU ·iv3<>(SB), X0 + MOVO X0, 0(R10) + XORQ CX, 0(R10) // 0(R10) = ·iv3 ^ (CX || 0) + + MOVOU ·c40<>(SB), X13 + MOVOU ·c48<>(SB), X14 + + MOVOU 0(AX), X12 + MOVOU 16(AX), X15 + + MOVQ 0(BX), R8 + MOVQ 8(BX), R9 + +loop: + ADDQ $128, R8 + CMPQ R8, $128 + JGE noinc + INCQ R9 + +noinc: + MOVQ R8, X8 + PINSRQ $1, R9, X8 + + MOVO X12, X0 + MOVO X15, X1 + MOVOU 32(AX), X2 + MOVOU 48(AX), X3 + MOVOU ·iv0<>(SB), X4 + MOVOU ·iv1<>(SB), X5 + MOVOU ·iv2<>(SB), X6 + + PXOR X8, X6 + MOVO 0(R10), X7 + + LOAD_MSG(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7) + MOVO X8, 16(R10) + MOVO X9, 32(R10) + MOVO X10, 48(R10) + MOVO X11, 64(R10) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + LOAD_MSG(X8, X9, X10, X11, SI, 8, 10, 12, 14, 9, 11, 13, 15) + MOVO X8, 80(R10) + MOVO X9, 96(R10) + MOVO X10, 112(R10) + MOVO X11, 128(R10) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + LOAD_MSG(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6) + MOVO X8, 144(R10) + MOVO X9, 160(R10) + MOVO X10, 176(R10) + MOVO X11, 192(R10) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + LOAD_MSG(X8, X9, X10, X11, SI, 1, 0, 11, 5, 12, 2, 7, 3) + MOVO X8, 208(R10) + MOVO X9, 224(R10) + MOVO X10, 240(R10) + MOVO X11, 256(R10) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + LOAD_MSG(X8, X9, X10, X11, SI, 11, 12, 5, 15, 8, 0, 2, 13) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + LOAD_MSG(X8, X9, X10, X11, SI, 10, 3, 7, 9, 14, 6, 1, 4) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + LOAD_MSG(X8, X9, X10, X11, SI, 7, 3, 13, 11, 9, 1, 12, 14) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + LOAD_MSG(X8, X9, X10, X11, SI, 2, 5, 4, 15, 6, 10, 0, 8) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + LOAD_MSG(X8, X9, X10, X11, SI, 9, 5, 2, 10, 0, 7, 4, 15) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + LOAD_MSG(X8, X9, X10, X11, SI, 14, 11, 6, 3, 1, 12, 8, 13) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + LOAD_MSG(X8, X9, X10, X11, SI, 2, 6, 0, 8, 12, 10, 11, 3) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + LOAD_MSG(X8, X9, X10, X11, SI, 4, 7, 15, 1, 13, 5, 14, 9) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + LOAD_MSG(X8, X9, X10, X11, SI, 12, 1, 14, 4, 5, 15, 13, 10) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + LOAD_MSG(X8, X9, X10, X11, SI, 0, 6, 9, 8, 7, 3, 2, 11) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + LOAD_MSG(X8, X9, X10, X11, SI, 13, 7, 12, 3, 11, 14, 1, 9) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + LOAD_MSG(X8, X9, X10, X11, SI, 5, 15, 8, 2, 0, 4, 6, 10) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + LOAD_MSG(X8, X9, X10, X11, SI, 6, 14, 11, 0, 15, 9, 3, 8) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + LOAD_MSG(X8, X9, X10, X11, SI, 12, 13, 1, 10, 2, 7, 4, 5) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + LOAD_MSG(X8, X9, X10, X11, SI, 10, 8, 7, 1, 2, 4, 6, 5) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + LOAD_MSG(X8, X9, X10, X11, SI, 15, 9, 3, 13, 11, 14, 12, 0) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 16(R10), 32(R10), 48(R10), 64(R10), X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 80(R10), 96(R10), 112(R10), 128(R10), X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 144(R10), 160(R10), 176(R10), 192(R10), X11, X13, X14) + SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9) + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 208(R10), 224(R10), 240(R10), 256(R10), X11, X13, X14) + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9) + + MOVOU 32(AX), X10 + MOVOU 48(AX), X11 + PXOR X0, X12 + PXOR X1, X15 + PXOR X2, X10 + PXOR X3, X11 + PXOR X4, X12 + PXOR X5, X15 + PXOR X6, X10 + PXOR X7, X11 + MOVOU X10, 32(AX) + MOVOU X11, 48(AX) + + LEAQ 128(SI), SI + SUBQ $128, DI + JNE loop + + MOVOU X12, 0(AX) + MOVOU X15, 16(AX) + + MOVQ R8, 0(BX) + MOVQ R9, 8(BX) + + RET diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go b/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go new file mode 100644 index 00000000..3168a8aa --- /dev/null +++ b/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go @@ -0,0 +1,182 @@ +// Copyright 2016 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 blake2b + +import ( + "encoding/binary" + "math/bits" +) + +// the precomputed values for BLAKE2b +// there are 12 16-byte arrays - one for each round +// the entries are calculated from the sigma constants. +var precomputed = [12][16]byte{ + {0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15}, + {14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3}, + {11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4}, + {7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8}, + {9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13}, + {2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9}, + {12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11}, + {13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10}, + {6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5}, + {10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0}, + {0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15}, // equal to the first + {14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3}, // equal to the second +} + +func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) { + var m [16]uint64 + c0, c1 := c[0], c[1] + + for i := 0; i < len(blocks); { + c0 += BlockSize + if c0 < BlockSize { + c1++ + } + + v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7] + v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7] + v12 ^= c0 + v13 ^= c1 + v14 ^= flag + + for j := range m { + m[j] = binary.LittleEndian.Uint64(blocks[i:]) + i += 8 + } + + for j := range precomputed { + s := &(precomputed[j]) + + v0 += m[s[0]] + v0 += v4 + v12 ^= v0 + v12 = bits.RotateLeft64(v12, -32) + v8 += v12 + v4 ^= v8 + v4 = bits.RotateLeft64(v4, -24) + v1 += m[s[1]] + v1 += v5 + v13 ^= v1 + v13 = bits.RotateLeft64(v13, -32) + v9 += v13 + v5 ^= v9 + v5 = bits.RotateLeft64(v5, -24) + v2 += m[s[2]] + v2 += v6 + v14 ^= v2 + v14 = bits.RotateLeft64(v14, -32) + v10 += v14 + v6 ^= v10 + v6 = bits.RotateLeft64(v6, -24) + v3 += m[s[3]] + v3 += v7 + v15 ^= v3 + v15 = bits.RotateLeft64(v15, -32) + v11 += v15 + v7 ^= v11 + v7 = bits.RotateLeft64(v7, -24) + + v0 += m[s[4]] + v0 += v4 + v12 ^= v0 + v12 = bits.RotateLeft64(v12, -16) + v8 += v12 + v4 ^= v8 + v4 = bits.RotateLeft64(v4, -63) + v1 += m[s[5]] + v1 += v5 + v13 ^= v1 + v13 = bits.RotateLeft64(v13, -16) + v9 += v13 + v5 ^= v9 + v5 = bits.RotateLeft64(v5, -63) + v2 += m[s[6]] + v2 += v6 + v14 ^= v2 + v14 = bits.RotateLeft64(v14, -16) + v10 += v14 + v6 ^= v10 + v6 = bits.RotateLeft64(v6, -63) + v3 += m[s[7]] + v3 += v7 + v15 ^= v3 + v15 = bits.RotateLeft64(v15, -16) + v11 += v15 + v7 ^= v11 + v7 = bits.RotateLeft64(v7, -63) + + v0 += m[s[8]] + v0 += v5 + v15 ^= v0 + v15 = bits.RotateLeft64(v15, -32) + v10 += v15 + v5 ^= v10 + v5 = bits.RotateLeft64(v5, -24) + v1 += m[s[9]] + v1 += v6 + v12 ^= v1 + v12 = bits.RotateLeft64(v12, -32) + v11 += v12 + v6 ^= v11 + v6 = bits.RotateLeft64(v6, -24) + v2 += m[s[10]] + v2 += v7 + v13 ^= v2 + v13 = bits.RotateLeft64(v13, -32) + v8 += v13 + v7 ^= v8 + v7 = bits.RotateLeft64(v7, -24) + v3 += m[s[11]] + v3 += v4 + v14 ^= v3 + v14 = bits.RotateLeft64(v14, -32) + v9 += v14 + v4 ^= v9 + v4 = bits.RotateLeft64(v4, -24) + + v0 += m[s[12]] + v0 += v5 + v15 ^= v0 + v15 = bits.RotateLeft64(v15, -16) + v10 += v15 + v5 ^= v10 + v5 = bits.RotateLeft64(v5, -63) + v1 += m[s[13]] + v1 += v6 + v12 ^= v1 + v12 = bits.RotateLeft64(v12, -16) + v11 += v12 + v6 ^= v11 + v6 = bits.RotateLeft64(v6, -63) + v2 += m[s[14]] + v2 += v7 + v13 ^= v2 + v13 = bits.RotateLeft64(v13, -16) + v8 += v13 + v7 ^= v8 + v7 = bits.RotateLeft64(v7, -63) + v3 += m[s[15]] + v3 += v4 + v14 ^= v3 + v14 = bits.RotateLeft64(v14, -16) + v9 += v14 + v4 ^= v9 + v4 = bits.RotateLeft64(v4, -63) + + } + + h[0] ^= v0 ^ v8 + h[1] ^= v1 ^ v9 + h[2] ^= v2 ^ v10 + h[3] ^= v3 ^ v11 + h[4] ^= v4 ^ v12 + h[5] ^= v5 ^ v13 + h[6] ^= v6 ^ v14 + h[7] ^= v7 ^ v15 + } + c[0], c[1] = c0, c1 +} diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go b/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go new file mode 100644 index 00000000..6e28668c --- /dev/null +++ b/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go @@ -0,0 +1,11 @@ +// Copyright 2016 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. + +//go:build !amd64 || purego || !gc + +package blake2b + +func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) { + hashBlocksGeneric(h, c, flag, blocks) +} diff --git a/vendor/golang.org/x/crypto/blake2b/blake2x.go b/vendor/golang.org/x/crypto/blake2b/blake2x.go new file mode 100644 index 00000000..52c414db --- /dev/null +++ b/vendor/golang.org/x/crypto/blake2b/blake2x.go @@ -0,0 +1,177 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package blake2b + +import ( + "encoding/binary" + "errors" + "io" +) + +// XOF defines the interface to hash functions that +// support arbitrary-length output. +type XOF interface { + // Write absorbs more data into the hash's state. It panics if called + // after Read. + io.Writer + + // Read reads more output from the hash. It returns io.EOF if the limit + // has been reached. + io.Reader + + // Clone returns a copy of the XOF in its current state. + Clone() XOF + + // Reset resets the XOF to its initial state. + Reset() +} + +// OutputLengthUnknown can be used as the size argument to NewXOF to indicate +// the length of the output is not known in advance. +const OutputLengthUnknown = 0 + +// magicUnknownOutputLength is a magic value for the output size that indicates +// an unknown number of output bytes. +const magicUnknownOutputLength = (1 << 32) - 1 + +// maxOutputLength is the absolute maximum number of bytes to produce when the +// number of output bytes is unknown. +const maxOutputLength = (1 << 32) * 64 + +// NewXOF creates a new variable-output-length hash. The hash either produce a +// known number of bytes (1 <= size < 2**32-1), or an unknown number of bytes +// (size == OutputLengthUnknown). In the latter case, an absolute limit of +// 256GiB applies. +// +// A non-nil key turns the hash into a MAC. The key must between +// zero and 32 bytes long. +func NewXOF(size uint32, key []byte) (XOF, error) { + if len(key) > Size { + return nil, errKeySize + } + if size == magicUnknownOutputLength { + // 2^32-1 indicates an unknown number of bytes and thus isn't a + // valid length. + return nil, errors.New("blake2b: XOF length too large") + } + if size == OutputLengthUnknown { + size = magicUnknownOutputLength + } + x := &xof{ + d: digest{ + size: Size, + keyLen: len(key), + }, + length: size, + } + copy(x.d.key[:], key) + x.Reset() + return x, nil +} + +type xof struct { + d digest + length uint32 + remaining uint64 + cfg, root, block [Size]byte + offset int + nodeOffset uint32 + readMode bool +} + +func (x *xof) Write(p []byte) (n int, err error) { + if x.readMode { + panic("blake2b: write to XOF after read") + } + return x.d.Write(p) +} + +func (x *xof) Clone() XOF { + clone := *x + return &clone +} + +func (x *xof) Reset() { + x.cfg[0] = byte(Size) + binary.LittleEndian.PutUint32(x.cfg[4:], uint32(Size)) // leaf length + binary.LittleEndian.PutUint32(x.cfg[12:], x.length) // XOF length + x.cfg[17] = byte(Size) // inner hash size + + x.d.Reset() + x.d.h[1] ^= uint64(x.length) << 32 + + x.remaining = uint64(x.length) + if x.remaining == magicUnknownOutputLength { + x.remaining = maxOutputLength + } + x.offset, x.nodeOffset = 0, 0 + x.readMode = false +} + +func (x *xof) Read(p []byte) (n int, err error) { + if !x.readMode { + x.d.finalize(&x.root) + x.readMode = true + } + + if x.remaining == 0 { + return 0, io.EOF + } + + n = len(p) + if uint64(n) > x.remaining { + n = int(x.remaining) + p = p[:n] + } + + if x.offset > 0 { + blockRemaining := Size - x.offset + if n < blockRemaining { + x.offset += copy(p, x.block[x.offset:]) + x.remaining -= uint64(n) + return + } + copy(p, x.block[x.offset:]) + p = p[blockRemaining:] + x.offset = 0 + x.remaining -= uint64(blockRemaining) + } + + for len(p) >= Size { + binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset) + x.nodeOffset++ + + x.d.initConfig(&x.cfg) + x.d.Write(x.root[:]) + x.d.finalize(&x.block) + + copy(p, x.block[:]) + p = p[Size:] + x.remaining -= uint64(Size) + } + + if todo := len(p); todo > 0 { + if x.remaining < uint64(Size) { + x.cfg[0] = byte(x.remaining) + } + binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset) + x.nodeOffset++ + + x.d.initConfig(&x.cfg) + x.d.Write(x.root[:]) + x.d.finalize(&x.block) + + x.offset = copy(p, x.block[:todo]) + x.remaining -= uint64(todo) + } + return +} + +func (d *digest) initConfig(cfg *[Size]byte) { + d.offset, d.c[0], d.c[1] = 0, 0, 0 + for i := range d.h { + d.h[i] = iv[i] ^ binary.LittleEndian.Uint64(cfg[i*8:]) + } +} diff --git a/vendor/golang.org/x/crypto/blake2b/register.go b/vendor/golang.org/x/crypto/blake2b/register.go new file mode 100644 index 00000000..54e446e1 --- /dev/null +++ b/vendor/golang.org/x/crypto/blake2b/register.go @@ -0,0 +1,30 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package blake2b + +import ( + "crypto" + "hash" +) + +func init() { + newHash256 := func() hash.Hash { + h, _ := New256(nil) + return h + } + newHash384 := func() hash.Hash { + h, _ := New384(nil) + return h + } + + newHash512 := func() hash.Hash { + h, _ := New512(nil) + return h + } + + crypto.RegisterHash(crypto.BLAKE2b_256, newHash256) + crypto.RegisterHash(crypto.BLAKE2b_384, newHash384) + crypto.RegisterHash(crypto.BLAKE2b_512, newHash512) +} diff --git a/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go b/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go index 2681af35..150f887e 100644 --- a/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go +++ b/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go @@ -13,7 +13,7 @@ import ( "sync" ) -// Regexp is a wrapper around regexp.Regexp, where the underlying regexp will be +// Regexp is a wrapper around [regexp.Regexp], where the underlying regexp will be // compiled the first time it is needed. type Regexp struct { str string diff --git a/vendor/golang.org/x/mod/modfile/read.go b/vendor/golang.org/x/mod/modfile/read.go index a503bc21..22056825 100644 --- a/vendor/golang.org/x/mod/modfile/read.go +++ b/vendor/golang.org/x/mod/modfile/read.go @@ -65,7 +65,7 @@ type Comments struct { } // Comment returns the receiver. This isn't useful by itself, but -// a Comments struct is embedded into all the expression +// a [Comments] struct is embedded into all the expression // implementation types, and this gives each of those a Comment // method to satisfy the Expr interface. func (c *Comments) Comment() *Comments { @@ -225,7 +225,7 @@ func (x *FileSyntax) Cleanup() { if ww == 0 { continue } - if ww == 1 { + if ww == 1 && len(stmt.RParen.Comments.Before) == 0 { // Collapse block into single line. line := &Line{ Comments: Comments{ diff --git a/vendor/golang.org/x/mod/modfile/rule.go b/vendor/golang.org/x/mod/modfile/rule.go index b4dd7997..0e7b7e26 100644 --- a/vendor/golang.org/x/mod/modfile/rule.go +++ b/vendor/golang.org/x/mod/modfile/rule.go @@ -5,17 +5,17 @@ // Package modfile implements a parser and formatter for go.mod files. // // The go.mod syntax is described in -// https://golang.org/cmd/go/#hdr-The_go_mod_file. +// https://pkg.go.dev/cmd/go/#hdr-The_go_mod_file. // -// The Parse and ParseLax functions both parse a go.mod file and return an +// The [Parse] and [ParseLax] functions both parse a go.mod file and return an // abstract syntax tree. ParseLax ignores unknown statements and may be used to // parse go.mod files that may have been developed with newer versions of Go. // -// The File struct returned by Parse and ParseLax represent an abstract -// go.mod file. File has several methods like AddNewRequire and DropReplace -// that can be used to programmatically edit a file. +// The [File] struct returned by Parse and ParseLax represent an abstract +// go.mod file. File has several methods like [File.AddNewRequire] and +// [File.DropReplace] that can be used to programmatically edit a file. // -// The Format function formats a File back to a byte slice which can be +// The [Format] function formats a File back to a byte slice which can be // written to a file. package modfile @@ -226,7 +226,7 @@ var dontFixRetract VersionFixer = func(_, vers string) (string, error) { // data is the content of the file. // // fix is an optional function that canonicalizes module versions. -// If fix is nil, all module versions must be canonical (module.CanonicalVersion +// If fix is nil, all module versions must be canonical ([module.CanonicalVersion] // must return the same string). func Parse(file string, data []byte, fix VersionFixer) (*File, error) { return parseToFile(file, data, fix, true) @@ -308,6 +308,7 @@ var laxGoVersionRE = lazyregexp.New(`^v?(([1-9][0-9]*)\.(0|[1-9][0-9]*))([^0-9]. // Toolchains must be named beginning with `go1`, // like "go1.20.3" or "go1.20.3-gccgo". As a special case, "default" is also permitted. +// TODO(samthanawalla): Replace regex with https://pkg.go.dev/go/version#IsValid in 1.23+ var ToolchainRE = lazyregexp.New(`^default$|^go1($|\.)`) func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, args []string, fix VersionFixer, strict bool) { @@ -367,7 +368,7 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a } } if !fixed { - errorf("invalid go version '%s': must match format 1.23", args[0]) + errorf("invalid go version '%s': must match format 1.23.0", args[0]) return } } @@ -384,7 +385,7 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a errorf("toolchain directive expects exactly one argument") return } else if strict && !ToolchainRE.MatchString(args[0]) { - errorf("invalid toolchain version '%s': must match format go1.23 or local", args[0]) + errorf("invalid toolchain version '%s': must match format go1.23.0 or default", args[0]) return } f.Toolchain = &Toolchain{Syntax: line} @@ -542,7 +543,7 @@ func parseReplace(filename string, line *Line, verb string, args []string, fix V if strings.Contains(ns, "@") { return nil, errorf("replacement module must match format 'path version', not 'path@version'") } - return nil, errorf("replacement module without version must be directory path (rooted or starting with ./ or ../)") + return nil, errorf("replacement module without version must be directory path (rooted or starting with . or ..)") } if filepath.Separator == '/' && strings.Contains(ns, `\`) { return nil, errorf("replacement directory appears to be Windows path (on a non-windows system)") @@ -555,7 +556,6 @@ func parseReplace(filename string, line *Line, verb string, args []string, fix V } if IsDirectoryPath(ns) { return nil, errorf("replacement module directory path %q cannot have version", ns) - } } return &Replace{ @@ -631,7 +631,7 @@ func (f *WorkFile) add(errs *ErrorList, line *Line, verb string, args []string, errorf("go directive expects exactly one argument") return } else if !GoVersionRE.MatchString(args[0]) { - errorf("invalid go version '%s': must match format 1.23", args[0]) + errorf("invalid go version '%s': must match format 1.23.0", args[0]) return } @@ -647,7 +647,7 @@ func (f *WorkFile) add(errs *ErrorList, line *Line, verb string, args []string, errorf("toolchain directive expects exactly one argument") return } else if !ToolchainRE.MatchString(args[0]) { - errorf("invalid toolchain version '%s': must match format go1.23 or local", args[0]) + errorf("invalid toolchain version '%s': must match format go1.23.0 or default", args[0]) return } @@ -679,14 +679,15 @@ func (f *WorkFile) add(errs *ErrorList, line *Line, verb string, args []string, } } -// IsDirectoryPath reports whether the given path should be interpreted -// as a directory path. Just like on the go command line, relative paths +// IsDirectoryPath reports whether the given path should be interpreted as a directory path. +// Just like on the go command line, relative paths starting with a '.' or '..' path component // and rooted paths are directory paths; the rest are module paths. func IsDirectoryPath(ns string) bool { // Because go.mod files can move from one system to another, // we check all known path syntaxes, both Unix and Windows. - return strings.HasPrefix(ns, "./") || strings.HasPrefix(ns, "../") || strings.HasPrefix(ns, "/") || - strings.HasPrefix(ns, `.\`) || strings.HasPrefix(ns, `..\`) || strings.HasPrefix(ns, `\`) || + return ns == "." || strings.HasPrefix(ns, "./") || strings.HasPrefix(ns, `.\`) || + ns == ".." || strings.HasPrefix(ns, "../") || strings.HasPrefix(ns, `..\`) || + strings.HasPrefix(ns, "/") || strings.HasPrefix(ns, `\`) || len(ns) >= 2 && ('A' <= ns[0] && ns[0] <= 'Z' || 'a' <= ns[0] && ns[0] <= 'z') && ns[1] == ':' } @@ -923,7 +924,7 @@ func (f *File) Format() ([]byte, error) { } // Cleanup cleans up the file f after any edit operations. -// To avoid quadratic behavior, modifications like DropRequire +// To avoid quadratic behavior, modifications like [File.DropRequire] // clear the entry but do not remove it from the slice. // Cleanup cleans out all the cleared entries. func (f *File) Cleanup() { @@ -974,6 +975,8 @@ func (f *File) AddGoStmt(version string) error { var hint Expr if f.Module != nil && f.Module.Syntax != nil { hint = f.Module.Syntax + } else if f.Syntax == nil { + f.Syntax = new(FileSyntax) } f.Go = &Go{ Version: version, @@ -1075,8 +1078,8 @@ func (f *File) AddNewRequire(path, vers string, indirect bool) { // The requirements in req must specify at most one distinct version for each // module path. // -// If any existing requirements may be removed, the caller should call Cleanup -// after all edits are complete. +// If any existing requirements may be removed, the caller should call +// [File.Cleanup] after all edits are complete. func (f *File) SetRequire(req []*Require) { type elem struct { version string diff --git a/vendor/golang.org/x/mod/modfile/work.go b/vendor/golang.org/x/mod/modfile/work.go index 75dc1c54..d7b99376 100644 --- a/vendor/golang.org/x/mod/modfile/work.go +++ b/vendor/golang.org/x/mod/modfile/work.go @@ -34,7 +34,7 @@ type Use struct { // data is the content of the file. // // fix is an optional function that canonicalizes module versions. -// If fix is nil, all module versions must be canonical (module.CanonicalVersion +// If fix is nil, all module versions must be canonical ([module.CanonicalVersion] // must return the same string). func ParseWork(file string, data []byte, fix VersionFixer) (*WorkFile, error) { fs, err := parse(file, data) @@ -83,7 +83,7 @@ func ParseWork(file string, data []byte, fix VersionFixer) (*WorkFile, error) { } // Cleanup cleans up the file f after any edit operations. -// To avoid quadratic behavior, modifications like DropRequire +// To avoid quadratic behavior, modifications like [WorkFile.DropRequire] // clear the entry but do not remove it from the slice. // Cleanup cleans out all the cleared entries. func (f *WorkFile) Cleanup() { diff --git a/vendor/golang.org/x/mod/module/module.go b/vendor/golang.org/x/mod/module/module.go index e9dec6e6..2a364b22 100644 --- a/vendor/golang.org/x/mod/module/module.go +++ b/vendor/golang.org/x/mod/module/module.go @@ -4,7 +4,7 @@ // Package module defines the module.Version type along with support code. // -// The module.Version type is a simple Path, Version pair: +// The [module.Version] type is a simple Path, Version pair: // // type Version struct { // Path string @@ -12,7 +12,7 @@ // } // // There are no restrictions imposed directly by use of this structure, -// but additional checking functions, most notably Check, verify that +// but additional checking functions, most notably [Check], verify that // a particular path, version pair is valid. // // # Escaped Paths @@ -140,7 +140,7 @@ type ModuleError struct { Err error } -// VersionError returns a ModuleError derived from a Version and error, +// VersionError returns a [ModuleError] derived from a [Version] and error, // or err itself if it is already such an error. func VersionError(v Version, err error) error { var mErr *ModuleError @@ -169,7 +169,7 @@ func (e *ModuleError) Unwrap() error { return e.Err } // An InvalidVersionError indicates an error specific to a version, with the // module path unknown or specified externally. // -// A ModuleError may wrap an InvalidVersionError, but an InvalidVersionError +// A [ModuleError] may wrap an InvalidVersionError, but an InvalidVersionError // must not wrap a ModuleError. type InvalidVersionError struct { Version string @@ -193,8 +193,8 @@ func (e *InvalidVersionError) Error() string { func (e *InvalidVersionError) Unwrap() error { return e.Err } // An InvalidPathError indicates a module, import, or file path doesn't -// satisfy all naming constraints. See CheckPath, CheckImportPath, -// and CheckFilePath for specific restrictions. +// satisfy all naming constraints. See [CheckPath], [CheckImportPath], +// and [CheckFilePath] for specific restrictions. type InvalidPathError struct { Kind string // "module", "import", or "file" Path string @@ -294,7 +294,7 @@ func fileNameOK(r rune) bool { } // CheckPath checks that a module path is valid. -// A valid module path is a valid import path, as checked by CheckImportPath, +// A valid module path is a valid import path, as checked by [CheckImportPath], // with three additional constraints. // First, the leading path element (up to the first slash, if any), // by convention a domain name, must contain only lower-case ASCII letters, @@ -380,7 +380,7 @@ const ( // checkPath returns an error describing why the path is not valid. // Because these checks apply to module, import, and file paths, // and because other checks may be applied, the caller is expected to wrap -// this error with InvalidPathError. +// this error with [InvalidPathError]. func checkPath(path string, kind pathKind) error { if !utf8.ValidString(path) { return fmt.Errorf("invalid UTF-8") @@ -532,7 +532,7 @@ var badWindowsNames = []string{ // they require ".vN" instead of "/vN", and for all N, not just N >= 2. // SplitPathVersion returns with ok = false when presented with // a path whose last path element does not satisfy the constraints -// applied by CheckPath, such as "example.com/pkg/v1" or "example.com/pkg/v1.2". +// applied by [CheckPath], such as "example.com/pkg/v1" or "example.com/pkg/v1.2". func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) { if strings.HasPrefix(path, "gopkg.in/") { return splitGopkgIn(path) @@ -582,7 +582,7 @@ func splitGopkgIn(path string) (prefix, pathMajor string, ok bool) { // MatchPathMajor reports whether the semantic version v // matches the path major version pathMajor. // -// MatchPathMajor returns true if and only if CheckPathMajor returns nil. +// MatchPathMajor returns true if and only if [CheckPathMajor] returns nil. func MatchPathMajor(v, pathMajor string) bool { return CheckPathMajor(v, pathMajor) == nil } @@ -622,7 +622,7 @@ func CheckPathMajor(v, pathMajor string) error { // PathMajorPrefix returns the major-version tag prefix implied by pathMajor. // An empty PathMajorPrefix allows either v0 or v1. // -// Note that MatchPathMajor may accept some versions that do not actually begin +// Note that [MatchPathMajor] may accept some versions that do not actually begin // with this prefix: namely, it accepts a 'v0.0.0-' prefix for a '.v1' // pathMajor, even though that pathMajor implies 'v1' tagging. func PathMajorPrefix(pathMajor string) string { @@ -643,7 +643,7 @@ func PathMajorPrefix(pathMajor string) string { } // CanonicalVersion returns the canonical form of the version string v. -// It is the same as semver.Canonical(v) except that it preserves the special build suffix "+incompatible". +// It is the same as [semver.Canonical] except that it preserves the special build suffix "+incompatible". func CanonicalVersion(v string) string { cv := semver.Canonical(v) if semver.Build(v) == "+incompatible" { @@ -652,8 +652,8 @@ func CanonicalVersion(v string) string { return cv } -// Sort sorts the list by Path, breaking ties by comparing Version fields. -// The Version fields are interpreted as semantic versions (using semver.Compare) +// Sort sorts the list by Path, breaking ties by comparing [Version] fields. +// The Version fields are interpreted as semantic versions (using [semver.Compare]) // optionally followed by a tie-breaking suffix introduced by a slash character, // like in "v0.0.1/go.mod". func Sort(list []Version) { @@ -793,7 +793,7 @@ func unescapeString(escaped string) (string, bool) { } // MatchPrefixPatterns reports whether any path prefix of target matches one of -// the glob patterns (as defined by path.Match) in the comma-separated globs +// the glob patterns (as defined by [path.Match]) in the comma-separated globs // list. This implements the algorithm used when matching a module path to the // GOPRIVATE environment variable, as described by 'go help module-private'. // diff --git a/vendor/golang.org/x/mod/module/pseudo.go b/vendor/golang.org/x/mod/module/pseudo.go index f04ad378..9cf19d32 100644 --- a/vendor/golang.org/x/mod/module/pseudo.go +++ b/vendor/golang.org/x/mod/module/pseudo.go @@ -125,7 +125,7 @@ func IsPseudoVersion(v string) bool { } // IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base, -// timestamp, and revision, as returned by ZeroPseudoVersion. +// timestamp, and revision, as returned by [ZeroPseudoVersion]. func IsZeroPseudoVersion(v string) bool { return v == ZeroPseudoVersion(semver.Major(v)) } diff --git a/vendor/golang.org/x/mod/semver/semver.go b/vendor/golang.org/x/mod/semver/semver.go index a30a22bf..9a2dfd33 100644 --- a/vendor/golang.org/x/mod/semver/semver.go +++ b/vendor/golang.org/x/mod/semver/semver.go @@ -140,7 +140,7 @@ func Compare(v, w string) int { // Max canonicalizes its arguments and then returns the version string // that compares greater. // -// Deprecated: use Compare instead. In most cases, returning a canonicalized +// Deprecated: use [Compare] instead. In most cases, returning a canonicalized // version is not expected or desired. func Max(v, w string) string { v = Canonical(v) @@ -151,7 +151,7 @@ func Max(v, w string) string { return w } -// ByVersion implements sort.Interface for sorting semantic version strings. +// ByVersion implements [sort.Interface] for sorting semantic version strings. type ByVersion []string func (vs ByVersion) Len() int { return len(vs) } @@ -164,7 +164,7 @@ func (vs ByVersion) Less(i, j int) bool { return vs[i] < vs[j] } -// Sort sorts a list of semantic version strings using ByVersion. +// Sort sorts a list of semantic version strings using [ByVersion]. func Sort(list []string) { sort.Sort(ByVersion(list)) } diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go deleted file mode 100644 index cf66309c..00000000 --- a/vendor/golang.org/x/net/context/context.go +++ /dev/null @@ -1,56 +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 context defines the Context type, which carries deadlines, -// cancelation signals, and other request-scoped values across API boundaries -// and between processes. -// As of Go 1.7 this package is available in the standard library under the -// name context. https://golang.org/pkg/context. -// -// Incoming requests to a server should create a Context, and outgoing calls to -// servers should accept a Context. The chain of function calls between must -// propagate the Context, optionally replacing it with a modified copy created -// using WithDeadline, WithTimeout, WithCancel, or WithValue. -// -// Programs that use Contexts should follow these rules to keep interfaces -// consistent across packages and enable static analysis tools to check context -// propagation: -// -// Do not store Contexts inside a struct type; instead, pass a Context -// explicitly to each function that needs it. The Context should be the first -// parameter, typically named ctx: -// -// func DoSomething(ctx context.Context, arg Arg) error { -// // ... use ctx ... -// } -// -// Do not pass a nil Context, even if a function permits it. Pass context.TODO -// if you are unsure about which Context to use. -// -// Use context Values only for request-scoped data that transits processes and -// APIs, not for passing optional parameters to functions. -// -// The same Context may be passed to functions running in different goroutines; -// Contexts are safe for simultaneous use by multiple goroutines. -// -// See http://blog.golang.org/context for example code for a server that uses -// Contexts. -package context // import "golang.org/x/net/context" - -// Background returns a non-nil, empty Context. It is never canceled, has no -// values, and has no deadline. It is typically used by the main function, -// initialization, and tests, and as the top-level Context for incoming -// requests. -func Background() Context { - return background -} - -// TODO returns a non-nil, empty Context. Code should use context.TODO when -// it's unclear which Context to use or it is not yet available (because the -// surrounding function has not yet been extended to accept a Context -// parameter). TODO is recognized by static analysis tools that determine -// whether Contexts are propagated correctly in a program. -func TODO() Context { - return todo -} diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go deleted file mode 100644 index 2cb9c408..00000000 --- a/vendor/golang.org/x/net/context/go17.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2016 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. - -//go:build go1.7 -// +build go1.7 - -package context - -import ( - "context" // standard library's context, as of Go 1.7 - "time" -) - -var ( - todo = context.TODO() - background = context.Background() -) - -// Canceled is the error returned by Context.Err when the context is canceled. -var Canceled = context.Canceled - -// DeadlineExceeded is the error returned by Context.Err when the context's -// deadline passes. -var DeadlineExceeded = context.DeadlineExceeded - -// WithCancel returns a copy of parent with a new Done channel. The returned -// context's Done channel is closed when the returned cancel function is called -// or when the parent context's Done channel is closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { - ctx, f := context.WithCancel(parent) - return ctx, f -} - -// WithDeadline returns a copy of the parent context with the deadline adjusted -// to be no later than d. If the parent's deadline is already earlier than d, -// WithDeadline(parent, d) is semantically equivalent to parent. The returned -// context's Done channel is closed when the deadline expires, when the returned -// cancel function is called, or when the parent context's Done channel is -// closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { - ctx, f := context.WithDeadline(parent, deadline) - return ctx, f -} - -// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete: -// -// func slowOperationWithTimeout(ctx context.Context) (Result, error) { -// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) -// defer cancel() // releases resources if slowOperation completes before timeout elapses -// return slowOperation(ctx) -// } -func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { - return WithDeadline(parent, time.Now().Add(timeout)) -} - -// WithValue returns a copy of parent in which the value associated with key is -// val. -// -// Use context Values only for request-scoped data that transits processes and -// APIs, not for passing optional parameters to functions. -func WithValue(parent Context, key interface{}, val interface{}) Context { - return context.WithValue(parent, key, val) -} diff --git a/vendor/golang.org/x/net/context/go19.go b/vendor/golang.org/x/net/context/go19.go deleted file mode 100644 index 64d31ecc..00000000 --- a/vendor/golang.org/x/net/context/go19.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.9 -// +build go1.9 - -package context - -import "context" // standard library's context, as of Go 1.7 - -// A Context carries a deadline, a cancelation signal, and other values across -// API boundaries. -// -// Context's methods may be called by multiple goroutines simultaneously. -type Context = context.Context - -// A CancelFunc tells an operation to abandon its work. -// A CancelFunc does not wait for the work to stop. -// After the first call, subsequent calls to a CancelFunc do nothing. -type CancelFunc = context.CancelFunc diff --git a/vendor/golang.org/x/net/context/pre_go17.go b/vendor/golang.org/x/net/context/pre_go17.go deleted file mode 100644 index 7b6b6851..00000000 --- a/vendor/golang.org/x/net/context/pre_go17.go +++ /dev/null @@ -1,301 +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. - -//go:build !go1.7 -// +build !go1.7 - -package context - -import ( - "errors" - "fmt" - "sync" - "time" -) - -// An emptyCtx is never canceled, has no values, and has no deadline. It is not -// struct{}, since vars of this type must have distinct addresses. -type emptyCtx int - -func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { - return -} - -func (*emptyCtx) Done() <-chan struct{} { - return nil -} - -func (*emptyCtx) Err() error { - return nil -} - -func (*emptyCtx) Value(key interface{}) interface{} { - return nil -} - -func (e *emptyCtx) String() string { - switch e { - case background: - return "context.Background" - case todo: - return "context.TODO" - } - return "unknown empty Context" -} - -var ( - background = new(emptyCtx) - todo = new(emptyCtx) -) - -// Canceled is the error returned by Context.Err when the context is canceled. -var Canceled = errors.New("context canceled") - -// DeadlineExceeded is the error returned by Context.Err when the context's -// deadline passes. -var DeadlineExceeded = errors.New("context deadline exceeded") - -// WithCancel returns a copy of parent with a new Done channel. The returned -// context's Done channel is closed when the returned cancel function is called -// or when the parent context's Done channel is closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { - c := newCancelCtx(parent) - propagateCancel(parent, c) - return c, func() { c.cancel(true, Canceled) } -} - -// newCancelCtx returns an initialized cancelCtx. -func newCancelCtx(parent Context) *cancelCtx { - return &cancelCtx{ - Context: parent, - done: make(chan struct{}), - } -} - -// propagateCancel arranges for child to be canceled when parent is. -func propagateCancel(parent Context, child canceler) { - if parent.Done() == nil { - return // parent is never canceled - } - if p, ok := parentCancelCtx(parent); ok { - p.mu.Lock() - if p.err != nil { - // parent has already been canceled - child.cancel(false, p.err) - } else { - if p.children == nil { - p.children = make(map[canceler]bool) - } - p.children[child] = true - } - p.mu.Unlock() - } else { - go func() { - select { - case <-parent.Done(): - child.cancel(false, parent.Err()) - case <-child.Done(): - } - }() - } -} - -// parentCancelCtx follows a chain of parent references until it finds a -// *cancelCtx. This function understands how each of the concrete types in this -// package represents its parent. -func parentCancelCtx(parent Context) (*cancelCtx, bool) { - for { - switch c := parent.(type) { - case *cancelCtx: - return c, true - case *timerCtx: - return c.cancelCtx, true - case *valueCtx: - parent = c.Context - default: - return nil, false - } - } -} - -// removeChild removes a context from its parent. -func removeChild(parent Context, child canceler) { - p, ok := parentCancelCtx(parent) - if !ok { - return - } - p.mu.Lock() - if p.children != nil { - delete(p.children, child) - } - p.mu.Unlock() -} - -// A canceler is a context type that can be canceled directly. The -// implementations are *cancelCtx and *timerCtx. -type canceler interface { - cancel(removeFromParent bool, err error) - Done() <-chan struct{} -} - -// A cancelCtx can be canceled. When canceled, it also cancels any children -// that implement canceler. -type cancelCtx struct { - Context - - done chan struct{} // closed by the first cancel call. - - mu sync.Mutex - children map[canceler]bool // set to nil by the first cancel call - err error // set to non-nil by the first cancel call -} - -func (c *cancelCtx) Done() <-chan struct{} { - return c.done -} - -func (c *cancelCtx) Err() error { - c.mu.Lock() - defer c.mu.Unlock() - return c.err -} - -func (c *cancelCtx) String() string { - return fmt.Sprintf("%v.WithCancel", c.Context) -} - -// cancel closes c.done, cancels each of c's children, and, if -// removeFromParent is true, removes c from its parent's children. -func (c *cancelCtx) cancel(removeFromParent bool, err error) { - if err == nil { - panic("context: internal error: missing cancel error") - } - c.mu.Lock() - if c.err != nil { - c.mu.Unlock() - return // already canceled - } - c.err = err - close(c.done) - for child := range c.children { - // NOTE: acquiring the child's lock while holding parent's lock. - child.cancel(false, err) - } - c.children = nil - c.mu.Unlock() - - if removeFromParent { - removeChild(c.Context, c) - } -} - -// WithDeadline returns a copy of the parent context with the deadline adjusted -// to be no later than d. If the parent's deadline is already earlier than d, -// WithDeadline(parent, d) is semantically equivalent to parent. The returned -// context's Done channel is closed when the deadline expires, when the returned -// cancel function is called, or when the parent context's Done channel is -// closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { - if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { - // The current deadline is already sooner than the new one. - return WithCancel(parent) - } - c := &timerCtx{ - cancelCtx: newCancelCtx(parent), - deadline: deadline, - } - propagateCancel(parent, c) - d := deadline.Sub(time.Now()) - if d <= 0 { - c.cancel(true, DeadlineExceeded) // deadline has already passed - return c, func() { c.cancel(true, Canceled) } - } - c.mu.Lock() - defer c.mu.Unlock() - if c.err == nil { - c.timer = time.AfterFunc(d, func() { - c.cancel(true, DeadlineExceeded) - }) - } - return c, func() { c.cancel(true, Canceled) } -} - -// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to -// implement Done and Err. It implements cancel by stopping its timer then -// delegating to cancelCtx.cancel. -type timerCtx struct { - *cancelCtx - timer *time.Timer // Under cancelCtx.mu. - - deadline time.Time -} - -func (c *timerCtx) Deadline() (deadline time.Time, ok bool) { - return c.deadline, true -} - -func (c *timerCtx) String() string { - return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now())) -} - -func (c *timerCtx) cancel(removeFromParent bool, err error) { - c.cancelCtx.cancel(false, err) - if removeFromParent { - // Remove this timerCtx from its parent cancelCtx's children. - removeChild(c.cancelCtx.Context, c) - } - c.mu.Lock() - if c.timer != nil { - c.timer.Stop() - c.timer = nil - } - c.mu.Unlock() -} - -// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete: -// -// func slowOperationWithTimeout(ctx context.Context) (Result, error) { -// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) -// defer cancel() // releases resources if slowOperation completes before timeout elapses -// return slowOperation(ctx) -// } -func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { - return WithDeadline(parent, time.Now().Add(timeout)) -} - -// WithValue returns a copy of parent in which the value associated with key is -// val. -// -// Use context Values only for request-scoped data that transits processes and -// APIs, not for passing optional parameters to functions. -func WithValue(parent Context, key interface{}, val interface{}) Context { - return &valueCtx{parent, key, val} -} - -// A valueCtx carries a key-value pair. It implements Value for that key and -// delegates all other calls to the embedded Context. -type valueCtx struct { - Context - key, val interface{} -} - -func (c *valueCtx) String() string { - return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val) -} - -func (c *valueCtx) Value(key interface{}) interface{} { - if c.key == key { - return c.val - } - return c.Context.Value(key) -} diff --git a/vendor/golang.org/x/net/context/pre_go19.go b/vendor/golang.org/x/net/context/pre_go19.go deleted file mode 100644 index 1f971534..00000000 --- a/vendor/golang.org/x/net/context/pre_go19.go +++ /dev/null @@ -1,110 +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. - -//go:build !go1.9 -// +build !go1.9 - -package context - -import "time" - -// A Context carries a deadline, a cancelation signal, and other values across -// API boundaries. -// -// Context's methods may be called by multiple goroutines simultaneously. -type Context interface { - // Deadline returns the time when work done on behalf of this context - // should be canceled. Deadline returns ok==false when no deadline is - // set. Successive calls to Deadline return the same results. - Deadline() (deadline time.Time, ok bool) - - // Done returns a channel that's closed when work done on behalf of this - // context should be canceled. Done may return nil if this context can - // never be canceled. Successive calls to Done return the same value. - // - // WithCancel arranges for Done to be closed when cancel is called; - // WithDeadline arranges for Done to be closed when the deadline - // expires; WithTimeout arranges for Done to be closed when the timeout - // elapses. - // - // Done is provided for use in select statements: - // - // // Stream generates values with DoSomething and sends them to out - // // until DoSomething returns an error or ctx.Done is closed. - // func Stream(ctx context.Context, out chan<- Value) error { - // for { - // v, err := DoSomething(ctx) - // if err != nil { - // return err - // } - // select { - // case <-ctx.Done(): - // return ctx.Err() - // case out <- v: - // } - // } - // } - // - // See http://blog.golang.org/pipelines for more examples of how to use - // a Done channel for cancelation. - Done() <-chan struct{} - - // Err returns a non-nil error value after Done is closed. Err returns - // Canceled if the context was canceled or DeadlineExceeded if the - // context's deadline passed. No other values for Err are defined. - // After Done is closed, successive calls to Err return the same value. - Err() error - - // Value returns the value associated with this context for key, or nil - // if no value is associated with key. Successive calls to Value with - // the same key returns the same result. - // - // Use context values only for request-scoped data that transits - // processes and API boundaries, not for passing optional parameters to - // functions. - // - // A key identifies a specific value in a Context. Functions that wish - // to store values in Context typically allocate a key in a global - // variable then use that key as the argument to context.WithValue and - // Context.Value. A key can be any type that supports equality; - // packages should define keys as an unexported type to avoid - // collisions. - // - // Packages that define a Context key should provide type-safe accessors - // for the values stores using that key: - // - // // Package user defines a User type that's stored in Contexts. - // package user - // - // import "golang.org/x/net/context" - // - // // User is the type of value stored in the Contexts. - // type User struct {...} - // - // // key is an unexported type for keys defined in this package. - // // This prevents collisions with keys defined in other packages. - // type key int - // - // // userKey is the key for user.User values in Contexts. It is - // // unexported; clients use user.NewContext and user.FromContext - // // instead of using this key directly. - // var userKey key = 0 - // - // // NewContext returns a new Context that carries value u. - // func NewContext(ctx context.Context, u *User) context.Context { - // return context.WithValue(ctx, userKey, u) - // } - // - // // FromContext returns the User value stored in ctx, if any. - // func FromContext(ctx context.Context) (*User, bool) { - // u, ok := ctx.Value(userKey).(*User) - // return u, ok - // } - Value(key interface{}) interface{} -} - -// A CancelFunc tells an operation to abandon its work. -// A CancelFunc does not wait for the work to stop. -// After the first call, subsequent calls to a CancelFunc do nothing. -type CancelFunc func() diff --git a/vendor/golang.org/x/net/http2/databuffer.go b/vendor/golang.org/x/net/http2/databuffer.go index a3067f8d..e6f55cbd 100644 --- a/vendor/golang.org/x/net/http2/databuffer.go +++ b/vendor/golang.org/x/net/http2/databuffer.go @@ -20,41 +20,44 @@ import ( // TODO: Benchmark to determine if the pools are necessary. The GC may have // improved enough that we can instead allocate chunks like this: // make([]byte, max(16<<10, expectedBytesRemaining)) -var ( - dataChunkSizeClasses = []int{ - 1 << 10, - 2 << 10, - 4 << 10, - 8 << 10, - 16 << 10, - } - dataChunkPools = [...]sync.Pool{ - {New: func() interface{} { return make([]byte, 1<<10) }}, - {New: func() interface{} { return make([]byte, 2<<10) }}, - {New: func() interface{} { return make([]byte, 4<<10) }}, - {New: func() interface{} { return make([]byte, 8<<10) }}, - {New: func() interface{} { return make([]byte, 16<<10) }}, - } -) +var dataChunkPools = [...]sync.Pool{ + {New: func() interface{} { return new([1 << 10]byte) }}, + {New: func() interface{} { return new([2 << 10]byte) }}, + {New: func() interface{} { return new([4 << 10]byte) }}, + {New: func() interface{} { return new([8 << 10]byte) }}, + {New: func() interface{} { return new([16 << 10]byte) }}, +} func getDataBufferChunk(size int64) []byte { - i := 0 - for ; i < len(dataChunkSizeClasses)-1; i++ { - if size <= int64(dataChunkSizeClasses[i]) { - break - } + switch { + case size <= 1<<10: + return dataChunkPools[0].Get().(*[1 << 10]byte)[:] + case size <= 2<<10: + return dataChunkPools[1].Get().(*[2 << 10]byte)[:] + case size <= 4<<10: + return dataChunkPools[2].Get().(*[4 << 10]byte)[:] + case size <= 8<<10: + return dataChunkPools[3].Get().(*[8 << 10]byte)[:] + default: + return dataChunkPools[4].Get().(*[16 << 10]byte)[:] } - return dataChunkPools[i].Get().([]byte) } func putDataBufferChunk(p []byte) { - for i, n := range dataChunkSizeClasses { - if len(p) == n { - dataChunkPools[i].Put(p) - return - } + switch len(p) { + case 1 << 10: + dataChunkPools[0].Put((*[1 << 10]byte)(p)) + case 2 << 10: + dataChunkPools[1].Put((*[2 << 10]byte)(p)) + case 4 << 10: + dataChunkPools[2].Put((*[4 << 10]byte)(p)) + case 8 << 10: + dataChunkPools[3].Put((*[8 << 10]byte)(p)) + case 16 << 10: + dataChunkPools[4].Put((*[16 << 10]byte)(p)) + default: + panic(fmt.Sprintf("unexpected buffer len=%v", len(p))) } - panic(fmt.Sprintf("unexpected buffer len=%v", len(p))) } // dataBuffer is an io.ReadWriter backed by a list of data chunks. diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index c1f6b90d..43557ab7 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -1510,13 +1510,12 @@ func (mh *MetaHeadersFrame) checkPseudos() error { } func (fr *Framer) maxHeaderStringLen() int { - v := fr.maxHeaderListSize() - if uint32(int(v)) == v { - return int(v) + v := int(fr.maxHeaderListSize()) + if v < 0 { + // If maxHeaderListSize overflows an int, use no limit (0). + return 0 } - // They had a crazy big number for MaxHeaderBytes anyway, - // so give them unlimited header lengths: - return 0 + return v } // readMetaFrame returns 0 or more CONTINUATION frames from fr and @@ -1565,6 +1564,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { if size > remainSize { hdec.SetEmitEnabled(false) mh.Truncated = true + remainSize = 0 return } remainSize -= size @@ -1577,6 +1577,36 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { var hc headersOrContinuation = hf for { frag := hc.HeaderBlockFragment() + + // Avoid parsing large amounts of headers that we will then discard. + // If the sender exceeds the max header list size by too much, + // skip parsing the fragment and close the connection. + // + // "Too much" is either any CONTINUATION frame after we've already + // exceeded the max header list size (in which case remainSize is 0), + // or a frame whose encoded size is more than twice the remaining + // header list bytes we're willing to accept. + if int64(len(frag)) > int64(2*remainSize) { + if VerboseLogs { + log.Printf("http2: header list too large") + } + // It would be nice to send a RST_STREAM before sending the GOAWAY, + // but the structure of the server's frame writer makes this difficult. + return nil, ConnectionError(ErrCodeProtocol) + } + + // Also close the connection after any CONTINUATION frame following an + // invalid header, since we stop tracking the size of the headers after + // an invalid one. + if invalid != nil { + if VerboseLogs { + log.Printf("http2: invalid header: %v", invalid) + } + // It would be nice to send a RST_STREAM before sending the GOAWAY, + // but the structure of the server's frame writer makes this difficult. + return nil, ConnectionError(ErrCodeProtocol) + } + if _, err := hdec.Write(frag); err != nil { return nil, ConnectionError(ErrCodeCompression) } diff --git a/vendor/golang.org/x/net/http2/go111.go b/vendor/golang.org/x/net/http2/go111.go deleted file mode 100644 index 5bf62b03..00000000 --- a/vendor/golang.org/x/net/http2/go111.go +++ /dev/null @@ -1,30 +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. - -//go:build go1.11 -// +build go1.11 - -package http2 - -import ( - "net/http/httptrace" - "net/textproto" -) - -func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { - return trace != nil && trace.WroteHeaderField != nil -} - -func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) { - if trace != nil && trace.WroteHeaderField != nil { - trace.WroteHeaderField(k, []string{v}) - } -} - -func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error { - if trace != nil { - return trace.Got1xxResponse - } - return nil -} diff --git a/vendor/golang.org/x/net/http2/go115.go b/vendor/golang.org/x/net/http2/go115.go deleted file mode 100644 index 908af1ab..00000000 --- a/vendor/golang.org/x/net/http2/go115.go +++ /dev/null @@ -1,27 +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. - -//go:build go1.15 -// +build go1.15 - -package http2 - -import ( - "context" - "crypto/tls" -) - -// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS -// connection. -func (t *Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) { - dialer := &tls.Dialer{ - Config: cfg, - } - cn, err := dialer.DialContext(ctx, network, addr) - if err != nil { - return nil, err - } - tlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed - return tlsCn, nil -} diff --git a/vendor/golang.org/x/net/http2/go118.go b/vendor/golang.org/x/net/http2/go118.go deleted file mode 100644 index aca4b2b3..00000000 --- a/vendor/golang.org/x/net/http2/go118.go +++ /dev/null @@ -1,17 +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. - -//go:build go1.18 -// +build go1.18 - -package http2 - -import ( - "crypto/tls" - "net" -) - -func tlsUnderlyingConn(tc *tls.Conn) net.Conn { - return tc.NetConn() -} diff --git a/vendor/golang.org/x/net/http2/not_go111.go b/vendor/golang.org/x/net/http2/not_go111.go deleted file mode 100644 index cc0baa81..00000000 --- a/vendor/golang.org/x/net/http2/not_go111.go +++ /dev/null @@ -1,21 +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. - -//go:build !go1.11 -// +build !go1.11 - -package http2 - -import ( - "net/http/httptrace" - "net/textproto" -) - -func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { return false } - -func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) {} - -func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error { - return nil -} diff --git a/vendor/golang.org/x/net/http2/not_go115.go b/vendor/golang.org/x/net/http2/not_go115.go deleted file mode 100644 index e6c04cf7..00000000 --- a/vendor/golang.org/x/net/http2/not_go115.go +++ /dev/null @@ -1,31 +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. - -//go:build !go1.15 -// +build !go1.15 - -package http2 - -import ( - "context" - "crypto/tls" -) - -// dialTLSWithContext opens a TLS connection. -func (t *Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) { - cn, err := tls.Dial(network, addr, cfg) - if err != nil { - return nil, err - } - if err := cn.Handshake(); err != nil { - return nil, err - } - if cfg.InsecureSkipVerify { - return cn, nil - } - if err := cn.VerifyHostname(cfg.ServerName); err != nil { - return nil, err - } - return cn, nil -} diff --git a/vendor/golang.org/x/net/http2/not_go118.go b/vendor/golang.org/x/net/http2/not_go118.go deleted file mode 100644 index eab532c9..00000000 --- a/vendor/golang.org/x/net/http2/not_go118.go +++ /dev/null @@ -1,17 +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. - -//go:build !go1.18 -// +build !go1.18 - -package http2 - -import ( - "crypto/tls" - "net" -) - -func tlsUnderlyingConn(tc *tls.Conn) net.Conn { - return nil -} diff --git a/vendor/golang.org/x/net/http2/pipe.go b/vendor/golang.org/x/net/http2/pipe.go index 684d984f..3b9f06b9 100644 --- a/vendor/golang.org/x/net/http2/pipe.go +++ b/vendor/golang.org/x/net/http2/pipe.go @@ -77,7 +77,10 @@ func (p *pipe) Read(d []byte) (n int, err error) { } } -var errClosedPipeWrite = errors.New("write on closed buffer") +var ( + errClosedPipeWrite = errors.New("write on closed buffer") + errUninitializedPipeWrite = errors.New("write on uninitialized buffer") +) // Write copies bytes from p into the buffer and wakes a reader. // It is an error to write more data than the buffer can hold. @@ -91,6 +94,12 @@ func (p *pipe) Write(d []byte) (n int, err error) { if p.err != nil || p.breakErr != nil { return 0, errClosedPipeWrite } + // pipe.setBuffer is never invoked, leaving the buffer uninitialized. + // We shouldn't try to write to an uninitialized pipe, + // but returning an error is better than panicking. + if p.b == nil { + return 0, errUninitializedPipeWrite + } return p.b.Write(d) } diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index 02c88b6b..ce2e8b40 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -124,6 +124,7 @@ type Server struct { // IdleTimeout specifies how long until idle clients should be // closed with a GOAWAY frame. PING frames are not considered // activity for the purposes of IdleTimeout. + // If zero or negative, there is no timeout. IdleTimeout time.Duration // MaxUploadBufferPerConnection is the size of the initial flow @@ -434,7 +435,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { // passes the connection off to us with the deadline already set. // Write deadlines are set per stream in serverConn.newStream. // Disarm the net.Conn write deadline here. - if sc.hs.WriteTimeout != 0 { + if sc.hs.WriteTimeout > 0 { sc.conn.SetWriteDeadline(time.Time{}) } @@ -924,7 +925,7 @@ func (sc *serverConn) serve() { sc.setConnState(http.StateActive) sc.setConnState(http.StateIdle) - if sc.srv.IdleTimeout != 0 { + if sc.srv.IdleTimeout > 0 { sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) defer sc.idleTimer.Stop() } @@ -1637,7 +1638,7 @@ func (sc *serverConn) closeStream(st *stream, err error) { delete(sc.streams, st.id) if len(sc.streams) == 0 { sc.setConnState(http.StateIdle) - if sc.srv.IdleTimeout != 0 { + if sc.srv.IdleTimeout > 0 { sc.idleTimer.Reset(sc.srv.IdleTimeout) } if h1ServerKeepAlivesDisabled(sc.hs) { @@ -2017,7 +2018,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // similar to how the http1 server works. Here it's // technically more like the http1 Server's ReadHeaderTimeout // (in Go 1.8), though. That's a more sane option anyway. - if sc.hs.ReadTimeout != 0 { + if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) } @@ -2038,7 +2039,7 @@ func (sc *serverConn) upgradeRequest(req *http.Request) { // Disable any read deadline set by the net/http package // prior to the upgrade. - if sc.hs.ReadTimeout != 0 { + if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) } @@ -2116,7 +2117,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream st.flow.conn = &sc.flow // link to conn-level counter st.flow.add(sc.initialStreamSendWindowSize) st.inflow.init(sc.srv.initialStreamRecvWindowSize()) - if sc.hs.WriteTimeout != 0 { + if sc.hs.WriteTimeout > 0 { st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) } @@ -2549,7 +2550,6 @@ type responseWriterState struct { wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet. sentHeader bool // have we sent the header frame? handlerDone bool // handler has finished - dirty bool // a Write failed; don't reuse this responseWriterState sentContentLen int64 // non-zero if handler set a Content-Length header wroteBytes int64 @@ -2669,7 +2669,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { date: date, }) if err != nil { - rws.dirty = true return 0, err } if endStream { @@ -2690,7 +2689,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { if len(p) > 0 || endStream { // only send a 0 byte DATA frame if we're ending the stream. if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil { - rws.dirty = true return 0, err } } @@ -2702,9 +2700,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { trailers: rws.trailers, endStream: true, }) - if err != nil { - rws.dirty = true - } return len(p), err } return len(p), nil @@ -2920,14 +2915,12 @@ func (rws *responseWriterState) writeHeader(code int) { h.Del("Transfer-Encoding") } - if rws.conn.writeHeaders(rws.stream, &writeResHeaders{ + rws.conn.writeHeaders(rws.stream, &writeResHeaders{ streamID: rws.stream.id, httpResCode: code, h: h, endStream: rws.handlerDone && !rws.hasTrailers(), - }) != nil { - rws.dirty = true - } + }) return } @@ -2992,19 +2985,10 @@ func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int, func (w *responseWriter) handlerDone() { rws := w.rws - dirty := rws.dirty rws.handlerDone = true w.Flush() w.rws = nil - if !dirty { - // Only recycle the pool if all prior Write calls to - // the serverConn goroutine completed successfully. If - // they returned earlier due to resets from the peer - // there might still be write goroutines outstanding - // from the serverConn referencing the rws memory. See - // issue 20704. - responseWriterStatePool.Put(rws) - } + responseWriterStatePool.Put(rws) } // Push errors. @@ -3187,6 +3171,7 @@ func (sc *serverConn) startPush(msg *startPushRequest) { panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err)) } + sc.curHandlers++ go sc.runHandler(rw, req, sc.handler.ServeHTTP) return promisedID, nil } diff --git a/vendor/golang.org/x/net/http2/testsync.go b/vendor/golang.org/x/net/http2/testsync.go new file mode 100644 index 00000000..61075bd1 --- /dev/null +++ b/vendor/golang.org/x/net/http2/testsync.go @@ -0,0 +1,331 @@ +// 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 http2 + +import ( + "context" + "sync" + "time" +) + +// testSyncHooks coordinates goroutines in tests. +// +// For example, a call to ClientConn.RoundTrip involves several goroutines, including: +// - the goroutine running RoundTrip; +// - the clientStream.doRequest goroutine, which writes the request; and +// - the clientStream.readLoop goroutine, which reads the response. +// +// Using testSyncHooks, a test can start a RoundTrip and identify when all these goroutines +// are blocked waiting for some condition such as reading the Request.Body or waiting for +// flow control to become available. +// +// The testSyncHooks also manage timers and synthetic time in tests. +// This permits us to, for example, start a request and cause it to time out waiting for +// response headers without resorting to time.Sleep calls. +type testSyncHooks struct { + // active/inactive act as a mutex and condition variable. + // + // - neither chan contains a value: testSyncHooks is locked. + // - active contains a value: unlocked, and at least one goroutine is not blocked + // - inactive contains a value: unlocked, and all goroutines are blocked + active chan struct{} + inactive chan struct{} + + // goroutine counts + total int // total goroutines + condwait map[*sync.Cond]int // blocked in sync.Cond.Wait + blocked []*testBlockedGoroutine // otherwise blocked + + // fake time + now time.Time + timers []*fakeTimer + + // Transport testing: Report various events. + newclientconn func(*ClientConn) + newstream func(*clientStream) +} + +// testBlockedGoroutine is a blocked goroutine. +type testBlockedGoroutine struct { + f func() bool // blocked until f returns true + ch chan struct{} // closed when unblocked +} + +func newTestSyncHooks() *testSyncHooks { + h := &testSyncHooks{ + active: make(chan struct{}, 1), + inactive: make(chan struct{}, 1), + condwait: map[*sync.Cond]int{}, + } + h.inactive <- struct{}{} + h.now = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC) + return h +} + +// lock acquires the testSyncHooks mutex. +func (h *testSyncHooks) lock() { + select { + case <-h.active: + case <-h.inactive: + } +} + +// waitInactive waits for all goroutines to become inactive. +func (h *testSyncHooks) waitInactive() { + for { + <-h.inactive + if !h.unlock() { + break + } + } +} + +// unlock releases the testSyncHooks mutex. +// It reports whether any goroutines are active. +func (h *testSyncHooks) unlock() (active bool) { + // Look for a blocked goroutine which can be unblocked. + blocked := h.blocked[:0] + unblocked := false + for _, b := range h.blocked { + if !unblocked && b.f() { + unblocked = true + close(b.ch) + } else { + blocked = append(blocked, b) + } + } + h.blocked = blocked + + // Count goroutines blocked on condition variables. + condwait := 0 + for _, count := range h.condwait { + condwait += count + } + + if h.total > condwait+len(blocked) { + h.active <- struct{}{} + return true + } else { + h.inactive <- struct{}{} + return false + } +} + +// goRun starts a new goroutine. +func (h *testSyncHooks) goRun(f func()) { + h.lock() + h.total++ + h.unlock() + go func() { + defer func() { + h.lock() + h.total-- + h.unlock() + }() + f() + }() +} + +// blockUntil indicates that a goroutine is blocked waiting for some condition to become true. +// It waits until f returns true before proceeding. +// +// Example usage: +// +// h.blockUntil(func() bool { +// // Is the context done yet? +// select { +// case <-ctx.Done(): +// default: +// return false +// } +// return true +// }) +// // Wait for the context to become done. +// <-ctx.Done() +// +// The function f passed to blockUntil must be non-blocking and idempotent. +func (h *testSyncHooks) blockUntil(f func() bool) { + if f() { + return + } + ch := make(chan struct{}) + h.lock() + h.blocked = append(h.blocked, &testBlockedGoroutine{ + f: f, + ch: ch, + }) + h.unlock() + <-ch +} + +// broadcast is sync.Cond.Broadcast. +func (h *testSyncHooks) condBroadcast(cond *sync.Cond) { + h.lock() + delete(h.condwait, cond) + h.unlock() + cond.Broadcast() +} + +// broadcast is sync.Cond.Wait. +func (h *testSyncHooks) condWait(cond *sync.Cond) { + h.lock() + h.condwait[cond]++ + h.unlock() +} + +// newTimer creates a new fake timer. +func (h *testSyncHooks) newTimer(d time.Duration) timer { + h.lock() + defer h.unlock() + t := &fakeTimer{ + hooks: h, + when: h.now.Add(d), + c: make(chan time.Time), + } + h.timers = append(h.timers, t) + return t +} + +// afterFunc creates a new fake AfterFunc timer. +func (h *testSyncHooks) afterFunc(d time.Duration, f func()) timer { + h.lock() + defer h.unlock() + t := &fakeTimer{ + hooks: h, + when: h.now.Add(d), + f: f, + } + h.timers = append(h.timers, t) + return t +} + +func (h *testSyncHooks) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { + ctx, cancel := context.WithCancel(ctx) + t := h.afterFunc(d, cancel) + return ctx, func() { + t.Stop() + cancel() + } +} + +func (h *testSyncHooks) timeUntilEvent() time.Duration { + h.lock() + defer h.unlock() + var next time.Time + for _, t := range h.timers { + if next.IsZero() || t.when.Before(next) { + next = t.when + } + } + if d := next.Sub(h.now); d > 0 { + return d + } + return 0 +} + +// advance advances time and causes synthetic timers to fire. +func (h *testSyncHooks) advance(d time.Duration) { + h.lock() + defer h.unlock() + h.now = h.now.Add(d) + timers := h.timers[:0] + for _, t := range h.timers { + t := t // remove after go.mod depends on go1.22 + t.mu.Lock() + switch { + case t.when.After(h.now): + timers = append(timers, t) + case t.when.IsZero(): + // stopped timer + default: + t.when = time.Time{} + if t.c != nil { + close(t.c) + } + if t.f != nil { + h.total++ + go func() { + defer func() { + h.lock() + h.total-- + h.unlock() + }() + t.f() + }() + } + } + t.mu.Unlock() + } + h.timers = timers +} + +// A timer wraps a time.Timer, or a synthetic equivalent in tests. +// Unlike time.Timer, timer is single-use: The timer channel is closed when the timer expires. +type timer interface { + C() <-chan time.Time + Stop() bool + Reset(d time.Duration) bool +} + +// timeTimer implements timer using real time. +type timeTimer struct { + t *time.Timer + c chan time.Time +} + +// newTimeTimer creates a new timer using real time. +func newTimeTimer(d time.Duration) timer { + ch := make(chan time.Time) + t := time.AfterFunc(d, func() { + close(ch) + }) + return &timeTimer{t, ch} +} + +// newTimeAfterFunc creates an AfterFunc timer using real time. +func newTimeAfterFunc(d time.Duration, f func()) timer { + return &timeTimer{ + t: time.AfterFunc(d, f), + } +} + +func (t timeTimer) C() <-chan time.Time { return t.c } +func (t timeTimer) Stop() bool { return t.t.Stop() } +func (t timeTimer) Reset(d time.Duration) bool { return t.t.Reset(d) } + +// fakeTimer implements timer using fake time. +type fakeTimer struct { + hooks *testSyncHooks + + mu sync.Mutex + when time.Time // when the timer will fire + c chan time.Time // closed when the timer fires; mutually exclusive with f + f func() // called when the timer fires; mutually exclusive with c +} + +func (t *fakeTimer) C() <-chan time.Time { return t.c } + +func (t *fakeTimer) Stop() bool { + t.mu.Lock() + defer t.mu.Unlock() + stopped := t.when.IsZero() + t.when = time.Time{} + return stopped +} + +func (t *fakeTimer) Reset(d time.Duration) bool { + if t.c != nil || t.f == nil { + panic("fakeTimer only supports Reset on AfterFunc timers") + } + t.mu.Lock() + defer t.mu.Unlock() + t.hooks.lock() + defer t.hooks.unlock() + active := !t.when.IsZero() + t.when = t.hooks.now.Add(d) + if !active { + t.hooks.timers = append(t.hooks.timers, t) + } + return active +} diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 4515b22c..ce375c8c 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -147,6 +147,12 @@ type Transport struct { // waiting for their turn. StrictMaxConcurrentStreams bool + // IdleConnTimeout is the maximum amount of time an idle + // (keep-alive) connection will remain idle before closing + // itself. + // Zero means no limit. + IdleConnTimeout time.Duration + // ReadIdleTimeout is the timeout after which a health check using ping // frame will be carried out if no frame is received on the connection. // Note that a ping response will is considered a received frame, so if @@ -178,6 +184,8 @@ type Transport struct { connPoolOnce sync.Once connPoolOrDef ClientConnPool // non-nil version of ConnPool + + syncHooks *testSyncHooks } func (t *Transport) maxHeaderListSize() uint32 { @@ -302,7 +310,7 @@ type ClientConn struct { readerErr error // set before readerDone is closed idleTimeout time.Duration // or 0 for never - idleTimer *time.Timer + idleTimer timer mu sync.Mutex // guards following cond *sync.Cond // hold mu; broadcast on flow/closed changes @@ -344,6 +352,60 @@ type ClientConn struct { werr error // first write error that has occurred hbuf bytes.Buffer // HPACK encoder writes into this henc *hpack.Encoder + + syncHooks *testSyncHooks // can be nil +} + +// Hook points used for testing. +// Outside of tests, cc.syncHooks is nil and these all have minimal implementations. +// Inside tests, see the testSyncHooks function docs. + +// goRun starts a new goroutine. +func (cc *ClientConn) goRun(f func()) { + if cc.syncHooks != nil { + cc.syncHooks.goRun(f) + return + } + go f() +} + +// condBroadcast is cc.cond.Broadcast. +func (cc *ClientConn) condBroadcast() { + if cc.syncHooks != nil { + cc.syncHooks.condBroadcast(cc.cond) + } + cc.cond.Broadcast() +} + +// condWait is cc.cond.Wait. +func (cc *ClientConn) condWait() { + if cc.syncHooks != nil { + cc.syncHooks.condWait(cc.cond) + } + cc.cond.Wait() +} + +// newTimer creates a new time.Timer, or a synthetic timer in tests. +func (cc *ClientConn) newTimer(d time.Duration) timer { + if cc.syncHooks != nil { + return cc.syncHooks.newTimer(d) + } + return newTimeTimer(d) +} + +// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. +func (cc *ClientConn) afterFunc(d time.Duration, f func()) timer { + if cc.syncHooks != nil { + return cc.syncHooks.afterFunc(d, f) + } + return newTimeAfterFunc(d, f) +} + +func (cc *ClientConn) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { + if cc.syncHooks != nil { + return cc.syncHooks.contextWithTimeout(ctx, d) + } + return context.WithTimeout(ctx, d) } // clientStream is the state for a single HTTP/2 stream. One of these @@ -425,7 +487,7 @@ func (cs *clientStream) abortStreamLocked(err error) { // TODO(dneil): Clean up tests where cs.cc.cond is nil. if cs.cc.cond != nil { // Wake up writeRequestBody if it is waiting on flow control. - cs.cc.cond.Broadcast() + cs.cc.condBroadcast() } } @@ -435,7 +497,7 @@ func (cs *clientStream) abortRequestBodyWrite() { defer cc.mu.Unlock() if cs.reqBody != nil && cs.reqBodyClosed == nil { cs.closeReqBodyLocked() - cc.cond.Broadcast() + cc.condBroadcast() } } @@ -445,10 +507,10 @@ func (cs *clientStream) closeReqBodyLocked() { } cs.reqBodyClosed = make(chan struct{}) reqBodyClosed := cs.reqBodyClosed - go func() { + cs.cc.goRun(func() { cs.reqBody.Close() close(reqBodyClosed) - }() + }) } type stickyErrWriter struct { @@ -537,15 +599,6 @@ func authorityAddr(scheme string, authority string) (addr string) { return net.JoinHostPort(host, port) } -var retryBackoffHook func(time.Duration) *time.Timer - -func backoffNewTimer(d time.Duration) *time.Timer { - if retryBackoffHook != nil { - return retryBackoffHook(d) - } - return time.NewTimer(d) -} - // RoundTripOpt is like RoundTrip, but takes options. func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) { @@ -573,13 +626,27 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res backoff := float64(uint(1) << (uint(retry) - 1)) backoff += backoff * (0.1 * mathrand.Float64()) d := time.Second * time.Duration(backoff) - timer := backoffNewTimer(d) + var tm timer + if t.syncHooks != nil { + tm = t.syncHooks.newTimer(d) + t.syncHooks.blockUntil(func() bool { + select { + case <-tm.C(): + case <-req.Context().Done(): + default: + return false + } + return true + }) + } else { + tm = newTimeTimer(d) + } select { - case <-timer.C: + case <-tm.C(): t.vlogf("RoundTrip retrying after failure: %v", roundTripErr) continue case <-req.Context().Done(): - timer.Stop() + tm.Stop() err = req.Context().Err() } } @@ -658,6 +725,9 @@ func canRetryError(err error) bool { } func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) { + if t.syncHooks != nil { + return t.newClientConn(nil, singleUse, t.syncHooks) + } host, _, err := net.SplitHostPort(addr) if err != nil { return nil, err @@ -666,7 +736,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b if err != nil { return nil, err } - return t.newClientConn(tconn, singleUse) + return t.newClientConn(tconn, singleUse, nil) } func (t *Transport) newTLSConfig(host string) *tls.Config { @@ -732,10 +802,10 @@ func (t *Transport) maxEncoderHeaderTableSize() uint32 { } func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { - return t.newClientConn(c, t.disableKeepAlives()) + return t.newClientConn(c, t.disableKeepAlives(), nil) } -func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) { +func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHooks) (*ClientConn, error) { cc := &ClientConn{ t: t, tconn: c, @@ -750,10 +820,15 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro wantSettingsAck: true, pings: make(map[[8]byte]chan struct{}), reqHeaderMu: make(chan struct{}, 1), + syncHooks: hooks, + } + if hooks != nil { + hooks.newclientconn(cc) + c = cc.tconn } if d := t.idleConnTimeout(); d != 0 { cc.idleTimeout = d - cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout) + cc.idleTimer = cc.afterFunc(d, cc.onIdleTimeout) } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) @@ -818,7 +893,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro return nil, cc.werr } - go cc.readLoop() + cc.goRun(cc.readLoop) return cc, nil } @@ -826,7 +901,7 @@ func (cc *ClientConn) healthCheck() { pingTimeout := cc.t.pingTimeout() // We don't need to periodically ping in the health check, because the readLoop of ClientConn will // trigger the healthCheck again if there is no frame received. - ctx, cancel := context.WithTimeout(context.Background(), pingTimeout) + ctx, cancel := cc.contextWithTimeout(context.Background(), pingTimeout) defer cancel() cc.vlogf("http2: Transport sending health check") err := cc.Ping(ctx) @@ -1018,7 +1093,7 @@ func (cc *ClientConn) forceCloseConn() { if !ok { return } - if nc := tlsUnderlyingConn(tc); nc != nil { + if nc := tc.NetConn(); nc != nil { nc.Close() } } @@ -1056,7 +1131,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { // Wait for all in-flight streams to complete or connection to close done := make(chan struct{}) cancelled := false // guarded by cc.mu - go func() { + cc.goRun(func() { cc.mu.Lock() defer cc.mu.Unlock() for { @@ -1068,9 +1143,9 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { if cancelled { break } - cc.cond.Wait() + cc.condWait() } - }() + }) shutdownEnterWaitStateHook() select { case <-done: @@ -1080,7 +1155,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { cc.mu.Lock() // Free the goroutine above cancelled = true - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() return ctx.Err() } @@ -1118,7 +1193,7 @@ func (cc *ClientConn) closeForError(err error) { for _, cs := range cc.streams { cs.abortStreamLocked(err) } - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() cc.closeConn() } @@ -1215,6 +1290,10 @@ func (cc *ClientConn) decrStreamReservationsLocked() { } func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { + return cc.roundTrip(req, nil) +} + +func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) (*http.Response, error) { ctx := req.Context() cs := &clientStream{ cc: cc, @@ -1229,9 +1308,23 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { respHeaderRecv: make(chan struct{}), donec: make(chan struct{}), } - go cs.doRequest(req) + cc.goRun(func() { + cs.doRequest(req) + }) waitDone := func() error { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.donec: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.donec: return nil @@ -1292,7 +1385,24 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { return err } + if streamf != nil { + streamf(cs) + } + for { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.respHeaderRecv: + case <-cs.abort: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.respHeaderRecv: return handleResponseHeaders() @@ -1348,6 +1458,21 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { if cc.reqHeaderMu == nil { panic("RoundTrip on uninitialized ClientConn") // for tests } + var newStreamHook func(*clientStream) + if cc.syncHooks != nil { + newStreamHook = cc.syncHooks.newstream + cc.syncHooks.blockUntil(func() bool { + select { + case cc.reqHeaderMu <- struct{}{}: + <-cc.reqHeaderMu + case <-cs.reqCancel: + case <-ctx.Done(): + default: + return false + } + return true + }) + } select { case cc.reqHeaderMu <- struct{}{}: case <-cs.reqCancel: @@ -1372,6 +1497,10 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { } cc.mu.Unlock() + if newStreamHook != nil { + newStreamHook(cs) + } + // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? if !cc.t.disableCompression() && req.Header.Get("Accept-Encoding") == "" && @@ -1452,15 +1581,30 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { var respHeaderTimer <-chan time.Time var respHeaderRecv chan struct{} if d := cc.responseHeaderTimeout(); d != 0 { - timer := time.NewTimer(d) + timer := cc.newTimer(d) defer timer.Stop() - respHeaderTimer = timer.C + respHeaderTimer = timer.C() respHeaderRecv = cs.respHeaderRecv } // Wait until the peer half-closes its end of the stream, // or until the request is aborted (via context, error, or otherwise), // whichever comes first. for { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.peerClosed: + case <-respHeaderTimer: + case <-respHeaderRecv: + case <-cs.abort: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.peerClosed: return nil @@ -1609,7 +1753,7 @@ func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { return nil } cc.pendingRequests++ - cc.cond.Wait() + cc.condWait() cc.pendingRequests-- select { case <-cs.abort: @@ -1871,10 +2015,26 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) cs.flow.take(take) return take, nil } - cc.cond.Wait() + cc.condWait() } } +func validateHeaders(hdrs http.Header) string { + for k, vv := range hdrs { + if !httpguts.ValidHeaderFieldName(k) { + return fmt.Sprintf("name %q", k) + } + for _, v := range vv { + if !httpguts.ValidHeaderFieldValue(v) { + // Don't include the value in the error, + // because it may be sensitive. + return fmt.Sprintf("value for header %q", k) + } + } + } + return "" +} + var errNilRequestURL = errors.New("http2: Request.URI is nil") // requires cc.wmu be held. @@ -1912,19 +2072,14 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail } } - // Check for any invalid headers and return an error before we + // Check for any invalid headers+trailers and return an error before we // potentially pollute our hpack state. (We want to be able to // continue to reuse the hpack encoder for future requests) - for k, vv := range req.Header { - if !httpguts.ValidHeaderFieldName(k) { - return nil, fmt.Errorf("invalid HTTP header name %q", k) - } - for _, v := range vv { - if !httpguts.ValidHeaderFieldValue(v) { - // Don't include the value in the error, because it may be sensitive. - return nil, fmt.Errorf("invalid HTTP header value for header %q", k) - } - } + if err := validateHeaders(req.Header); err != "" { + return nil, fmt.Errorf("invalid HTTP header %s", err) + } + if err := validateHeaders(req.Trailer); err != "" { + return nil, fmt.Errorf("invalid HTTP trailer %s", err) } enumerateHeaders := func(f func(name, value string)) { @@ -2143,7 +2298,7 @@ func (cc *ClientConn) forgetStreamID(id uint32) { } // Wake up writeRequestBody via clientStream.awaitFlowControl and // wake up RoundTrip if there is a pending request. - cc.cond.Broadcast() + cc.condBroadcast() closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 { @@ -2231,7 +2386,7 @@ func (rl *clientConnReadLoop) cleanup() { cs.abortStreamLocked(err) } } - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() } @@ -2266,10 +2421,9 @@ func (rl *clientConnReadLoop) run() error { cc := rl.cc gotSettings := false readIdleTimeout := cc.t.ReadIdleTimeout - var t *time.Timer + var t timer if readIdleTimeout != 0 { - t = time.AfterFunc(readIdleTimeout, cc.healthCheck) - defer t.Stop() + t = cc.afterFunc(readIdleTimeout, cc.healthCheck) } for { f, err := cc.fr.ReadFrame() @@ -2684,7 +2838,7 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { }) return nil } - if !cs.firstByte { + if !cs.pastHeaders { cc.logf("protocol error: received DATA before a HEADERS frame") rl.endStreamError(cs, StreamError{ StreamID: f.StreamID, @@ -2867,7 +3021,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { for _, cs := range cc.streams { cs.flow.add(delta) } - cc.cond.Broadcast() + cc.condBroadcast() cc.initialWindowSize = s.Val case SettingHeaderTableSize: @@ -2911,9 +3065,18 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { fl = &cs.flow } if !fl.add(int32(f.Increment)) { + // For stream, the sender sends RST_STREAM with an error code of FLOW_CONTROL_ERROR + if cs != nil { + rl.endStreamError(cs, StreamError{ + StreamID: f.StreamID, + Code: ErrCodeFlowControl, + }) + return nil + } + return ConnectionError(ErrCodeFlowControl) } - cc.cond.Broadcast() + cc.condBroadcast() return nil } @@ -2955,24 +3118,38 @@ func (cc *ClientConn) Ping(ctx context.Context) error { } cc.mu.Unlock() } - errc := make(chan error, 1) - go func() { + var pingError error + errc := make(chan struct{}) + cc.goRun(func() { cc.wmu.Lock() defer cc.wmu.Unlock() - if err := cc.fr.WritePing(false, p); err != nil { - errc <- err + if pingError = cc.fr.WritePing(false, p); pingError != nil { + close(errc) return } - if err := cc.bw.Flush(); err != nil { - errc <- err + if pingError = cc.bw.Flush(); pingError != nil { + close(errc) return } - }() + }) + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-c: + case <-errc: + case <-ctx.Done(): + case <-cc.readerDone: + default: + return false + } + return true + }) + } select { case <-c: return nil - case err := <-errc: - return err + case <-errc: + return pingError case <-ctx.Done(): return ctx.Err() case <-cc.readerDone: @@ -3141,9 +3318,17 @@ func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, err } func (t *Transport) idleConnTimeout() time.Duration { + // to keep things backwards compatible, we use non-zero values of + // IdleConnTimeout, followed by using the IdleConnTimeout on the underlying + // http1 transport, followed by 0 + if t.IdleConnTimeout != 0 { + return t.IdleConnTimeout + } + if t.t1 != nil { return t.t1.IdleConnTimeout } + return 0 } @@ -3201,3 +3386,34 @@ func traceFirstResponseByte(trace *httptrace.ClientTrace) { trace.GotFirstResponseByte() } } + +func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { + return trace != nil && trace.WroteHeaderField != nil +} + +func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) { + if trace != nil && trace.WroteHeaderField != nil { + trace.WroteHeaderField(k, []string{v}) + } +} + +func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error { + if trace != nil { + return trace.Got1xxResponse + } + return nil +} + +// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS +// connection. +func (t *Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) { + dialer := &tls.Dialer{ + Config: cfg, + } + cn, err := dialer.DialContext(ctx, network, addr) + if err != nil { + return nil, err + } + tlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed + return tlsCn, nil +} diff --git a/vendor/golang.org/x/net/idna/go118.go b/vendor/golang.org/x/net/idna/go118.go index c5c4338d..712f1ad8 100644 --- a/vendor/golang.org/x/net/idna/go118.go +++ b/vendor/golang.org/x/net/idna/go118.go @@ -5,7 +5,6 @@ // license that can be found in the LICENSE file. //go:build go1.18 -// +build go1.18 package idna diff --git a/vendor/golang.org/x/net/idna/idna10.0.0.go b/vendor/golang.org/x/net/idna/idna10.0.0.go index 64ccf85f..7b371788 100644 --- a/vendor/golang.org/x/net/idna/idna10.0.0.go +++ b/vendor/golang.org/x/net/idna/idna10.0.0.go @@ -5,7 +5,6 @@ // license that can be found in the LICENSE file. //go:build go1.10 -// +build go1.10 // Package idna implements IDNA2008 using the compatibility processing // defined by UTS (Unicode Technical Standard) #46, which defines a standard to diff --git a/vendor/golang.org/x/net/idna/idna9.0.0.go b/vendor/golang.org/x/net/idna/idna9.0.0.go index ee1698ce..cc6a892a 100644 --- a/vendor/golang.org/x/net/idna/idna9.0.0.go +++ b/vendor/golang.org/x/net/idna/idna9.0.0.go @@ -5,7 +5,6 @@ // license that can be found in the LICENSE file. //go:build !go1.10 -// +build !go1.10 // Package idna implements IDNA2008 using the compatibility processing // defined by UTS (Unicode Technical Standard) #46, which defines a standard to diff --git a/vendor/golang.org/x/net/idna/pre_go118.go b/vendor/golang.org/x/net/idna/pre_go118.go index 3aaccab1..40e74bb3 100644 --- a/vendor/golang.org/x/net/idna/pre_go118.go +++ b/vendor/golang.org/x/net/idna/pre_go118.go @@ -5,7 +5,6 @@ // license that can be found in the LICENSE file. //go:build !go1.18 -// +build !go1.18 package idna diff --git a/vendor/golang.org/x/net/idna/tables10.0.0.go b/vendor/golang.org/x/net/idna/tables10.0.0.go index d1d62ef4..c6c2bf10 100644 --- a/vendor/golang.org/x/net/idna/tables10.0.0.go +++ b/vendor/golang.org/x/net/idna/tables10.0.0.go @@ -1,7 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. //go:build go1.10 && !go1.13 -// +build go1.10,!go1.13 package idna diff --git a/vendor/golang.org/x/net/idna/tables11.0.0.go b/vendor/golang.org/x/net/idna/tables11.0.0.go index 167efba7..76789393 100644 --- a/vendor/golang.org/x/net/idna/tables11.0.0.go +++ b/vendor/golang.org/x/net/idna/tables11.0.0.go @@ -1,7 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. //go:build go1.13 && !go1.14 -// +build go1.13,!go1.14 package idna diff --git a/vendor/golang.org/x/net/idna/tables12.0.0.go b/vendor/golang.org/x/net/idna/tables12.0.0.go index ab40f7bc..0600cd2a 100644 --- a/vendor/golang.org/x/net/idna/tables12.0.0.go +++ b/vendor/golang.org/x/net/idna/tables12.0.0.go @@ -1,7 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. //go:build go1.14 && !go1.16 -// +build go1.14,!go1.16 package idna diff --git a/vendor/golang.org/x/net/idna/tables13.0.0.go b/vendor/golang.org/x/net/idna/tables13.0.0.go index 66701ead..2fb768ef 100644 --- a/vendor/golang.org/x/net/idna/tables13.0.0.go +++ b/vendor/golang.org/x/net/idna/tables13.0.0.go @@ -1,7 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. //go:build go1.16 && !go1.21 -// +build go1.16,!go1.21 package idna diff --git a/vendor/golang.org/x/net/idna/tables15.0.0.go b/vendor/golang.org/x/net/idna/tables15.0.0.go index 40033778..5ff05fe1 100644 --- a/vendor/golang.org/x/net/idna/tables15.0.0.go +++ b/vendor/golang.org/x/net/idna/tables15.0.0.go @@ -1,7 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. //go:build go1.21 -// +build go1.21 package idna diff --git a/vendor/golang.org/x/net/idna/tables9.0.0.go b/vendor/golang.org/x/net/idna/tables9.0.0.go index 4074b533..0f25e84c 100644 --- a/vendor/golang.org/x/net/idna/tables9.0.0.go +++ b/vendor/golang.org/x/net/idna/tables9.0.0.go @@ -1,7 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. //go:build !go1.10 -// +build !go1.10 package idna diff --git a/vendor/golang.org/x/net/idna/trie12.0.0.go b/vendor/golang.org/x/net/idna/trie12.0.0.go index bb63f904..8a75b966 100644 --- a/vendor/golang.org/x/net/idna/trie12.0.0.go +++ b/vendor/golang.org/x/net/idna/trie12.0.0.go @@ -5,7 +5,6 @@ // license that can be found in the LICENSE file. //go:build !go1.16 -// +build !go1.16 package idna diff --git a/vendor/golang.org/x/net/idna/trie13.0.0.go b/vendor/golang.org/x/net/idna/trie13.0.0.go index 7d68a8dc..fa45bb90 100644 --- a/vendor/golang.org/x/net/idna/trie13.0.0.go +++ b/vendor/golang.org/x/net/idna/trie13.0.0.go @@ -5,7 +5,6 @@ // license that can be found in the LICENSE file. //go:build go1.16 -// +build go1.16 package idna diff --git a/vendor/golang.org/x/sync/LICENSE b/vendor/golang.org/x/sync/LICENSE new file mode 100644 index 00000000..6a66aea5 --- /dev/null +++ b/vendor/golang.org/x/sync/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/sync/PATENTS b/vendor/golang.org/x/sync/PATENTS new file mode 100644 index 00000000..73309904 --- /dev/null +++ b/vendor/golang.org/x/sync/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google 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, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go new file mode 100644 index 00000000..948a3ee6 --- /dev/null +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -0,0 +1,135 @@ +// Copyright 2016 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 errgroup provides synchronization, error propagation, and Context +// cancelation for groups of goroutines working on subtasks of a common task. +// +// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks +// returning errors. +package errgroup + +import ( + "context" + "fmt" + "sync" +) + +type token struct{} + +// A Group is a collection of goroutines working on subtasks that are part of +// the same overall task. +// +// A zero Group is valid, has no limit on the number of active goroutines, +// and does not cancel on error. +type Group struct { + cancel func(error) + + wg sync.WaitGroup + + sem chan token + + errOnce sync.Once + err error +} + +func (g *Group) done() { + if g.sem != nil { + <-g.sem + } + g.wg.Done() +} + +// WithContext returns a new Group and an associated Context derived from ctx. +// +// The derived Context is canceled the first time a function passed to Go +// returns a non-nil error or the first time Wait returns, whichever occurs +// first. +func WithContext(ctx context.Context) (*Group, context.Context) { + ctx, cancel := withCancelCause(ctx) + return &Group{cancel: cancel}, ctx +} + +// Wait blocks until all function calls from the Go method have returned, then +// returns the first non-nil error (if any) from them. +func (g *Group) Wait() error { + g.wg.Wait() + if g.cancel != nil { + g.cancel(g.err) + } + return g.err +} + +// Go calls the given function in a new goroutine. +// It blocks until the new goroutine can be added without the number of +// active goroutines in the group exceeding the configured limit. +// +// The first call to return a non-nil error cancels the group's context, if the +// group was created by calling WithContext. The error will be returned by Wait. +func (g *Group) Go(f func() error) { + if g.sem != nil { + g.sem <- token{} + } + + g.wg.Add(1) + go func() { + defer g.done() + + if err := f(); err != nil { + g.errOnce.Do(func() { + g.err = err + if g.cancel != nil { + g.cancel(g.err) + } + }) + } + }() +} + +// TryGo calls the given function in a new goroutine only if the number of +// active goroutines in the group is currently below the configured limit. +// +// The return value reports whether the goroutine was started. +func (g *Group) TryGo(f func() error) bool { + if g.sem != nil { + select { + case g.sem <- token{}: + // Note: this allows barging iff channels in general allow barging. + default: + return false + } + } + + g.wg.Add(1) + go func() { + defer g.done() + + if err := f(); err != nil { + g.errOnce.Do(func() { + g.err = err + if g.cancel != nil { + g.cancel(g.err) + } + }) + } + }() + return true +} + +// SetLimit limits the number of active goroutines in this group to at most n. +// A negative value indicates no limit. +// +// Any subsequent call to the Go method will block until it can add an active +// goroutine without exceeding the configured limit. +// +// The limit must not be modified while any goroutines in the group are active. +func (g *Group) SetLimit(n int) { + if n < 0 { + g.sem = nil + return + } + if len(g.sem) != 0 { + panic(fmt.Errorf("errgroup: modify limit while %v goroutines in the group are still active", len(g.sem))) + } + g.sem = make(chan token, n) +} diff --git a/vendor/golang.org/x/sync/errgroup/go120.go b/vendor/golang.org/x/sync/errgroup/go120.go new file mode 100644 index 00000000..f93c740b --- /dev/null +++ b/vendor/golang.org/x/sync/errgroup/go120.go @@ -0,0 +1,13 @@ +// 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. + +//go:build go1.20 + +package errgroup + +import "context" + +func withCancelCause(parent context.Context) (context.Context, func(error)) { + return context.WithCancelCause(parent) +} diff --git a/vendor/golang.org/x/sync/errgroup/pre_go120.go b/vendor/golang.org/x/sync/errgroup/pre_go120.go new file mode 100644 index 00000000..88ce3343 --- /dev/null +++ b/vendor/golang.org/x/sync/errgroup/pre_go120.go @@ -0,0 +1,14 @@ +// 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. + +//go:build !go1.20 + +package errgroup + +import "context" + +func withCancelCause(parent context.Context) (context.Context, func(error)) { + ctx, cancel := context.WithCancel(parent) + return ctx, func(error) { cancel() } +} diff --git a/vendor/golang.org/x/sys/unix/aliases.go b/vendor/golang.org/x/sys/unix/aliases.go index e7d3df4b..b0e41985 100644 --- a/vendor/golang.org/x/sys/unix/aliases.go +++ b/vendor/golang.org/x/sys/unix/aliases.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9 +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos package unix diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 6202638b..fdcaa974 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -248,6 +248,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -283,10 +284,6 @@ struct ltchars { #include #endif -#ifndef MSG_FASTOPEN -#define MSG_FASTOPEN 0x20000000 -#endif - #ifndef PTRACE_GETREGS #define PTRACE_GETREGS 0xc #endif @@ -295,14 +292,6 @@ struct ltchars { #define PTRACE_SETREGS 0xd #endif -#ifndef SOL_NETLINK -#define SOL_NETLINK 270 -#endif - -#ifndef SOL_SMC -#define SOL_SMC 286 -#endif - #ifdef SOL_BLUETOOTH // SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h // but it is already in bluetooth_linux.go @@ -319,10 +308,23 @@ struct ltchars { #undef TIPC_WAIT_FOREVER #define TIPC_WAIT_FOREVER 0xffffffff -// Copied from linux/l2tp.h -// Including linux/l2tp.h here causes conflicts between linux/in.h -// and netinet/in.h included via net/route.h above. -#define IPPROTO_L2TP 115 +// Copied from linux/netfilter/nf_nat.h +// Including linux/netfilter/nf_nat.h here causes conflicts between linux/in.h +// and netinet/in.h. +#define NF_NAT_RANGE_MAP_IPS (1 << 0) +#define NF_NAT_RANGE_PROTO_SPECIFIED (1 << 1) +#define NF_NAT_RANGE_PROTO_RANDOM (1 << 2) +#define NF_NAT_RANGE_PERSISTENT (1 << 3) +#define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4) +#define NF_NAT_RANGE_PROTO_OFFSET (1 << 5) +#define NF_NAT_RANGE_NETMAP (1 << 6) +#define NF_NAT_RANGE_PROTO_RANDOM_ALL \ + (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY) +#define NF_NAT_RANGE_MASK \ + (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED | \ + NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT | \ + NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET | \ + NF_NAT_RANGE_NETMAP) // Copied from linux/hid.h. // Keep in sync with the size of the referenced fields. @@ -582,7 +584,7 @@ ccflags="$@" $2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ || $2 ~ /^KEYCTL_/ || $2 ~ /^PERF_/ || - $2 ~ /^SECCOMP_MODE_/ || + $2 ~ /^SECCOMP_/ || $2 ~ /^SEEK_/ || $2 ~ /^SCHED_/ || $2 ~ /^SPLICE_/ || @@ -603,6 +605,9 @@ ccflags="$@" $2 ~ /^FSOPT_/ || $2 ~ /^WDIO[CFS]_/ || $2 ~ /^NFN/ || + $2 !~ /^NFT_META_IIFTYPE/ && + $2 ~ /^NFT_/ || + $2 ~ /^NF_NAT_/ || $2 ~ /^XDP_/ || $2 ~ /^RWF_/ || $2 ~ /^(HDIO|WIN|SMART)_/ || diff --git a/vendor/golang.org/x/sys/unix/mmap_nomremap.go b/vendor/golang.org/x/sys/unix/mmap_nomremap.go index 4b68e597..7f602ffd 100644 --- a/vendor/golang.org/x/sys/unix/mmap_nomremap.go +++ b/vendor/golang.org/x/sys/unix/mmap_nomremap.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris +//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris || zos package unix diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go index 16dc6993..2f0fa76e 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build darwin && go1.12 +//go:build darwin package unix diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go index 64d1bb4d..2b57e0f7 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -13,6 +13,7 @@ package unix import ( + "errors" "sync" "unsafe" ) @@ -169,25 +170,26 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { func Uname(uname *Utsname) error { mib := []_C_int{CTL_KERN, KERN_OSTYPE} n := unsafe.Sizeof(uname.Sysname) - if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { + // Suppress ENOMEM errors to be compatible with the C library __xuname() implementation. + if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_HOSTNAME} n = unsafe.Sizeof(uname.Nodename) - if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_OSRELEASE} n = unsafe.Sizeof(uname.Release) - if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_VERSION} n = unsafe.Sizeof(uname.Version) - if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } @@ -205,7 +207,7 @@ func Uname(uname *Utsname) error { mib = []_C_int{CTL_HW, HW_MACHINE} n = unsafe.Sizeof(uname.Machine) - if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 0f85e29e..5682e262 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1849,6 +1849,105 @@ func Dup2(oldfd, newfd int) error { //sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error) //sys Fsopen(fsName string, flags int) (fd int, err error) //sys Fspick(dirfd int, pathName string, flags int) (fd int, err error) + +//sys fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) + +func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) { + var keyp *byte + if keyp, err = BytePtrFromString(key); err != nil { + return + } + return fsconfig(fd, cmd, keyp, value, aux) +} + +// FsconfigSetFlag is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_FLAG. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +func FsconfigSetFlag(fd int, key string) (err error) { + return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0) +} + +// FsconfigSetString is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_STRING. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is the parameter value to set. +func FsconfigSetString(fd int, key string, value string) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(value); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0) +} + +// FsconfigSetBinary is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_BINARY. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is the parameter value to set. +func FsconfigSetBinary(fd int, key string, value []byte) (err error) { + if len(value) == 0 { + return EINVAL + } + return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value)) +} + +// FsconfigSetPath is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_PATH. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// path is a non-empty path for specified key. +// atfd is a file descriptor at which to start lookup from or AT_FDCWD. +func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(path); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd) +} + +// FsconfigSetPathEmpty is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as +// FconfigSetPath but with AT_PATH_EMPTY implied. +func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(path); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd) +} + +// FsconfigSetFd is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_FD. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is a file descriptor to be assigned to specified key. +func FsconfigSetFd(fd int, key string, value int) (err error) { + return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value) +} + +// FsconfigCreate is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_CMD_CREATE. +// +// fd is the filesystem context to act upon. +func FsconfigCreate(fd int) (err error) { + return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0) +} + +// FsconfigReconfigure is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_CMD_RECONFIGURE. +// +// fd is the filesystem context to act upon. +func FsconfigReconfigure(fd int) (err error) { + return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0) +} + //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 //sysnb Getpgid(pid int) (pgid int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go index b473038c..27c41b6f 100644 --- a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go @@ -1520,6 +1520,14 @@ func (m *mmapper) Munmap(data []byte) (err error) { return nil } +func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { + return mapper.Mmap(fd, offset, length, prot, flags) +} + +func Munmap(b []byte) (err error) { + return mapper.Munmap(b) +} + func Read(fd int, p []byte) (n int, err error) { n, err = read(fd, p) if raceenabled { diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index c73cfe2f..36bf8399 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -1785,6 +1785,8 @@ const ( LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20 LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000 LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2 + LANDLOCK_ACCESS_NET_BIND_TCP = 0x1 + LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 LINUX_REBOOT_CMD_CAD_OFF = 0x0 LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef @@ -2127,6 +2129,60 @@ const ( NFNL_SUBSYS_QUEUE = 0x3 NFNL_SUBSYS_ULOG = 0x4 NFS_SUPER_MAGIC = 0x6969 + NFT_CHAIN_FLAGS = 0x7 + NFT_CHAIN_MAXNAMELEN = 0x100 + NFT_CT_MAX = 0x17 + NFT_DATA_RESERVED_MASK = 0xffffff00 + NFT_DATA_VALUE_MAXLEN = 0x40 + NFT_EXTHDR_OP_MAX = 0x4 + NFT_FIB_RESULT_MAX = 0x3 + NFT_INNER_MASK = 0xf + NFT_LOGLEVEL_MAX = 0x8 + NFT_NAME_MAXLEN = 0x100 + NFT_NG_MAX = 0x1 + NFT_OBJECT_CONNLIMIT = 0x5 + NFT_OBJECT_COUNTER = 0x1 + NFT_OBJECT_CT_EXPECT = 0x9 + NFT_OBJECT_CT_HELPER = 0x3 + NFT_OBJECT_CT_TIMEOUT = 0x7 + NFT_OBJECT_LIMIT = 0x4 + NFT_OBJECT_MAX = 0xa + NFT_OBJECT_QUOTA = 0x2 + NFT_OBJECT_SECMARK = 0x8 + NFT_OBJECT_SYNPROXY = 0xa + NFT_OBJECT_TUNNEL = 0x6 + NFT_OBJECT_UNSPEC = 0x0 + NFT_OBJ_MAXNAMELEN = 0x100 + NFT_OSF_MAXGENRELEN = 0x10 + NFT_QUEUE_FLAG_BYPASS = 0x1 + NFT_QUEUE_FLAG_CPU_FANOUT = 0x2 + NFT_QUEUE_FLAG_MASK = 0x3 + NFT_REG32_COUNT = 0x10 + NFT_REG32_SIZE = 0x4 + NFT_REG_MAX = 0x4 + NFT_REG_SIZE = 0x10 + NFT_REJECT_ICMPX_MAX = 0x3 + NFT_RT_MAX = 0x4 + NFT_SECMARK_CTX_MAXLEN = 0x100 + NFT_SET_MAXNAMELEN = 0x100 + NFT_SOCKET_MAX = 0x3 + NFT_TABLE_F_MASK = 0x3 + NFT_TABLE_MAXNAMELEN = 0x100 + NFT_TRACETYPE_MAX = 0x3 + NFT_TUNNEL_F_MASK = 0x7 + NFT_TUNNEL_MAX = 0x1 + NFT_TUNNEL_MODE_MAX = 0x2 + NFT_USERDATA_MAXLEN = 0x100 + NFT_XFRM_KEY_MAX = 0x6 + NF_NAT_RANGE_MAP_IPS = 0x1 + NF_NAT_RANGE_MASK = 0x7f + NF_NAT_RANGE_NETMAP = 0x40 + NF_NAT_RANGE_PERSISTENT = 0x8 + NF_NAT_RANGE_PROTO_OFFSET = 0x20 + NF_NAT_RANGE_PROTO_RANDOM = 0x4 + NF_NAT_RANGE_PROTO_RANDOM_ALL = 0x14 + NF_NAT_RANGE_PROTO_RANDOM_FULLY = 0x10 + NF_NAT_RANGE_PROTO_SPECIFIED = 0x2 NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 @@ -2411,6 +2467,7 @@ const ( PR_MCE_KILL_GET = 0x22 PR_MCE_KILL_LATE = 0x0 PR_MCE_KILL_SET = 0x1 + PR_MDWE_NO_INHERIT = 0x2 PR_MDWE_REFUSE_EXEC_GAIN = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b @@ -2615,8 +2672,9 @@ const ( RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 - RTAX_FEATURE_MASK = 0xf + RTAX_FEATURE_MASK = 0x1f RTAX_FEATURE_SACK = 0x2 + RTAX_FEATURE_TCP_USEC_TS = 0x10 RTAX_FEATURE_TIMESTAMP = 0x4 RTAX_HOPLIMIT = 0xa RTAX_INITCWND = 0xb @@ -2859,9 +2917,38 @@ const ( SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x1d SC_LOG_FLUSH = 0x100000 + SECCOMP_ADDFD_FLAG_SEND = 0x2 + SECCOMP_ADDFD_FLAG_SETFD = 0x1 + SECCOMP_FILTER_FLAG_LOG = 0x2 + SECCOMP_FILTER_FLAG_NEW_LISTENER = 0x8 + SECCOMP_FILTER_FLAG_SPEC_ALLOW = 0x4 + SECCOMP_FILTER_FLAG_TSYNC = 0x1 + SECCOMP_FILTER_FLAG_TSYNC_ESRCH = 0x10 + SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV = 0x20 + SECCOMP_GET_ACTION_AVAIL = 0x2 + SECCOMP_GET_NOTIF_SIZES = 0x3 + SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100 + SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101 + SECCOMP_IOC_MAGIC = '!' SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECCOMP_RET_ACTION = 0x7fff0000 + SECCOMP_RET_ACTION_FULL = 0xffff0000 + SECCOMP_RET_ALLOW = 0x7fff0000 + SECCOMP_RET_DATA = 0xffff + SECCOMP_RET_ERRNO = 0x50000 + SECCOMP_RET_KILL = 0x0 + SECCOMP_RET_KILL_PROCESS = 0x80000000 + SECCOMP_RET_KILL_THREAD = 0x0 + SECCOMP_RET_LOG = 0x7ffc0000 + SECCOMP_RET_TRACE = 0x7ff00000 + SECCOMP_RET_TRAP = 0x30000 + SECCOMP_RET_USER_NOTIF = 0x7fc00000 + SECCOMP_SET_MODE_FILTER = 0x1 + SECCOMP_SET_MODE_STRICT = 0x0 + SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 0x1 + SECCOMP_USER_NOTIF_FLAG_CONTINUE = 0x1 SECRETMEM_MAGIC = 0x5345434d SECURITYFS_MAGIC = 0x73636673 SEEK_CUR = 0x1 @@ -3021,6 +3108,7 @@ const ( SOL_TIPC = 0x10f SOL_TLS = 0x11a SOL_UDP = 0x11 + SOL_VSOCK = 0x11f SOL_X25 = 0x106 SOL_XDP = 0x11b SOMAXCONN = 0x1000 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 4920821c..42ff8c3c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 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 a0c1e411..dca43600 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -282,6 +282,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 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 c6398556..5cca668a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -288,6 +288,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 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 47cc62e2..d8cae6d1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -278,6 +278,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 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 27ac4a09..28e39afd 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -275,6 +275,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 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 54694642..cd66e92c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 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 3adb81d7..c1595eba 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 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 2dfe98f0..ee9456b0 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 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 f5398f84..8cfca81e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 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 c54f152d..60b0deb3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -336,6 +336,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 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 76057dc7..f90aa728 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -340,6 +340,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 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 e0c3725e..ba9e0150 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -340,6 +340,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 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 18f2813e..07cdfd6e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -272,6 +272,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 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 11619d4e..2f1dd214 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -344,6 +344,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 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 396d994d..f40519d9 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -335,6 +335,9 @@ const ( SCM_TIMESTAMPNS = 0x21 SCM_TXTIME = 0x3f SCM_WIFI_STATUS = 0x25 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x400000 SFD_NONBLOCK = 0x4000 SF_FP = 0x38 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 1488d271..87d8612a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -906,6 +906,16 @@ func Fspick(dirfd int, pathName string, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) { + _, _, e1 := Syscall6(SYS_FSCONFIG, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(value)), uintptr(aux), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdents(fd int, buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index a1d06159..9dc42410 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index 5b2a7409..0d3a0751 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index f6eda134..c39f7776 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go index 55df20ae..57571d07 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go index 8c1155cb..e62963e6 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go index 7cc80c58..00831354 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go index 0688737f..79029ed5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index fcf3ecbd..0cc3ce49 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -448,4 +448,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index f56dc250..856d92d6 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -371,4 +371,7 @@ const ( SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 974bf246..8d467094 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -412,4 +412,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 39a2739e..edc17324 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -315,4 +315,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index cf9c9d77..445eba20 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -309,4 +309,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index 10b7362e..adba01bc 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -432,4 +432,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 4450 SYS_CACHESTAT = 4451 SYS_FCHMODAT2 = 4452 + SYS_MAP_SHADOW_STACK = 4453 + SYS_FUTEX_WAKE = 4454 + SYS_FUTEX_WAIT = 4455 + SYS_FUTEX_REQUEUE = 4456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index cd4d8b4f..014c4e9c 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -362,4 +362,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 5450 SYS_CACHESTAT = 5451 SYS_FCHMODAT2 = 5452 + SYS_MAP_SHADOW_STACK = 5453 + SYS_FUTEX_WAKE = 5454 + SYS_FUTEX_WAIT = 5455 + SYS_FUTEX_REQUEUE = 5456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 2c0efca8..ccc97d74 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -362,4 +362,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 5450 SYS_CACHESTAT = 5451 SYS_FCHMODAT2 = 5452 + SYS_MAP_SHADOW_STACK = 5453 + SYS_FUTEX_WAKE = 5454 + SYS_FUTEX_WAIT = 5455 + SYS_FUTEX_REQUEUE = 5456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index a72e31d3..ec2b64a9 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -432,4 +432,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 4450 SYS_CACHESTAT = 4451 SYS_FCHMODAT2 = 4452 + SYS_MAP_SHADOW_STACK = 4453 + SYS_FUTEX_WAKE = 4454 + SYS_FUTEX_WAIT = 4455 + SYS_FUTEX_REQUEUE = 4456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index c7d1e374..21a839e3 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -439,4 +439,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index f4d4838c..c11121ec 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -411,4 +411,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index b64f0e59..909b631f 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -411,4 +411,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 95711195..e49bed16 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -316,4 +316,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index f94e943b..66017d2d 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -377,4 +377,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index ba0c2bc5..47bab18d 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -390,4 +390,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index bbf8399f..eff6bcde 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -174,7 +174,8 @@ type FscryptPolicyV2 struct { Contents_encryption_mode uint8 Filenames_encryption_mode uint8 Flags uint8 - _ [4]uint8 + Log2_data_unit_size uint8 + _ [3]uint8 Master_key_identifier [16]uint8 } @@ -455,60 +456,63 @@ type Ucred struct { } type TCPInfo struct { - State uint8 - Ca_state uint8 - Retransmits uint8 - Probes uint8 - Backoff uint8 - Options uint8 - Rto uint32 - Ato uint32 - Snd_mss uint32 - Rcv_mss uint32 - Unacked uint32 - Sacked uint32 - Lost uint32 - Retrans uint32 - Fackets uint32 - Last_data_sent uint32 - Last_ack_sent uint32 - Last_data_recv uint32 - Last_ack_recv uint32 - Pmtu uint32 - Rcv_ssthresh uint32 - Rtt uint32 - Rttvar uint32 - Snd_ssthresh uint32 - Snd_cwnd uint32 - Advmss uint32 - Reordering uint32 - Rcv_rtt uint32 - Rcv_space uint32 - Total_retrans uint32 - Pacing_rate uint64 - Max_pacing_rate uint64 - Bytes_acked uint64 - Bytes_received uint64 - Segs_out uint32 - Segs_in uint32 - Notsent_bytes uint32 - Min_rtt uint32 - Data_segs_in uint32 - Data_segs_out uint32 - Delivery_rate uint64 - Busy_time uint64 - Rwnd_limited uint64 - Sndbuf_limited uint64 - Delivered uint32 - Delivered_ce uint32 - Bytes_sent uint64 - Bytes_retrans uint64 - Dsack_dups uint32 - Reord_seen uint32 - Rcv_ooopack uint32 - Snd_wnd uint32 - Rcv_wnd uint32 - Rehash uint32 + State uint8 + Ca_state uint8 + Retransmits uint8 + Probes uint8 + Backoff uint8 + Options uint8 + Rto uint32 + Ato uint32 + Snd_mss uint32 + Rcv_mss uint32 + Unacked uint32 + Sacked uint32 + Lost uint32 + Retrans uint32 + Fackets uint32 + Last_data_sent uint32 + Last_ack_sent uint32 + Last_data_recv uint32 + Last_ack_recv uint32 + Pmtu uint32 + Rcv_ssthresh uint32 + Rtt uint32 + Rttvar uint32 + Snd_ssthresh uint32 + Snd_cwnd uint32 + Advmss uint32 + Reordering uint32 + Rcv_rtt uint32 + Rcv_space uint32 + Total_retrans uint32 + Pacing_rate uint64 + Max_pacing_rate uint64 + Bytes_acked uint64 + Bytes_received uint64 + Segs_out uint32 + Segs_in uint32 + Notsent_bytes uint32 + Min_rtt uint32 + Data_segs_in uint32 + Data_segs_out uint32 + Delivery_rate uint64 + Busy_time uint64 + Rwnd_limited uint64 + Sndbuf_limited uint64 + Delivered uint32 + Delivered_ce uint32 + Bytes_sent uint64 + Bytes_retrans uint64 + Dsack_dups uint32 + Reord_seen uint32 + Rcv_ooopack uint32 + Snd_wnd uint32 + Rcv_wnd uint32 + Rehash uint32 + Total_rto uint16 + Total_rto_recoveries uint16 + Total_rto_time uint32 } type CanFilter struct { @@ -551,7 +555,7 @@ const ( SizeofIPv6MTUInfo = 0x20 SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc - SizeofTCPInfo = 0xf0 + SizeofTCPInfo = 0xf8 SizeofCanFilter = 0x8 SizeofTCPRepairOpt = 0x8 ) @@ -832,6 +836,15 @@ const ( FSPICK_EMPTY_PATH = 0x8 FSMOUNT_CLOEXEC = 0x1 + + FSCONFIG_SET_FLAG = 0x0 + FSCONFIG_SET_STRING = 0x1 + FSCONFIG_SET_BINARY = 0x2 + FSCONFIG_SET_PATH = 0x3 + FSCONFIG_SET_PATH_EMPTY = 0x4 + FSCONFIG_SET_FD = 0x5 + FSCONFIG_CMD_CREATE = 0x6 + FSCONFIG_CMD_RECONFIGURE = 0x7 ) type OpenHow struct { @@ -1546,6 +1559,7 @@ const ( IFLA_DEVLINK_PORT = 0x3e IFLA_GSO_IPV4_MAX_SIZE = 0x3f IFLA_GRO_IPV4_MAX_SIZE = 0x40 + IFLA_DPLL_PIN = 0x41 IFLA_PROTO_DOWN_REASON_UNSPEC = 0x0 IFLA_PROTO_DOWN_REASON_MASK = 0x1 IFLA_PROTO_DOWN_REASON_VALUE = 0x2 @@ -1561,6 +1575,7 @@ const ( IFLA_INET6_ICMP6STATS = 0x6 IFLA_INET6_TOKEN = 0x7 IFLA_INET6_ADDR_GEN_MODE = 0x8 + IFLA_INET6_RA_MTU = 0x9 IFLA_BR_UNSPEC = 0x0 IFLA_BR_FORWARD_DELAY = 0x1 IFLA_BR_HELLO_TIME = 0x2 @@ -1608,6 +1623,9 @@ const ( IFLA_BR_MCAST_MLD_VERSION = 0x2c IFLA_BR_VLAN_STATS_PER_PORT = 0x2d IFLA_BR_MULTI_BOOLOPT = 0x2e + IFLA_BR_MCAST_QUERIER_STATE = 0x2f + IFLA_BR_FDB_N_LEARNED = 0x30 + IFLA_BR_FDB_MAX_LEARNED = 0x31 IFLA_BRPORT_UNSPEC = 0x0 IFLA_BRPORT_STATE = 0x1 IFLA_BRPORT_PRIORITY = 0x2 @@ -1645,6 +1663,14 @@ const ( IFLA_BRPORT_BACKUP_PORT = 0x22 IFLA_BRPORT_MRP_RING_OPEN = 0x23 IFLA_BRPORT_MRP_IN_OPEN = 0x24 + IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT = 0x25 + IFLA_BRPORT_MCAST_EHT_HOSTS_CNT = 0x26 + IFLA_BRPORT_LOCKED = 0x27 + IFLA_BRPORT_MAB = 0x28 + IFLA_BRPORT_MCAST_N_GROUPS = 0x29 + IFLA_BRPORT_MCAST_MAX_GROUPS = 0x2a + IFLA_BRPORT_NEIGH_VLAN_SUPPRESS = 0x2b + IFLA_BRPORT_BACKUP_NHID = 0x2c IFLA_INFO_UNSPEC = 0x0 IFLA_INFO_KIND = 0x1 IFLA_INFO_DATA = 0x2 @@ -1666,6 +1692,9 @@ const ( IFLA_MACVLAN_MACADDR = 0x4 IFLA_MACVLAN_MACADDR_DATA = 0x5 IFLA_MACVLAN_MACADDR_COUNT = 0x6 + IFLA_MACVLAN_BC_QUEUE_LEN = 0x7 + IFLA_MACVLAN_BC_QUEUE_LEN_USED = 0x8 + IFLA_MACVLAN_BC_CUTOFF = 0x9 IFLA_VRF_UNSPEC = 0x0 IFLA_VRF_TABLE = 0x1 IFLA_VRF_PORT_UNSPEC = 0x0 @@ -1689,9 +1718,22 @@ const ( IFLA_XFRM_UNSPEC = 0x0 IFLA_XFRM_LINK = 0x1 IFLA_XFRM_IF_ID = 0x2 + IFLA_XFRM_COLLECT_METADATA = 0x3 IFLA_IPVLAN_UNSPEC = 0x0 IFLA_IPVLAN_MODE = 0x1 IFLA_IPVLAN_FLAGS = 0x2 + NETKIT_NEXT = -0x1 + NETKIT_PASS = 0x0 + NETKIT_DROP = 0x2 + NETKIT_REDIRECT = 0x7 + NETKIT_L2 = 0x0 + NETKIT_L3 = 0x1 + IFLA_NETKIT_UNSPEC = 0x0 + IFLA_NETKIT_PEER_INFO = 0x1 + IFLA_NETKIT_PRIMARY = 0x2 + IFLA_NETKIT_POLICY = 0x3 + IFLA_NETKIT_PEER_POLICY = 0x4 + IFLA_NETKIT_MODE = 0x5 IFLA_VXLAN_UNSPEC = 0x0 IFLA_VXLAN_ID = 0x1 IFLA_VXLAN_GROUP = 0x2 @@ -1722,6 +1764,8 @@ const ( IFLA_VXLAN_GPE = 0x1b IFLA_VXLAN_TTL_INHERIT = 0x1c IFLA_VXLAN_DF = 0x1d + IFLA_VXLAN_VNIFILTER = 0x1e + IFLA_VXLAN_LOCALBYPASS = 0x1f IFLA_GENEVE_UNSPEC = 0x0 IFLA_GENEVE_ID = 0x1 IFLA_GENEVE_REMOTE = 0x2 @@ -1736,6 +1780,7 @@ const ( IFLA_GENEVE_LABEL = 0xb IFLA_GENEVE_TTL_INHERIT = 0xc IFLA_GENEVE_DF = 0xd + IFLA_GENEVE_INNER_PROTO_INHERIT = 0xe IFLA_BAREUDP_UNSPEC = 0x0 IFLA_BAREUDP_PORT = 0x1 IFLA_BAREUDP_ETHERTYPE = 0x2 @@ -1748,6 +1793,8 @@ const ( IFLA_GTP_FD1 = 0x2 IFLA_GTP_PDP_HASHSIZE = 0x3 IFLA_GTP_ROLE = 0x4 + IFLA_GTP_CREATE_SOCKETS = 0x5 + IFLA_GTP_RESTART_COUNT = 0x6 IFLA_BOND_UNSPEC = 0x0 IFLA_BOND_MODE = 0x1 IFLA_BOND_ACTIVE_SLAVE = 0x2 @@ -1777,6 +1824,9 @@ const ( IFLA_BOND_AD_ACTOR_SYSTEM = 0x1a IFLA_BOND_TLB_DYNAMIC_LB = 0x1b IFLA_BOND_PEER_NOTIF_DELAY = 0x1c + IFLA_BOND_AD_LACP_ACTIVE = 0x1d + IFLA_BOND_MISSED_MAX = 0x1e + IFLA_BOND_NS_IP6_TARGET = 0x1f IFLA_BOND_AD_INFO_UNSPEC = 0x0 IFLA_BOND_AD_INFO_AGGREGATOR = 0x1 IFLA_BOND_AD_INFO_NUM_PORTS = 0x2 @@ -1792,6 +1842,7 @@ const ( IFLA_BOND_SLAVE_AD_AGGREGATOR_ID = 0x6 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE = 0x7 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE = 0x8 + IFLA_BOND_SLAVE_PRIO = 0x9 IFLA_VF_INFO_UNSPEC = 0x0 IFLA_VF_INFO = 0x1 IFLA_VF_UNSPEC = 0x0 @@ -1850,8 +1901,16 @@ const ( IFLA_STATS_LINK_XSTATS_SLAVE = 0x3 IFLA_STATS_LINK_OFFLOAD_XSTATS = 0x4 IFLA_STATS_AF_SPEC = 0x5 + IFLA_STATS_GETSET_UNSPEC = 0x0 + IFLA_STATS_GET_FILTERS = 0x1 + IFLA_STATS_SET_OFFLOAD_XSTATS_L3_STATS = 0x2 IFLA_OFFLOAD_XSTATS_UNSPEC = 0x0 IFLA_OFFLOAD_XSTATS_CPU_HIT = 0x1 + IFLA_OFFLOAD_XSTATS_HW_S_INFO = 0x2 + IFLA_OFFLOAD_XSTATS_L3_STATS = 0x3 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_UNSPEC = 0x0 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST = 0x1 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED = 0x2 IFLA_XDP_UNSPEC = 0x0 IFLA_XDP_FD = 0x1 IFLA_XDP_ATTACHED = 0x2 @@ -1881,6 +1940,11 @@ const ( IFLA_RMNET_UNSPEC = 0x0 IFLA_RMNET_MUX_ID = 0x1 IFLA_RMNET_FLAGS = 0x2 + IFLA_MCTP_UNSPEC = 0x0 + IFLA_MCTP_NET = 0x1 + IFLA_DSA_UNSPEC = 0x0 + IFLA_DSA_CONDUIT = 0x1 + IFLA_DSA_MASTER = 0x1 ) const ( @@ -3399,7 +3463,7 @@ const ( DEVLINK_PORT_FN_ATTR_STATE = 0x2 DEVLINK_PORT_FN_ATTR_OPSTATE = 0x3 DEVLINK_PORT_FN_ATTR_CAPS = 0x4 - DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x4 + DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x5 ) type FsverityDigest struct { @@ -4183,7 +4247,8 @@ const ( ) type LandlockRulesetAttr struct { - Access_fs uint64 + Access_fs uint64 + Access_net uint64 } type LandlockPathBeneathAttr struct { @@ -5134,7 +5199,7 @@ const ( NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf - NL80211_FREQUENCY_ATTR_MAX = 0x1b + NL80211_FREQUENCY_ATTR_MAX = 0x1c NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc @@ -5547,7 +5612,7 @@ const ( NL80211_REGDOM_TYPE_CUSTOM_WORLD = 0x2 NL80211_REGDOM_TYPE_INTERSECTION = 0x3 NL80211_REGDOM_TYPE_WORLD = 0x1 - NL80211_REG_RULE_ATTR_MAX = 0x7 + NL80211_REG_RULE_ATTR_MAX = 0x8 NL80211_REKEY_DATA_AKM = 0x4 NL80211_REKEY_DATA_KCK = 0x2 NL80211_REKEY_DATA_KEK = 0x1 diff --git a/vendor/golang.org/x/sys/windows/env_windows.go b/vendor/golang.org/x/sys/windows/env_windows.go index b8ad1925..d4577a42 100644 --- a/vendor/golang.org/x/sys/windows/env_windows.go +++ b/vendor/golang.org/x/sys/windows/env_windows.go @@ -37,14 +37,17 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) { return nil, err } defer DestroyEnvironmentBlock(block) - blockp := unsafe.Pointer(block) - for { - entry := UTF16PtrToString((*uint16)(blockp)) - if len(entry) == 0 { - break + size := unsafe.Sizeof(*block) + for *block != 0 { + // find NUL terminator + end := unsafe.Pointer(block) + for *(*uint16)(end) != 0 { + end = unsafe.Add(end, size) } - env = append(env, entry) - blockp = unsafe.Add(blockp, 2*(len(entry)+1)) + + entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size) + env = append(env, UTF16ToString(entry)) + block = (*uint16)(unsafe.Add(end, size)) } return env, nil } diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 47dc5796..6525c62f 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -125,8 +125,7 @@ func UTF16PtrToString(p *uint16) string { for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ { ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p)) } - - return string(utf16.Decode(unsafe.Slice(p, n))) + return UTF16ToString(unsafe.Slice(p, n)) } func Getpagesize() int { return 4096 } @@ -166,6 +165,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW //sys CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) [failretval==InvalidHandle] = CreateNamedPipeW //sys ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) +//sys DisconnectNamedPipe(pipe Handle) (err error) //sys GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) //sys GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW //sys SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) = SetNamedPipeHandleState @@ -194,6 +194,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW //sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW //sys SetEndOfFile(handle Handle) (err error) +//sys SetFileValidData(handle Handle, validDataLength int64) (err error) //sys GetSystemTimeAsFileTime(time *Filetime) //sys GetSystemTimePreciseAsFileTime(time *Filetime) //sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] @@ -348,8 +349,19 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetProcessPriorityBoost(process Handle, disable bool) (err error) = kernel32.SetProcessPriorityBoost //sys GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32) //sys SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error) +//sys ClearCommBreak(handle Handle) (err error) +//sys ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error) +//sys EscapeCommFunction(handle Handle, dwFunc uint32) (err error) +//sys GetCommState(handle Handle, lpDCB *DCB) (err error) +//sys GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error) //sys GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) +//sys PurgeComm(handle Handle, dwFlags uint32) (err error) +//sys SetCommBreak(handle Handle) (err error) +//sys SetCommMask(handle Handle, dwEvtMask uint32) (err error) +//sys SetCommState(handle Handle, lpDCB *DCB) (err error) //sys SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) +//sys SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error) +//sys WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error) //sys GetActiveProcessorCount(groupNumber uint16) (ret uint32) //sys GetMaximumProcessorCount(groupNumber uint16) (ret uint32) //sys EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) = user32.EnumWindows @@ -1834,3 +1846,73 @@ func ResizePseudoConsole(pconsole Handle, size Coord) error { // accept arguments that can be casted to uintptr, and Coord can't. return resizePseudoConsole(pconsole, *((*uint32)(unsafe.Pointer(&size)))) } + +// DCB constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-dcb. +const ( + CBR_110 = 110 + CBR_300 = 300 + CBR_600 = 600 + CBR_1200 = 1200 + CBR_2400 = 2400 + CBR_4800 = 4800 + CBR_9600 = 9600 + CBR_14400 = 14400 + CBR_19200 = 19200 + CBR_38400 = 38400 + CBR_57600 = 57600 + CBR_115200 = 115200 + CBR_128000 = 128000 + CBR_256000 = 256000 + + DTR_CONTROL_DISABLE = 0x00000000 + DTR_CONTROL_ENABLE = 0x00000010 + DTR_CONTROL_HANDSHAKE = 0x00000020 + + RTS_CONTROL_DISABLE = 0x00000000 + RTS_CONTROL_ENABLE = 0x00001000 + RTS_CONTROL_HANDSHAKE = 0x00002000 + RTS_CONTROL_TOGGLE = 0x00003000 + + NOPARITY = 0 + ODDPARITY = 1 + EVENPARITY = 2 + MARKPARITY = 3 + SPACEPARITY = 4 + + ONESTOPBIT = 0 + ONE5STOPBITS = 1 + TWOSTOPBITS = 2 +) + +// EscapeCommFunction constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-escapecommfunction. +const ( + SETXOFF = 1 + SETXON = 2 + SETRTS = 3 + CLRRTS = 4 + SETDTR = 5 + CLRDTR = 6 + SETBREAK = 8 + CLRBREAK = 9 +) + +// PurgeComm constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-purgecomm. +const ( + PURGE_TXABORT = 0x0001 + PURGE_RXABORT = 0x0002 + PURGE_TXCLEAR = 0x0004 + PURGE_RXCLEAR = 0x0008 +) + +// SetCommMask constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setcommmask. +const ( + EV_RXCHAR = 0x0001 + EV_RXFLAG = 0x0002 + EV_TXEMPTY = 0x0004 + EV_CTS = 0x0008 + EV_DSR = 0x0010 + EV_RLSD = 0x0020 + EV_BREAK = 0x0040 + EV_ERR = 0x0080 + EV_RING = 0x0100 +) diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 359780f6..d8cb71db 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -3380,3 +3380,27 @@ type BLOB struct { Size uint32 BlobData *byte } + +type ComStat struct { + Flags uint32 + CBInQue uint32 + CBOutQue uint32 +} + +type DCB struct { + DCBlength uint32 + BaudRate uint32 + Flags uint32 + wReserved uint16 + XonLim uint16 + XoffLim uint16 + ByteSize uint8 + Parity uint8 + StopBits uint8 + XonChar byte + XoffChar byte + ErrorChar byte + EofChar byte + EvtChar byte + wReserved1 uint16 +} diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 146a1f01..5c6035dd 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -188,6 +188,8 @@ var ( procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") procCancelIo = modkernel32.NewProc("CancelIo") procCancelIoEx = modkernel32.NewProc("CancelIoEx") + procClearCommBreak = modkernel32.NewProc("ClearCommBreak") + procClearCommError = modkernel32.NewProc("ClearCommError") procCloseHandle = modkernel32.NewProc("CloseHandle") procClosePseudoConsole = modkernel32.NewProc("ClosePseudoConsole") procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") @@ -212,7 +214,9 @@ var ( procDeleteProcThreadAttributeList = modkernel32.NewProc("DeleteProcThreadAttributeList") procDeleteVolumeMountPointW = modkernel32.NewProc("DeleteVolumeMountPointW") procDeviceIoControl = modkernel32.NewProc("DeviceIoControl") + procDisconnectNamedPipe = modkernel32.NewProc("DisconnectNamedPipe") procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") + procEscapeCommFunction = modkernel32.NewProc("EscapeCommFunction") procExitProcess = modkernel32.NewProc("ExitProcess") procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW") procFindClose = modkernel32.NewProc("FindClose") @@ -236,6 +240,8 @@ var ( procGenerateConsoleCtrlEvent = modkernel32.NewProc("GenerateConsoleCtrlEvent") procGetACP = modkernel32.NewProc("GetACP") procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount") + procGetCommModemStatus = modkernel32.NewProc("GetCommModemStatus") + procGetCommState = modkernel32.NewProc("GetCommState") procGetCommTimeouts = modkernel32.NewProc("GetCommTimeouts") procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") @@ -322,6 +328,7 @@ var ( procProcess32NextW = modkernel32.NewProc("Process32NextW") procProcessIdToSessionId = modkernel32.NewProc("ProcessIdToSessionId") procPulseEvent = modkernel32.NewProc("PulseEvent") + procPurgeComm = modkernel32.NewProc("PurgeComm") procQueryDosDeviceW = modkernel32.NewProc("QueryDosDeviceW") procQueryFullProcessImageNameW = modkernel32.NewProc("QueryFullProcessImageNameW") procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject") @@ -335,6 +342,9 @@ var ( procResetEvent = modkernel32.NewProc("ResetEvent") procResizePseudoConsole = modkernel32.NewProc("ResizePseudoConsole") procResumeThread = modkernel32.NewProc("ResumeThread") + procSetCommBreak = modkernel32.NewProc("SetCommBreak") + procSetCommMask = modkernel32.NewProc("SetCommMask") + procSetCommState = modkernel32.NewProc("SetCommState") procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts") procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition") procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") @@ -350,6 +360,7 @@ var ( procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle") procSetFilePointer = modkernel32.NewProc("SetFilePointer") procSetFileTime = modkernel32.NewProc("SetFileTime") + procSetFileValidData = modkernel32.NewProc("SetFileValidData") procSetHandleInformation = modkernel32.NewProc("SetHandleInformation") procSetInformationJobObject = modkernel32.NewProc("SetInformationJobObject") procSetNamedPipeHandleState = modkernel32.NewProc("SetNamedPipeHandleState") @@ -360,6 +371,7 @@ var ( procSetStdHandle = modkernel32.NewProc("SetStdHandle") procSetVolumeLabelW = modkernel32.NewProc("SetVolumeLabelW") procSetVolumeMountPointW = modkernel32.NewProc("SetVolumeMountPointW") + procSetupComm = modkernel32.NewProc("SetupComm") procSizeofResource = modkernel32.NewProc("SizeofResource") procSleepEx = modkernel32.NewProc("SleepEx") procTerminateJobObject = modkernel32.NewProc("TerminateJobObject") @@ -378,6 +390,7 @@ var ( procVirtualQueryEx = modkernel32.NewProc("VirtualQueryEx") procVirtualUnlock = modkernel32.NewProc("VirtualUnlock") procWTSGetActiveConsoleSessionId = modkernel32.NewProc("WTSGetActiveConsoleSessionId") + procWaitCommEvent = modkernel32.NewProc("WaitCommEvent") procWaitForMultipleObjects = modkernel32.NewProc("WaitForMultipleObjects") procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") procWriteConsoleW = modkernel32.NewProc("WriteConsoleW") @@ -1640,6 +1653,22 @@ func CancelIoEx(s Handle, o *Overlapped) (err error) { return } +func ClearCommBreak(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procClearCommBreak.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error) { + r1, _, e1 := syscall.Syscall(procClearCommError.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpErrors)), uintptr(unsafe.Pointer(lpStat))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func CloseHandle(handle Handle) (err error) { r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0) if r1 == 0 { @@ -1844,6 +1873,14 @@ func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBuff return } +func DisconnectNamedPipe(pipe Handle) (err error) { + r1, _, e1 := syscall.Syscall(procDisconnectNamedPipe.Addr(), 1, uintptr(pipe), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) { var _p0 uint32 if bInheritHandle { @@ -1856,6 +1893,14 @@ func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetP return } +func EscapeCommFunction(handle Handle, dwFunc uint32) (err error) { + r1, _, e1 := syscall.Syscall(procEscapeCommFunction.Addr(), 2, uintptr(handle), uintptr(dwFunc), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func ExitProcess(exitcode uint32) { syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0) return @@ -2057,6 +2102,22 @@ func GetActiveProcessorCount(groupNumber uint16) (ret uint32) { return } +func GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetCommModemStatus.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpModemStat)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetCommState(handle Handle, lpDCB *DCB) (err error) { + r1, _, e1 := syscall.Syscall(procGetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { r1, _, e1 := syscall.Syscall(procGetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0) if r1 == 0 { @@ -2809,6 +2870,14 @@ func PulseEvent(event Handle) (err error) { return } +func PurgeComm(handle Handle, dwFlags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procPurgeComm.Addr(), 2, uintptr(handle), uintptr(dwFlags), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) { r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max)) n = uint32(r0) @@ -2923,6 +2992,30 @@ func ResumeThread(thread Handle) (ret uint32, err error) { return } +func SetCommBreak(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procSetCommBreak.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetCommMask(handle Handle, dwEvtMask uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetCommMask.Addr(), 2, uintptr(handle), uintptr(dwEvtMask), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetCommState(handle Handle, lpDCB *DCB) (err error) { + r1, _, e1 := syscall.Syscall(procSetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { r1, _, e1 := syscall.Syscall(procSetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0) if r1 == 0 { @@ -3051,6 +3144,14 @@ func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetim return } +func SetFileValidData(handle Handle, validDataLength int64) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) { r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags)) if r1 == 0 { @@ -3136,6 +3237,14 @@ func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err erro return } +func SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetupComm.Addr(), 3, uintptr(handle), uintptr(dwInQueue), uintptr(dwOutQueue)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SizeofResource(module Handle, resInfo Handle) (size uint32, err error) { r0, _, e1 := syscall.Syscall(procSizeofResource.Addr(), 2, uintptr(module), uintptr(resInfo), 0) size = uint32(r0) @@ -3282,6 +3391,14 @@ func WTSGetActiveConsoleSessionId() (sessionID uint32) { return } +func WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall(procWaitCommEvent.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpEvtMask)), uintptr(unsafe.Pointer(lpOverlapped))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMilliseconds uint32) (event uint32, err error) { var _p0 uint32 if waitAll { diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE new file mode 100644 index 00000000..6a66aea5 --- /dev/null +++ b/vendor/golang.org/x/tools/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS new file mode 100644 index 00000000..73309904 --- /dev/null +++ b/vendor/golang.org/x/tools/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google 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, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/tools/cmd/stringer/stringer.go b/vendor/golang.org/x/tools/cmd/stringer/stringer.go new file mode 100644 index 00000000..2b19c93e --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/stringer/stringer.go @@ -0,0 +1,660 @@ +// 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. + +// Stringer is a tool to automate the creation of methods that satisfy the fmt.Stringer +// interface. Given the name of a (signed or unsigned) integer type T that has constants +// defined, stringer will create a new self-contained Go source file implementing +// +// func (t T) String() string +// +// The file is created in the same package and directory as the package that defines T. +// It has helpful defaults designed for use with go generate. +// +// Stringer works best with constants that are consecutive values such as created using iota, +// but creates good code regardless. In the future it might also provide custom support for +// constant sets that are bit patterns. +// +// For example, given this snippet, +// +// package painkiller +// +// type Pill int +// +// const ( +// Placebo Pill = iota +// Aspirin +// Ibuprofen +// Paracetamol +// Acetaminophen = Paracetamol +// ) +// +// running this command +// +// stringer -type=Pill +// +// in the same directory will create the file pill_string.go, in package painkiller, +// containing a definition of +// +// func (Pill) String() string +// +// That method will translate the value of a Pill constant to the string representation +// of the respective constant name, so that the call fmt.Print(painkiller.Aspirin) will +// print the string "Aspirin". +// +// Typically this process would be run using go generate, like this: +// +// //go:generate stringer -type=Pill +// +// If multiple constants have the same value, the lexically first matching name will +// be used (in the example, Acetaminophen will print as "Paracetamol"). +// +// With no arguments, it processes the package in the current directory. +// Otherwise, the arguments must name a single directory holding a Go package +// or a set of Go source files that represent a single Go package. +// +// The -type flag accepts a comma-separated list of types so a single run can +// generate methods for multiple types. The default output file is t_string.go, +// where t is the lower-cased name of the first type listed. It can be overridden +// with the -output flag. +// +// The -linecomment flag tells stringer to generate the text of any line comment, trimmed +// of leading spaces, instead of the constant name. For instance, if the constants above had a +// Pill prefix, one could write +// +// PillAspirin // Aspirin +// +// to suppress it in the output. +package main // import "golang.org/x/tools/cmd/stringer" + +import ( + "bytes" + "flag" + "fmt" + "go/ast" + "go/constant" + "go/format" + "go/token" + "go/types" + "log" + "os" + "path/filepath" + "sort" + "strings" + + "golang.org/x/tools/go/packages" +) + +var ( + typeNames = flag.String("type", "", "comma-separated list of type names; must be set") + output = flag.String("output", "", "output file name; default srcdir/_string.go") + trimprefix = flag.String("trimprefix", "", "trim the `prefix` from the generated constant names") + linecomment = flag.Bool("linecomment", false, "use line comment text as printed text when present") + buildTags = flag.String("tags", "", "comma-separated list of build tags to apply") +) + +// Usage is a replacement usage function for the flags package. +func Usage() { + fmt.Fprintf(os.Stderr, "Usage of stringer:\n") + fmt.Fprintf(os.Stderr, "\tstringer [flags] -type T [directory]\n") + fmt.Fprintf(os.Stderr, "\tstringer [flags] -type T files... # Must be a single package\n") + fmt.Fprintf(os.Stderr, "For more information, see:\n") + fmt.Fprintf(os.Stderr, "\thttps://pkg.go.dev/golang.org/x/tools/cmd/stringer\n") + fmt.Fprintf(os.Stderr, "Flags:\n") + flag.PrintDefaults() +} + +func main() { + log.SetFlags(0) + log.SetPrefix("stringer: ") + flag.Usage = Usage + flag.Parse() + if len(*typeNames) == 0 { + flag.Usage() + os.Exit(2) + } + types := strings.Split(*typeNames, ",") + var tags []string + if len(*buildTags) > 0 { + tags = strings.Split(*buildTags, ",") + } + + // We accept either one directory or a list of files. Which do we have? + args := flag.Args() + if len(args) == 0 { + // Default: process whole package in current directory. + args = []string{"."} + } + + // Parse the package once. + var dir string + g := Generator{ + trimPrefix: *trimprefix, + lineComment: *linecomment, + } + // TODO(suzmue): accept other patterns for packages (directories, list of files, import paths, etc). + if len(args) == 1 && isDirectory(args[0]) { + dir = args[0] + } else { + if len(tags) != 0 { + log.Fatal("-tags option applies only to directories, not when files are specified") + } + dir = filepath.Dir(args[0]) + } + + g.parsePackage(args, tags) + + // Print the header and package clause. + g.Printf("// Code generated by \"stringer %s\"; DO NOT EDIT.\n", strings.Join(os.Args[1:], " ")) + g.Printf("\n") + g.Printf("package %s", g.pkg.name) + g.Printf("\n") + g.Printf("import \"strconv\"\n") // Used by all methods. + + // Run generate for each type. + for _, typeName := range types { + g.generate(typeName) + } + + // Format the output. + src := g.format() + + // Write to file. + outputName := *output + if outputName == "" { + baseName := fmt.Sprintf("%s_string.go", types[0]) + outputName = filepath.Join(dir, strings.ToLower(baseName)) + } + err := os.WriteFile(outputName, src, 0644) + if err != nil { + log.Fatalf("writing output: %s", err) + } +} + +// isDirectory reports whether the named file is a directory. +func isDirectory(name string) bool { + info, err := os.Stat(name) + if err != nil { + log.Fatal(err) + } + return info.IsDir() +} + +// Generator holds the state of the analysis. Primarily used to buffer +// the output for format.Source. +type Generator struct { + buf bytes.Buffer // Accumulated output. + pkg *Package // Package we are scanning. + + trimPrefix string + lineComment bool + + logf func(format string, args ...interface{}) // test logging hook; nil when not testing +} + +func (g *Generator) Printf(format string, args ...interface{}) { + fmt.Fprintf(&g.buf, format, args...) +} + +// File holds a single parsed file and associated data. +type File struct { + pkg *Package // Package to which this file belongs. + file *ast.File // Parsed AST. + // These fields are reset for each type being generated. + typeName string // Name of the constant type. + values []Value // Accumulator for constant values of that type. + + trimPrefix string + lineComment bool +} + +type Package struct { + name string + defs map[*ast.Ident]types.Object + files []*File +} + +// parsePackage analyzes the single package constructed from the patterns and tags. +// parsePackage exits if there is an error. +func (g *Generator) parsePackage(patterns []string, tags []string) { + cfg := &packages.Config{ + Mode: packages.NeedName | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedSyntax, + // TODO: Need to think about constants in test files. Maybe write type_string_test.go + // in a separate pass? For later. + Tests: false, + BuildFlags: []string{fmt.Sprintf("-tags=%s", strings.Join(tags, " "))}, + Logf: g.logf, + } + pkgs, err := packages.Load(cfg, patterns...) + if err != nil { + log.Fatal(err) + } + if len(pkgs) != 1 { + log.Fatalf("error: %d packages matching %v", len(pkgs), strings.Join(patterns, " ")) + } + g.addPackage(pkgs[0]) +} + +// addPackage adds a type checked Package and its syntax files to the generator. +func (g *Generator) addPackage(pkg *packages.Package) { + g.pkg = &Package{ + name: pkg.Name, + defs: pkg.TypesInfo.Defs, + files: make([]*File, len(pkg.Syntax)), + } + + for i, file := range pkg.Syntax { + g.pkg.files[i] = &File{ + file: file, + pkg: g.pkg, + trimPrefix: g.trimPrefix, + lineComment: g.lineComment, + } + } +} + +// generate produces the String method for the named type. +func (g *Generator) generate(typeName string) { + values := make([]Value, 0, 100) + for _, file := range g.pkg.files { + // Set the state for this run of the walker. + file.typeName = typeName + file.values = nil + if file.file != nil { + ast.Inspect(file.file, file.genDecl) + values = append(values, file.values...) + } + } + + if len(values) == 0 { + log.Fatalf("no values defined for type %s", typeName) + } + // Generate code that will fail if the constants change value. + g.Printf("func _() {\n") + g.Printf("\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n") + g.Printf("\t// Re-run the stringer command to generate them again.\n") + g.Printf("\tvar x [1]struct{}\n") + for _, v := range values { + g.Printf("\t_ = x[%s - %s]\n", v.originalName, v.str) + } + g.Printf("}\n") + runs := splitIntoRuns(values) + // The decision of which pattern to use depends on the number of + // runs in the numbers. If there's only one, it's easy. For more than + // one, there's a tradeoff between complexity and size of the data + // and code vs. the simplicity of a map. A map takes more space, + // but so does the code. The decision here (crossover at 10) is + // arbitrary, but considers that for large numbers of runs the cost + // of the linear scan in the switch might become important, and + // rather than use yet another algorithm such as binary search, + // we punt and use a map. In any case, the likelihood of a map + // being necessary for any realistic example other than bitmasks + // is very low. And bitmasks probably deserve their own analysis, + // to be done some other day. + switch { + case len(runs) == 1: + g.buildOneRun(runs, typeName) + case len(runs) <= 10: + g.buildMultipleRuns(runs, typeName) + default: + g.buildMap(runs, typeName) + } +} + +// splitIntoRuns breaks the values into runs of contiguous sequences. +// For example, given 1,2,3,5,6,7 it returns {1,2,3},{5,6,7}. +// The input slice is known to be non-empty. +func splitIntoRuns(values []Value) [][]Value { + // We use stable sort so the lexically first name is chosen for equal elements. + sort.Stable(byValue(values)) + // Remove duplicates. Stable sort has put the one we want to print first, + // so use that one. The String method won't care about which named constant + // was the argument, so the first name for the given value is the only one to keep. + // We need to do this because identical values would cause the switch or map + // to fail to compile. + j := 1 + for i := 1; i < len(values); i++ { + if values[i].value != values[i-1].value { + values[j] = values[i] + j++ + } + } + values = values[:j] + runs := make([][]Value, 0, 10) + for len(values) > 0 { + // One contiguous sequence per outer loop. + i := 1 + for i < len(values) && values[i].value == values[i-1].value+1 { + i++ + } + runs = append(runs, values[:i]) + values = values[i:] + } + return runs +} + +// format returns the gofmt-ed contents of the Generator's buffer. +func (g *Generator) format() []byte { + src, err := format.Source(g.buf.Bytes()) + if err != nil { + // Should never happen, but can arise when developing this code. + // The user can compile the output to see the error. + log.Printf("warning: internal error: invalid Go generated: %s", err) + log.Printf("warning: compile the package to analyze the error") + return g.buf.Bytes() + } + return src +} + +// Value represents a declared constant. +type Value struct { + originalName string // The name of the constant. + name string // The name with trimmed prefix. + // The value is stored as a bit pattern alone. The boolean tells us + // whether to interpret it as an int64 or a uint64; the only place + // this matters is when sorting. + // Much of the time the str field is all we need; it is printed + // by Value.String. + value uint64 // Will be converted to int64 when needed. + signed bool // Whether the constant is a signed type. + str string // The string representation given by the "go/constant" package. +} + +func (v *Value) String() string { + return v.str +} + +// byValue lets us sort the constants into increasing order. +// We take care in the Less method to sort in signed or unsigned order, +// as appropriate. +type byValue []Value + +func (b byValue) Len() int { return len(b) } +func (b byValue) Swap(i, j int) { b[i], b[j] = b[j], b[i] } +func (b byValue) Less(i, j int) bool { + if b[i].signed { + return int64(b[i].value) < int64(b[j].value) + } + return b[i].value < b[j].value +} + +// genDecl processes one declaration clause. +func (f *File) genDecl(node ast.Node) bool { + decl, ok := node.(*ast.GenDecl) + if !ok || decl.Tok != token.CONST { + // We only care about const declarations. + return true + } + // The name of the type of the constants we are declaring. + // Can change if this is a multi-element declaration. + typ := "" + // Loop over the elements of the declaration. Each element is a ValueSpec: + // a list of names possibly followed by a type, possibly followed by values. + // If the type and value are both missing, we carry down the type (and value, + // but the "go/types" package takes care of that). + for _, spec := range decl.Specs { + vspec := spec.(*ast.ValueSpec) // Guaranteed to succeed as this is CONST. + if vspec.Type == nil && len(vspec.Values) > 0 { + // "X = 1". With no type but a value. If the constant is untyped, + // skip this vspec and reset the remembered type. + typ = "" + + // If this is a simple type conversion, remember the type. + // We don't mind if this is actually a call; a qualified call won't + // be matched (that will be SelectorExpr, not Ident), and only unusual + // situations will result in a function call that appears to be + // a type conversion. + ce, ok := vspec.Values[0].(*ast.CallExpr) + if !ok { + continue + } + id, ok := ce.Fun.(*ast.Ident) + if !ok { + continue + } + typ = id.Name + } + if vspec.Type != nil { + // "X T". We have a type. Remember it. + ident, ok := vspec.Type.(*ast.Ident) + if !ok { + continue + } + typ = ident.Name + } + if typ != f.typeName { + // This is not the type we're looking for. + continue + } + // We now have a list of names (from one line of source code) all being + // declared with the desired type. + // Grab their names and actual values and store them in f.values. + for _, name := range vspec.Names { + if name.Name == "_" { + continue + } + // This dance lets the type checker find the values for us. It's a + // bit tricky: look up the object declared by the name, find its + // types.Const, and extract its value. + obj, ok := f.pkg.defs[name] + if !ok { + log.Fatalf("no value for constant %s", name) + } + info := obj.Type().Underlying().(*types.Basic).Info() + if info&types.IsInteger == 0 { + log.Fatalf("can't handle non-integer constant type %s", typ) + } + value := obj.(*types.Const).Val() // Guaranteed to succeed as this is CONST. + if value.Kind() != constant.Int { + log.Fatalf("can't happen: constant is not an integer %s", name) + } + i64, isInt := constant.Int64Val(value) + u64, isUint := constant.Uint64Val(value) + if !isInt && !isUint { + log.Fatalf("internal error: value of %s is not an integer: %s", name, value.String()) + } + if !isInt { + u64 = uint64(i64) + } + v := Value{ + originalName: name.Name, + value: u64, + signed: info&types.IsUnsigned == 0, + str: value.String(), + } + if c := vspec.Comment; f.lineComment && c != nil && len(c.List) == 1 { + v.name = strings.TrimSpace(c.Text()) + } else { + v.name = strings.TrimPrefix(v.originalName, f.trimPrefix) + } + f.values = append(f.values, v) + } + } + return false +} + +// Helpers + +// usize returns the number of bits of the smallest unsigned integer +// type that will hold n. Used to create the smallest possible slice of +// integers to use as indexes into the concatenated strings. +func usize(n int) int { + switch { + case n < 1<<8: + return 8 + case n < 1<<16: + return 16 + default: + // 2^32 is enough constants for anyone. + return 32 + } +} + +// declareIndexAndNameVars declares the index slices and concatenated names +// strings representing the runs of values. +func (g *Generator) declareIndexAndNameVars(runs [][]Value, typeName string) { + var indexes, names []string + for i, run := range runs { + index, name := g.createIndexAndNameDecl(run, typeName, fmt.Sprintf("_%d", i)) + if len(run) != 1 { + indexes = append(indexes, index) + } + names = append(names, name) + } + g.Printf("const (\n") + for _, name := range names { + g.Printf("\t%s\n", name) + } + g.Printf(")\n\n") + + if len(indexes) > 0 { + g.Printf("var (") + for _, index := range indexes { + g.Printf("\t%s\n", index) + } + g.Printf(")\n\n") + } +} + +// declareIndexAndNameVar is the single-run version of declareIndexAndNameVars +func (g *Generator) declareIndexAndNameVar(run []Value, typeName string) { + index, name := g.createIndexAndNameDecl(run, typeName, "") + g.Printf("const %s\n", name) + g.Printf("var %s\n", index) +} + +// createIndexAndNameDecl returns the pair of declarations for the run. The caller will add "const" and "var". +func (g *Generator) createIndexAndNameDecl(run []Value, typeName string, suffix string) (string, string) { + b := new(bytes.Buffer) + indexes := make([]int, len(run)) + for i := range run { + b.WriteString(run[i].name) + indexes[i] = b.Len() + } + nameConst := fmt.Sprintf("_%s_name%s = %q", typeName, suffix, b.String()) + nameLen := b.Len() + b.Reset() + fmt.Fprintf(b, "_%s_index%s = [...]uint%d{0, ", typeName, suffix, usize(nameLen)) + for i, v := range indexes { + if i > 0 { + fmt.Fprintf(b, ", ") + } + fmt.Fprintf(b, "%d", v) + } + fmt.Fprintf(b, "}") + return b.String(), nameConst +} + +// declareNameVars declares the concatenated names string representing all the values in the runs. +func (g *Generator) declareNameVars(runs [][]Value, typeName string, suffix string) { + g.Printf("const _%s_name%s = \"", typeName, suffix) + for _, run := range runs { + for i := range run { + g.Printf("%s", run[i].name) + } + } + g.Printf("\"\n") +} + +// buildOneRun generates the variables and String method for a single run of contiguous values. +func (g *Generator) buildOneRun(runs [][]Value, typeName string) { + values := runs[0] + g.Printf("\n") + g.declareIndexAndNameVar(values, typeName) + // The generated code is simple enough to write as a Printf format. + lessThanZero := "" + if values[0].signed { + lessThanZero = "i < 0 || " + } + if values[0].value == 0 { // Signed or unsigned, 0 is still 0. + g.Printf(stringOneRun, typeName, usize(len(values)), lessThanZero) + } else { + g.Printf(stringOneRunWithOffset, typeName, values[0].String(), usize(len(values)), lessThanZero) + } +} + +// Arguments to format are: +// +// [1]: type name +// [2]: size of index element (8 for uint8 etc.) +// [3]: less than zero check (for signed types) +const stringOneRun = `func (i %[1]s) String() string { + if %[3]si >= %[1]s(len(_%[1]s_index)-1) { + return "%[1]s(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _%[1]s_name[_%[1]s_index[i]:_%[1]s_index[i+1]] +} +` + +// Arguments to format are: +// [1]: type name +// [2]: lowest defined value for type, as a string +// [3]: size of index element (8 for uint8 etc.) +// [4]: less than zero check (for signed types) +/* + */ +const stringOneRunWithOffset = `func (i %[1]s) String() string { + i -= %[2]s + if %[4]si >= %[1]s(len(_%[1]s_index)-1) { + return "%[1]s(" + strconv.FormatInt(int64(i + %[2]s), 10) + ")" + } + return _%[1]s_name[_%[1]s_index[i] : _%[1]s_index[i+1]] +} +` + +// buildMultipleRuns generates the variables and String method for multiple runs of contiguous values. +// For this pattern, a single Printf format won't do. +func (g *Generator) buildMultipleRuns(runs [][]Value, typeName string) { + g.Printf("\n") + g.declareIndexAndNameVars(runs, typeName) + g.Printf("func (i %s) String() string {\n", typeName) + g.Printf("\tswitch {\n") + for i, values := range runs { + if len(values) == 1 { + g.Printf("\tcase i == %s:\n", &values[0]) + g.Printf("\t\treturn _%s_name_%d\n", typeName, i) + continue + } + if values[0].value == 0 && !values[0].signed { + // For an unsigned lower bound of 0, "0 <= i" would be redundant. + g.Printf("\tcase i <= %s:\n", &values[len(values)-1]) + } else { + g.Printf("\tcase %s <= i && i <= %s:\n", &values[0], &values[len(values)-1]) + } + if values[0].value != 0 { + g.Printf("\t\ti -= %s\n", &values[0]) + } + g.Printf("\t\treturn _%s_name_%d[_%s_index_%d[i]:_%s_index_%d[i+1]]\n", + typeName, i, typeName, i, typeName, i) + } + g.Printf("\tdefault:\n") + g.Printf("\t\treturn \"%s(\" + strconv.FormatInt(int64(i), 10) + \")\"\n", typeName) + g.Printf("\t}\n") + g.Printf("}\n") +} + +// buildMap handles the case where the space is so sparse a map is a reasonable fallback. +// It's a rare situation but has simple code. +func (g *Generator) buildMap(runs [][]Value, typeName string) { + g.Printf("\n") + g.declareNameVars(runs, typeName, "") + g.Printf("\nvar _%s_map = map[%s]string{\n", typeName, typeName) + n := 0 + for _, values := range runs { + for _, value := range values { + g.Printf("\t%s: _%s_name[%d:%d],\n", &value, typeName, n, n+len(value.name)) + n += len(value.name) + } + } + g.Printf("}\n\n") + g.Printf(stringMap, typeName) +} + +// Argument to format is the type name. +const stringMap = `func (i %[1]s) String() string { + if str, ok := _%[1]s_map[i]; ok { + return str + } + return "%[1]s(" + strconv.FormatInt(int64(i), 10) + ")" +} +` diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go new file mode 100644 index 00000000..137cc8df --- /dev/null +++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go @@ -0,0 +1,186 @@ +// Copyright 2016 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 gcexportdata provides functions for locating, reading, and +// writing export data files containing type information produced by the +// gc compiler. This package supports go1.7 export data format and all +// later versions. +// +// Although it might seem convenient for this package to live alongside +// go/types in the standard library, this would cause version skew +// problems for developer tools that use it, since they must be able to +// consume the outputs of the gc compiler both before and after a Go +// update such as from Go 1.7 to Go 1.8. Because this package lives in +// golang.org/x/tools, sites can update their version of this repo some +// time before the Go 1.8 release and rebuild and redeploy their +// developer tools, which will then be able to consume both Go 1.7 and +// Go 1.8 export data files, so they will work before and after the +// Go update. (See discussion at https://golang.org/issue/15651.) +package gcexportdata // import "golang.org/x/tools/go/gcexportdata" + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "go/token" + "go/types" + "io" + "os/exec" + + "golang.org/x/tools/internal/gcimporter" +) + +// Find returns the name of an object (.o) or archive (.a) file +// containing type information for the specified import path, +// using the go command. +// If no file was found, an empty filename is returned. +// +// A relative srcDir is interpreted relative to the current working directory. +// +// Find also returns the package's resolved (canonical) import path, +// reflecting the effects of srcDir and vendoring on importPath. +// +// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, +// which is more efficient. +func Find(importPath, srcDir string) (filename, path string) { + cmd := exec.Command("go", "list", "-json", "-export", "--", importPath) + cmd.Dir = srcDir + out, err := cmd.Output() + if err != nil { + return "", "" + } + var data struct { + ImportPath string + Export string + } + json.Unmarshal(out, &data) + return data.Export, data.ImportPath +} + +// NewReader returns a reader for the export data section of an object +// (.o) or archive (.a) file read from r. The new reader may provide +// additional trailing data beyond the end of the export data. +func NewReader(r io.Reader) (io.Reader, error) { + buf := bufio.NewReader(r) + _, size, err := gcimporter.FindExportData(buf) + if err != nil { + return nil, err + } + + if size >= 0 { + // We were given an archive and found the __.PKGDEF in it. + // This tells us the size of the export data, and we don't + // need to return the entire file. + return &io.LimitedReader{ + R: buf, + N: size, + }, nil + } else { + // We were given an object file. As such, we don't know how large + // the export data is and must return the entire file. + return buf, nil + } +} + +// readAll works the same way as io.ReadAll, but avoids allocations and copies +// by preallocating a byte slice of the necessary size if the size is known up +// front. This is always possible when the input is an archive. In that case, +// NewReader will return the known size using an io.LimitedReader. +func readAll(r io.Reader) ([]byte, error) { + if lr, ok := r.(*io.LimitedReader); ok { + data := make([]byte, lr.N) + _, err := io.ReadFull(lr, data) + return data, err + } + return io.ReadAll(r) +} + +// Read reads export data from in, decodes it, and returns type +// information for the package. +// +// The package path (effectively its linker symbol prefix) is +// specified by path, since unlike the package name, this information +// may not be recorded in the export data. +// +// File position information is added to fset. +// +// Read may inspect and add to the imports map to ensure that references +// within the export data to other packages are consistent. The caller +// must ensure that imports[path] does not exist, or exists but is +// incomplete (see types.Package.Complete), and Read inserts the +// resulting package into this map entry. +// +// On return, the state of the reader is undefined. +func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) { + data, err := readAll(in) + if err != nil { + return nil, fmt.Errorf("reading export data for %q: %v", path, err) + } + + if bytes.HasPrefix(data, []byte("!")) { + return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path) + } + + // The indexed export format starts with an 'i'; the older + // binary export format starts with a 'c', 'd', or 'v' + // (from "version"). Select appropriate importer. + if len(data) > 0 { + switch data[0] { + case 'v', 'c', 'd': // binary, till go1.10 + return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0]) + + case 'i': // indexed, till go1.19 + _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) + return pkg, err + + case 'u': // unified, from go1.20 + _, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path) + return pkg, err + + default: + l := len(data) + if l > 10 { + l = 10 + } + return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), path) + } + } + return nil, fmt.Errorf("empty export data for %s", path) +} + +// Write writes encoded type information for the specified package to out. +// The FileSet provides file position information for named objects. +func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error { + if _, err := io.WriteString(out, "i"); err != nil { + return err + } + return gcimporter.IExportData(out, fset, pkg) +} + +// ReadBundle reads an export bundle from in, decodes it, and returns type +// information for the packages. +// File position information is added to fset. +// +// ReadBundle may inspect and add to the imports map to ensure that references +// within the export bundle to other packages are consistent. +// +// On return, the state of the reader is undefined. +// +// Experimental: This API is experimental and may change in the future. +func ReadBundle(in io.Reader, fset *token.FileSet, imports map[string]*types.Package) ([]*types.Package, error) { + data, err := readAll(in) + if err != nil { + return nil, fmt.Errorf("reading export bundle: %v", err) + } + return gcimporter.IImportBundle(fset, imports, data) +} + +// WriteBundle writes encoded type information for the specified packages to out. +// The FileSet provides file position information for named objects. +// +// Experimental: This API is experimental and may change in the future. +func WriteBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error { + return gcimporter.IExportBundle(out, fset, pkgs) +} diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go new file mode 100644 index 00000000..37a7247e --- /dev/null +++ b/vendor/golang.org/x/tools/go/gcexportdata/importer.go @@ -0,0 +1,75 @@ +// Copyright 2016 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 gcexportdata + +import ( + "fmt" + "go/token" + "go/types" + "os" +) + +// NewImporter returns a new instance of the types.Importer interface +// that reads type information from export data files written by gc. +// The Importer also satisfies types.ImporterFrom. +// +// Export data files are located using "go build" workspace conventions +// and the build.Default context. +// +// Use this importer instead of go/importer.For("gc", ...) to avoid the +// version-skew problems described in the documentation of this package, +// or to control the FileSet or access the imports map populated during +// package loading. +// +// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, +// which is more efficient. +func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { + return importer{fset, imports} +} + +type importer struct { + fset *token.FileSet + imports map[string]*types.Package +} + +func (imp importer) Import(importPath string) (*types.Package, error) { + return imp.ImportFrom(importPath, "", 0) +} + +func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) { + filename, path := Find(importPath, srcDir) + if filename == "" { + if importPath == "unsafe" { + // Even for unsafe, call Find first in case + // the package was vendored. + return types.Unsafe, nil + } + return nil, fmt.Errorf("can't find import: %s", importPath) + } + + if pkg, ok := imp.imports[path]; ok && pkg.Complete() { + return pkg, nil // cache hit + } + + // open file + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer func() { + f.Close() + if err != nil { + // add file name to error + err = fmt.Errorf("reading export data: %s: %v", filename, err) + } + }() + + r, err := NewReader(f) + if err != nil { + return nil, err + } + + return Read(r, imp.fset, imp.imports, path) +} diff --git a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go new file mode 100644 index 00000000..333676b7 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go @@ -0,0 +1,53 @@ +// 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 packagesdriver fetches type sizes for go/packages and go/analysis. +package packagesdriver + +import ( + "context" + "fmt" + "strings" + + "golang.org/x/tools/internal/gocommand" +) + +func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) { + inv.Verb = "list" + inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"} + stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv) + var goarch, compiler string + if rawErr != nil { + rawErrMsg := rawErr.Error() + if strings.Contains(rawErrMsg, "cannot find main module") || + strings.Contains(rawErrMsg, "go.mod file not found") { + // User's running outside of a module. + // All bets are off. Get GOARCH and guess compiler is gc. + // TODO(matloob): Is this a problem in practice? + inv.Verb = "env" + inv.Args = []string{"GOARCH"} + envout, enverr := gocmdRunner.Run(ctx, inv) + if enverr != nil { + return "", "", enverr + } + goarch = strings.TrimSpace(envout.String()) + compiler = "gc" + } else if friendlyErr != nil { + return "", "", friendlyErr + } else { + // This should be unreachable, but be defensive + // in case RunRaw's error results are inconsistent. + return "", "", rawErr + } + } else { + fields := strings.Fields(stdout.String()) + if len(fields) < 2 { + return "", "", fmt.Errorf("could not parse GOARCH and Go compiler in format \" \":\nstdout: <<%s>>\nstderr: <<%s>>", + stdout.String(), stderr.String()) + } + goarch = fields[0] + compiler = fields[1] + } + return compiler, goarch, nil +} diff --git a/vendor/golang.org/x/tools/go/packages/doc.go b/vendor/golang.org/x/tools/go/packages/doc.go new file mode 100644 index 00000000..a8d7b06a --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/doc.go @@ -0,0 +1,250 @@ +// 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 packages loads Go packages for inspection and analysis. + +The [Load] function takes as input a list of patterns and returns a +list of [Package] values describing individual packages matched by those +patterns. +A [Config] specifies configuration options, the most important of which is +the [LoadMode], which controls the amount of detail in the loaded packages. + +Load passes most patterns directly to the underlying build tool. +The default build tool is the go command. +Its supported patterns are described at +https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns. +Other build systems may be supported by providing a "driver"; +see [The driver protocol]. + +All patterns with the prefix "query=", where query is a +non-empty string of letters from [a-z], are reserved and may be +interpreted as query operators. + +Two query operators are currently supported: "file" and "pattern". + +The query "file=path/to/file.go" matches the package or packages enclosing +the Go source file path/to/file.go. For example "file=~/go/src/fmt/print.go" +might return the packages "fmt" and "fmt [fmt.test]". + +The query "pattern=string" causes "string" to be passed directly to +the underlying build tool. In most cases this is unnecessary, +but an application can use Load("pattern=" + x) as an escaping mechanism +to ensure that x is not interpreted as a query operator if it contains '='. + +All other query operators are reserved for future use and currently +cause Load to report an error. + +The Package struct provides basic information about the package, including + + - ID, a unique identifier for the package in the returned set; + - GoFiles, the names of the package's Go source files; + - Imports, a map from source import strings to the Packages they name; + - Types, the type information for the package's exported symbols; + - Syntax, the parsed syntax trees for the package's source code; and + - TypesInfo, the result of a complete type-check of the package syntax trees. + +(See the documentation for type Package for the complete list of fields +and more detailed descriptions.) + +For example, + + Load(nil, "bytes", "unicode...") + +returns four Package structs describing the standard library packages +bytes, unicode, unicode/utf16, and unicode/utf8. Note that one pattern +can match multiple packages and that a package might be matched by +multiple patterns: in general it is not possible to determine which +packages correspond to which patterns. + +Note that the list returned by Load contains only the packages matched +by the patterns. Their dependencies can be found by walking the import +graph using the Imports fields. + +The Load function can be configured by passing a pointer to a Config as +the first argument. A nil Config is equivalent to the zero Config, which +causes Load to run in LoadFiles mode, collecting minimal information. +See the documentation for type Config for details. + +As noted earlier, the Config.Mode controls the amount of detail +reported about the loaded packages. See the documentation for type LoadMode +for details. + +Most tools should pass their command-line arguments (after any flags) +uninterpreted to [Load], so that it can interpret them +according to the conventions of the underlying build system. + +See the Example function for typical usage. + +# The driver protocol + +[Load] may be used to load Go packages even in Go projects that use +alternative build systems, by installing an appropriate "driver" +program for the build system and specifying its location in the +GOPACKAGESDRIVER environment variable. +For example, +https://github.com/bazelbuild/rules_go/wiki/Editor-and-tool-integration +explains how to use the driver for Bazel. + +The driver program is responsible for interpreting patterns in its +preferred notation and reporting information about the packages that +those patterns identify. Drivers must also support the special "file=" +and "pattern=" patterns described above. + +The patterns are provided as positional command-line arguments. A +JSON-encoded [DriverRequest] message providing additional information +is written to the driver's standard input. The driver must write a +JSON-encoded [DriverResponse] message to its standard output. (This +message differs from the JSON schema produced by 'go list'.) +*/ +package packages // import "golang.org/x/tools/go/packages" + +/* + +Motivation and design considerations + +The new package's design solves problems addressed by two existing +packages: go/build, which locates and describes packages, and +golang.org/x/tools/go/loader, which loads, parses and type-checks them. +The go/build.Package structure encodes too much of the 'go build' way +of organizing projects, leaving us in need of a data type that describes a +package of Go source code independent of the underlying build system. +We wanted something that works equally well with go build and vgo, and +also other build systems such as Bazel and Blaze, making it possible to +construct analysis tools that work in all these environments. +Tools such as errcheck and staticcheck were essentially unavailable to +the Go community at Google, and some of Google's internal tools for Go +are unavailable externally. +This new package provides a uniform way to obtain package metadata by +querying each of these build systems, optionally supporting their +preferred command-line notations for packages, so that tools integrate +neatly with users' build environments. The Metadata query function +executes an external query tool appropriate to the current workspace. + +Loading packages always returns the complete import graph "all the way down", +even if all you want is information about a single package, because the query +mechanisms of all the build systems we currently support ({go,vgo} list, and +blaze/bazel aspect-based query) cannot provide detailed information +about one package without visiting all its dependencies too, so there is +no additional asymptotic cost to providing transitive information. +(This property might not be true of a hypothetical 5th build system.) + +In calls to TypeCheck, all initial packages, and any package that +transitively depends on one of them, must be loaded from source. +Consider A->B->C->D->E: if A,C are initial, A,B,C must be loaded from +source; D may be loaded from export data, and E may not be loaded at all +(though it's possible that D's export data mentions it, so a +types.Package may be created for it and exposed.) + +The old loader had a feature to suppress type-checking of function +bodies on a per-package basis, primarily intended to reduce the work of +obtaining type information for imported packages. Now that imports are +satisfied by export data, the optimization no longer seems necessary. + +Despite some early attempts, the old loader did not exploit export data, +instead always using the equivalent of WholeProgram mode. This was due +to the complexity of mixing source and export data packages (now +resolved by the upward traversal mentioned above), and because export data +files were nearly always missing or stale. Now that 'go build' supports +caching, all the underlying build systems can guarantee to produce +export data in a reasonable (amortized) time. + +Test "main" packages synthesized by the build system are now reported as +first-class packages, avoiding the need for clients (such as go/ssa) to +reinvent this generation logic. + +One way in which go/packages is simpler than the old loader is in its +treatment of in-package tests. In-package tests are packages that +consist of all the files of the library under test, plus the test files. +The old loader constructed in-package tests by a two-phase process of +mutation called "augmentation": first it would construct and type check +all the ordinary library packages and type-check the packages that +depend on them; then it would add more (test) files to the package and +type-check again. This two-phase approach had four major problems: +1) in processing the tests, the loader modified the library package, + leaving no way for a client application to see both the test + package and the library package; one would mutate into the other. +2) because test files can declare additional methods on types defined in + the library portion of the package, the dispatch of method calls in + the library portion was affected by the presence of the test files. + This should have been a clue that the packages were logically + different. +3) this model of "augmentation" assumed at most one in-package test + per library package, which is true of projects using 'go build', + but not other build systems. +4) because of the two-phase nature of test processing, all packages that + import the library package had to be processed before augmentation, + forcing a "one-shot" API and preventing the client from calling Load + in several times in sequence as is now possible in WholeProgram mode. + (TypeCheck mode has a similar one-shot restriction for a different reason.) + +Early drafts of this package supported "multi-shot" operation. +Although it allowed clients to make a sequence of calls (or concurrent +calls) to Load, building up the graph of Packages incrementally, +it was of marginal value: it complicated the API +(since it allowed some options to vary across calls but not others), +it complicated the implementation, +it cannot be made to work in Types mode, as explained above, +and it was less efficient than making one combined call (when this is possible). +Among the clients we have inspected, none made multiple calls to load +but could not be easily and satisfactorily modified to make only a single call. +However, applications changes may be required. +For example, the ssadump command loads the user-specified packages +and in addition the runtime package. It is tempting to simply append +"runtime" to the user-provided list, but that does not work if the user +specified an ad-hoc package such as [a.go b.go]. +Instead, ssadump no longer requests the runtime package, +but seeks it among the dependencies of the user-specified packages, +and emits an error if it is not found. + +Overlays: The Overlay field in the Config allows providing alternate contents +for Go source files, by providing a mapping from file path to contents. +go/packages will pull in new imports added in overlay files when go/packages +is run in LoadImports mode or greater. +Overlay support for the go list driver isn't complete yet: if the file doesn't +exist on disk, it will only be recognized in an overlay if it is a non-test file +and the package would be reported even without the overlay. + +Questions & Tasks + +- Add GOARCH/GOOS? + They are not portable concepts, but could be made portable. + Our goal has been to allow users to express themselves using the conventions + of the underlying build system: if the build system honors GOARCH + during a build and during a metadata query, then so should + applications built atop that query mechanism. + Conversely, if the target architecture of the build is determined by + command-line flags, the application can pass the relevant + flags through to the build system using a command such as: + myapp -query_flag="--cpu=amd64" -query_flag="--os=darwin" + However, this approach is low-level, unwieldy, and non-portable. + GOOS and GOARCH seem important enough to warrant a dedicated option. + +- How should we handle partial failures such as a mixture of good and + malformed patterns, existing and non-existent packages, successful and + failed builds, import failures, import cycles, and so on, in a call to + Load? + +- Support bazel, blaze, and go1.10 list, not just go1.11 list. + +- Handle (and test) various partial success cases, e.g. + a mixture of good packages and: + invalid patterns + nonexistent packages + empty packages + packages with malformed package or import declarations + unreadable files + import cycles + other parse errors + type errors + Make sure we record errors at the correct place in the graph. + +- Missing packages among initial arguments are not reported. + Return bogus packages for them, like golist does. + +- "undeclared name" errors (for example) are reported out of source file + order. I suspect this is due to the breadth-first resolution now used + by go/types. Is that a bug? Discuss with gri. + +*/ diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go new file mode 100644 index 00000000..4335c1eb --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/external.go @@ -0,0 +1,140 @@ +// 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 packages + +// This file defines the protocol that enables an external "driver" +// tool to supply package metadata in place of 'go list'. + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "os/exec" + "strings" +) + +// DriverRequest defines the schema of a request for package metadata +// from an external driver program. The JSON-encoded DriverRequest +// message is provided to the driver program's standard input. The +// query patterns are provided as command-line arguments. +// +// See the package documentation for an overview. +type DriverRequest struct { + Mode LoadMode `json:"mode"` + + // Env specifies the environment the underlying build system should be run in. + Env []string `json:"env"` + + // BuildFlags are flags that should be passed to the underlying build system. + BuildFlags []string `json:"build_flags"` + + // Tests specifies whether the patterns should also return test packages. + Tests bool `json:"tests"` + + // Overlay maps file paths (relative to the driver's working directory) to the byte contents + // of overlay files. + Overlay map[string][]byte `json:"overlay"` +} + +// DriverResponse defines the schema of a response from an external +// driver program, providing the results of a query for package +// metadata. The driver program must write a JSON-encoded +// DriverResponse message to its standard output. +// +// See the package documentation for an overview. +type DriverResponse struct { + // NotHandled is returned if the request can't be handled by the current + // driver. If an external driver returns a response with NotHandled, the + // rest of the DriverResponse is ignored, and go/packages will fallback + // to the next driver. If go/packages is extended in the future to support + // lists of multiple drivers, go/packages will fall back to the next driver. + NotHandled bool + + // Compiler and Arch are the arguments pass of types.SizesFor + // to get a types.Sizes to use when type checking. + Compiler string + Arch string + + // Roots is the set of package IDs that make up the root packages. + // We have to encode this separately because when we encode a single package + // we cannot know if it is one of the roots as that requires knowledge of the + // graph it is part of. + Roots []string `json:",omitempty"` + + // Packages is the full set of packages in the graph. + // The packages are not connected into a graph. + // The Imports if populated will be stubs that only have their ID set. + // Imports will be connected and then type and syntax information added in a + // later pass (see refine). + Packages []*Package + + // GoVersion is the minor version number used by the driver + // (e.g. the go command on the PATH) when selecting .go files. + // Zero means unknown. + GoVersion int +} + +// driver is the type for functions that query the build system for the +// packages named by the patterns. +type driver func(cfg *Config, patterns ...string) (*DriverResponse, error) + +// findExternalDriver returns the file path of a tool that supplies +// the build system package structure, or "" if not found." +// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its +// value, otherwise it searches for a binary named gopackagesdriver on the PATH. +func findExternalDriver(cfg *Config) driver { + const toolPrefix = "GOPACKAGESDRIVER=" + tool := "" + for _, env := range cfg.Env { + if val := strings.TrimPrefix(env, toolPrefix); val != env { + tool = val + } + } + if tool != "" && tool == "off" { + return nil + } + if tool == "" { + var err error + tool, err = exec.LookPath("gopackagesdriver") + if err != nil { + return nil + } + } + return func(cfg *Config, words ...string) (*DriverResponse, error) { + req, err := json.Marshal(DriverRequest{ + Mode: cfg.Mode, + Env: cfg.Env, + BuildFlags: cfg.BuildFlags, + Tests: cfg.Tests, + Overlay: cfg.Overlay, + }) + if err != nil { + return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) + } + + buf := new(bytes.Buffer) + stderr := new(bytes.Buffer) + cmd := exec.CommandContext(cfg.Context, tool, words...) + cmd.Dir = cfg.Dir + cmd.Env = cfg.Env + cmd.Stdin = bytes.NewReader(req) + cmd.Stdout = buf + cmd.Stderr = stderr + + if err := cmd.Run(); err != nil { + return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) + } + if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" { + fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr) + } + + var response DriverResponse + if err := json.Unmarshal(buf.Bytes(), &response); err != nil { + return nil, err + } + return &response, nil + } +} diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go new file mode 100644 index 00000000..22305d9c --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/golist.go @@ -0,0 +1,1106 @@ +// 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 packages + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log" + "os" + "os/exec" + "path" + "path/filepath" + "reflect" + "sort" + "strconv" + "strings" + "sync" + "unicode" + + "golang.org/x/tools/go/internal/packagesdriver" + "golang.org/x/tools/internal/gocommand" + "golang.org/x/tools/internal/packagesinternal" +) + +// debug controls verbose logging. +var debug, _ = strconv.ParseBool(os.Getenv("GOPACKAGESDEBUG")) + +// A goTooOldError reports that the go command +// found by exec.LookPath is too old to use the new go list behavior. +type goTooOldError struct { + error +} + +// responseDeduper wraps a DriverResponse, deduplicating its contents. +type responseDeduper struct { + seenRoots map[string]bool + seenPackages map[string]*Package + dr *DriverResponse +} + +func newDeduper() *responseDeduper { + return &responseDeduper{ + dr: &DriverResponse{}, + seenRoots: map[string]bool{}, + seenPackages: map[string]*Package{}, + } +} + +// addAll fills in r with a DriverResponse. +func (r *responseDeduper) addAll(dr *DriverResponse) { + for _, pkg := range dr.Packages { + r.addPackage(pkg) + } + for _, root := range dr.Roots { + r.addRoot(root) + } + r.dr.GoVersion = dr.GoVersion +} + +func (r *responseDeduper) addPackage(p *Package) { + if r.seenPackages[p.ID] != nil { + return + } + r.seenPackages[p.ID] = p + r.dr.Packages = append(r.dr.Packages, p) +} + +func (r *responseDeduper) addRoot(id string) { + if r.seenRoots[id] { + return + } + r.seenRoots[id] = true + r.dr.Roots = append(r.dr.Roots, id) +} + +type golistState struct { + cfg *Config + ctx context.Context + + envOnce sync.Once + goEnvError error + goEnv map[string]string + + rootsOnce sync.Once + rootDirsError error + rootDirs map[string]string + + goVersionOnce sync.Once + goVersionError error + goVersion int // The X in Go 1.X. + + // vendorDirs caches the (non)existence of vendor directories. + vendorDirs map[string]bool +} + +// getEnv returns Go environment variables. Only specific variables are +// populated -- computing all of them is slow. +func (state *golistState) getEnv() (map[string]string, error) { + state.envOnce.Do(func() { + var b *bytes.Buffer + b, state.goEnvError = state.invokeGo("env", "-json", "GOMOD", "GOPATH") + if state.goEnvError != nil { + return + } + + state.goEnv = make(map[string]string) + decoder := json.NewDecoder(b) + if state.goEnvError = decoder.Decode(&state.goEnv); state.goEnvError != nil { + return + } + }) + return state.goEnv, state.goEnvError +} + +// mustGetEnv is a convenience function that can be used if getEnv has already succeeded. +func (state *golistState) mustGetEnv() map[string]string { + env, err := state.getEnv() + if err != nil { + panic(fmt.Sprintf("mustGetEnv: %v", err)) + } + return env +} + +// goListDriver uses the go list command to interpret the patterns and produce +// the build system package structure. +// See driver for more details. +func goListDriver(cfg *Config, patterns ...string) (_ *DriverResponse, err error) { + // Make sure that any asynchronous go commands are killed when we return. + parentCtx := cfg.Context + if parentCtx == nil { + parentCtx = context.Background() + } + ctx, cancel := context.WithCancel(parentCtx) + defer cancel() + + response := newDeduper() + + state := &golistState{ + cfg: cfg, + ctx: ctx, + vendorDirs: map[string]bool{}, + } + + // Fill in response.Sizes asynchronously if necessary. + if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 { + errCh := make(chan error) + go func() { + compiler, arch, err := packagesdriver.GetSizesForArgsGolist(ctx, state.cfgInvocation(), cfg.gocmdRunner) + response.dr.Compiler = compiler + response.dr.Arch = arch + errCh <- err + }() + defer func() { + if sizesErr := <-errCh; sizesErr != nil { + err = sizesErr + } + }() + } + + // Determine files requested in contains patterns + var containFiles []string + restPatterns := make([]string, 0, len(patterns)) + // Extract file= and other [querytype]= patterns. Report an error if querytype + // doesn't exist. +extractQueries: + for _, pattern := range patterns { + eqidx := strings.Index(pattern, "=") + if eqidx < 0 { + restPatterns = append(restPatterns, pattern) + } else { + query, value := pattern[:eqidx], pattern[eqidx+len("="):] + switch query { + case "file": + containFiles = append(containFiles, value) + case "pattern": + restPatterns = append(restPatterns, value) + case "": // not a reserved query + restPatterns = append(restPatterns, pattern) + default: + for _, rune := range query { + if rune < 'a' || rune > 'z' { // not a reserved query + restPatterns = append(restPatterns, pattern) + continue extractQueries + } + } + // Reject all other patterns containing "=" + return nil, fmt.Errorf("invalid query type %q in query pattern %q", query, pattern) + } + } + } + + // See if we have any patterns to pass through to go list. Zero initial + // patterns also requires a go list call, since it's the equivalent of + // ".". + if len(restPatterns) > 0 || len(patterns) == 0 { + dr, err := state.createDriverResponse(restPatterns...) + if err != nil { + return nil, err + } + response.addAll(dr) + } + + if len(containFiles) != 0 { + if err := state.runContainsQueries(response, containFiles); err != nil { + return nil, err + } + } + + // (We may yet return an error due to defer.) + return response.dr, nil +} + +func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error { + for _, query := range queries { + // TODO(matloob): Do only one query per directory. + fdir := filepath.Dir(query) + // Pass absolute path of directory to go list so that it knows to treat it as a directory, + // not a package path. + pattern, err := filepath.Abs(fdir) + if err != nil { + return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err) + } + dirResponse, err := state.createDriverResponse(pattern) + + // If there was an error loading the package, or no packages are returned, + // or the package is returned with errors, try to load the file as an + // ad-hoc package. + // Usually the error will appear in a returned package, but may not if we're + // in module mode and the ad-hoc is located outside a module. + if err != nil || len(dirResponse.Packages) == 0 || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && + len(dirResponse.Packages[0].Errors) == 1 { + var queryErr error + if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil { + return err // return the original error + } + } + isRoot := make(map[string]bool, len(dirResponse.Roots)) + for _, root := range dirResponse.Roots { + isRoot[root] = true + } + for _, pkg := range dirResponse.Packages { + // Add any new packages to the main set + // We don't bother to filter packages that will be dropped by the changes of roots, + // that will happen anyway during graph construction outside this function. + // Over-reporting packages is not a problem. + response.addPackage(pkg) + // if the package was not a root one, it cannot have the file + if !isRoot[pkg.ID] { + continue + } + for _, pkgFile := range pkg.GoFiles { + if filepath.Base(query) == filepath.Base(pkgFile) { + response.addRoot(pkg.ID) + break + } + } + } + } + return nil +} + +// adhocPackage attempts to load or construct an ad-hoc package for a given +// query, if the original call to the driver produced inadequate results. +func (state *golistState) adhocPackage(pattern, query string) (*DriverResponse, error) { + response, err := state.createDriverResponse(query) + if err != nil { + return nil, err + } + // If we get nothing back from `go list`, + // try to make this file into its own ad-hoc package. + // TODO(rstambler): Should this check against the original response? + if len(response.Packages) == 0 { + response.Packages = append(response.Packages, &Package{ + ID: "command-line-arguments", + PkgPath: query, + GoFiles: []string{query}, + CompiledGoFiles: []string{query}, + Imports: make(map[string]*Package), + }) + response.Roots = append(response.Roots, "command-line-arguments") + } + // Handle special cases. + if len(response.Packages) == 1 { + // golang/go#33482: If this is a file= query for ad-hoc packages where + // the file only exists on an overlay, and exists outside of a module, + // add the file to the package and remove the errors. + if response.Packages[0].ID == "command-line-arguments" || + filepath.ToSlash(response.Packages[0].PkgPath) == filepath.ToSlash(query) { + if len(response.Packages[0].GoFiles) == 0 { + filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath + // TODO(matloob): check if the file is outside of a root dir? + for path := range state.cfg.Overlay { + if path == filename { + response.Packages[0].Errors = nil + response.Packages[0].GoFiles = []string{path} + response.Packages[0].CompiledGoFiles = []string{path} + } + } + } + } + } + return response, nil +} + +// Fields must match go list; +// see $GOROOT/src/cmd/go/internal/load/pkg.go. +type jsonPackage struct { + ImportPath string + Dir string + Name string + Export string + GoFiles []string + CompiledGoFiles []string + IgnoredGoFiles []string + IgnoredOtherFiles []string + EmbedPatterns []string + EmbedFiles []string + CFiles []string + CgoFiles []string + CXXFiles []string + MFiles []string + HFiles []string + FFiles []string + SFiles []string + SwigFiles []string + SwigCXXFiles []string + SysoFiles []string + Imports []string + ImportMap map[string]string + Deps []string + Module *Module + TestGoFiles []string + TestImports []string + XTestGoFiles []string + XTestImports []string + ForTest string // q in a "p [q.test]" package, else "" + DepOnly bool + + Error *packagesinternal.PackageError + DepsErrors []*packagesinternal.PackageError +} + +type jsonPackageError struct { + ImportStack []string + Pos string + Err string +} + +func otherFiles(p *jsonPackage) [][]string { + return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles} +} + +// createDriverResponse uses the "go list" command to expand the pattern +// words and return a response for the specified packages. +func (state *golistState) createDriverResponse(words ...string) (*DriverResponse, error) { + // go list uses the following identifiers in ImportPath and Imports: + // + // "p" -- importable package or main (command) + // "q.test" -- q's test executable + // "p [q.test]" -- variant of p as built for q's test executable + // "q_test [q.test]" -- q's external test package + // + // The packages p that are built differently for a test q.test + // are q itself, plus any helpers used by the external test q_test, + // typically including "testing" and all its dependencies. + + // Run "go list" for complete + // information on the specified packages. + goVersion, err := state.getGoVersion() + if err != nil { + return nil, err + } + buf, err := state.invokeGo("list", golistargs(state.cfg, words, goVersion)...) + if err != nil { + return nil, err + } + + seen := make(map[string]*jsonPackage) + pkgs := make(map[string]*Package) + additionalErrors := make(map[string][]Error) + // Decode the JSON and convert it to Package form. + response := &DriverResponse{ + GoVersion: goVersion, + } + for dec := json.NewDecoder(buf); dec.More(); { + p := new(jsonPackage) + if err := dec.Decode(p); err != nil { + return nil, fmt.Errorf("JSON decoding failed: %v", err) + } + + if p.ImportPath == "" { + // The documentation for go list says that “[e]rroneous packages will have + // a non-empty ImportPath”. If for some reason it comes back empty, we + // prefer to error out rather than silently discarding data or handing + // back a package without any way to refer to it. + if p.Error != nil { + return nil, Error{ + Pos: p.Error.Pos, + Msg: p.Error.Err, + } + } + return nil, fmt.Errorf("package missing import path: %+v", p) + } + + // Work around https://golang.org/issue/33157: + // go list -e, when given an absolute path, will find the package contained at + // that directory. But when no package exists there, it will return a fake package + // with an error and the ImportPath set to the absolute path provided to go list. + // Try to convert that absolute path to what its package path would be if it's + // contained in a known module or GOPATH entry. This will allow the package to be + // properly "reclaimed" when overlays are processed. + if filepath.IsAbs(p.ImportPath) && p.Error != nil { + pkgPath, ok, err := state.getPkgPath(p.ImportPath) + if err != nil { + return nil, err + } + if ok { + p.ImportPath = pkgPath + } + } + + if old, found := seen[p.ImportPath]; found { + // If one version of the package has an error, and the other doesn't, assume + // that this is a case where go list is reporting a fake dependency variant + // of the imported package: When a package tries to invalidly import another + // package, go list emits a variant of the imported package (with the same + // import path, but with an error on it, and the package will have a + // DepError set on it). An example of when this can happen is for imports of + // main packages: main packages can not be imported, but they may be + // separately matched and listed by another pattern. + // See golang.org/issue/36188 for more details. + + // The plan is that eventually, hopefully in Go 1.15, the error will be + // reported on the importing package rather than the duplicate "fake" + // version of the imported package. Once all supported versions of Go + // have the new behavior this logic can be deleted. + // TODO(matloob): delete the workaround logic once all supported versions of + // Go return the errors on the proper package. + + // There should be exactly one version of a package that doesn't have an + // error. + if old.Error == nil && p.Error == nil { + if !reflect.DeepEqual(p, old) { + return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath) + } + continue + } + + // Determine if this package's error needs to be bubbled up. + // This is a hack, and we expect for go list to eventually set the error + // on the package. + if old.Error != nil { + var errkind string + if strings.Contains(old.Error.Err, "not an importable package") { + errkind = "not an importable package" + } else if strings.Contains(old.Error.Err, "use of internal package") && strings.Contains(old.Error.Err, "not allowed") { + errkind = "use of internal package not allowed" + } + if errkind != "" { + if len(old.Error.ImportStack) < 1 { + return nil, fmt.Errorf(`internal error: go list gave a %q error with empty import stack`, errkind) + } + importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1] + if importingPkg == old.ImportPath { + // Using an older version of Go which put this package itself on top of import + // stack, instead of the importer. Look for importer in second from top + // position. + if len(old.Error.ImportStack) < 2 { + return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`, errkind) + } + importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2] + } + additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{ + Pos: old.Error.Pos, + Msg: old.Error.Err, + Kind: ListError, + }) + } + } + + // Make sure that if there's a version of the package without an error, + // that's the one reported to the user. + if old.Error == nil { + continue + } + + // This package will replace the old one at the end of the loop. + } + seen[p.ImportPath] = p + + pkg := &Package{ + Name: p.Name, + ID: p.ImportPath, + GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles), + CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles), + OtherFiles: absJoin(p.Dir, otherFiles(p)...), + EmbedFiles: absJoin(p.Dir, p.EmbedFiles), + EmbedPatterns: absJoin(p.Dir, p.EmbedPatterns), + IgnoredFiles: absJoin(p.Dir, p.IgnoredGoFiles, p.IgnoredOtherFiles), + forTest: p.ForTest, + depsErrors: p.DepsErrors, + Module: p.Module, + } + + if (state.cfg.Mode&typecheckCgo) != 0 && len(p.CgoFiles) != 0 { + if len(p.CompiledGoFiles) > len(p.GoFiles) { + // We need the cgo definitions, which are in the first + // CompiledGoFile after the non-cgo ones. This is a hack but there + // isn't currently a better way to find it. We also need the pure + // Go files and unprocessed cgo files, all of which are already + // in pkg.GoFiles. + cgoTypes := p.CompiledGoFiles[len(p.GoFiles)] + pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...) + } else { + // golang/go#38990: go list silently fails to do cgo processing + pkg.CompiledGoFiles = nil + pkg.Errors = append(pkg.Errors, Error{ + Msg: "go list failed to return CompiledGoFiles. This may indicate failure to perform cgo processing; try building at the command line. See https://golang.org/issue/38990.", + Kind: ListError, + }) + } + } + + // Work around https://golang.org/issue/28749: + // cmd/go puts assembly, C, and C++ files in CompiledGoFiles. + // Remove files from CompiledGoFiles that are non-go files + // (or are not files that look like they are from the cache). + if len(pkg.CompiledGoFiles) > 0 { + out := pkg.CompiledGoFiles[:0] + for _, f := range pkg.CompiledGoFiles { + if ext := filepath.Ext(f); ext != ".go" && ext != "" { // ext == "" means the file is from the cache, so probably cgo-processed file + continue + } + out = append(out, f) + } + pkg.CompiledGoFiles = out + } + + // Extract the PkgPath from the package's ID. + if i := strings.IndexByte(pkg.ID, ' '); i >= 0 { + pkg.PkgPath = pkg.ID[:i] + } else { + pkg.PkgPath = pkg.ID + } + + if pkg.PkgPath == "unsafe" { + pkg.CompiledGoFiles = nil // ignore fake unsafe.go file (#59929) + } else if len(pkg.CompiledGoFiles) == 0 { + // Work around for pre-go.1.11 versions of go list. + // TODO(matloob): they should be handled by the fallback. + // Can we delete this? + pkg.CompiledGoFiles = pkg.GoFiles + } + + // Assume go list emits only absolute paths for Dir. + if p.Dir != "" && !filepath.IsAbs(p.Dir) { + log.Fatalf("internal error: go list returned non-absolute Package.Dir: %s", p.Dir) + } + + if p.Export != "" && !filepath.IsAbs(p.Export) { + pkg.ExportFile = filepath.Join(p.Dir, p.Export) + } else { + pkg.ExportFile = p.Export + } + + // imports + // + // Imports contains the IDs of all imported packages. + // ImportsMap records (path, ID) only where they differ. + ids := make(map[string]bool) + for _, id := range p.Imports { + ids[id] = true + } + pkg.Imports = make(map[string]*Package) + for path, id := range p.ImportMap { + pkg.Imports[path] = &Package{ID: id} // non-identity import + delete(ids, id) + } + for id := range ids { + if id == "C" { + continue + } + + pkg.Imports[id] = &Package{ID: id} // identity import + } + if !p.DepOnly { + response.Roots = append(response.Roots, pkg.ID) + } + + // Temporary work-around for golang/go#39986. Parse filenames out of + // error messages. This happens if there are unrecoverable syntax + // errors in the source, so we can't match on a specific error message. + // + // TODO(rfindley): remove this heuristic, in favor of considering + // InvalidGoFiles from the list driver. + if err := p.Error; err != nil && state.shouldAddFilenameFromError(p) { + addFilenameFromPos := func(pos string) bool { + split := strings.Split(pos, ":") + if len(split) < 1 { + return false + } + filename := strings.TrimSpace(split[0]) + if filename == "" { + return false + } + if !filepath.IsAbs(filename) { + filename = filepath.Join(state.cfg.Dir, filename) + } + info, _ := os.Stat(filename) + if info == nil { + return false + } + pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename) + pkg.GoFiles = append(pkg.GoFiles, filename) + return true + } + found := addFilenameFromPos(err.Pos) + // In some cases, go list only reports the error position in the + // error text, not the error position. One such case is when the + // file's package name is a keyword (see golang.org/issue/39763). + if !found { + addFilenameFromPos(err.Err) + } + } + + if p.Error != nil { + msg := strings.TrimSpace(p.Error.Err) // Trim to work around golang.org/issue/32363. + // Address golang.org/issue/35964 by appending import stack to error message. + if msg == "import cycle not allowed" && len(p.Error.ImportStack) != 0 { + msg += fmt.Sprintf(": import stack: %v", p.Error.ImportStack) + } + pkg.Errors = append(pkg.Errors, Error{ + Pos: p.Error.Pos, + Msg: msg, + Kind: ListError, + }) + } + + pkgs[pkg.ID] = pkg + } + + for id, errs := range additionalErrors { + if p, ok := pkgs[id]; ok { + p.Errors = append(p.Errors, errs...) + } + } + for _, pkg := range pkgs { + response.Packages = append(response.Packages, pkg) + } + sort.Slice(response.Packages, func(i, j int) bool { return response.Packages[i].ID < response.Packages[j].ID }) + + return response, nil +} + +func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool { + if len(p.GoFiles) > 0 || len(p.CompiledGoFiles) > 0 { + return false + } + + goV, err := state.getGoVersion() + if err != nil { + return false + } + + // On Go 1.14 and earlier, only add filenames from errors if the import stack is empty. + // The import stack behaves differently for these versions than newer Go versions. + if goV < 15 { + return len(p.Error.ImportStack) == 0 + } + + // On Go 1.15 and later, only parse filenames out of error if there's no import stack, + // or the current package is at the top of the import stack. This is not guaranteed + // to work perfectly, but should avoid some cases where files in errors don't belong to this + // package. + return len(p.Error.ImportStack) == 0 || p.Error.ImportStack[len(p.Error.ImportStack)-1] == p.ImportPath +} + +// getGoVersion returns the effective minor version of the go command. +func (state *golistState) getGoVersion() (int, error) { + state.goVersionOnce.Do(func() { + state.goVersion, state.goVersionError = gocommand.GoVersion(state.ctx, state.cfgInvocation(), state.cfg.gocmdRunner) + }) + return state.goVersion, state.goVersionError +} + +// getPkgPath finds the package path of a directory if it's relative to a root +// directory. +func (state *golistState) getPkgPath(dir string) (string, bool, error) { + absDir, err := filepath.Abs(dir) + if err != nil { + return "", false, err + } + roots, err := state.determineRootDirs() + if err != nil { + return "", false, err + } + + for rdir, rpath := range roots { + // Make sure that the directory is in the module, + // to avoid creating a path relative to another module. + if !strings.HasPrefix(absDir, rdir) { + continue + } + // TODO(matloob): This doesn't properly handle symlinks. + r, err := filepath.Rel(rdir, dir) + if err != nil { + continue + } + if rpath != "" { + // We choose only one root even though the directory even it can belong in multiple modules + // or GOPATH entries. This is okay because we only need to work with absolute dirs when a + // file is missing from disk, for instance when gopls calls go/packages in an overlay. + // Once the file is saved, gopls, or the next invocation of the tool will get the correct + // result straight from golist. + // TODO(matloob): Implement module tiebreaking? + return path.Join(rpath, filepath.ToSlash(r)), true, nil + } + return filepath.ToSlash(r), true, nil + } + return "", false, nil +} + +// absJoin absolutizes and flattens the lists of files. +func absJoin(dir string, fileses ...[]string) (res []string) { + for _, files := range fileses { + for _, file := range files { + if !filepath.IsAbs(file) { + file = filepath.Join(dir, file) + } + res = append(res, file) + } + } + return res +} + +func jsonFlag(cfg *Config, goVersion int) string { + if goVersion < 19 { + return "-json" + } + var fields []string + added := make(map[string]bool) + addFields := func(fs ...string) { + for _, f := range fs { + if !added[f] { + added[f] = true + fields = append(fields, f) + } + } + } + addFields("Name", "ImportPath", "Error") // These fields are always needed + if cfg.Mode&NeedFiles != 0 || cfg.Mode&NeedTypes != 0 { + addFields("Dir", "GoFiles", "IgnoredGoFiles", "IgnoredOtherFiles", "CFiles", + "CgoFiles", "CXXFiles", "MFiles", "HFiles", "FFiles", "SFiles", + "SwigFiles", "SwigCXXFiles", "SysoFiles") + if cfg.Tests { + addFields("TestGoFiles", "XTestGoFiles") + } + } + if cfg.Mode&NeedTypes != 0 { + // CompiledGoFiles seems to be required for the test case TestCgoNoSyntax, + // even when -compiled isn't passed in. + // TODO(#52435): Should we make the test ask for -compiled, or automatically + // request CompiledGoFiles in certain circumstances? + addFields("Dir", "CompiledGoFiles") + } + if cfg.Mode&NeedCompiledGoFiles != 0 { + addFields("Dir", "CompiledGoFiles", "Export") + } + if cfg.Mode&NeedImports != 0 { + // When imports are requested, DepOnly is used to distinguish between packages + // explicitly requested and transitive imports of those packages. + addFields("DepOnly", "Imports", "ImportMap") + if cfg.Tests { + addFields("TestImports", "XTestImports") + } + } + if cfg.Mode&NeedDeps != 0 { + addFields("DepOnly") + } + if usesExportData(cfg) { + // Request Dir in the unlikely case Export is not absolute. + addFields("Dir", "Export") + } + if cfg.Mode&needInternalForTest != 0 { + addFields("ForTest") + } + if cfg.Mode&needInternalDepsErrors != 0 { + addFields("DepsErrors") + } + if cfg.Mode&NeedModule != 0 { + addFields("Module") + } + if cfg.Mode&NeedEmbedFiles != 0 { + addFields("EmbedFiles") + } + if cfg.Mode&NeedEmbedPatterns != 0 { + addFields("EmbedPatterns") + } + return "-json=" + strings.Join(fields, ",") +} + +func golistargs(cfg *Config, words []string, goVersion int) []string { + const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo + fullargs := []string{ + "-e", jsonFlag(cfg, goVersion), + fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0), + fmt.Sprintf("-test=%t", cfg.Tests), + fmt.Sprintf("-export=%t", usesExportData(cfg)), + fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0), + // go list doesn't let you pass -test and -find together, + // probably because you'd just get the TestMain. + fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0 && !usesExportData(cfg)), + } + + // golang/go#60456: with go1.21 and later, go list serves pgo variants, which + // can be costly to compute and may result in redundant processing for the + // caller. Disable these variants. If someone wants to add e.g. a NeedPGO + // mode flag, that should be a separate proposal. + if goVersion >= 21 { + fullargs = append(fullargs, "-pgo=off") + } + + fullargs = append(fullargs, cfg.BuildFlags...) + fullargs = append(fullargs, "--") + fullargs = append(fullargs, words...) + return fullargs +} + +// cfgInvocation returns an Invocation that reflects cfg's settings. +func (state *golistState) cfgInvocation() gocommand.Invocation { + cfg := state.cfg + return gocommand.Invocation{ + BuildFlags: cfg.BuildFlags, + ModFile: cfg.modFile, + ModFlag: cfg.modFlag, + CleanEnv: cfg.Env != nil, + Env: cfg.Env, + Logf: cfg.Logf, + WorkingDir: cfg.Dir, + } +} + +// invokeGo returns the stdout of a go command invocation. +func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) { + cfg := state.cfg + + inv := state.cfgInvocation() + + // For Go versions 1.16 and above, `go list` accepts overlays directly via + // the -overlay flag. Set it, if it's available. + // + // The check for "list" is not necessarily required, but we should avoid + // getting the go version if possible. + if verb == "list" { + goVersion, err := state.getGoVersion() + if err != nil { + return nil, err + } + if goVersion >= 16 { + filename, cleanup, err := state.writeOverlays() + if err != nil { + return nil, err + } + defer cleanup() + inv.Overlay = filename + } + } + inv.Verb = verb + inv.Args = args + gocmdRunner := cfg.gocmdRunner + if gocmdRunner == nil { + gocmdRunner = &gocommand.Runner{} + } + stdout, stderr, friendlyErr, err := gocmdRunner.RunRaw(cfg.Context, inv) + if err != nil { + // Check for 'go' executable not being found. + if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound { + return nil, fmt.Errorf("'go list' driver requires 'go', but %s", exec.ErrNotFound) + } + + exitErr, ok := err.(*exec.ExitError) + if !ok { + // Catastrophic error: + // - context cancellation + return nil, fmt.Errorf("couldn't run 'go': %w", err) + } + + // Old go version? + if strings.Contains(stderr.String(), "flag provided but not defined") { + return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)} + } + + // Related to #24854 + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "unexpected directory layout") { + return nil, friendlyErr + } + + // Is there an error running the C compiler in cgo? This will be reported in the "Error" field + // and should be suppressed by go list -e. + // + // This condition is not perfect yet because the error message can include other error messages than runtime/cgo. + isPkgPathRune := func(r rune) bool { + // From https://golang.org/ref/spec#Import_declarations: + // Implementation restriction: A compiler may restrict ImportPaths to non-empty strings + // using only characters belonging to Unicode's L, M, N, P, and S general categories + // (the Graphic characters without spaces) and may also exclude the + // characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character U+FFFD. + return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) && + !strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r) + } + // golang/go#36770: Handle case where cmd/go prints module download messages before the error. + msg := stderr.String() + for strings.HasPrefix(msg, "go: downloading") { + msg = msg[strings.IndexRune(msg, '\n')+1:] + } + if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") { + msg := msg[len("# "):] + if strings.HasPrefix(strings.TrimLeftFunc(msg, isPkgPathRune), "\n") { + return stdout, nil + } + // Treat pkg-config errors as a special case (golang.org/issue/36770). + if strings.HasPrefix(msg, "pkg-config") { + return stdout, nil + } + } + + // This error only appears in stderr. See golang.org/cl/166398 for a fix in go list to show + // the error in the Err section of stdout in case -e option is provided. + // This fix is provided for backwards compatibility. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") { + output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Similar to the previous error, but currently lacks a fix in Go. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must all be in one directory") { + output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Backwards compatibility for Go 1.11 because 1.12 and 1.13 put the directory in the ImportPath. + // If the package doesn't exist, put the absolute path of the directory into the error message, + // as Go 1.13 list does. + const noSuchDirectory = "no such directory" + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), noSuchDirectory) { + errstr := stderr.String() + abspath := strings.TrimSpace(errstr[strings.Index(errstr, noSuchDirectory)+len(noSuchDirectory):]) + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + abspath, strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Workaround for #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist. + // Note that the error message we look for in this case is different that the one looked for above. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no such file or directory") { + output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Workaround for #34273. go list -e with GO111MODULE=on has incorrect behavior when listing a + // directory outside any module. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside available modules") { + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + // TODO(matloob): command-line-arguments isn't correct here. + "command-line-arguments", strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Another variation of the previous error + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside module root") { + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + // TODO(matloob): command-line-arguments isn't correct here. + "command-line-arguments", strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Workaround for an instance of golang.org/issue/26755: go list -e will return a non-zero exit + // status if there's a dependency on a package that doesn't exist. But it should return + // a zero exit status and set an error on that package. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") { + // Don't clobber stdout if `go list` actually returned something. + if len(stdout.String()) > 0 { + return stdout, nil + } + // try to extract package name from string + stderrStr := stderr.String() + var importPath string + colon := strings.Index(stderrStr, ":") + if colon > 0 && strings.HasPrefix(stderrStr, "go build ") { + importPath = stderrStr[len("go build "):colon] + } + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + importPath, strings.Trim(stderrStr, "\n")) + return bytes.NewBufferString(output), nil + } + + // Export mode entails a build. + // If that build fails, errors appear on stderr + // (despite the -e flag) and the Export field is blank. + // Do not fail in that case. + // The same is true if an ad-hoc package given to go list doesn't exist. + // TODO(matloob): Remove these once we can depend on go list to exit with a zero status with -e even when + // packages don't exist or a build fails. + if !usesExportData(cfg) && !containsGoFile(args) { + return nil, friendlyErr + } + } + return stdout, nil +} + +// OverlayJSON is the format overlay files are expected to be in. +// The Replace map maps from overlaid paths to replacement paths: +// the Go command will forward all reads trying to open +// each overlaid path to its replacement path, or consider the overlaid +// path not to exist if the replacement path is empty. +// +// From golang/go#39958. +type OverlayJSON struct { + Replace map[string]string `json:"replace,omitempty"` +} + +// writeOverlays writes out files for go list's -overlay flag, as described +// above. +func (state *golistState) writeOverlays() (filename string, cleanup func(), err error) { + // Do nothing if there are no overlays in the config. + if len(state.cfg.Overlay) == 0 { + return "", func() {}, nil + } + dir, err := os.MkdirTemp("", "gopackages-*") + if err != nil { + return "", nil, err + } + // The caller must clean up this directory, unless this function returns an + // error. + cleanup = func() { + os.RemoveAll(dir) + } + defer func() { + if err != nil { + cleanup() + } + }() + overlays := map[string]string{} + for k, v := range state.cfg.Overlay { + // Create a unique filename for the overlaid files, to avoid + // creating nested directories. + noSeparator := strings.Join(strings.Split(filepath.ToSlash(k), "/"), "") + f, err := os.CreateTemp(dir, fmt.Sprintf("*-%s", noSeparator)) + if err != nil { + return "", func() {}, err + } + if _, err := f.Write(v); err != nil { + return "", func() {}, err + } + if err := f.Close(); err != nil { + return "", func() {}, err + } + overlays[k] = f.Name() + } + b, err := json.Marshal(OverlayJSON{Replace: overlays}) + if err != nil { + return "", func() {}, err + } + // Write out the overlay file that contains the filepath mappings. + filename = filepath.Join(dir, "overlay.json") + if err := os.WriteFile(filename, b, 0665); err != nil { + return "", func() {}, err + } + return filename, cleanup, nil +} + +func containsGoFile(s []string) bool { + for _, f := range s { + if strings.HasSuffix(f, ".go") { + return true + } + } + return false +} + +func cmdDebugStr(cmd *exec.Cmd) string { + env := make(map[string]string) + for _, kv := range cmd.Env { + split := strings.SplitN(kv, "=", 2) + k, v := split[0], split[1] + env[k] = v + } + + var args []string + for _, arg := range cmd.Args { + quoted := strconv.Quote(arg) + if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { + args = append(args, quoted) + } else { + args = append(args, arg) + } + } + return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) +} diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go new file mode 100644 index 00000000..d823c474 --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/golist_overlay.go @@ -0,0 +1,83 @@ +// 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 packages + +import ( + "encoding/json" + "path/filepath" + + "golang.org/x/tools/internal/gocommand" +) + +// determineRootDirs returns a mapping from absolute directories that could +// contain code to their corresponding import path prefixes. +func (state *golistState) determineRootDirs() (map[string]string, error) { + env, err := state.getEnv() + if err != nil { + return nil, err + } + if env["GOMOD"] != "" { + state.rootsOnce.Do(func() { + state.rootDirs, state.rootDirsError = state.determineRootDirsModules() + }) + } else { + state.rootsOnce.Do(func() { + state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH() + }) + } + return state.rootDirs, state.rootDirsError +} + +func (state *golistState) determineRootDirsModules() (map[string]string, error) { + // List all of the modules--the first will be the directory for the main + // module. Any replaced modules will also need to be treated as roots. + // Editing files in the module cache isn't a great idea, so we don't + // plan to ever support that. + out, err := state.invokeGo("list", "-m", "-json", "all") + if err != nil { + // 'go list all' will fail if we're outside of a module and + // GO111MODULE=on. Try falling back without 'all'. + var innerErr error + out, innerErr = state.invokeGo("list", "-m", "-json") + if innerErr != nil { + return nil, err + } + } + roots := map[string]string{} + modules := map[string]string{} + var i int + for dec := json.NewDecoder(out); dec.More(); { + mod := new(gocommand.ModuleJSON) + if err := dec.Decode(mod); err != nil { + return nil, err + } + if mod.Dir != "" && mod.Path != "" { + // This is a valid module; add it to the map. + absDir, err := filepath.Abs(mod.Dir) + if err != nil { + return nil, err + } + modules[absDir] = mod.Path + // The first result is the main module. + if i == 0 || mod.Replace != nil && mod.Replace.Path != "" { + roots[absDir] = mod.Path + } + } + i++ + } + return roots, nil +} + +func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) { + m := map[string]string{} + for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) { + absDir, err := filepath.Abs(dir) + if err != nil { + return nil, err + } + m[filepath.Join(absDir, "src")] = "" + } + return m, nil +} diff --git a/vendor/golang.org/x/tools/go/packages/loadmode_string.go b/vendor/golang.org/x/tools/go/packages/loadmode_string.go new file mode 100644 index 00000000..5c080d21 --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/loadmode_string.go @@ -0,0 +1,57 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package packages + +import ( + "fmt" + "strings" +) + +var allModes = []LoadMode{ + NeedName, + NeedFiles, + NeedCompiledGoFiles, + NeedImports, + NeedDeps, + NeedExportFile, + NeedTypes, + NeedSyntax, + NeedTypesInfo, + NeedTypesSizes, +} + +var modeStrings = []string{ + "NeedName", + "NeedFiles", + "NeedCompiledGoFiles", + "NeedImports", + "NeedDeps", + "NeedExportFile", + "NeedTypes", + "NeedSyntax", + "NeedTypesInfo", + "NeedTypesSizes", +} + +func (mod LoadMode) String() string { + m := mod + if m == 0 { + return "LoadMode(0)" + } + var out []string + for i, x := range allModes { + if x > m { + break + } + if (m & x) != 0 { + out = append(out, modeStrings[i]) + m = m ^ x + } + } + if m != 0 { + out = append(out, "Unknown") + } + return fmt.Sprintf("LoadMode(%s)", strings.Join(out, "|")) +} diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go new file mode 100644 index 00000000..865d9059 --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/packages.go @@ -0,0 +1,1426 @@ +// 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 packages + +// See doc.go for package documentation and implementation notes. + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "go/ast" + "go/parser" + "go/scanner" + "go/token" + "go/types" + "io" + "log" + "os" + "path/filepath" + "runtime" + "strings" + "sync" + "time" + + "golang.org/x/sync/errgroup" + + "golang.org/x/tools/go/gcexportdata" + "golang.org/x/tools/internal/gocommand" + "golang.org/x/tools/internal/packagesinternal" + "golang.org/x/tools/internal/typesinternal" + "golang.org/x/tools/internal/versions" +) + +// A LoadMode controls the amount of detail to return when loading. +// The bits below can be combined to specify which fields should be +// filled in the result packages. +// The zero value is a special case, equivalent to combining +// the NeedName, NeedFiles, and NeedCompiledGoFiles bits. +// ID and Errors (if present) will always be filled. +// Load may return more information than requested. +type LoadMode int + +const ( + // NeedName adds Name and PkgPath. + NeedName LoadMode = 1 << iota + + // NeedFiles adds GoFiles and OtherFiles. + NeedFiles + + // NeedCompiledGoFiles adds CompiledGoFiles. + NeedCompiledGoFiles + + // NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain + // "placeholder" Packages with only the ID set. + NeedImports + + // NeedDeps adds the fields requested by the LoadMode in the packages in Imports. + NeedDeps + + // NeedExportFile adds ExportFile. + NeedExportFile + + // NeedTypes adds Types, Fset, and IllTyped. + NeedTypes + + // NeedSyntax adds Syntax. + NeedSyntax + + // NeedTypesInfo adds TypesInfo. + NeedTypesInfo + + // NeedTypesSizes adds TypesSizes. + NeedTypesSizes + + // needInternalDepsErrors adds the internal deps errors field for use by gopls. + needInternalDepsErrors + + // needInternalForTest adds the internal forTest field. + // Tests must also be set on the context for this field to be populated. + needInternalForTest + + // typecheckCgo enables full support for type checking cgo. Requires Go 1.15+. + // Modifies CompiledGoFiles and Types, and has no effect on its own. + typecheckCgo + + // NeedModule adds Module. + NeedModule + + // NeedEmbedFiles adds EmbedFiles. + NeedEmbedFiles + + // NeedEmbedPatterns adds EmbedPatterns. + NeedEmbedPatterns +) + +const ( + // Deprecated: LoadFiles exists for historical compatibility + // and should not be used. Please directly specify the needed fields using the Need values. + LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles + + // Deprecated: LoadImports exists for historical compatibility + // and should not be used. Please directly specify the needed fields using the Need values. + LoadImports = LoadFiles | NeedImports + + // Deprecated: LoadTypes exists for historical compatibility + // and should not be used. Please directly specify the needed fields using the Need values. + LoadTypes = LoadImports | NeedTypes | NeedTypesSizes + + // Deprecated: LoadSyntax exists for historical compatibility + // and should not be used. Please directly specify the needed fields using the Need values. + LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo + + // Deprecated: LoadAllSyntax exists for historical compatibility + // and should not be used. Please directly specify the needed fields using the Need values. + LoadAllSyntax = LoadSyntax | NeedDeps + + // Deprecated: NeedExportsFile is a historical misspelling of NeedExportFile. + NeedExportsFile = NeedExportFile +) + +// A Config specifies details about how packages should be loaded. +// The zero value is a valid configuration. +// Calls to Load do not modify this struct. +type Config struct { + // Mode controls the level of information returned for each package. + Mode LoadMode + + // Context specifies the context for the load operation. + // If the context is cancelled, the loader may stop early + // and return an ErrCancelled error. + // If Context is nil, the load cannot be cancelled. + Context context.Context + + // Logf is the logger for the config. + // If the user provides a logger, debug logging is enabled. + // If the GOPACKAGESDEBUG environment variable is set to true, + // but the logger is nil, default to log.Printf. + Logf func(format string, args ...interface{}) + + // Dir is the directory in which to run the build system's query tool + // that provides information about the packages. + // If Dir is empty, the tool is run in the current directory. + Dir string + + // Env is the environment to use when invoking the build system's query tool. + // If Env is nil, the current environment is used. + // As in os/exec's Cmd, only the last value in the slice for + // each environment key is used. To specify the setting of only + // a few variables, append to the current environment, as in: + // + // opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386") + // + Env []string + + // gocmdRunner guards go command calls from concurrency errors. + gocmdRunner *gocommand.Runner + + // BuildFlags is a list of command-line flags to be passed through to + // the build system's query tool. + BuildFlags []string + + // modFile will be used for -modfile in go command invocations. + modFile string + + // modFlag will be used for -modfile in go command invocations. + modFlag string + + // Fset provides source position information for syntax trees and types. + // If Fset is nil, Load will use a new fileset, but preserve Fset's value. + Fset *token.FileSet + + // ParseFile is called to read and parse each file + // when preparing a package's type-checked syntax tree. + // It must be safe to call ParseFile simultaneously from multiple goroutines. + // If ParseFile is nil, the loader will uses parser.ParseFile. + // + // ParseFile should parse the source from src and use filename only for + // recording position information. + // + // An application may supply a custom implementation of ParseFile + // to change the effective file contents or the behavior of the parser, + // or to modify the syntax tree. For example, selectively eliminating + // unwanted function bodies can significantly accelerate type checking. + ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) + + // If Tests is set, the loader includes not just the packages + // matching a particular pattern but also any related test packages, + // including test-only variants of the package and the test executable. + // + // For example, when using the go command, loading "fmt" with Tests=true + // returns four packages, with IDs "fmt" (the standard package), + // "fmt [fmt.test]" (the package as compiled for the test), + // "fmt_test" (the test functions from source files in package fmt_test), + // and "fmt.test" (the test binary). + // + // In build systems with explicit names for tests, + // setting Tests may have no effect. + Tests bool + + // Overlay provides a mapping of absolute file paths to file contents. + // If the file with the given path already exists, the parser will use the + // alternative file contents provided by the map. + // + // Overlays provide incomplete support for when a given file doesn't + // already exist on disk. See the package doc above for more details. + Overlay map[string][]byte +} + +// Load loads and returns the Go packages named by the given patterns. +// +// Config specifies loading options; +// nil behaves the same as an empty Config. +// +// Load returns an error if any of the patterns was invalid +// as defined by the underlying build system. +// It may return an empty list of packages without an error, +// for instance for an empty expansion of a valid wildcard. +// Errors associated with a particular package are recorded in the +// corresponding Package's Errors list, and do not cause Load to +// return an error. Clients may need to handle such errors before +// proceeding with further analysis. The PrintErrors function is +// provided for convenient display of all errors. +func Load(cfg *Config, patterns ...string) ([]*Package, error) { + ld := newLoader(cfg) + response, external, err := defaultDriver(&ld.Config, patterns...) + if err != nil { + return nil, err + } + + ld.sizes = types.SizesFor(response.Compiler, response.Arch) + if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 { + // Type size information is needed but unavailable. + if external { + // An external driver may fail to populate the Compiler/GOARCH fields, + // especially since they are relatively new (see #63700). + // Provide a sensible fallback in this case. + ld.sizes = types.SizesFor("gc", runtime.GOARCH) + if ld.sizes == nil { // gccgo-only arch + ld.sizes = types.SizesFor("gc", "amd64") + } + } else { + // Go list should never fail to deliver accurate size information. + // Reject the whole Load since the error is the same for every package. + return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q", + response.Compiler, response.Arch) + } + } + + return ld.refine(response) +} + +// defaultDriver is a driver that implements go/packages' fallback behavior. +// It will try to request to an external driver, if one exists. If there's +// no external driver, or the driver returns a response with NotHandled set, +// defaultDriver will fall back to the go list driver. +// The boolean result indicates that an external driver handled the request. +func defaultDriver(cfg *Config, patterns ...string) (*DriverResponse, bool, error) { + const ( + // windowsArgMax specifies the maximum command line length for + // the Windows' CreateProcess function. + windowsArgMax = 32767 + // maxEnvSize is a very rough estimation of the maximum environment + // size of a user. + maxEnvSize = 16384 + // safeArgMax specifies the maximum safe command line length to use + // by the underlying driver excl. the environment. We choose the Windows' + // ARG_MAX as the starting point because it's one of the lowest ARG_MAX + // constants out of the different supported platforms, + // e.g., https://www.in-ulm.de/~mascheck/various/argmax/#results. + safeArgMax = windowsArgMax - maxEnvSize + ) + chunks, err := splitIntoChunks(patterns, safeArgMax) + if err != nil { + return nil, false, err + } + + if driver := findExternalDriver(cfg); driver != nil { + response, err := callDriverOnChunks(driver, cfg, chunks) + if err != nil { + return nil, false, err + } else if !response.NotHandled { + return response, true, nil + } + // (fall through) + } + + response, err := callDriverOnChunks(goListDriver, cfg, chunks) + if err != nil { + return nil, false, err + } + return response, false, err +} + +// splitIntoChunks chunks the slice so that the total number of characters +// in a chunk is no longer than argMax. +func splitIntoChunks(patterns []string, argMax int) ([][]string, error) { + if argMax <= 0 { + return nil, errors.New("failed to split patterns into chunks, negative safe argMax value") + } + var chunks [][]string + charsInChunk := 0 + nextChunkStart := 0 + for i, v := range patterns { + vChars := len(v) + if vChars > argMax { + // a single pattern is longer than the maximum safe ARG_MAX, hardly should happen + return nil, errors.New("failed to split patterns into chunks, a pattern is too long") + } + charsInChunk += vChars + 1 // +1 is for a whitespace between patterns that has to be counted too + if charsInChunk > argMax { + chunks = append(chunks, patterns[nextChunkStart:i]) + nextChunkStart = i + charsInChunk = vChars + } + } + // add the last chunk + if nextChunkStart < len(patterns) { + chunks = append(chunks, patterns[nextChunkStart:]) + } + return chunks, nil +} + +func callDriverOnChunks(driver driver, cfg *Config, chunks [][]string) (*DriverResponse, error) { + if len(chunks) == 0 { + return driver(cfg) + } + responses := make([]*DriverResponse, len(chunks)) + errNotHandled := errors.New("driver returned NotHandled") + var g errgroup.Group + for i, chunk := range chunks { + i := i + chunk := chunk + g.Go(func() (err error) { + responses[i], err = driver(cfg, chunk...) + if responses[i] != nil && responses[i].NotHandled { + err = errNotHandled + } + return err + }) + } + if err := g.Wait(); err != nil { + if errors.Is(err, errNotHandled) { + return &DriverResponse{NotHandled: true}, nil + } + return nil, err + } + return mergeResponses(responses...), nil +} + +func mergeResponses(responses ...*DriverResponse) *DriverResponse { + if len(responses) == 0 { + return nil + } + response := newDeduper() + response.dr.NotHandled = false + response.dr.Compiler = responses[0].Compiler + response.dr.Arch = responses[0].Arch + response.dr.GoVersion = responses[0].GoVersion + for _, v := range responses { + response.addAll(v) + } + return response.dr +} + +// A Package describes a loaded Go package. +type Package struct { + // ID is a unique identifier for a package, + // in a syntax provided by the underlying build system. + // + // Because the syntax varies based on the build system, + // clients should treat IDs as opaque and not attempt to + // interpret them. + ID string + + // Name is the package name as it appears in the package source code. + Name string + + // PkgPath is the package path as used by the go/types package. + PkgPath string + + // Errors contains any errors encountered querying the metadata + // of the package, or while parsing or type-checking its files. + Errors []Error + + // TypeErrors contains the subset of errors produced during type checking. + TypeErrors []types.Error + + // GoFiles lists the absolute file paths of the package's Go source files. + // It may include files that should not be compiled, for example because + // they contain non-matching build tags, are documentary pseudo-files such as + // unsafe/unsafe.go or builtin/builtin.go, or are subject to cgo preprocessing. + GoFiles []string + + // CompiledGoFiles lists the absolute file paths of the package's source + // files that are suitable for type checking. + // This may differ from GoFiles if files are processed before compilation. + CompiledGoFiles []string + + // OtherFiles lists the absolute file paths of the package's non-Go source files, + // including assembly, C, C++, Fortran, Objective-C, SWIG, and so on. + OtherFiles []string + + // EmbedFiles lists the absolute file paths of the package's files + // embedded with go:embed. + EmbedFiles []string + + // EmbedPatterns lists the absolute file patterns of the package's + // files embedded with go:embed. + EmbedPatterns []string + + // IgnoredFiles lists source files that are not part of the package + // using the current build configuration but that might be part of + // the package using other build configurations. + IgnoredFiles []string + + // ExportFile is the absolute path to a file containing type + // information for the package as provided by the build system. + ExportFile string + + // Imports maps import paths appearing in the package's Go source files + // to corresponding loaded Packages. + Imports map[string]*Package + + // Types provides type information for the package. + // The NeedTypes LoadMode bit sets this field for packages matching the + // patterns; type information for dependencies may be missing or incomplete, + // unless NeedDeps and NeedImports are also set. + Types *types.Package + + // Fset provides position information for Types, TypesInfo, and Syntax. + // It is set only when Types is set. + Fset *token.FileSet + + // IllTyped indicates whether the package or any dependency contains errors. + // It is set only when Types is set. + IllTyped bool + + // Syntax is the package's syntax trees, for the files listed in CompiledGoFiles. + // + // The NeedSyntax LoadMode bit populates this field for packages matching the patterns. + // If NeedDeps and NeedImports are also set, this field will also be populated + // for dependencies. + // + // Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are + // removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles. + Syntax []*ast.File + + // TypesInfo provides type information about the package's syntax trees. + // It is set only when Syntax is set. + TypesInfo *types.Info + + // TypesSizes provides the effective size function for types in TypesInfo. + TypesSizes types.Sizes + + // forTest is the package under test, if any. + forTest string + + // depsErrors is the DepsErrors field from the go list response, if any. + depsErrors []*packagesinternal.PackageError + + // module is the module information for the package if it exists. + Module *Module +} + +// Module provides module information for a package. +type Module struct { + Path string // module path + Version string // module version + Replace *Module // replaced by this module + Time *time.Time // time version was created + Main bool // is this the main module? + Indirect bool // is this module only an indirect dependency of main module? + Dir string // directory holding files for this module, if any + GoMod string // path to go.mod file used when loading this module, if any + GoVersion string // go version used in module + Error *ModuleError // error loading module +} + +// ModuleError holds errors loading a module. +type ModuleError struct { + Err string // the error itself +} + +func init() { + packagesinternal.GetForTest = func(p interface{}) string { + return p.(*Package).forTest + } + packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError { + return p.(*Package).depsErrors + } + packagesinternal.SetModFile = func(config interface{}, value string) { + config.(*Config).modFile = value + } + packagesinternal.SetModFlag = func(config interface{}, value string) { + config.(*Config).modFlag = value + } + packagesinternal.TypecheckCgo = int(typecheckCgo) + packagesinternal.DepsErrors = int(needInternalDepsErrors) + packagesinternal.ForTest = int(needInternalForTest) +} + +// An Error describes a problem with a package's metadata, syntax, or types. +type Error struct { + Pos string // "file:line:col" or "file:line" or "" or "-" + Msg string + Kind ErrorKind +} + +// ErrorKind describes the source of the error, allowing the user to +// differentiate between errors generated by the driver, the parser, or the +// type-checker. +type ErrorKind int + +const ( + UnknownError ErrorKind = iota + ListError + ParseError + TypeError +) + +func (err Error) Error() string { + pos := err.Pos + if pos == "" { + pos = "-" // like token.Position{}.String() + } + return pos + ": " + err.Msg +} + +// flatPackage is the JSON form of Package +// It drops all the type and syntax fields, and transforms the Imports +// +// TODO(adonovan): identify this struct with Package, effectively +// publishing the JSON protocol. +type flatPackage struct { + ID string + Name string `json:",omitempty"` + PkgPath string `json:",omitempty"` + Errors []Error `json:",omitempty"` + GoFiles []string `json:",omitempty"` + CompiledGoFiles []string `json:",omitempty"` + OtherFiles []string `json:",omitempty"` + EmbedFiles []string `json:",omitempty"` + EmbedPatterns []string `json:",omitempty"` + IgnoredFiles []string `json:",omitempty"` + ExportFile string `json:",omitempty"` + Imports map[string]string `json:",omitempty"` +} + +// MarshalJSON returns the Package in its JSON form. +// For the most part, the structure fields are written out unmodified, and +// the type and syntax fields are skipped. +// The imports are written out as just a map of path to package id. +// The errors are written using a custom type that tries to preserve the +// structure of error types we know about. +// +// This method exists to enable support for additional build systems. It is +// not intended for use by clients of the API and we may change the format. +func (p *Package) MarshalJSON() ([]byte, error) { + flat := &flatPackage{ + ID: p.ID, + Name: p.Name, + PkgPath: p.PkgPath, + Errors: p.Errors, + GoFiles: p.GoFiles, + CompiledGoFiles: p.CompiledGoFiles, + OtherFiles: p.OtherFiles, + EmbedFiles: p.EmbedFiles, + EmbedPatterns: p.EmbedPatterns, + IgnoredFiles: p.IgnoredFiles, + ExportFile: p.ExportFile, + } + if len(p.Imports) > 0 { + flat.Imports = make(map[string]string, len(p.Imports)) + for path, ipkg := range p.Imports { + flat.Imports[path] = ipkg.ID + } + } + return json.Marshal(flat) +} + +// UnmarshalJSON reads in a Package from its JSON format. +// See MarshalJSON for details about the format accepted. +func (p *Package) UnmarshalJSON(b []byte) error { + flat := &flatPackage{} + if err := json.Unmarshal(b, &flat); err != nil { + return err + } + *p = Package{ + ID: flat.ID, + Name: flat.Name, + PkgPath: flat.PkgPath, + Errors: flat.Errors, + GoFiles: flat.GoFiles, + CompiledGoFiles: flat.CompiledGoFiles, + OtherFiles: flat.OtherFiles, + EmbedFiles: flat.EmbedFiles, + EmbedPatterns: flat.EmbedPatterns, + ExportFile: flat.ExportFile, + } + if len(flat.Imports) > 0 { + p.Imports = make(map[string]*Package, len(flat.Imports)) + for path, id := range flat.Imports { + p.Imports[path] = &Package{ID: id} + } + } + return nil +} + +func (p *Package) String() string { return p.ID } + +// loaderPackage augments Package with state used during the loading phase +type loaderPackage struct { + *Package + importErrors map[string]error // maps each bad import to its error + loadOnce sync.Once + color uint8 // for cycle detection + needsrc bool // load from source (Mode >= LoadTypes) + needtypes bool // type information is either requested or depended on + initial bool // package was matched by a pattern + goVersion int // minor version number of go command on PATH +} + +// loader holds the working state of a single call to load. +type loader struct { + pkgs map[string]*loaderPackage + Config + sizes types.Sizes // non-nil if needed by mode + parseCache map[string]*parseValue + parseCacheMu sync.Mutex + exportMu sync.Mutex // enforces mutual exclusion of exportdata operations + + // Config.Mode contains the implied mode (see impliedLoadMode). + // Implied mode contains all the fields we need the data for. + // In requestedMode there are the actually requested fields. + // We'll zero them out before returning packages to the user. + // This makes it easier for us to get the conditions where + // we need certain modes right. + requestedMode LoadMode +} + +type parseValue struct { + f *ast.File + err error + ready chan struct{} +} + +func newLoader(cfg *Config) *loader { + ld := &loader{ + parseCache: map[string]*parseValue{}, + } + if cfg != nil { + ld.Config = *cfg + // If the user has provided a logger, use it. + ld.Config.Logf = cfg.Logf + } + if ld.Config.Logf == nil { + // If the GOPACKAGESDEBUG environment variable is set to true, + // but the user has not provided a logger, default to log.Printf. + if debug { + ld.Config.Logf = log.Printf + } else { + ld.Config.Logf = func(format string, args ...interface{}) {} + } + } + if ld.Config.Mode == 0 { + ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles // Preserve zero behavior of Mode for backwards compatibility. + } + if ld.Config.Env == nil { + ld.Config.Env = os.Environ() + } + if ld.Config.gocmdRunner == nil { + ld.Config.gocmdRunner = &gocommand.Runner{} + } + if ld.Context == nil { + ld.Context = context.Background() + } + if ld.Dir == "" { + if dir, err := os.Getwd(); err == nil { + ld.Dir = dir + } + } + + // Save the actually requested fields. We'll zero them out before returning packages to the user. + ld.requestedMode = ld.Mode + ld.Mode = impliedLoadMode(ld.Mode) + + if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 { + if ld.Fset == nil { + ld.Fset = token.NewFileSet() + } + + // ParseFile is required even in LoadTypes mode + // because we load source if export data is missing. + if ld.ParseFile == nil { + ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { + const mode = parser.AllErrors | parser.ParseComments + return parser.ParseFile(fset, filename, src, mode) + } + } + } + + return ld +} + +// refine connects the supplied packages into a graph and then adds type +// and syntax information as requested by the LoadMode. +func (ld *loader) refine(response *DriverResponse) ([]*Package, error) { + roots := response.Roots + rootMap := make(map[string]int, len(roots)) + for i, root := range roots { + rootMap[root] = i + } + ld.pkgs = make(map[string]*loaderPackage) + // first pass, fixup and build the map and roots + var initial = make([]*loaderPackage, len(roots)) + for _, pkg := range response.Packages { + rootIndex := -1 + if i, found := rootMap[pkg.ID]; found { + rootIndex = i + } + + // Overlays can invalidate export data. + // TODO(matloob): make this check fine-grained based on dependencies on overlaid files + exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe" + // This package needs type information if the caller requested types and the package is + // either a root, or it's a non-root and the user requested dependencies ... + needtypes := (ld.Mode&NeedTypes|NeedTypesInfo != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) + // This package needs source if the call requested source (or types info, which implies source) + // and the package is either a root, or itas a non- root and the user requested dependencies... + needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) || + // ... or if we need types and the exportData is invalid. We fall back to (incompletely) + // typechecking packages from source if they fail to compile. + (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe" + lpkg := &loaderPackage{ + Package: pkg, + needtypes: needtypes, + needsrc: needsrc, + goVersion: response.GoVersion, + } + ld.pkgs[lpkg.ID] = lpkg + if rootIndex >= 0 { + initial[rootIndex] = lpkg + lpkg.initial = true + } + } + for i, root := range roots { + if initial[i] == nil { + return nil, fmt.Errorf("root package %v is missing", root) + } + } + + if ld.Mode&NeedImports != 0 { + // Materialize the import graph. + + const ( + white = 0 // new + grey = 1 // in progress + black = 2 // complete + ) + + // visit traverses the import graph, depth-first, + // and materializes the graph as Packages.Imports. + // + // Valid imports are saved in the Packages.Import map. + // Invalid imports (cycles and missing nodes) are saved in the importErrors map. + // Thus, even in the presence of both kinds of errors, + // the Import graph remains a DAG. + // + // visit returns whether the package needs src or has a transitive + // dependency on a package that does. These are the only packages + // for which we load source code. + var stack []*loaderPackage + var visit func(lpkg *loaderPackage) bool + visit = func(lpkg *loaderPackage) bool { + switch lpkg.color { + case black: + return lpkg.needsrc + case grey: + panic("internal error: grey node") + } + lpkg.color = grey + stack = append(stack, lpkg) // push + stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports + lpkg.Imports = make(map[string]*Package, len(stubs)) + for importPath, ipkg := range stubs { + var importErr error + imp := ld.pkgs[ipkg.ID] + if imp == nil { + // (includes package "C" when DisableCgo) + importErr = fmt.Errorf("missing package: %q", ipkg.ID) + } else if imp.color == grey { + importErr = fmt.Errorf("import cycle: %s", stack) + } + if importErr != nil { + if lpkg.importErrors == nil { + lpkg.importErrors = make(map[string]error) + } + lpkg.importErrors[importPath] = importErr + continue + } + + if visit(imp) { + lpkg.needsrc = true + } + lpkg.Imports[importPath] = imp.Package + } + + // Complete type information is required for the + // immediate dependencies of each source package. + if lpkg.needsrc && ld.Mode&NeedTypes != 0 { + for _, ipkg := range lpkg.Imports { + ld.pkgs[ipkg.ID].needtypes = true + } + } + + // NeedTypeSizes causes TypeSizes to be set even + // on packages for which types aren't needed. + if ld.Mode&NeedTypesSizes != 0 { + lpkg.TypesSizes = ld.sizes + } + stack = stack[:len(stack)-1] // pop + lpkg.color = black + + return lpkg.needsrc + } + + // For each initial package, create its import DAG. + for _, lpkg := range initial { + visit(lpkg) + } + + } else { + // !NeedImports: drop the stub (ID-only) import packages + // that we are not even going to try to resolve. + for _, lpkg := range initial { + lpkg.Imports = nil + } + } + + // Load type data and syntax if needed, starting at + // the initial packages (roots of the import DAG). + if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 { + var wg sync.WaitGroup + for _, lpkg := range initial { + wg.Add(1) + go func(lpkg *loaderPackage) { + ld.loadRecursive(lpkg) + wg.Done() + }(lpkg) + } + wg.Wait() + } + + result := make([]*Package, len(initial)) + for i, lpkg := range initial { + result[i] = lpkg.Package + } + for i := range ld.pkgs { + // Clear all unrequested fields, + // to catch programs that use more than they request. + if ld.requestedMode&NeedName == 0 { + ld.pkgs[i].Name = "" + ld.pkgs[i].PkgPath = "" + } + if ld.requestedMode&NeedFiles == 0 { + ld.pkgs[i].GoFiles = nil + ld.pkgs[i].OtherFiles = nil + ld.pkgs[i].IgnoredFiles = nil + } + if ld.requestedMode&NeedEmbedFiles == 0 { + ld.pkgs[i].EmbedFiles = nil + } + if ld.requestedMode&NeedEmbedPatterns == 0 { + ld.pkgs[i].EmbedPatterns = nil + } + if ld.requestedMode&NeedCompiledGoFiles == 0 { + ld.pkgs[i].CompiledGoFiles = nil + } + if ld.requestedMode&NeedImports == 0 { + ld.pkgs[i].Imports = nil + } + if ld.requestedMode&NeedExportFile == 0 { + ld.pkgs[i].ExportFile = "" + } + if ld.requestedMode&NeedTypes == 0 { + ld.pkgs[i].Types = nil + ld.pkgs[i].Fset = nil + ld.pkgs[i].IllTyped = false + } + if ld.requestedMode&NeedSyntax == 0 { + ld.pkgs[i].Syntax = nil + } + if ld.requestedMode&NeedTypesInfo == 0 { + ld.pkgs[i].TypesInfo = nil + } + if ld.requestedMode&NeedTypesSizes == 0 { + ld.pkgs[i].TypesSizes = nil + } + if ld.requestedMode&NeedModule == 0 { + ld.pkgs[i].Module = nil + } + } + + return result, nil +} + +// loadRecursive loads the specified package and its dependencies, +// recursively, in parallel, in topological order. +// It is atomic and idempotent. +// Precondition: ld.Mode&NeedTypes. +func (ld *loader) loadRecursive(lpkg *loaderPackage) { + lpkg.loadOnce.Do(func() { + // Load the direct dependencies, in parallel. + var wg sync.WaitGroup + for _, ipkg := range lpkg.Imports { + imp := ld.pkgs[ipkg.ID] + wg.Add(1) + go func(imp *loaderPackage) { + ld.loadRecursive(imp) + wg.Done() + }(imp) + } + wg.Wait() + ld.loadPackage(lpkg) + }) +} + +// loadPackage loads the specified package. +// It must be called only once per Package, +// after immediate dependencies are loaded. +// Precondition: ld.Mode & NeedTypes. +func (ld *loader) loadPackage(lpkg *loaderPackage) { + if lpkg.PkgPath == "unsafe" { + // Fill in the blanks to avoid surprises. + lpkg.Types = types.Unsafe + lpkg.Fset = ld.Fset + lpkg.Syntax = []*ast.File{} + lpkg.TypesInfo = new(types.Info) + lpkg.TypesSizes = ld.sizes + return + } + + // Call NewPackage directly with explicit name. + // This avoids skew between golist and go/types when the files' + // package declarations are inconsistent. + lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name) + lpkg.Fset = ld.Fset + + // Subtle: we populate all Types fields with an empty Package + // before loading export data so that export data processing + // never has to create a types.Package for an indirect dependency, + // which would then require that such created packages be explicitly + // inserted back into the Import graph as a final step after export data loading. + // (Hence this return is after the Types assignment.) + // The Diamond test exercises this case. + if !lpkg.needtypes && !lpkg.needsrc { + return + } + if !lpkg.needsrc { + if err := ld.loadFromExportData(lpkg); err != nil { + lpkg.Errors = append(lpkg.Errors, Error{ + Pos: "-", + Msg: err.Error(), + Kind: UnknownError, // e.g. can't find/open/parse export data + }) + } + return // not a source package, don't get syntax trees + } + + appendError := func(err error) { + // Convert various error types into the one true Error. + var errs []Error + switch err := err.(type) { + case Error: + // from driver + errs = append(errs, err) + + case *os.PathError: + // from parser + errs = append(errs, Error{ + Pos: err.Path + ":1", + Msg: err.Err.Error(), + Kind: ParseError, + }) + + case scanner.ErrorList: + // from parser + for _, err := range err { + errs = append(errs, Error{ + Pos: err.Pos.String(), + Msg: err.Msg, + Kind: ParseError, + }) + } + + case types.Error: + // from type checker + lpkg.TypeErrors = append(lpkg.TypeErrors, err) + errs = append(errs, Error{ + Pos: err.Fset.Position(err.Pos).String(), + Msg: err.Msg, + Kind: TypeError, + }) + + default: + // unexpected impoverished error from parser? + errs = append(errs, Error{ + Pos: "-", + Msg: err.Error(), + Kind: UnknownError, + }) + + // If you see this error message, please file a bug. + log.Printf("internal error: error %q (%T) without position", err, err) + } + + lpkg.Errors = append(lpkg.Errors, errs...) + } + + // If the go command on the PATH is newer than the runtime, + // then the go/{scanner,ast,parser,types} packages from the + // standard library may be unable to process the files + // selected by go list. + // + // There is currently no way to downgrade the effective + // version of the go command (see issue 52078), so we proceed + // with the newer go command but, in case of parse or type + // errors, we emit an additional diagnostic. + // + // See: + // - golang.org/issue/52078 (flag to set release tags) + // - golang.org/issue/50825 (gopls legacy version support) + // - golang.org/issue/55883 (go/packages confusing error) + // + // Should we assert a hard minimum of (currently) go1.16 here? + var runtimeVersion int + if _, err := fmt.Sscanf(runtime.Version(), "go1.%d", &runtimeVersion); err == nil && runtimeVersion < lpkg.goVersion { + defer func() { + if len(lpkg.Errors) > 0 { + appendError(Error{ + Pos: "-", + Msg: fmt.Sprintf("This application uses version go1.%d of the source-processing packages but runs version go1.%d of 'go list'. It may fail to process source files that rely on newer language features. If so, rebuild the application using a newer version of Go.", runtimeVersion, lpkg.goVersion), + Kind: UnknownError, + }) + } + }() + } + + if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" { + // The config requested loading sources and types, but sources are missing. + // Add an error to the package and fall back to loading from export data. + appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError}) + _ = ld.loadFromExportData(lpkg) // ignore any secondary errors + + return // can't get syntax trees for this package + } + + files, errs := ld.parseFiles(lpkg.CompiledGoFiles) + for _, err := range errs { + appendError(err) + } + + lpkg.Syntax = files + if ld.Config.Mode&NeedTypes == 0 { + return + } + + lpkg.TypesInfo = &types.Info{ + Types: make(map[ast.Expr]types.TypeAndValue), + Defs: make(map[*ast.Ident]types.Object), + Uses: make(map[*ast.Ident]types.Object), + Implicits: make(map[ast.Node]types.Object), + Instances: make(map[*ast.Ident]types.Instance), + Scopes: make(map[ast.Node]*types.Scope), + Selections: make(map[*ast.SelectorExpr]*types.Selection), + } + versions.InitFileVersions(lpkg.TypesInfo) + lpkg.TypesSizes = ld.sizes + + importer := importerFunc(func(path string) (*types.Package, error) { + if path == "unsafe" { + return types.Unsafe, nil + } + + // The imports map is keyed by import path. + ipkg := lpkg.Imports[path] + if ipkg == nil { + if err := lpkg.importErrors[path]; err != nil { + return nil, err + } + // There was skew between the metadata and the + // import declarations, likely due to an edit + // race, or because the ParseFile feature was + // used to supply alternative file contents. + return nil, fmt.Errorf("no metadata for %s", path) + } + + if ipkg.Types != nil && ipkg.Types.Complete() { + return ipkg.Types, nil + } + log.Fatalf("internal error: package %q without types was imported from %q", path, lpkg) + panic("unreachable") + }) + + // type-check + tc := &types.Config{ + Importer: importer, + + // Type-check bodies of functions only in initial packages. + // Example: for import graph A->B->C and initial packages {A,C}, + // we can ignore function bodies in B. + IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial, + + Error: appendError, + Sizes: ld.sizes, // may be nil + } + if lpkg.Module != nil && lpkg.Module.GoVersion != "" { + tc.GoVersion = "go" + lpkg.Module.GoVersion + } + if (ld.Mode & typecheckCgo) != 0 { + if !typesinternal.SetUsesCgo(tc) { + appendError(Error{ + Msg: "typecheckCgo requires Go 1.15+", + Kind: ListError, + }) + return + } + } + + typErr := types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) + lpkg.importErrors = nil // no longer needed + + // In go/types go1.21 and go1.22, Checker.Files failed fast with a + // a "too new" error, without calling tc.Error and without + // proceeding to type-check the package (#66525). + // We rely on the runtimeVersion error to give the suggested remedy. + if typErr != nil && len(lpkg.Errors) == 0 && len(lpkg.Syntax) > 0 { + if msg := typErr.Error(); strings.HasPrefix(msg, "package requires newer Go version") { + appendError(types.Error{ + Fset: ld.Fset, + Pos: lpkg.Syntax[0].Package, + Msg: msg, + }) + } + } + + // If !Cgo, the type-checker uses FakeImportC mode, so + // it doesn't invoke the importer for import "C", + // nor report an error for the import, + // or for any undefined C.f reference. + // We must detect this explicitly and correctly + // mark the package as IllTyped (by reporting an error). + // TODO(adonovan): if these errors are annoying, + // we could just set IllTyped quietly. + if tc.FakeImportC { + outer: + for _, f := range lpkg.Syntax { + for _, imp := range f.Imports { + if imp.Path.Value == `"C"` { + err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`} + appendError(err) + break outer + } + } + } + } + + // If types.Checker.Files had an error that was unreported, + // make sure to report the unknown error so the package is illTyped. + if typErr != nil && len(lpkg.Errors) == 0 { + appendError(typErr) + } + + // Record accumulated errors. + illTyped := len(lpkg.Errors) > 0 + if !illTyped { + for _, imp := range lpkg.Imports { + if imp.IllTyped { + illTyped = true + break + } + } + } + lpkg.IllTyped = illTyped +} + +// An importFunc is an implementation of the single-method +// types.Importer interface based on a function value. +type importerFunc func(path string) (*types.Package, error) + +func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } + +// We use a counting semaphore to limit +// the number of parallel I/O calls per process. +var ioLimit = make(chan bool, 20) + +func (ld *loader) parseFile(filename string) (*ast.File, error) { + ld.parseCacheMu.Lock() + v, ok := ld.parseCache[filename] + if ok { + // cache hit + ld.parseCacheMu.Unlock() + <-v.ready + } else { + // cache miss + v = &parseValue{ready: make(chan struct{})} + ld.parseCache[filename] = v + ld.parseCacheMu.Unlock() + + var src []byte + for f, contents := range ld.Config.Overlay { + if sameFile(f, filename) { + src = contents + } + } + var err error + if src == nil { + ioLimit <- true // wait + src, err = os.ReadFile(filename) + <-ioLimit // signal + } + if err != nil { + v.err = err + } else { + v.f, v.err = ld.ParseFile(ld.Fset, filename, src) + } + + close(v.ready) + } + return v.f, v.err +} + +// parseFiles reads and parses the Go source files and returns the ASTs +// of the ones that could be at least partially parsed, along with a +// list of I/O and parse errors encountered. +// +// Because files are scanned in parallel, the token.Pos +// positions of the resulting ast.Files are not ordered. +func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) { + var wg sync.WaitGroup + n := len(filenames) + parsed := make([]*ast.File, n) + errors := make([]error, n) + for i, file := range filenames { + if ld.Config.Context.Err() != nil { + parsed[i] = nil + errors[i] = ld.Config.Context.Err() + continue + } + wg.Add(1) + go func(i int, filename string) { + parsed[i], errors[i] = ld.parseFile(filename) + wg.Done() + }(i, file) + } + wg.Wait() + + // Eliminate nils, preserving order. + var o int + for _, f := range parsed { + if f != nil { + parsed[o] = f + o++ + } + } + parsed = parsed[:o] + + o = 0 + for _, err := range errors { + if err != nil { + errors[o] = err + o++ + } + } + errors = errors[:o] + + return parsed, errors +} + +// sameFile returns true if x and y have the same basename and denote +// the same file. +func sameFile(x, y string) bool { + if x == y { + // It could be the case that y doesn't exist. + // For instance, it may be an overlay file that + // hasn't been written to disk. To handle that case + // let x == y through. (We added the exact absolute path + // string to the CompiledGoFiles list, so the unwritten + // overlay case implies x==y.) + return true + } + if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation) + if xi, err := os.Stat(x); err == nil { + if yi, err := os.Stat(y); err == nil { + return os.SameFile(xi, yi) + } + } + } + return false +} + +// loadFromExportData ensures that type information is present for the specified +// package, loading it from an export data file on the first request. +// On success it sets lpkg.Types to a new Package. +func (ld *loader) loadFromExportData(lpkg *loaderPackage) error { + if lpkg.PkgPath == "" { + log.Fatalf("internal error: Package %s has no PkgPath", lpkg) + } + + // Because gcexportdata.Read has the potential to create or + // modify the types.Package for each node in the transitive + // closure of dependencies of lpkg, all exportdata operations + // must be sequential. (Finer-grained locking would require + // changes to the gcexportdata API.) + // + // The exportMu lock guards the lpkg.Types field and the + // types.Package it points to, for each loaderPackage in the graph. + // + // Not all accesses to Package.Pkg need to be protected by exportMu: + // graph ordering ensures that direct dependencies of source + // packages are fully loaded before the importer reads their Pkg field. + ld.exportMu.Lock() + defer ld.exportMu.Unlock() + + if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() { + return nil // cache hit + } + + lpkg.IllTyped = true // fail safe + + if lpkg.ExportFile == "" { + // Errors while building export data will have been printed to stderr. + return fmt.Errorf("no export data file") + } + f, err := os.Open(lpkg.ExportFile) + if err != nil { + return err + } + defer f.Close() + + // Read gc export data. + // + // We don't currently support gccgo export data because all + // underlying workspaces use the gc toolchain. (Even build + // systems that support gccgo don't use it for workspace + // queries.) + r, err := gcexportdata.NewReader(f) + if err != nil { + return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) + } + + // Build the view. + // + // The gcexportdata machinery has no concept of package ID. + // It identifies packages by their PkgPath, which although not + // globally unique is unique within the scope of one invocation + // of the linker, type-checker, or gcexportdata. + // + // So, we must build a PkgPath-keyed view of the global + // (conceptually ID-keyed) cache of packages and pass it to + // gcexportdata. The view must contain every existing + // package that might possibly be mentioned by the + // current package---its transitive closure. + // + // In loadPackage, we unconditionally create a types.Package for + // each dependency so that export data loading does not + // create new ones. + // + // TODO(adonovan): it would be simpler and more efficient + // if the export data machinery invoked a callback to + // get-or-create a package instead of a map. + // + view := make(map[string]*types.Package) // view seen by gcexportdata + seen := make(map[*loaderPackage]bool) // all visited packages + var visit func(pkgs map[string]*Package) + visit = func(pkgs map[string]*Package) { + for _, p := range pkgs { + lpkg := ld.pkgs[p.ID] + if !seen[lpkg] { + seen[lpkg] = true + view[lpkg.PkgPath] = lpkg.Types + visit(lpkg.Imports) + } + } + } + visit(lpkg.Imports) + + viewLen := len(view) + 1 // adding the self package + // Parse the export data. + // (May modify incomplete packages in view but not create new ones.) + tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath) + if err != nil { + return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) + } + if _, ok := view["go.shape"]; ok { + // Account for the pseudopackage "go.shape" that gets + // created by generic code. + viewLen++ + } + if viewLen != len(view) { + log.Panicf("golang.org/x/tools/go/packages: unexpected new packages during load of %s", lpkg.PkgPath) + } + + lpkg.Types = tpkg + lpkg.IllTyped = false + return nil +} + +// impliedLoadMode returns loadMode with its dependencies. +func impliedLoadMode(loadMode LoadMode) LoadMode { + if loadMode&(NeedDeps|NeedTypes|NeedTypesInfo) != 0 { + // All these things require knowing the import graph. + loadMode |= NeedImports + } + + return loadMode +} + +func usesExportData(cfg *Config) bool { + return cfg.Mode&NeedExportFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0 +} + +var _ interface{} = io.Discard // assert build toolchain is go1.16 or later diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go new file mode 100644 index 00000000..a1dcc40b --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/visit.go @@ -0,0 +1,59 @@ +// 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 packages + +import ( + "fmt" + "os" + "sort" +) + +// Visit visits all the packages in the import graph whose roots are +// pkgs, calling the optional pre function the first time each package +// is encountered (preorder), and the optional post function after a +// package's dependencies have been visited (postorder). +// The boolean result of pre(pkg) determines whether +// the imports of package pkg are visited. +func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { + seen := make(map[*Package]bool) + var visit func(*Package) + visit = func(pkg *Package) { + if !seen[pkg] { + seen[pkg] = true + + if pre == nil || pre(pkg) { + paths := make([]string, 0, len(pkg.Imports)) + for path := range pkg.Imports { + paths = append(paths, path) + } + sort.Strings(paths) // Imports is a map, this makes visit stable + for _, path := range paths { + visit(pkg.Imports[path]) + } + } + + if post != nil { + post(pkg) + } + } + } + for _, pkg := range pkgs { + visit(pkg) + } +} + +// PrintErrors prints to os.Stderr the accumulated errors of all +// packages in the import graph rooted at pkgs, dependencies first. +// PrintErrors returns the number of errors printed. +func PrintErrors(pkgs []*Package) int { + var n int + Visit(pkgs, nil, func(pkg *Package) { + for _, err := range pkg.Errors { + fmt.Fprintln(os.Stderr, err) + n++ + } + }) + return n +} diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go new file mode 100644 index 00000000..a2386c34 --- /dev/null +++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go @@ -0,0 +1,753 @@ +// 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 objectpath defines a naming scheme for types.Objects +// (that is, named entities in Go programs) relative to their enclosing +// package. +// +// Type-checker objects are canonical, so they are usually identified by +// their address in memory (a pointer), but a pointer has meaning only +// within one address space. By contrast, objectpath names allow the +// identity of an object to be sent from one program to another, +// establishing a correspondence between types.Object variables that are +// distinct but logically equivalent. +// +// A single object may have multiple paths. In this example, +// +// type A struct{ X int } +// type B A +// +// the field X has two paths due to its membership of both A and B. +// The For(obj) function always returns one of these paths, arbitrarily +// but consistently. +package objectpath + +import ( + "fmt" + "go/types" + "strconv" + "strings" + + "golang.org/x/tools/internal/aliases" + "golang.org/x/tools/internal/typesinternal" +) + +// TODO(adonovan): think about generic aliases. + +// A Path is an opaque name that identifies a types.Object +// relative to its package. Conceptually, the name consists of a +// sequence of destructuring operations applied to the package scope +// to obtain the original object. +// The name does not include the package itself. +type Path string + +// Encoding +// +// An object path is a textual and (with training) human-readable encoding +// of a sequence of destructuring operators, starting from a types.Package. +// The sequences represent a path through the package/object/type graph. +// We classify these operators by their type: +// +// PO package->object Package.Scope.Lookup +// OT object->type Object.Type +// TT type->type Type.{Elem,Key,Params,Results,Underlying} [EKPRU] +// TO type->object Type.{At,Field,Method,Obj} [AFMO] +// +// All valid paths start with a package and end at an object +// and thus may be defined by the regular language: +// +// objectpath = PO (OT TT* TO)* +// +// The concrete encoding follows directly: +// - The only PO operator is Package.Scope.Lookup, which requires an identifier. +// - The only OT operator is Object.Type, +// which we encode as '.' because dot cannot appear in an identifier. +// - The TT operators are encoded as [EKPRUTC]; +// one of these (TypeParam) requires an integer operand, +// which is encoded as a string of decimal digits. +// - The TO operators are encoded as [AFMO]; +// three of these (At,Field,Method) require an integer operand, +// which is encoded as a string of decimal digits. +// These indices are stable across different representations +// of the same package, even source and export data. +// The indices used are implementation specific and may not correspond to +// the argument to the go/types function. +// +// In the example below, +// +// package p +// +// type T interface { +// f() (a string, b struct{ X int }) +// } +// +// field X has the path "T.UM0.RA1.F0", +// representing the following sequence of operations: +// +// p.Lookup("T") T +// .Type().Underlying().Method(0). f +// .Type().Results().At(1) b +// .Type().Field(0) X +// +// The encoding is not maximally compact---every R or P is +// followed by an A, for example---but this simplifies the +// encoder and decoder. +const ( + // object->type operators + opType = '.' // .Type() (Object) + + // type->type operators + opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map) + opKey = 'K' // .Key() (Map) + opParams = 'P' // .Params() (Signature) + opResults = 'R' // .Results() (Signature) + opUnderlying = 'U' // .Underlying() (Named) + opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature) + opConstraint = 'C' // .Constraint() (TypeParam) + + // type->object operators + opAt = 'A' // .At(i) (Tuple) + opField = 'F' // .Field(i) (Struct) + opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored) + opObj = 'O' // .Obj() (Named, TypeParam) +) + +// For is equivalent to new(Encoder).For(obj). +// +// It may be more efficient to reuse a single Encoder across several calls. +func For(obj types.Object) (Path, error) { + return new(Encoder).For(obj) +} + +// An Encoder amortizes the cost of encoding the paths of multiple objects. +// The zero value of an Encoder is ready to use. +type Encoder struct { + scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects +} + +// For returns the path to an object relative to its package, +// or an error if the object is not accessible from the package's Scope. +// +// The For function guarantees to return a path only for the following objects: +// - package-level types +// - exported package-level non-types +// - methods +// - parameter and result variables +// - struct fields +// These objects are sufficient to define the API of their package. +// The objects described by a package's export data are drawn from this set. +// +// The set of objects accessible from a package's Scope depends on +// whether the package was produced by type-checking syntax, or +// reading export data; the latter may have a smaller Scope since +// export data trims objects that are not reachable from an exported +// declaration. For example, the For function will return a path for +// an exported method of an unexported type that is not reachable +// from any public declaration; this path will cause the Object +// function to fail if called on a package loaded from export data. +// TODO(adonovan): is this a bug or feature? Should this package +// compute accessibility in the same way? +// +// For does not return a path for predeclared names, imported package +// names, local names, and unexported package-level names (except +// types). +// +// Example: given this definition, +// +// package p +// +// type T interface { +// f() (a string, b struct{ X int }) +// } +// +// For(X) would return a path that denotes the following sequence of operations: +// +// p.Scope().Lookup("T") (TypeName T) +// .Type().Underlying().Method(0). (method Func f) +// .Type().Results().At(1) (field Var b) +// .Type().Field(0) (field Var X) +// +// where p is the package (*types.Package) to which X belongs. +func (enc *Encoder) For(obj types.Object) (Path, error) { + pkg := obj.Pkg() + + // This table lists the cases of interest. + // + // Object Action + // ------ ------ + // nil reject + // builtin reject + // pkgname reject + // label reject + // var + // package-level accept + // func param/result accept + // local reject + // struct field accept + // const + // package-level accept + // local reject + // func + // package-level accept + // init functions reject + // concrete method accept + // interface method accept + // type + // package-level accept + // local reject + // + // The only accessible package-level objects are members of pkg itself. + // + // The cases are handled in four steps: + // + // 1. reject nil and builtin + // 2. accept package-level objects + // 3. reject obviously invalid objects + // 4. search the API for the path to the param/result/field/method. + + // 1. reference to nil or builtin? + if pkg == nil { + return "", fmt.Errorf("predeclared %s has no path", obj) + } + scope := pkg.Scope() + + // 2. package-level object? + if scope.Lookup(obj.Name()) == obj { + // Only exported objects (and non-exported types) have a path. + // Non-exported types may be referenced by other objects. + if _, ok := obj.(*types.TypeName); !ok && !obj.Exported() { + return "", fmt.Errorf("no path for non-exported %v", obj) + } + return Path(obj.Name()), nil + } + + // 3. Not a package-level object. + // Reject obviously non-viable cases. + switch obj := obj.(type) { + case *types.TypeName: + if _, ok := aliases.Unalias(obj.Type()).(*types.TypeParam); !ok { + // With the exception of type parameters, only package-level type names + // have a path. + return "", fmt.Errorf("no path for %v", obj) + } + case *types.Const, // Only package-level constants have a path. + *types.Label, // Labels are function-local. + *types.PkgName: // PkgNames are file-local. + return "", fmt.Errorf("no path for %v", obj) + + case *types.Var: + // Could be: + // - a field (obj.IsField()) + // - a func parameter or result + // - a local var. + // Sadly there is no way to distinguish + // a param/result from a local + // so we must proceed to the find. + + case *types.Func: + // A func, if not package-level, must be a method. + if recv := obj.Type().(*types.Signature).Recv(); recv == nil { + return "", fmt.Errorf("func is not a method: %v", obj) + } + + if path, ok := enc.concreteMethod(obj); ok { + // Fast path for concrete methods that avoids looping over scope. + return path, nil + } + + default: + panic(obj) + } + + // 4. Search the API for the path to the var (field/param/result) or method. + + // First inspect package-level named types. + // In the presence of path aliases, these give + // the best paths because non-types may + // refer to types, but not the reverse. + empty := make([]byte, 0, 48) // initial space + objs := enc.scopeObjects(scope) + for _, o := range objs { + tname, ok := o.(*types.TypeName) + if !ok { + continue // handle non-types in second pass + } + + path := append(empty, o.Name()...) + path = append(path, opType) + + T := o.Type() + + if tname.IsAlias() { + // type alias + if r := find(obj, T, path, nil); r != nil { + return Path(r), nil + } + } else { + if named, _ := T.(*types.Named); named != nil { + if r := findTypeParam(obj, named.TypeParams(), path, nil); r != nil { + // generic named type + return Path(r), nil + } + } + // defined (named) type + if r := find(obj, T.Underlying(), append(path, opUnderlying), nil); r != nil { + return Path(r), nil + } + } + } + + // Then inspect everything else: + // non-types, and declared methods of defined types. + for _, o := range objs { + path := append(empty, o.Name()...) + if _, ok := o.(*types.TypeName); !ok { + if o.Exported() { + // exported non-type (const, var, func) + if r := find(obj, o.Type(), append(path, opType), nil); r != nil { + return Path(r), nil + } + } + continue + } + + // Inspect declared methods of defined types. + if T, ok := aliases.Unalias(o.Type()).(*types.Named); ok { + path = append(path, opType) + // The method index here is always with respect + // to the underlying go/types data structures, + // which ultimately derives from source order + // and must be preserved by export data. + for i := 0; i < T.NumMethods(); i++ { + m := T.Method(i) + path2 := appendOpArg(path, opMethod, i) + if m == obj { + return Path(path2), nil // found declared method + } + if r := find(obj, m.Type(), append(path2, opType), nil); r != nil { + return Path(r), nil + } + } + } + } + + return "", fmt.Errorf("can't find path for %v in %s", obj, pkg.Path()) +} + +func appendOpArg(path []byte, op byte, arg int) []byte { + path = append(path, op) + path = strconv.AppendInt(path, int64(arg), 10) + return path +} + +// concreteMethod returns the path for meth, which must have a non-nil receiver. +// The second return value indicates success and may be false if the method is +// an interface method or if it is an instantiated method. +// +// This function is just an optimization that avoids the general scope walking +// approach. You are expected to fall back to the general approach if this +// function fails. +func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) { + // Concrete methods can only be declared on package-scoped named types. For + // that reason we can skip the expensive walk over the package scope: the + // path will always be package -> named type -> method. We can trivially get + // the type name from the receiver, and only have to look over the type's + // methods to find the method index. + // + // Methods on generic types require special consideration, however. Consider + // the following package: + // + // L1: type S[T any] struct{} + // L2: func (recv S[A]) Foo() { recv.Bar() } + // L3: func (recv S[B]) Bar() { } + // L4: type Alias = S[int] + // L5: func _[T any]() { var s S[int]; s.Foo() } + // + // The receivers of methods on generic types are instantiations. L2 and L3 + // instantiate S with the type-parameters A and B, which are scoped to the + // respective methods. L4 and L5 each instantiate S with int. Each of these + // instantiations has its own method set, full of methods (and thus objects) + // with receivers whose types are the respective instantiations. In other + // words, we have + // + // S[A].Foo, S[A].Bar + // S[B].Foo, S[B].Bar + // S[int].Foo, S[int].Bar + // + // We may thus be trying to produce object paths for any of these objects. + // + // S[A].Foo and S[B].Bar are the origin methods, and their paths are S.Foo + // and S.Bar, which are the paths that this function naturally produces. + // + // S[A].Bar, S[B].Foo, and both methods on S[int] are instantiations that + // don't correspond to the origin methods. For S[int], this is significant. + // The most precise object path for S[int].Foo, for example, is Alias.Foo, + // not S.Foo. Our function, however, would produce S.Foo, which would + // resolve to a different object. + // + // For S[A].Bar and S[B].Foo it could be argued that S.Bar and S.Foo are + // still the correct paths, since only the origin methods have meaningful + // paths. But this is likely only true for trivial cases and has edge cases. + // Since this function is only an optimization, we err on the side of giving + // up, deferring to the slower but definitely correct algorithm. Most users + // of objectpath will only be giving us origin methods, anyway, as referring + // to instantiated methods is usually not useful. + + if meth.Origin() != meth { + return "", false + } + + _, named := typesinternal.ReceiverNamed(meth.Type().(*types.Signature).Recv()) + if named == nil { + return "", false + } + + if types.IsInterface(named) { + // Named interfaces don't have to be package-scoped + // + // TODO(dominikh): opt: if scope.Lookup(name) == named, then we can apply this optimization to interface + // methods, too, I think. + return "", false + } + + // Preallocate space for the name, opType, opMethod, and some digits. + name := named.Obj().Name() + path := make([]byte, 0, len(name)+8) + path = append(path, name...) + path = append(path, opType) + + // Method indices are w.r.t. the go/types data structures, + // ultimately deriving from source order, + // which is preserved by export data. + for i := 0; i < named.NumMethods(); i++ { + if named.Method(i) == meth { + path = appendOpArg(path, opMethod, i) + return Path(path), true + } + } + + // Due to golang/go#59944, go/types fails to associate the receiver with + // certain methods on cgo types. + // + // TODO(rfindley): replace this panic once golang/go#59944 is fixed in all Go + // versions gopls supports. + return "", false + // panic(fmt.Sprintf("couldn't find method %s on type %s; methods: %#v", meth, named, enc.namedMethods(named))) +} + +// find finds obj within type T, returning the path to it, or nil if not found. +// +// The seen map is used to short circuit cycles through type parameters. If +// nil, it will be allocated as necessary. +func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]bool) []byte { + switch T := T.(type) { + case *aliases.Alias: + return find(obj, aliases.Unalias(T), path, seen) + case *types.Basic, *types.Named: + // Named types belonging to pkg were handled already, + // so T must belong to another package. No path. + return nil + case *types.Pointer: + return find(obj, T.Elem(), append(path, opElem), seen) + case *types.Slice: + return find(obj, T.Elem(), append(path, opElem), seen) + case *types.Array: + return find(obj, T.Elem(), append(path, opElem), seen) + case *types.Chan: + return find(obj, T.Elem(), append(path, opElem), seen) + case *types.Map: + if r := find(obj, T.Key(), append(path, opKey), seen); r != nil { + return r + } + return find(obj, T.Elem(), append(path, opElem), seen) + case *types.Signature: + if r := findTypeParam(obj, T.TypeParams(), path, seen); r != nil { + return r + } + if r := find(obj, T.Params(), append(path, opParams), seen); r != nil { + return r + } + return find(obj, T.Results(), append(path, opResults), seen) + case *types.Struct: + for i := 0; i < T.NumFields(); i++ { + fld := T.Field(i) + path2 := appendOpArg(path, opField, i) + if fld == obj { + return path2 // found field var + } + if r := find(obj, fld.Type(), append(path2, opType), seen); r != nil { + return r + } + } + return nil + case *types.Tuple: + for i := 0; i < T.Len(); i++ { + v := T.At(i) + path2 := appendOpArg(path, opAt, i) + if v == obj { + return path2 // found param/result var + } + if r := find(obj, v.Type(), append(path2, opType), seen); r != nil { + return r + } + } + return nil + case *types.Interface: + for i := 0; i < T.NumMethods(); i++ { + m := T.Method(i) + path2 := appendOpArg(path, opMethod, i) + if m == obj { + return path2 // found interface method + } + if r := find(obj, m.Type(), append(path2, opType), seen); r != nil { + return r + } + } + return nil + case *types.TypeParam: + name := T.Obj() + if name == obj { + return append(path, opObj) + } + if seen[name] { + return nil + } + if seen == nil { + seen = make(map[*types.TypeName]bool) + } + seen[name] = true + if r := find(obj, T.Constraint(), append(path, opConstraint), seen); r != nil { + return r + } + return nil + } + panic(T) +} + +func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte { + for i := 0; i < list.Len(); i++ { + tparam := list.At(i) + path2 := appendOpArg(path, opTypeParam, i) + if r := find(obj, tparam, path2, seen); r != nil { + return r + } + } + return nil +} + +// Object returns the object denoted by path p within the package pkg. +func Object(pkg *types.Package, p Path) (types.Object, error) { + pathstr := string(p) + if pathstr == "" { + return nil, fmt.Errorf("empty path") + } + + var pkgobj, suffix string + if dot := strings.IndexByte(pathstr, opType); dot < 0 { + pkgobj = pathstr + } else { + pkgobj = pathstr[:dot] + suffix = pathstr[dot:] // suffix starts with "." + } + + obj := pkg.Scope().Lookup(pkgobj) + if obj == nil { + return nil, fmt.Errorf("package %s does not contain %q", pkg.Path(), pkgobj) + } + + // abstraction of *types.{Pointer,Slice,Array,Chan,Map} + type hasElem interface { + Elem() types.Type + } + // abstraction of *types.{Named,Signature} + type hasTypeParams interface { + TypeParams() *types.TypeParamList + } + // abstraction of *types.{Named,TypeParam} + type hasObj interface { + Obj() *types.TypeName + } + + // The loop state is the pair (t, obj), + // exactly one of which is non-nil, initially obj. + // All suffixes start with '.' (the only object->type operation), + // followed by optional type->type operations, + // then a type->object operation. + // The cycle then repeats. + var t types.Type + for suffix != "" { + code := suffix[0] + suffix = suffix[1:] + + // Codes [AFM] have an integer operand. + var index int + switch code { + case opAt, opField, opMethod, opTypeParam: + rest := strings.TrimLeft(suffix, "0123456789") + numerals := suffix[:len(suffix)-len(rest)] + suffix = rest + i, err := strconv.Atoi(numerals) + if err != nil { + return nil, fmt.Errorf("invalid path: bad numeric operand %q for code %q", numerals, code) + } + index = int(i) + case opObj: + // no operand + default: + // The suffix must end with a type->object operation. + if suffix == "" { + return nil, fmt.Errorf("invalid path: ends with %q, want [AFMO]", code) + } + } + + if code == opType { + if t != nil { + return nil, fmt.Errorf("invalid path: unexpected %q in type context", opType) + } + t = obj.Type() + obj = nil + continue + } + + if t == nil { + return nil, fmt.Errorf("invalid path: code %q in object context", code) + } + + // Inv: t != nil, obj == nil + + t = aliases.Unalias(t) + switch code { + case opElem: + hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want pointer, slice, array, chan or map)", code, t, t) + } + t = hasElem.Elem() + + case opKey: + mapType, ok := t.(*types.Map) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want map)", code, t, t) + } + t = mapType.Key() + + case opParams: + sig, ok := t.(*types.Signature) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) + } + t = sig.Params() + + case opResults: + sig, ok := t.(*types.Signature) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) + } + t = sig.Results() + + case opUnderlying: + named, ok := t.(*types.Named) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named)", code, t, t) + } + t = named.Underlying() + + case opTypeParam: + hasTypeParams, ok := t.(hasTypeParams) // Named, Signature + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or signature)", code, t, t) + } + tparams := hasTypeParams.TypeParams() + if n := tparams.Len(); index >= n { + return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) + } + t = tparams.At(index) + + case opConstraint: + tparam, ok := t.(*types.TypeParam) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t) + } + t = tparam.Constraint() + + case opAt: + tuple, ok := t.(*types.Tuple) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want tuple)", code, t, t) + } + if n := tuple.Len(); index >= n { + return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) + } + obj = tuple.At(index) + t = nil + + case opField: + structType, ok := t.(*types.Struct) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want struct)", code, t, t) + } + if n := structType.NumFields(); index >= n { + return nil, fmt.Errorf("field index %d out of range [0-%d)", index, n) + } + obj = structType.Field(index) + t = nil + + case opMethod: + switch t := t.(type) { + case *types.Interface: + if index >= t.NumMethods() { + return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods()) + } + obj = t.Method(index) // Id-ordered + + case *types.Named: + if index >= t.NumMethods() { + return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods()) + } + obj = t.Method(index) + + default: + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t) + } + t = nil + + case opObj: + hasObj, ok := t.(hasObj) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or type param)", code, t, t) + } + obj = hasObj.Obj() + t = nil + + default: + return nil, fmt.Errorf("invalid path: unknown code %q", code) + } + } + + if obj.Pkg() != pkg { + return nil, fmt.Errorf("path denotes %s, which belongs to a different package", obj) + } + + return obj, nil // success +} + +// scopeObjects is a memoization of scope objects. +// Callers must not modify the result. +func (enc *Encoder) scopeObjects(scope *types.Scope) []types.Object { + m := enc.scopeMemo + if m == nil { + m = make(map[*types.Scope][]types.Object) + enc.scopeMemo = m + } + objs, ok := m[scope] + if !ok { + names := scope.Names() // allocates and sorts + objs = make([]types.Object, len(names)) + for i, name := range names { + objs[i] = scope.Lookup(name) + } + m[scope] = objs + } + return objs +} diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases.go b/vendor/golang.org/x/tools/internal/aliases/aliases.go new file mode 100644 index 00000000..f89112c8 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/aliases/aliases.go @@ -0,0 +1,28 @@ +// 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 aliases + +import ( + "go/token" + "go/types" +) + +// Package aliases defines backward compatible shims +// for the types.Alias type representation added in 1.22. +// This defines placeholders for x/tools until 1.26. + +// NewAlias creates a new TypeName in Package pkg that +// is an alias for the type rhs. +// +// When GoVersion>=1.22 and GODEBUG=gotypesalias=1, +// the Type() of the return value is a *types.Alias. +func NewAlias(pos token.Pos, pkg *types.Package, name string, rhs types.Type) *types.TypeName { + if enabled() { + tname := types.NewTypeName(pos, pkg, name, nil) + newAlias(tname, rhs) + return tname + } + return types.NewTypeName(pos, pkg, name, rhs) +} diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go b/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go new file mode 100644 index 00000000..1872b56f --- /dev/null +++ b/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go @@ -0,0 +1,30 @@ +// 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. + +//go:build !go1.22 +// +build !go1.22 + +package aliases + +import ( + "go/types" +) + +// Alias is a placeholder for a go/types.Alias for <=1.21. +// It will never be created by go/types. +type Alias struct{} + +func (*Alias) String() string { panic("unreachable") } + +func (*Alias) Underlying() types.Type { panic("unreachable") } + +func (*Alias) Obj() *types.TypeName { panic("unreachable") } + +// Unalias returns the type t for go <=1.21. +func Unalias(t types.Type) types.Type { return t } + +// Always false for go <=1.21. Ignores GODEBUG. +func enabled() bool { return false } + +func newAlias(name *types.TypeName, rhs types.Type) *Alias { panic("unreachable") } diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go b/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go new file mode 100644 index 00000000..8b921162 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go @@ -0,0 +1,72 @@ +// 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. + +//go:build go1.22 +// +build go1.22 + +package aliases + +import ( + "go/ast" + "go/parser" + "go/token" + "go/types" + "os" + "strings" + "sync" +) + +// Alias is an alias of types.Alias. +type Alias = types.Alias + +// Unalias is a wrapper of types.Unalias. +func Unalias(t types.Type) types.Type { return types.Unalias(t) } + +// newAlias is an internal alias around types.NewAlias. +// Direct usage is discouraged as the moment. +// Try to use NewAlias instead. +func newAlias(tname *types.TypeName, rhs types.Type) *Alias { + a := types.NewAlias(tname, rhs) + // TODO(go.dev/issue/65455): Remove kludgy workaround to set a.actual as a side-effect. + Unalias(a) + return a +} + +// enabled returns true when types.Aliases are enabled. +func enabled() bool { + // Use the gotypesalias value in GODEBUG if set. + godebug := os.Getenv("GODEBUG") + value := -1 // last set value. + for _, f := range strings.Split(godebug, ",") { + switch f { + case "gotypesalias=1": + value = 1 + case "gotypesalias=0": + value = 0 + } + } + switch value { + case 0: + return false + case 1: + return true + default: + return aliasesDefault() + } +} + +// aliasesDefault reports if aliases are enabled by default. +func aliasesDefault() bool { + // Dynamically check if Aliases will be produced from go/types. + aliasesDefaultOnce.Do(func() { + fset := token.NewFileSet() + f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", 0) + pkg, _ := new(types.Config).Check("p", fset, []*ast.File{f}, nil) + _, gotypesaliasDefault = pkg.Scope().Lookup("A").Type().(*types.Alias) + }) + return gotypesaliasDefault +} + +var gotypesaliasDefault bool +var aliasesDefaultOnce sync.Once diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go new file mode 100644 index 00000000..a6cf0e64 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/core/event.go @@ -0,0 +1,85 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package core provides support for event based telemetry. +package core + +import ( + "fmt" + "time" + + "golang.org/x/tools/internal/event/label" +) + +// Event holds the information about an event of note that occurred. +type Event struct { + at time.Time + + // As events are often on the stack, storing the first few labels directly + // in the event can avoid an allocation at all for the very common cases of + // simple events. + // The length needs to be large enough to cope with the majority of events + // but no so large as to cause undue stack pressure. + // A log message with two values will use 3 labels (one for each value and + // one for the message itself). + + static [3]label.Label // inline storage for the first few labels + dynamic []label.Label // dynamically sized storage for remaining labels +} + +// eventLabelMap implements label.Map for a the labels of an Event. +type eventLabelMap struct { + event Event +} + +func (ev Event) At() time.Time { return ev.at } + +func (ev Event) Format(f fmt.State, r rune) { + if !ev.at.IsZero() { + fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 ")) + } + for index := 0; ev.Valid(index); index++ { + if l := ev.Label(index); l.Valid() { + fmt.Fprintf(f, "\n\t%v", l) + } + } +} + +func (ev Event) Valid(index int) bool { + return index >= 0 && index < len(ev.static)+len(ev.dynamic) +} + +func (ev Event) Label(index int) label.Label { + if index < len(ev.static) { + return ev.static[index] + } + return ev.dynamic[index-len(ev.static)] +} + +func (ev Event) Find(key label.Key) label.Label { + for _, l := range ev.static { + if l.Key() == key { + return l + } + } + for _, l := range ev.dynamic { + if l.Key() == key { + return l + } + } + return label.Label{} +} + +func MakeEvent(static [3]label.Label, labels []label.Label) Event { + return Event{ + static: static, + dynamic: labels, + } +} + +// CloneEvent event returns a copy of the event with the time adjusted to at. +func CloneEvent(ev Event, at time.Time) Event { + ev.at = at + return ev +} diff --git a/vendor/golang.org/x/tools/internal/event/core/export.go b/vendor/golang.org/x/tools/internal/event/core/export.go new file mode 100644 index 00000000..05f3a9a5 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/core/export.go @@ -0,0 +1,70 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package core + +import ( + "context" + "sync/atomic" + "time" + "unsafe" + + "golang.org/x/tools/internal/event/label" +) + +// Exporter is a function that handles events. +// It may return a modified context and event. +type Exporter func(context.Context, Event, label.Map) context.Context + +var ( + exporter unsafe.Pointer +) + +// SetExporter sets the global exporter function that handles all events. +// The exporter is called synchronously from the event call site, so it should +// return quickly so as not to hold up user code. +func SetExporter(e Exporter) { + p := unsafe.Pointer(&e) + if e == nil { + // &e is always valid, and so p is always valid, but for the early abort + // of ProcessEvent to be efficient it needs to make the nil check on the + // pointer without having to dereference it, so we make the nil function + // also a nil pointer + p = nil + } + atomic.StorePointer(&exporter, p) +} + +// deliver is called to deliver an event to the supplied exporter. +// it will fill in the time. +func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context { + // add the current time to the event + ev.at = time.Now() + // hand the event off to the current exporter + return exporter(ctx, ev, ev) +} + +// Export is called to deliver an event to the global exporter if set. +func Export(ctx context.Context, ev Event) context.Context { + // get the global exporter and abort early if there is not one + exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) + if exporterPtr == nil { + return ctx + } + return deliver(ctx, *exporterPtr, ev) +} + +// ExportPair is called to deliver a start event to the supplied exporter. +// It also returns a function that will deliver the end event to the same +// exporter. +// It will fill in the time. +func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) { + // get the global exporter and abort early if there is not one + exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) + if exporterPtr == nil { + return ctx, func() {} + } + ctx = deliver(ctx, *exporterPtr, begin) + return ctx, func() { deliver(ctx, *exporterPtr, end) } +} diff --git a/vendor/golang.org/x/tools/internal/event/core/fast.go b/vendor/golang.org/x/tools/internal/event/core/fast.go new file mode 100644 index 00000000..06c1d461 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/core/fast.go @@ -0,0 +1,77 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package core + +import ( + "context" + + "golang.org/x/tools/internal/event/keys" + "golang.org/x/tools/internal/event/label" +) + +// Log1 takes a message and one label delivers a log event to the exporter. +// It is a customized version of Print that is faster and does no allocation. +func Log1(ctx context.Context, message string, t1 label.Label) { + Export(ctx, MakeEvent([3]label.Label{ + keys.Msg.Of(message), + t1, + }, nil)) +} + +// Log2 takes a message and two labels and delivers a log event to the exporter. +// It is a customized version of Print that is faster and does no allocation. +func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) { + Export(ctx, MakeEvent([3]label.Label{ + keys.Msg.Of(message), + t1, + t2, + }, nil)) +} + +// Metric1 sends a label event to the exporter with the supplied labels. +func Metric1(ctx context.Context, t1 label.Label) context.Context { + return Export(ctx, MakeEvent([3]label.Label{ + keys.Metric.New(), + t1, + }, nil)) +} + +// Metric2 sends a label event to the exporter with the supplied labels. +func Metric2(ctx context.Context, t1, t2 label.Label) context.Context { + return Export(ctx, MakeEvent([3]label.Label{ + keys.Metric.New(), + t1, + t2, + }, nil)) +} + +// Start1 sends a span start event with the supplied label list to the exporter. +// It also returns a function that will end the span, which should normally be +// deferred. +func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) { + return ExportPair(ctx, + MakeEvent([3]label.Label{ + keys.Start.Of(name), + t1, + }, nil), + MakeEvent([3]label.Label{ + keys.End.New(), + }, nil)) +} + +// Start2 sends a span start event with the supplied label list to the exporter. +// It also returns a function that will end the span, which should normally be +// deferred. +func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) { + return ExportPair(ctx, + MakeEvent([3]label.Label{ + keys.Start.Of(name), + t1, + t2, + }, nil), + MakeEvent([3]label.Label{ + keys.End.New(), + }, nil)) +} diff --git a/vendor/golang.org/x/tools/internal/event/doc.go b/vendor/golang.org/x/tools/internal/event/doc.go new file mode 100644 index 00000000..5dc6e6ba --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/doc.go @@ -0,0 +1,7 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package event provides a set of packages that cover the main +// concepts of telemetry in an implementation agnostic way. +package event diff --git a/vendor/golang.org/x/tools/internal/event/event.go b/vendor/golang.org/x/tools/internal/event/event.go new file mode 100644 index 00000000..4d55e577 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/event.go @@ -0,0 +1,127 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package event + +import ( + "context" + + "golang.org/x/tools/internal/event/core" + "golang.org/x/tools/internal/event/keys" + "golang.org/x/tools/internal/event/label" +) + +// Exporter is a function that handles events. +// It may return a modified context and event. +type Exporter func(context.Context, core.Event, label.Map) context.Context + +// SetExporter sets the global exporter function that handles all events. +// The exporter is called synchronously from the event call site, so it should +// return quickly so as not to hold up user code. +func SetExporter(e Exporter) { + core.SetExporter(core.Exporter(e)) +} + +// Log takes a message and a label list and combines them into a single event +// before delivering them to the exporter. +func Log(ctx context.Context, message string, labels ...label.Label) { + core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Msg.Of(message), + }, labels)) +} + +// IsLog returns true if the event was built by the Log function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsLog(ev core.Event) bool { + return ev.Label(0).Key() == keys.Msg +} + +// Error takes a message and a label list and combines them into a single event +// before delivering them to the exporter. It captures the error in the +// delivered event. +func Error(ctx context.Context, message string, err error, labels ...label.Label) { + core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Msg.Of(message), + keys.Err.Of(err), + }, labels)) +} + +// IsError returns true if the event was built by the Error function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsError(ev core.Event) bool { + return ev.Label(0).Key() == keys.Msg && + ev.Label(1).Key() == keys.Err +} + +// Metric sends a label event to the exporter with the supplied labels. +func Metric(ctx context.Context, labels ...label.Label) { + core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Metric.New(), + }, labels)) +} + +// IsMetric returns true if the event was built by the Metric function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsMetric(ev core.Event) bool { + return ev.Label(0).Key() == keys.Metric +} + +// Label sends a label event to the exporter with the supplied labels. +func Label(ctx context.Context, labels ...label.Label) context.Context { + return core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Label.New(), + }, labels)) +} + +// IsLabel returns true if the event was built by the Label function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsLabel(ev core.Event) bool { + return ev.Label(0).Key() == keys.Label +} + +// Start sends a span start event with the supplied label list to the exporter. +// It also returns a function that will end the span, which should normally be +// deferred. +func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) { + return core.ExportPair(ctx, + core.MakeEvent([3]label.Label{ + keys.Start.Of(name), + }, labels), + core.MakeEvent([3]label.Label{ + keys.End.New(), + }, nil)) +} + +// IsStart returns true if the event was built by the Start function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsStart(ev core.Event) bool { + return ev.Label(0).Key() == keys.Start +} + +// IsEnd returns true if the event was built by the End function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsEnd(ev core.Event) bool { + return ev.Label(0).Key() == keys.End +} + +// Detach returns a context without an associated span. +// This allows the creation of spans that are not children of the current span. +func Detach(ctx context.Context) context.Context { + return core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Detach.New(), + }, nil)) +} + +// IsDetach returns true if the event was built by the Detach function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsDetach(ev core.Event) bool { + return ev.Label(0).Key() == keys.Detach +} diff --git a/vendor/golang.org/x/tools/internal/event/keys/keys.go b/vendor/golang.org/x/tools/internal/event/keys/keys.go new file mode 100644 index 00000000..a02206e3 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/keys/keys.go @@ -0,0 +1,564 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package keys + +import ( + "fmt" + "io" + "math" + "strconv" + + "golang.org/x/tools/internal/event/label" +) + +// Value represents a key for untyped values. +type Value struct { + name string + description string +} + +// New creates a new Key for untyped values. +func New(name, description string) *Value { + return &Value{name: name, description: description} +} + +func (k *Value) Name() string { return k.name } +func (k *Value) Description() string { return k.description } + +func (k *Value) Format(w io.Writer, buf []byte, l label.Label) { + fmt.Fprint(w, k.From(l)) +} + +// Get can be used to get a label for the key from a label.Map. +func (k *Value) Get(lm label.Map) interface{} { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return nil +} + +// From can be used to get a value from a Label. +func (k *Value) From(t label.Label) interface{} { return t.UnpackValue() } + +// Of creates a new Label with this key and the supplied value. +func (k *Value) Of(value interface{}) label.Label { return label.OfValue(k, value) } + +// Tag represents a key for tagging labels that have no value. +// These are used when the existence of the label is the entire information it +// carries, such as marking events to be of a specific kind, or from a specific +// package. +type Tag struct { + name string + description string +} + +// NewTag creates a new Key for tagging labels. +func NewTag(name, description string) *Tag { + return &Tag{name: name, description: description} +} + +func (k *Tag) Name() string { return k.name } +func (k *Tag) Description() string { return k.description } + +func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {} + +// New creates a new Label with this key. +func (k *Tag) New() label.Label { return label.OfValue(k, nil) } + +// Int represents a key +type Int struct { + name string + description string +} + +// NewInt creates a new Key for int values. +func NewInt(name, description string) *Int { + return &Int{name: name, description: description} +} + +func (k *Int) Name() string { return k.name } +func (k *Int) Description() string { return k.description } + +func (k *Int) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Int) Get(lm label.Map) int { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Int) From(t label.Label) int { return int(t.Unpack64()) } + +// Int8 represents a key +type Int8 struct { + name string + description string +} + +// NewInt8 creates a new Key for int8 values. +func NewInt8(name, description string) *Int8 { + return &Int8{name: name, description: description} +} + +func (k *Int8) Name() string { return k.name } +func (k *Int8) Description() string { return k.description } + +func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Int8) Get(lm label.Map) int8 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) } + +// Int16 represents a key +type Int16 struct { + name string + description string +} + +// NewInt16 creates a new Key for int16 values. +func NewInt16(name, description string) *Int16 { + return &Int16{name: name, description: description} +} + +func (k *Int16) Name() string { return k.name } +func (k *Int16) Description() string { return k.description } + +func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Int16) Get(lm label.Map) int16 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) } + +// Int32 represents a key +type Int32 struct { + name string + description string +} + +// NewInt32 creates a new Key for int32 values. +func NewInt32(name, description string) *Int32 { + return &Int32{name: name, description: description} +} + +func (k *Int32) Name() string { return k.name } +func (k *Int32) Description() string { return k.description } + +func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Int32) Get(lm label.Map) int32 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) } + +// Int64 represents a key +type Int64 struct { + name string + description string +} + +// NewInt64 creates a new Key for int64 values. +func NewInt64(name, description string) *Int64 { + return &Int64{name: name, description: description} +} + +func (k *Int64) Name() string { return k.name } +func (k *Int64) Description() string { return k.description } + +func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendInt(buf, k.From(l), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Int64) Get(lm label.Map) int64 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) } + +// UInt represents a key +type UInt struct { + name string + description string +} + +// NewUInt creates a new Key for uint values. +func NewUInt(name, description string) *UInt { + return &UInt{name: name, description: description} +} + +func (k *UInt) Name() string { return k.name } +func (k *UInt) Description() string { return k.description } + +func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *UInt) Get(lm label.Map) uint { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) } + +// UInt8 represents a key +type UInt8 struct { + name string + description string +} + +// NewUInt8 creates a new Key for uint8 values. +func NewUInt8(name, description string) *UInt8 { + return &UInt8{name: name, description: description} +} + +func (k *UInt8) Name() string { return k.name } +func (k *UInt8) Description() string { return k.description } + +func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *UInt8) Get(lm label.Map) uint8 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) } + +// UInt16 represents a key +type UInt16 struct { + name string + description string +} + +// NewUInt16 creates a new Key for uint16 values. +func NewUInt16(name, description string) *UInt16 { + return &UInt16{name: name, description: description} +} + +func (k *UInt16) Name() string { return k.name } +func (k *UInt16) Description() string { return k.description } + +func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *UInt16) Get(lm label.Map) uint16 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) } + +// UInt32 represents a key +type UInt32 struct { + name string + description string +} + +// NewUInt32 creates a new Key for uint32 values. +func NewUInt32(name, description string) *UInt32 { + return &UInt32{name: name, description: description} +} + +func (k *UInt32) Name() string { return k.name } +func (k *UInt32) Description() string { return k.description } + +func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *UInt32) Get(lm label.Map) uint32 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) } + +// UInt64 represents a key +type UInt64 struct { + name string + description string +} + +// NewUInt64 creates a new Key for uint64 values. +func NewUInt64(name, description string) *UInt64 { + return &UInt64{name: name, description: description} +} + +func (k *UInt64) Name() string { return k.name } +func (k *UInt64) Description() string { return k.description } + +func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendUint(buf, k.From(l), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) } + +// Get can be used to get a label for the key from a label.Map. +func (k *UInt64) Get(lm label.Map) uint64 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() } + +// Float32 represents a key +type Float32 struct { + name string + description string +} + +// NewFloat32 creates a new Key for float32 values. +func NewFloat32(name, description string) *Float32 { + return &Float32{name: name, description: description} +} + +func (k *Float32) Name() string { return k.name } +func (k *Float32) Description() string { return k.description } + +func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Float32) Of(v float32) label.Label { + return label.Of64(k, uint64(math.Float32bits(v))) +} + +// Get can be used to get a label for the key from a label.Map. +func (k *Float32) Get(lm label.Map) float32 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Float32) From(t label.Label) float32 { + return math.Float32frombits(uint32(t.Unpack64())) +} + +// Float64 represents a key +type Float64 struct { + name string + description string +} + +// NewFloat64 creates a new Key for int64 values. +func NewFloat64(name, description string) *Float64 { + return &Float64{name: name, description: description} +} + +func (k *Float64) Name() string { return k.name } +func (k *Float64) Description() string { return k.description } + +func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Float64) Of(v float64) label.Label { + return label.Of64(k, math.Float64bits(v)) +} + +// Get can be used to get a label for the key from a label.Map. +func (k *Float64) Get(lm label.Map) float64 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Float64) From(t label.Label) float64 { + return math.Float64frombits(t.Unpack64()) +} + +// String represents a key +type String struct { + name string + description string +} + +// NewString creates a new Key for int64 values. +func NewString(name, description string) *String { + return &String{name: name, description: description} +} + +func (k *String) Name() string { return k.name } +func (k *String) Description() string { return k.description } + +func (k *String) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendQuote(buf, k.From(l))) +} + +// Of creates a new Label with this key and the supplied value. +func (k *String) Of(v string) label.Label { return label.OfString(k, v) } + +// Get can be used to get a label for the key from a label.Map. +func (k *String) Get(lm label.Map) string { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return "" +} + +// From can be used to get a value from a Label. +func (k *String) From(t label.Label) string { return t.UnpackString() } + +// Boolean represents a key +type Boolean struct { + name string + description string +} + +// NewBoolean creates a new Key for bool values. +func NewBoolean(name, description string) *Boolean { + return &Boolean{name: name, description: description} +} + +func (k *Boolean) Name() string { return k.name } +func (k *Boolean) Description() string { return k.description } + +func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendBool(buf, k.From(l))) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Boolean) Of(v bool) label.Label { + if v { + return label.Of64(k, 1) + } + return label.Of64(k, 0) +} + +// Get can be used to get a label for the key from a label.Map. +func (k *Boolean) Get(lm label.Map) bool { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return false +} + +// From can be used to get a value from a Label. +func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 } + +// Error represents a key +type Error struct { + name string + description string +} + +// NewError creates a new Key for int64 values. +func NewError(name, description string) *Error { + return &Error{name: name, description: description} +} + +func (k *Error) Name() string { return k.name } +func (k *Error) Description() string { return k.description } + +func (k *Error) Format(w io.Writer, buf []byte, l label.Label) { + io.WriteString(w, k.From(l).Error()) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Error) Get(lm label.Map) error { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return nil +} + +// From can be used to get a value from a Label. +func (k *Error) From(t label.Label) error { + err, _ := t.UnpackValue().(error) + return err +} diff --git a/vendor/golang.org/x/tools/internal/event/keys/standard.go b/vendor/golang.org/x/tools/internal/event/keys/standard.go new file mode 100644 index 00000000..7e958665 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/keys/standard.go @@ -0,0 +1,22 @@ +// 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 keys + +var ( + // Msg is a key used to add message strings to label lists. + Msg = NewString("message", "a readable message") + // Label is a key used to indicate an event adds labels to the context. + Label = NewTag("label", "a label context marker") + // Start is used for things like traces that have a name. + Start = NewString("start", "span start") + // Metric is a key used to indicate an event records metrics. + End = NewTag("end", "a span end marker") + // Metric is a key used to indicate an event records metrics. + Detach = NewTag("detach", "a span detach marker") + // Err is a key used to add error values to label lists. + Err = NewError("error", "an error that occurred") + // Metric is a key used to indicate an event records metrics. + Metric = NewTag("metric", "a metric event marker") +) diff --git a/vendor/golang.org/x/tools/internal/event/keys/util.go b/vendor/golang.org/x/tools/internal/event/keys/util.go new file mode 100644 index 00000000..c0e8e731 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/keys/util.go @@ -0,0 +1,21 @@ +// 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 keys + +import ( + "sort" + "strings" +) + +// Join returns a canonical join of the keys in S: +// a sorted comma-separated string list. +func Join[S ~[]T, T ~string](s S) string { + strs := make([]string, 0, len(s)) + for _, v := range s { + strs = append(strs, string(v)) + } + sort.Strings(strs) + return strings.Join(strs, ",") +} diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go new file mode 100644 index 00000000..0f526e1f --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/label/label.go @@ -0,0 +1,215 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package label + +import ( + "fmt" + "io" + "reflect" + "unsafe" +) + +// Key is used as the identity of a Label. +// Keys are intended to be compared by pointer only, the name should be unique +// for communicating with external systems, but it is not required or enforced. +type Key interface { + // Name returns the key name. + Name() string + // Description returns a string that can be used to describe the value. + Description() string + + // Format is used in formatting to append the value of the label to the + // supplied buffer. + // The formatter may use the supplied buf as a scratch area to avoid + // allocations. + Format(w io.Writer, buf []byte, l Label) +} + +// Label holds a key and value pair. +// It is normally used when passing around lists of labels. +type Label struct { + key Key + packed uint64 + untyped interface{} +} + +// Map is the interface to a collection of Labels indexed by key. +type Map interface { + // Find returns the label that matches the supplied key. + Find(key Key) Label +} + +// List is the interface to something that provides an iterable +// list of labels. +// Iteration should start from 0 and continue until Valid returns false. +type List interface { + // Valid returns true if the index is within range for the list. + // It does not imply the label at that index will itself be valid. + Valid(index int) bool + // Label returns the label at the given index. + Label(index int) Label +} + +// list implements LabelList for a list of Labels. +type list struct { + labels []Label +} + +// filter wraps a LabelList filtering out specific labels. +type filter struct { + keys []Key + underlying List +} + +// listMap implements LabelMap for a simple list of labels. +type listMap struct { + labels []Label +} + +// mapChain implements LabelMap for a list of underlying LabelMap. +type mapChain struct { + maps []Map +} + +// OfValue creates a new label from the key and value. +// This method is for implementing new key types, label creation should +// normally be done with the Of method of the key. +func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} } + +// UnpackValue assumes the label was built using LabelOfValue and returns the value +// that was passed to that constructor. +// This method is for implementing new key types, for type safety normal +// access should be done with the From method of the key. +func (t Label) UnpackValue() interface{} { return t.untyped } + +// Of64 creates a new label from a key and a uint64. This is often +// used for non uint64 values that can be packed into a uint64. +// This method is for implementing new key types, label creation should +// normally be done with the Of method of the key. +func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} } + +// Unpack64 assumes the label was built using LabelOf64 and returns the value that +// was passed to that constructor. +// This method is for implementing new key types, for type safety normal +// access should be done with the From method of the key. +func (t Label) Unpack64() uint64 { return t.packed } + +type stringptr unsafe.Pointer + +// OfString creates a new label from a key and a string. +// This method is for implementing new key types, label creation should +// normally be done with the Of method of the key. +func OfString(k Key, v string) Label { + hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) + return Label{ + key: k, + packed: uint64(hdr.Len), + untyped: stringptr(hdr.Data), + } +} + +// UnpackString assumes the label was built using LabelOfString and returns the +// value that was passed to that constructor. +// This method is for implementing new key types, for type safety normal +// access should be done with the From method of the key. +func (t Label) UnpackString() string { + var v string + hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) + hdr.Data = uintptr(t.untyped.(stringptr)) + hdr.Len = int(t.packed) + return v +} + +// Valid returns true if the Label is a valid one (it has a key). +func (t Label) Valid() bool { return t.key != nil } + +// Key returns the key of this Label. +func (t Label) Key() Key { return t.key } + +// Format is used for debug printing of labels. +func (t Label) Format(f fmt.State, r rune) { + if !t.Valid() { + io.WriteString(f, `nil`) + return + } + io.WriteString(f, t.Key().Name()) + io.WriteString(f, "=") + var buf [128]byte + t.Key().Format(f, buf[:0], t) +} + +func (l *list) Valid(index int) bool { + return index >= 0 && index < len(l.labels) +} + +func (l *list) Label(index int) Label { + return l.labels[index] +} + +func (f *filter) Valid(index int) bool { + return f.underlying.Valid(index) +} + +func (f *filter) Label(index int) Label { + l := f.underlying.Label(index) + for _, f := range f.keys { + if l.Key() == f { + return Label{} + } + } + return l +} + +func (lm listMap) Find(key Key) Label { + for _, l := range lm.labels { + if l.Key() == key { + return l + } + } + return Label{} +} + +func (c mapChain) Find(key Key) Label { + for _, src := range c.maps { + l := src.Find(key) + if l.Valid() { + return l + } + } + return Label{} +} + +var emptyList = &list{} + +func NewList(labels ...Label) List { + if len(labels) == 0 { + return emptyList + } + return &list{labels: labels} +} + +func Filter(l List, keys ...Key) List { + if len(keys) == 0 { + return l + } + return &filter{keys: keys, underlying: l} +} + +func NewMap(labels ...Label) Map { + return listMap{labels: labels} +} + +func MergeMaps(srcs ...Map) Map { + var nonNil []Map + for _, src := range srcs { + if src != nil { + nonNil = append(nonNil, src) + } + } + if len(nonNil) == 1 { + return nonNil[0] + } + return mapChain{maps: nonNil} +} diff --git a/vendor/golang.org/x/tools/internal/event/tag/tag.go b/vendor/golang.org/x/tools/internal/event/tag/tag.go new file mode 100644 index 00000000..581b26c2 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/tag/tag.go @@ -0,0 +1,59 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package tag provides the labels used for telemetry throughout gopls. +package tag + +import ( + "golang.org/x/tools/internal/event/keys" +) + +var ( + // create the label keys we use + Method = keys.NewString("method", "") + StatusCode = keys.NewString("status.code", "") + StatusMessage = keys.NewString("status.message", "") + RPCID = keys.NewString("id", "") + RPCDirection = keys.NewString("direction", "") + File = keys.NewString("file", "") + Directory = keys.New("directory", "") + URI = keys.New("URI", "") + Package = keys.NewString("package", "") // sorted comma-separated list of Package IDs + PackagePath = keys.NewString("package_path", "") + Query = keys.New("query", "") + Snapshot = keys.NewUInt64("snapshot", "") + Operation = keys.NewString("operation", "") + + Position = keys.New("position", "") + Category = keys.NewString("category", "") + PackageCount = keys.NewInt("packages", "") + Files = keys.New("files", "") + Port = keys.NewInt("port", "") + Type = keys.New("type", "") + HoverKind = keys.NewString("hoverkind", "") + + NewServer = keys.NewString("new_server", "A new server was added") + EndServer = keys.NewString("end_server", "A server was shut down") + + ServerID = keys.NewString("server", "The server ID an event is related to") + Logfile = keys.NewString("logfile", "") + DebugAddress = keys.NewString("debug_address", "") + GoplsPath = keys.NewString("gopls_path", "") + ClientID = keys.NewString("client_id", "") + + Level = keys.NewInt("level", "The logging level") +) + +var ( + // create the stats we measure + Started = keys.NewInt64("started", "Count of started RPCs.") + ReceivedBytes = keys.NewInt64("received_bytes", "Bytes received.") //, unit.Bytes) + SentBytes = keys.NewInt64("sent_bytes", "Bytes sent.") //, unit.Bytes) + Latency = keys.NewFloat64("latency_ms", "Elapsed time in milliseconds") //, unit.Milliseconds) +) + +const ( + Inbound = "in" + Outbound = "out" +) diff --git a/vendor/golang.org/x/tools/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/internal/gcimporter/bimport.go new file mode 100644 index 00000000..d98b0db2 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/bimport.go @@ -0,0 +1,150 @@ +// Copyright 2015 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 contains the remaining vestiges of +// $GOROOT/src/go/internal/gcimporter/bimport.go. + +package gcimporter + +import ( + "fmt" + "go/token" + "go/types" + "sync" +) + +func errorf(format string, args ...interface{}) { + panic(fmt.Sprintf(format, args...)) +} + +const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go + +// Synthesize a token.Pos +type fakeFileSet struct { + fset *token.FileSet + files map[string]*fileInfo +} + +type fileInfo struct { + file *token.File + lastline int +} + +const maxlines = 64 * 1024 + +func (s *fakeFileSet) pos(file string, line, column int) token.Pos { + // TODO(mdempsky): Make use of column. + + // Since we don't know the set of needed file positions, we reserve maxlines + // positions per file. We delay calling token.File.SetLines until all + // positions have been calculated (by way of fakeFileSet.setLines), so that + // we can avoid setting unnecessary lines. See also golang/go#46586. + f := s.files[file] + if f == nil { + f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)} + s.files[file] = f + } + if line > maxlines { + line = 1 + } + if line > f.lastline { + f.lastline = line + } + + // Return a fake position assuming that f.file consists only of newlines. + return token.Pos(f.file.Base() + line - 1) +} + +func (s *fakeFileSet) setLines() { + fakeLinesOnce.Do(func() { + fakeLines = make([]int, maxlines) + for i := range fakeLines { + fakeLines[i] = i + } + }) + for _, f := range s.files { + f.file.SetLines(fakeLines[:f.lastline]) + } +} + +var ( + fakeLines []int + fakeLinesOnce sync.Once +) + +func chanDir(d int) types.ChanDir { + // tag values must match the constants in cmd/compile/internal/gc/go.go + switch d { + case 1 /* Crecv */ : + return types.RecvOnly + case 2 /* Csend */ : + return types.SendOnly + case 3 /* Cboth */ : + return types.SendRecv + default: + errorf("unexpected channel dir %d", d) + return 0 + } +} + +var predeclOnce sync.Once +var predecl []types.Type // initialized lazily + +func predeclared() []types.Type { + predeclOnce.Do(func() { + // initialize lazily to be sure that all + // elements have been initialized before + predecl = []types.Type{ // basic types + types.Typ[types.Bool], + types.Typ[types.Int], + types.Typ[types.Int8], + types.Typ[types.Int16], + types.Typ[types.Int32], + types.Typ[types.Int64], + types.Typ[types.Uint], + types.Typ[types.Uint8], + types.Typ[types.Uint16], + types.Typ[types.Uint32], + types.Typ[types.Uint64], + types.Typ[types.Uintptr], + types.Typ[types.Float32], + types.Typ[types.Float64], + types.Typ[types.Complex64], + types.Typ[types.Complex128], + types.Typ[types.String], + + // basic type aliases + types.Universe.Lookup("byte").Type(), + types.Universe.Lookup("rune").Type(), + + // error + types.Universe.Lookup("error").Type(), + + // untyped types + types.Typ[types.UntypedBool], + types.Typ[types.UntypedInt], + types.Typ[types.UntypedRune], + types.Typ[types.UntypedFloat], + types.Typ[types.UntypedComplex], + types.Typ[types.UntypedString], + types.Typ[types.UntypedNil], + + // package unsafe + types.Typ[types.UnsafePointer], + + // invalid type + types.Typ[types.Invalid], // only appears in packages with errors + + // used internally by gc; never used by this package or in .a files + anyType{}, + } + predecl = append(predecl, additionalPredeclared()...) + }) + return predecl +} + +type anyType struct{} + +func (t anyType) Underlying() types.Type { return t } +func (t anyType) String() string { return "any" } diff --git a/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go new file mode 100644 index 00000000..f6437feb --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go @@ -0,0 +1,99 @@ +// Copyright 2011 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 is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go. + +// This file implements FindExportData. + +package gcimporter + +import ( + "bufio" + "fmt" + "io" + "strconv" + "strings" +) + +func readGopackHeader(r *bufio.Reader) (name string, size int64, err error) { + // See $GOROOT/include/ar.h. + hdr := make([]byte, 16+12+6+6+8+10+2) + _, err = io.ReadFull(r, hdr) + if err != nil { + return + } + // leave for debugging + if false { + fmt.Printf("header: %s", hdr) + } + s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) + length, err := strconv.Atoi(s) + size = int64(length) + if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { + err = fmt.Errorf("invalid archive header") + return + } + name = strings.TrimSpace(string(hdr[:16])) + return +} + +// FindExportData positions the reader r at the beginning of the +// export data section of an underlying GC-created object/archive +// file by reading from it. The reader must be positioned at the +// start of the file before calling this function. The hdr result +// is the string before the export data, either "$$" or "$$B". +// The size result is the length of the export data in bytes, or -1 if not known. +func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) { + // Read first line to make sure this is an object file. + line, err := r.ReadSlice('\n') + if err != nil { + err = fmt.Errorf("can't find export data (%v)", err) + return + } + + if string(line) == "!\n" { + // Archive file. Scan to __.PKGDEF. + var name string + if name, size, err = readGopackHeader(r); err != nil { + return + } + + // First entry should be __.PKGDEF. + if name != "__.PKGDEF" { + err = fmt.Errorf("go archive is missing __.PKGDEF") + return + } + + // Read first line of __.PKGDEF data, so that line + // is once again the first line of the input. + if line, err = r.ReadSlice('\n'); err != nil { + err = fmt.Errorf("can't find export data (%v)", err) + return + } + size -= int64(len(line)) + } + + // Now at __.PKGDEF in archive or still at beginning of file. + // Either way, line should begin with "go object ". + if !strings.HasPrefix(string(line), "go object ") { + err = fmt.Errorf("not a Go object file") + return + } + + // Skip over object header to export data. + // Begins after first line starting with $$. + for line[0] != '$' { + if line, err = r.ReadSlice('\n'); err != nil { + err = fmt.Errorf("can't find export data (%v)", err) + return + } + size -= int64(len(line)) + } + hdr = string(line) + if size < 0 { + size = -1 + } + + return +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go new file mode 100644 index 00000000..39df9112 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go @@ -0,0 +1,266 @@ +// Copyright 2011 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 is a reduced copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go. + +// Package gcimporter provides various functions for reading +// gc-generated object files that can be used to implement the +// Importer interface defined by the Go 1.5 standard library package. +// +// The encoding is deterministic: if the encoder is applied twice to +// the same types.Package data structure, both encodings are equal. +// This property may be important to avoid spurious changes in +// applications such as build systems. +// +// However, the encoder is not necessarily idempotent. Importing an +// exported package may yield a types.Package that, while it +// represents the same set of Go types as the original, may differ in +// the details of its internal representation. Because of these +// differences, re-encoding the imported package may yield a +// different, but equally valid, encoding of the package. +package gcimporter // import "golang.org/x/tools/internal/gcimporter" + +import ( + "bufio" + "bytes" + "fmt" + "go/build" + "go/token" + "go/types" + "io" + "os" + "os/exec" + "path/filepath" + "strings" + "sync" +) + +const ( + // Enable debug during development: it adds some additional checks, and + // prevents errors from being recovered. + debug = false + + // If trace is set, debugging output is printed to std out. + trace = false +) + +var exportMap sync.Map // package dir → func() (string, bool) + +// lookupGorootExport returns the location of the export data +// (normally found in the build cache, but located in GOROOT/pkg +// in prior Go releases) for the package located in pkgDir. +// +// (We use the package's directory instead of its import path +// mainly to simplify handling of the packages in src/vendor +// and cmd/vendor.) +func lookupGorootExport(pkgDir string) (string, bool) { + f, ok := exportMap.Load(pkgDir) + if !ok { + var ( + listOnce sync.Once + exportPath string + ) + f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) { + listOnce.Do(func() { + cmd := exec.Command("go", "list", "-export", "-f", "{{.Export}}", pkgDir) + cmd.Dir = build.Default.GOROOT + var output []byte + output, err := cmd.Output() + if err != nil { + return + } + + exports := strings.Split(string(bytes.TrimSpace(output)), "\n") + if len(exports) != 1 { + return + } + + exportPath = exports[0] + }) + + return exportPath, exportPath != "" + }) + } + + return f.(func() (string, bool))() +} + +var pkgExts = [...]string{".a", ".o"} + +// FindPkg returns the filename and unique package id for an import +// path based on package information provided by build.Import (using +// the build.Default build.Context). A relative srcDir is interpreted +// relative to the current working directory. +// If no file was found, an empty filename is returned. +func FindPkg(path, srcDir string) (filename, id string) { + if path == "" { + return + } + + var noext string + switch { + default: + // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" + // Don't require the source files to be present. + if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282 + srcDir = abs + } + bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary) + if bp.PkgObj == "" { + var ok bool + if bp.Goroot && bp.Dir != "" { + filename, ok = lookupGorootExport(bp.Dir) + } + if !ok { + id = path // make sure we have an id to print in error message + return + } + } else { + noext = strings.TrimSuffix(bp.PkgObj, ".a") + id = bp.ImportPath + } + + case build.IsLocalImport(path): + // "./x" -> "/this/directory/x.ext", "/this/directory/x" + noext = filepath.Join(srcDir, path) + id = noext + + case filepath.IsAbs(path): + // for completeness only - go/build.Import + // does not support absolute imports + // "/x" -> "/x.ext", "/x" + noext = path + id = path + } + + if false { // for debugging + if path != id { + fmt.Printf("%s -> %s\n", path, id) + } + } + + if filename != "" { + if f, err := os.Stat(filename); err == nil && !f.IsDir() { + return + } + } + + // try extensions + for _, ext := range pkgExts { + filename = noext + ext + if f, err := os.Stat(filename); err == nil && !f.IsDir() { + return + } + } + + filename = "" // not found + return +} + +// Import imports a gc-generated package given its import path and srcDir, adds +// the corresponding package object to the packages map, and returns the object. +// The packages map must contain all packages already imported. +func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) { + var rc io.ReadCloser + var filename, id string + if lookup != nil { + // With custom lookup specified, assume that caller has + // converted path to a canonical import path for use in the map. + if path == "unsafe" { + return types.Unsafe, nil + } + id = path + + // No need to re-import if the package was imported completely before. + if pkg = packages[id]; pkg != nil && pkg.Complete() { + return + } + f, err := lookup(path) + if err != nil { + return nil, err + } + rc = f + } else { + filename, id = FindPkg(path, srcDir) + if filename == "" { + if path == "unsafe" { + return types.Unsafe, nil + } + return nil, fmt.Errorf("can't find import: %q", id) + } + + // no need to re-import if the package was imported completely before + if pkg = packages[id]; pkg != nil && pkg.Complete() { + return + } + + // open file + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer func() { + if err != nil { + // add file name to error + err = fmt.Errorf("%s: %v", filename, err) + } + }() + rc = f + } + defer rc.Close() + + var hdr string + var size int64 + buf := bufio.NewReader(rc) + if hdr, size, err = FindExportData(buf); err != nil { + return + } + + switch hdr { + case "$$B\n": + var data []byte + data, err = io.ReadAll(buf) + if err != nil { + break + } + + // TODO(gri): allow clients of go/importer to provide a FileSet. + // Or, define a new standard go/types/gcexportdata package. + fset := token.NewFileSet() + + // Select appropriate importer. + if len(data) > 0 { + switch data[0] { + case 'v', 'c', 'd': // binary, till go1.10 + return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0]) + + case 'i': // indexed, till go1.19 + _, pkg, err := IImportData(fset, packages, data[1:], id) + return pkg, err + + case 'u': // unified, from go1.20 + _, pkg, err := UImportData(fset, packages, data[1:size], id) + return pkg, err + + default: + l := len(data) + if l > 10 { + l = 10 + } + return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), id) + } + } + + default: + err = fmt.Errorf("unknown export data header: %q", hdr) + } + + return +} + +type byPath []*types.Package + +func (a byPath) Len() int { return len(a) } +func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() } diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go new file mode 100644 index 00000000..683bd739 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go @@ -0,0 +1,1349 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Indexed binary package export. +// This file was derived from $GOROOT/src/cmd/compile/internal/gc/iexport.go; +// see that file for specification of the format. + +package gcimporter + +import ( + "bytes" + "encoding/binary" + "fmt" + "go/constant" + "go/token" + "go/types" + "io" + "math/big" + "reflect" + "sort" + "strconv" + "strings" + "unsafe" + + "golang.org/x/tools/go/types/objectpath" + "golang.org/x/tools/internal/aliases" + "golang.org/x/tools/internal/tokeninternal" +) + +// IExportShallow encodes "shallow" export data for the specified package. +// +// No promises are made about the encoding other than that it can be decoded by +// the same version of IIExportShallow. If you plan to save export data in the +// file system, be sure to include a cryptographic digest of the executable in +// the key to avoid version skew. +// +// If the provided reportf func is non-nil, it will be used for reporting bugs +// encountered during export. +// TODO(rfindley): remove reportf when we are confident enough in the new +// objectpath encoding. +func IExportShallow(fset *token.FileSet, pkg *types.Package, reportf ReportFunc) ([]byte, error) { + // In principle this operation can only fail if out.Write fails, + // but that's impossible for bytes.Buffer---and as a matter of + // fact iexportCommon doesn't even check for I/O errors. + // TODO(adonovan): handle I/O errors properly. + // TODO(adonovan): use byte slices throughout, avoiding copying. + const bundle, shallow = false, true + var out bytes.Buffer + err := iexportCommon(&out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}) + return out.Bytes(), err +} + +// IImportShallow decodes "shallow" types.Package data encoded by +// IExportShallow in the same executable. This function cannot import data from +// cmd/compile or gcexportdata.Write. +// +// The importer calls getPackages to obtain package symbols for all +// packages mentioned in the export data, including the one being +// decoded. +// +// If the provided reportf func is non-nil, it will be used for reporting bugs +// encountered during import. +// TODO(rfindley): remove reportf when we are confident enough in the new +// objectpath encoding. +func IImportShallow(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, path string, reportf ReportFunc) (*types.Package, error) { + const bundle = false + const shallow = true + pkgs, err := iimportCommon(fset, getPackages, data, bundle, path, shallow, reportf) + if err != nil { + return nil, err + } + return pkgs[0], nil +} + +// ReportFunc is the type of a function used to report formatted bugs. +type ReportFunc = func(string, ...interface{}) + +// Current bundled export format version. Increase with each format change. +// 0: initial implementation +const bundleVersion = 0 + +// IExportData writes indexed export data for pkg to out. +// +// If no file set is provided, position info will be missing. +// The package path of the top-level package will not be recorded, +// so that calls to IImportData can override with a provided package path. +func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error { + const bundle, shallow = false, false + return iexportCommon(out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}) +} + +// IExportBundle writes an indexed export bundle for pkgs to out. +func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error { + const bundle, shallow = true, false + return iexportCommon(out, fset, bundle, shallow, iexportVersion, pkgs) +} + +func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, version int, pkgs []*types.Package) (err error) { + if !debug { + defer func() { + if e := recover(); e != nil { + if ierr, ok := e.(internalError); ok { + err = ierr + return + } + // Not an internal error; panic again. + panic(e) + } + }() + } + + p := iexporter{ + fset: fset, + version: version, + shallow: shallow, + allPkgs: map[*types.Package]bool{}, + stringIndex: map[string]uint64{}, + declIndex: map[types.Object]uint64{}, + tparamNames: map[types.Object]string{}, + typIndex: map[types.Type]uint64{}, + } + if !bundle { + p.localpkg = pkgs[0] + } + + for i, pt := range predeclared() { + p.typIndex[pt] = uint64(i) + } + if len(p.typIndex) > predeclReserved { + panic(internalErrorf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)) + } + + // Initialize work queue with exported declarations. + for _, pkg := range pkgs { + scope := pkg.Scope() + for _, name := range scope.Names() { + if token.IsExported(name) { + p.pushDecl(scope.Lookup(name)) + } + } + + if bundle { + // Ensure pkg and its imports are included in the index. + p.allPkgs[pkg] = true + for _, imp := range pkg.Imports() { + p.allPkgs[imp] = true + } + } + } + + // Loop until no more work. + for !p.declTodo.empty() { + p.doDecl(p.declTodo.popHead()) + } + + // Produce index of offset of each file record in files. + var files intWriter + var fileOffset []uint64 // fileOffset[i] is offset in files of file encoded as i + if p.shallow { + fileOffset = make([]uint64, len(p.fileInfos)) + for i, info := range p.fileInfos { + fileOffset[i] = uint64(files.Len()) + p.encodeFile(&files, info.file, info.needed) + } + } + + // Append indices to data0 section. + dataLen := uint64(p.data0.Len()) + w := p.newWriter() + w.writeIndex(p.declIndex) + + if bundle { + w.uint64(uint64(len(pkgs))) + for _, pkg := range pkgs { + w.pkg(pkg) + imps := pkg.Imports() + w.uint64(uint64(len(imps))) + for _, imp := range imps { + w.pkg(imp) + } + } + } + w.flush() + + // Assemble header. + var hdr intWriter + if bundle { + hdr.uint64(bundleVersion) + } + hdr.uint64(uint64(p.version)) + hdr.uint64(uint64(p.strings.Len())) + if p.shallow { + hdr.uint64(uint64(files.Len())) + hdr.uint64(uint64(len(fileOffset))) + for _, offset := range fileOffset { + hdr.uint64(offset) + } + } + hdr.uint64(dataLen) + + // Flush output. + io.Copy(out, &hdr) + io.Copy(out, &p.strings) + if p.shallow { + io.Copy(out, &files) + } + io.Copy(out, &p.data0) + + return nil +} + +// encodeFile writes to w a representation of the file sufficient to +// faithfully restore position information about all needed offsets. +// Mutates the needed array. +func (p *iexporter) encodeFile(w *intWriter, file *token.File, needed []uint64) { + _ = needed[0] // precondition: needed is non-empty + + w.uint64(p.stringOff(file.Name())) + + size := uint64(file.Size()) + w.uint64(size) + + // Sort the set of needed offsets. Duplicates are harmless. + sort.Slice(needed, func(i, j int) bool { return needed[i] < needed[j] }) + + lines := tokeninternal.GetLines(file) // byte offset of each line start + w.uint64(uint64(len(lines))) + + // Rather than record the entire array of line start offsets, + // we save only a sparse list of (index, offset) pairs for + // the start of each line that contains a needed position. + var sparse [][2]int // (index, offset) pairs +outer: + for i, lineStart := range lines { + lineEnd := size + if i < len(lines)-1 { + lineEnd = uint64(lines[i+1]) + } + // Does this line contains a needed offset? + if needed[0] < lineEnd { + sparse = append(sparse, [2]int{i, lineStart}) + for needed[0] < lineEnd { + needed = needed[1:] + if len(needed) == 0 { + break outer + } + } + } + } + + // Delta-encode the columns. + w.uint64(uint64(len(sparse))) + var prev [2]int + for _, pair := range sparse { + w.uint64(uint64(pair[0] - prev[0])) + w.uint64(uint64(pair[1] - prev[1])) + prev = pair + } +} + +// writeIndex writes out an object index. mainIndex indicates whether +// we're writing out the main index, which is also read by +// non-compiler tools and includes a complete package description +// (i.e., name and height). +func (w *exportWriter) writeIndex(index map[types.Object]uint64) { + type pkgObj struct { + obj types.Object + name string // qualified name; differs from obj.Name for type params + } + // Build a map from packages to objects from that package. + pkgObjs := map[*types.Package][]pkgObj{} + + // For the main index, make sure to include every package that + // we reference, even if we're not exporting (or reexporting) + // any symbols from it. + if w.p.localpkg != nil { + pkgObjs[w.p.localpkg] = nil + } + for pkg := range w.p.allPkgs { + pkgObjs[pkg] = nil + } + + for obj := range index { + name := w.p.exportName(obj) + pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name}) + } + + var pkgs []*types.Package + for pkg, objs := range pkgObjs { + pkgs = append(pkgs, pkg) + + sort.Slice(objs, func(i, j int) bool { + return objs[i].name < objs[j].name + }) + } + + sort.Slice(pkgs, func(i, j int) bool { + return w.exportPath(pkgs[i]) < w.exportPath(pkgs[j]) + }) + + w.uint64(uint64(len(pkgs))) + for _, pkg := range pkgs { + w.string(w.exportPath(pkg)) + w.string(pkg.Name()) + w.uint64(uint64(0)) // package height is not needed for go/types + + objs := pkgObjs[pkg] + w.uint64(uint64(len(objs))) + for _, obj := range objs { + w.string(obj.name) + w.uint64(index[obj.obj]) + } + } +} + +// exportName returns the 'exported' name of an object. It differs from +// obj.Name() only for type parameters (see tparamExportName for details). +func (p *iexporter) exportName(obj types.Object) (res string) { + if name := p.tparamNames[obj]; name != "" { + return name + } + return obj.Name() +} + +type iexporter struct { + fset *token.FileSet + out *bytes.Buffer + version int + + shallow bool // don't put types from other packages in the index + objEncoder *objectpath.Encoder // encodes objects from other packages in shallow mode; lazily allocated + localpkg *types.Package // (nil in bundle mode) + + // allPkgs tracks all packages that have been referenced by + // the export data, so we can ensure to include them in the + // main index. + allPkgs map[*types.Package]bool + + declTodo objQueue + + strings intWriter + stringIndex map[string]uint64 + + // In shallow mode, object positions are encoded as (file, offset). + // Each file is recorded as a line-number table. + // Only the lines of needed positions are saved faithfully. + fileInfo map[*token.File]uint64 // value is index in fileInfos + fileInfos []*filePositions + + data0 intWriter + declIndex map[types.Object]uint64 + tparamNames map[types.Object]string // typeparam->exported name + typIndex map[types.Type]uint64 + + indent int // for tracing support +} + +type filePositions struct { + file *token.File + needed []uint64 // unordered list of needed file offsets +} + +func (p *iexporter) trace(format string, args ...interface{}) { + if !trace { + // Call sites should also be guarded, but having this check here allows + // easily enabling/disabling debug trace statements. + return + } + fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) +} + +// objectpathEncoder returns the lazily allocated objectpath.Encoder to use +// when encoding objects in other packages during shallow export. +// +// Using a shared Encoder amortizes some of cost of objectpath search. +func (p *iexporter) objectpathEncoder() *objectpath.Encoder { + if p.objEncoder == nil { + p.objEncoder = new(objectpath.Encoder) + } + return p.objEncoder +} + +// stringOff returns the offset of s within the string section. +// If not already present, it's added to the end. +func (p *iexporter) stringOff(s string) uint64 { + off, ok := p.stringIndex[s] + if !ok { + off = uint64(p.strings.Len()) + p.stringIndex[s] = off + + p.strings.uint64(uint64(len(s))) + p.strings.WriteString(s) + } + return off +} + +// fileIndexAndOffset returns the index of the token.File and the byte offset of pos within it. +func (p *iexporter) fileIndexAndOffset(file *token.File, pos token.Pos) (uint64, uint64) { + index, ok := p.fileInfo[file] + if !ok { + index = uint64(len(p.fileInfo)) + p.fileInfos = append(p.fileInfos, &filePositions{file: file}) + if p.fileInfo == nil { + p.fileInfo = make(map[*token.File]uint64) + } + p.fileInfo[file] = index + } + // Record each needed offset. + info := p.fileInfos[index] + offset := uint64(file.Offset(pos)) + info.needed = append(info.needed, offset) + + return index, offset +} + +// pushDecl adds n to the declaration work queue, if not already present. +func (p *iexporter) pushDecl(obj types.Object) { + // Package unsafe is known to the compiler and predeclared. + // Caller should not ask us to do export it. + if obj.Pkg() == types.Unsafe { + panic("cannot export package unsafe") + } + + // Shallow export data: don't index decls from other packages. + if p.shallow && obj.Pkg() != p.localpkg { + return + } + + if _, ok := p.declIndex[obj]; ok { + return + } + + p.declIndex[obj] = ^uint64(0) // mark obj present in work queue + p.declTodo.pushTail(obj) +} + +// exportWriter handles writing out individual data section chunks. +type exportWriter struct { + p *iexporter + + data intWriter + prevFile string + prevLine int64 + prevColumn int64 +} + +func (w *exportWriter) exportPath(pkg *types.Package) string { + if pkg == w.p.localpkg { + return "" + } + return pkg.Path() +} + +func (p *iexporter) doDecl(obj types.Object) { + if trace { + p.trace("exporting decl %v (%T)", obj, obj) + p.indent++ + defer func() { + p.indent-- + p.trace("=> %s", obj) + }() + } + w := p.newWriter() + + switch obj := obj.(type) { + case *types.Var: + w.tag(varTag) + w.pos(obj.Pos()) + w.typ(obj.Type(), obj.Pkg()) + + case *types.Func: + sig, _ := obj.Type().(*types.Signature) + if sig.Recv() != nil { + // We shouldn't see methods in the package scope, + // but the type checker may repair "func () F() {}" + // to "func (Invalid) F()" and then treat it like "func F()", + // so allow that. See golang/go#57729. + if sig.Recv().Type() != types.Typ[types.Invalid] { + panic(internalErrorf("unexpected method: %v", sig)) + } + } + + // Function. + if sig.TypeParams().Len() == 0 { + w.tag(funcTag) + } else { + w.tag(genericFuncTag) + } + w.pos(obj.Pos()) + // The tparam list of the function type is the declaration of the type + // params. So, write out the type params right now. Then those type params + // will be referenced via their type offset (via typOff) in all other + // places in the signature and function where they are used. + // + // While importing the type parameters, tparamList computes and records + // their export name, so that it can be later used when writing the index. + if tparams := sig.TypeParams(); tparams.Len() > 0 { + w.tparamList(obj.Name(), tparams, obj.Pkg()) + } + w.signature(sig) + + case *types.Const: + w.tag(constTag) + w.pos(obj.Pos()) + w.value(obj.Type(), obj.Val()) + + case *types.TypeName: + t := obj.Type() + + if tparam, ok := aliases.Unalias(t).(*types.TypeParam); ok { + w.tag(typeParamTag) + w.pos(obj.Pos()) + constraint := tparam.Constraint() + if p.version >= iexportVersionGo1_18 { + implicit := false + if iface, _ := aliases.Unalias(constraint).(*types.Interface); iface != nil { + implicit = iface.IsImplicit() + } + w.bool(implicit) + } + w.typ(constraint, obj.Pkg()) + break + } + + if obj.IsAlias() { + w.tag(aliasTag) + w.pos(obj.Pos()) + if alias, ok := t.(*aliases.Alias); ok { + // Preserve materialized aliases, + // even of non-exported types. + t = aliasRHS(alias) + } + w.typ(t, obj.Pkg()) + break + } + + // Defined type. + named, ok := t.(*types.Named) + if !ok { + panic(internalErrorf("%s is not a defined type", t)) + } + + if named.TypeParams().Len() == 0 { + w.tag(typeTag) + } else { + w.tag(genericTypeTag) + } + w.pos(obj.Pos()) + + if named.TypeParams().Len() > 0 { + // While importing the type parameters, tparamList computes and records + // their export name, so that it can be later used when writing the index. + w.tparamList(obj.Name(), named.TypeParams(), obj.Pkg()) + } + + underlying := named.Underlying() + w.typ(underlying, obj.Pkg()) + + if types.IsInterface(t) { + break + } + + n := named.NumMethods() + w.uint64(uint64(n)) + for i := 0; i < n; i++ { + m := named.Method(i) + w.pos(m.Pos()) + w.string(m.Name()) + sig, _ := m.Type().(*types.Signature) + + // Receiver type parameters are type arguments of the receiver type, so + // their name must be qualified before exporting recv. + if rparams := sig.RecvTypeParams(); rparams.Len() > 0 { + prefix := obj.Name() + "." + m.Name() + for i := 0; i < rparams.Len(); i++ { + rparam := rparams.At(i) + name := tparamExportName(prefix, rparam) + w.p.tparamNames[rparam.Obj()] = name + } + } + w.param(sig.Recv()) + w.signature(sig) + } + + default: + panic(internalErrorf("unexpected object: %v", obj)) + } + + p.declIndex[obj] = w.flush() +} + +func (w *exportWriter) tag(tag byte) { + w.data.WriteByte(tag) +} + +func (w *exportWriter) pos(pos token.Pos) { + if w.p.shallow { + w.posV2(pos) + } else if w.p.version >= iexportVersionPosCol { + w.posV1(pos) + } else { + w.posV0(pos) + } +} + +// posV2 encoding (used only in shallow mode) records positions as +// (file, offset), where file is the index in the token.File table +// (which records the file name and newline offsets) and offset is a +// byte offset. It effectively ignores //line directives. +func (w *exportWriter) posV2(pos token.Pos) { + if pos == token.NoPos { + w.uint64(0) + return + } + file := w.p.fset.File(pos) // fset must be non-nil + index, offset := w.p.fileIndexAndOffset(file, pos) + w.uint64(1 + index) + w.uint64(offset) +} + +func (w *exportWriter) posV1(pos token.Pos) { + if w.p.fset == nil { + w.int64(0) + return + } + + p := w.p.fset.Position(pos) + file := p.Filename + line := int64(p.Line) + column := int64(p.Column) + + deltaColumn := (column - w.prevColumn) << 1 + deltaLine := (line - w.prevLine) << 1 + + if file != w.prevFile { + deltaLine |= 1 + } + if deltaLine != 0 { + deltaColumn |= 1 + } + + w.int64(deltaColumn) + if deltaColumn&1 != 0 { + w.int64(deltaLine) + if deltaLine&1 != 0 { + w.string(file) + } + } + + w.prevFile = file + w.prevLine = line + w.prevColumn = column +} + +func (w *exportWriter) posV0(pos token.Pos) { + if w.p.fset == nil { + w.int64(0) + return + } + + p := w.p.fset.Position(pos) + file := p.Filename + line := int64(p.Line) + + // When file is the same as the last position (common case), + // we can save a few bytes by delta encoding just the line + // number. + // + // Note: Because data objects may be read out of order (or not + // at all), we can only apply delta encoding within a single + // object. This is handled implicitly by tracking prevFile and + // prevLine as fields of exportWriter. + + if file == w.prevFile { + delta := line - w.prevLine + w.int64(delta) + if delta == deltaNewFile { + w.int64(-1) + } + } else { + w.int64(deltaNewFile) + w.int64(line) // line >= 0 + w.string(file) + w.prevFile = file + } + w.prevLine = line +} + +func (w *exportWriter) pkg(pkg *types.Package) { + // Ensure any referenced packages are declared in the main index. + w.p.allPkgs[pkg] = true + + w.string(w.exportPath(pkg)) +} + +func (w *exportWriter) qualifiedType(obj *types.TypeName) { + name := w.p.exportName(obj) + + // Ensure any referenced declarations are written out too. + w.p.pushDecl(obj) + w.string(name) + w.pkg(obj.Pkg()) +} + +// TODO(rfindley): what does 'pkg' even mean here? It would be better to pass +// it in explicitly into signatures and structs that may use it for +// constructing fields. +func (w *exportWriter) typ(t types.Type, pkg *types.Package) { + w.data.uint64(w.p.typOff(t, pkg)) +} + +func (p *iexporter) newWriter() *exportWriter { + return &exportWriter{p: p} +} + +func (w *exportWriter) flush() uint64 { + off := uint64(w.p.data0.Len()) + io.Copy(&w.p.data0, &w.data) + return off +} + +func (p *iexporter) typOff(t types.Type, pkg *types.Package) uint64 { + off, ok := p.typIndex[t] + if !ok { + w := p.newWriter() + w.doTyp(t, pkg) + off = predeclReserved + w.flush() + p.typIndex[t] = off + } + return off +} + +func (w *exportWriter) startType(k itag) { + w.data.uint64(uint64(k)) +} + +func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { + if trace { + w.p.trace("exporting type %s (%T)", t, t) + w.p.indent++ + defer func() { + w.p.indent-- + w.p.trace("=> %s", t) + }() + } + switch t := t.(type) { + case *aliases.Alias: + // TODO(adonovan): support parameterized aliases, following *types.Named. + w.startType(aliasType) + w.qualifiedType(t.Obj()) + + case *types.Named: + if targs := t.TypeArgs(); targs.Len() > 0 { + w.startType(instanceType) + // TODO(rfindley): investigate if this position is correct, and if it + // matters. + w.pos(t.Obj().Pos()) + w.typeList(targs, pkg) + w.typ(t.Origin(), pkg) + return + } + w.startType(definedType) + w.qualifiedType(t.Obj()) + + case *types.TypeParam: + w.startType(typeParamType) + w.qualifiedType(t.Obj()) + + case *types.Pointer: + w.startType(pointerType) + w.typ(t.Elem(), pkg) + + case *types.Slice: + w.startType(sliceType) + w.typ(t.Elem(), pkg) + + case *types.Array: + w.startType(arrayType) + w.uint64(uint64(t.Len())) + w.typ(t.Elem(), pkg) + + case *types.Chan: + w.startType(chanType) + // 1 RecvOnly; 2 SendOnly; 3 SendRecv + var dir uint64 + switch t.Dir() { + case types.RecvOnly: + dir = 1 + case types.SendOnly: + dir = 2 + case types.SendRecv: + dir = 3 + } + w.uint64(dir) + w.typ(t.Elem(), pkg) + + case *types.Map: + w.startType(mapType) + w.typ(t.Key(), pkg) + w.typ(t.Elem(), pkg) + + case *types.Signature: + w.startType(signatureType) + w.pkg(pkg) + w.signature(t) + + case *types.Struct: + w.startType(structType) + n := t.NumFields() + // Even for struct{} we must emit some qualifying package, because that's + // what the compiler does, and thus that's what the importer expects. + fieldPkg := pkg + if n > 0 { + fieldPkg = t.Field(0).Pkg() + } + if fieldPkg == nil { + // TODO(rfindley): improve this very hacky logic. + // + // The importer expects a package to be set for all struct types, even + // those with no fields. A better encoding might be to set NumFields + // before pkg. setPkg panics with a nil package, which may be possible + // to reach with invalid packages (and perhaps valid packages, too?), so + // (arbitrarily) set the localpkg if available. + // + // Alternatively, we may be able to simply guarantee that pkg != nil, by + // reconsidering the encoding of constant values. + if w.p.shallow { + fieldPkg = w.p.localpkg + } else { + panic(internalErrorf("no package to set for empty struct")) + } + } + w.pkg(fieldPkg) + w.uint64(uint64(n)) + + for i := 0; i < n; i++ { + f := t.Field(i) + if w.p.shallow { + w.objectPath(f) + } + w.pos(f.Pos()) + w.string(f.Name()) // unexported fields implicitly qualified by prior setPkg + w.typ(f.Type(), fieldPkg) + w.bool(f.Anonymous()) + w.string(t.Tag(i)) // note (or tag) + } + + case *types.Interface: + w.startType(interfaceType) + w.pkg(pkg) + + n := t.NumEmbeddeds() + w.uint64(uint64(n)) + for i := 0; i < n; i++ { + ft := t.EmbeddedType(i) + tPkg := pkg + if named, _ := aliases.Unalias(ft).(*types.Named); named != nil { + w.pos(named.Obj().Pos()) + } else { + w.pos(token.NoPos) + } + w.typ(ft, tPkg) + } + + // See comment for struct fields. In shallow mode we change the encoding + // for interface methods that are promoted from other packages. + + n = t.NumExplicitMethods() + w.uint64(uint64(n)) + for i := 0; i < n; i++ { + m := t.ExplicitMethod(i) + if w.p.shallow { + w.objectPath(m) + } + w.pos(m.Pos()) + w.string(m.Name()) + sig, _ := m.Type().(*types.Signature) + w.signature(sig) + } + + case *types.Union: + w.startType(unionType) + nt := t.Len() + w.uint64(uint64(nt)) + for i := 0; i < nt; i++ { + term := t.Term(i) + w.bool(term.Tilde()) + w.typ(term.Type(), pkg) + } + + default: + panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t))) + } +} + +// objectPath writes the package and objectPath to use to look up obj in a +// different package, when encoding in "shallow" mode. +// +// When doing a shallow import, the importer creates only the local package, +// and requests package symbols for dependencies from the client. +// However, certain types defined in the local package may hold objects defined +// (perhaps deeply) within another package. +// +// For example, consider the following: +// +// package a +// func F() chan * map[string] struct { X int } +// +// package b +// import "a" +// var B = a.F() +// +// In this example, the type of b.B holds fields defined in package a. +// In order to have the correct canonical objects for the field defined in the +// type of B, they are encoded as objectPaths and later looked up in the +// importer. The same problem applies to interface methods. +func (w *exportWriter) objectPath(obj types.Object) { + if obj.Pkg() == nil || obj.Pkg() == w.p.localpkg { + // obj.Pkg() may be nil for the builtin error.Error. + // In this case, or if obj is declared in the local package, no need to + // encode. + w.string("") + return + } + objectPath, err := w.p.objectpathEncoder().For(obj) + if err != nil { + // Fall back to the empty string, which will cause the importer to create a + // new object, which matches earlier behavior. Creating a new object is + // sufficient for many purposes (such as type checking), but causes certain + // references algorithms to fail (golang/go#60819). However, we didn't + // notice this problem during months of gopls@v0.12.0 testing. + // + // TODO(golang/go#61674): this workaround is insufficient, as in the case + // where the field forwarded from an instantiated type that may not appear + // in the export data of the original package: + // + // // package a + // type A[P any] struct{ F P } + // + // // package b + // type B a.A[int] + // + // We need to update references algorithms not to depend on this + // de-duplication, at which point we may want to simply remove the + // workaround here. + w.string("") + return + } + w.string(string(objectPath)) + w.pkg(obj.Pkg()) +} + +func (w *exportWriter) signature(sig *types.Signature) { + w.paramList(sig.Params()) + w.paramList(sig.Results()) + if sig.Params().Len() > 0 { + w.bool(sig.Variadic()) + } +} + +func (w *exportWriter) typeList(ts *types.TypeList, pkg *types.Package) { + w.uint64(uint64(ts.Len())) + for i := 0; i < ts.Len(); i++ { + w.typ(ts.At(i), pkg) + } +} + +func (w *exportWriter) tparamList(prefix string, list *types.TypeParamList, pkg *types.Package) { + ll := uint64(list.Len()) + w.uint64(ll) + for i := 0; i < list.Len(); i++ { + tparam := list.At(i) + // Set the type parameter exportName before exporting its type. + exportName := tparamExportName(prefix, tparam) + w.p.tparamNames[tparam.Obj()] = exportName + w.typ(list.At(i), pkg) + } +} + +const blankMarker = "$" + +// tparamExportName returns the 'exported' name of a type parameter, which +// differs from its actual object name: it is prefixed with a qualifier, and +// blank type parameter names are disambiguated by their index in the type +// parameter list. +func tparamExportName(prefix string, tparam *types.TypeParam) string { + assert(prefix != "") + name := tparam.Obj().Name() + if name == "_" { + name = blankMarker + strconv.Itoa(tparam.Index()) + } + return prefix + "." + name +} + +// tparamName returns the real name of a type parameter, after stripping its +// qualifying prefix and reverting blank-name encoding. See tparamExportName +// for details. +func tparamName(exportName string) string { + // Remove the "path" from the type param name that makes it unique. + ix := strings.LastIndex(exportName, ".") + if ix < 0 { + errorf("malformed type parameter export name %s: missing prefix", exportName) + } + name := exportName[ix+1:] + if strings.HasPrefix(name, blankMarker) { + return "_" + } + return name +} + +func (w *exportWriter) paramList(tup *types.Tuple) { + n := tup.Len() + w.uint64(uint64(n)) + for i := 0; i < n; i++ { + w.param(tup.At(i)) + } +} + +func (w *exportWriter) param(obj types.Object) { + w.pos(obj.Pos()) + w.localIdent(obj) + w.typ(obj.Type(), obj.Pkg()) +} + +func (w *exportWriter) value(typ types.Type, v constant.Value) { + w.typ(typ, nil) + if w.p.version >= iexportVersionGo1_18 { + w.int64(int64(v.Kind())) + } + + if v.Kind() == constant.Unknown { + // golang/go#60605: treat unknown constant values as if they have invalid type + // + // This loses some fidelity over the package type-checked from source, but that + // is acceptable. + // + // TODO(rfindley): we should switch on the recorded constant kind rather + // than the constant type + return + } + + switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { + case types.IsBoolean: + w.bool(constant.BoolVal(v)) + case types.IsInteger: + var i big.Int + if i64, exact := constant.Int64Val(v); exact { + i.SetInt64(i64) + } else if ui64, exact := constant.Uint64Val(v); exact { + i.SetUint64(ui64) + } else { + i.SetString(v.ExactString(), 10) + } + w.mpint(&i, typ) + case types.IsFloat: + f := constantToFloat(v) + w.mpfloat(f, typ) + case types.IsComplex: + w.mpfloat(constantToFloat(constant.Real(v)), typ) + w.mpfloat(constantToFloat(constant.Imag(v)), typ) + case types.IsString: + w.string(constant.StringVal(v)) + default: + if b.Kind() == types.Invalid { + // package contains type errors + break + } + panic(internalErrorf("unexpected type %v (%v)", typ, typ.Underlying())) + } +} + +// constantToFloat converts a constant.Value with kind constant.Float to a +// big.Float. +func constantToFloat(x constant.Value) *big.Float { + x = constant.ToFloat(x) + // Use the same floating-point precision (512) as cmd/compile + // (see Mpprec in cmd/compile/internal/gc/mpfloat.go). + const mpprec = 512 + var f big.Float + f.SetPrec(mpprec) + if v, exact := constant.Float64Val(x); exact { + // float64 + f.SetFloat64(v) + } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int { + // TODO(gri): add big.Rat accessor to constant.Value. + n := valueToRat(num) + d := valueToRat(denom) + f.SetRat(n.Quo(n, d)) + } else { + // Value too large to represent as a fraction => inaccessible. + // TODO(gri): add big.Float accessor to constant.Value. + _, ok := f.SetString(x.ExactString()) + assert(ok) + } + return &f +} + +func valueToRat(x constant.Value) *big.Rat { + // Convert little-endian to big-endian. + // I can't believe this is necessary. + bytes := constant.Bytes(x) + for i := 0; i < len(bytes)/2; i++ { + bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i] + } + return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes)) +} + +// mpint exports a multi-precision integer. +// +// For unsigned types, small values are written out as a single +// byte. Larger values are written out as a length-prefixed big-endian +// byte string, where the length prefix is encoded as its complement. +// For example, bytes 0, 1, and 2 directly represent the integer +// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-, +// 2-, and 3-byte big-endian string follow. +// +// Encoding for signed types use the same general approach as for +// unsigned types, except small values use zig-zag encoding and the +// bottom bit of length prefix byte for large values is reserved as a +// sign bit. +// +// The exact boundary between small and large encodings varies +// according to the maximum number of bytes needed to encode a value +// of type typ. As a special case, 8-bit types are always encoded as a +// single byte. +// +// TODO(mdempsky): Is this level of complexity really worthwhile? +func (w *exportWriter) mpint(x *big.Int, typ types.Type) { + basic, ok := typ.Underlying().(*types.Basic) + if !ok { + panic(internalErrorf("unexpected type %v (%T)", typ.Underlying(), typ.Underlying())) + } + + signed, maxBytes := intSize(basic) + + negative := x.Sign() < 0 + if !signed && negative { + panic(internalErrorf("negative unsigned integer; type %v, value %v", typ, x)) + } + + b := x.Bytes() + if len(b) > 0 && b[0] == 0 { + panic(internalErrorf("leading zeros")) + } + if uint(len(b)) > maxBytes { + panic(internalErrorf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)) + } + + maxSmall := 256 - maxBytes + if signed { + maxSmall = 256 - 2*maxBytes + } + if maxBytes == 1 { + maxSmall = 256 + } + + // Check if x can use small value encoding. + if len(b) <= 1 { + var ux uint + if len(b) == 1 { + ux = uint(b[0]) + } + if signed { + ux <<= 1 + if negative { + ux-- + } + } + if ux < maxSmall { + w.data.WriteByte(byte(ux)) + return + } + } + + n := 256 - uint(len(b)) + if signed { + n = 256 - 2*uint(len(b)) + if negative { + n |= 1 + } + } + if n < maxSmall || n >= 256 { + panic(internalErrorf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)) + } + + w.data.WriteByte(byte(n)) + w.data.Write(b) +} + +// mpfloat exports a multi-precision floating point number. +// +// The number's value is decomposed into mantissa × 2**exponent, where +// mantissa is an integer. The value is written out as mantissa (as a +// multi-precision integer) and then the exponent, except exponent is +// omitted if mantissa is zero. +func (w *exportWriter) mpfloat(f *big.Float, typ types.Type) { + if f.IsInf() { + panic("infinite constant") + } + + // Break into f = mant × 2**exp, with 0.5 <= mant < 1. + var mant big.Float + exp := int64(f.MantExp(&mant)) + + // Scale so that mant is an integer. + prec := mant.MinPrec() + mant.SetMantExp(&mant, int(prec)) + exp -= int64(prec) + + manti, acc := mant.Int(nil) + if acc != big.Exact { + panic(internalErrorf("mantissa scaling failed for %f (%s)", f, acc)) + } + w.mpint(manti, typ) + if manti.Sign() != 0 { + w.int64(exp) + } +} + +func (w *exportWriter) bool(b bool) bool { + var x uint64 + if b { + x = 1 + } + w.uint64(x) + return b +} + +func (w *exportWriter) int64(x int64) { w.data.int64(x) } +func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) } +func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) } + +func (w *exportWriter) localIdent(obj types.Object) { + // Anonymous parameters. + if obj == nil { + w.string("") + return + } + + name := obj.Name() + if name == "_" { + w.string("_") + return + } + + w.string(name) +} + +type intWriter struct { + bytes.Buffer +} + +func (w *intWriter) int64(x int64) { + var buf [binary.MaxVarintLen64]byte + n := binary.PutVarint(buf[:], x) + w.Write(buf[:n]) +} + +func (w *intWriter) uint64(x uint64) { + var buf [binary.MaxVarintLen64]byte + n := binary.PutUvarint(buf[:], x) + w.Write(buf[:n]) +} + +func assert(cond bool) { + if !cond { + panic("internal error: assertion failed") + } +} + +// The below is copied from go/src/cmd/compile/internal/gc/syntax.go. + +// objQueue is a FIFO queue of types.Object. The zero value of objQueue is +// a ready-to-use empty queue. +type objQueue struct { + ring []types.Object + head, tail int +} + +// empty returns true if q contains no Nodes. +func (q *objQueue) empty() bool { + return q.head == q.tail +} + +// pushTail appends n to the tail of the queue. +func (q *objQueue) pushTail(obj types.Object) { + if len(q.ring) == 0 { + q.ring = make([]types.Object, 16) + } else if q.head+len(q.ring) == q.tail { + // Grow the ring. + nring := make([]types.Object, len(q.ring)*2) + // Copy the old elements. + part := q.ring[q.head%len(q.ring):] + if q.tail-q.head <= len(part) { + part = part[:q.tail-q.head] + copy(nring, part) + } else { + pos := copy(nring, part) + copy(nring[pos:], q.ring[:q.tail%len(q.ring)]) + } + q.ring, q.head, q.tail = nring, 0, q.tail-q.head + } + + q.ring[q.tail%len(q.ring)] = obj + q.tail++ +} + +// popHead pops a node from the head of the queue. It panics if q is empty. +func (q *objQueue) popHead() types.Object { + if q.empty() { + panic("dequeue empty") + } + obj := q.ring[q.head%len(q.ring)] + q.head++ + return obj +} + +// internalError represents an error generated inside this package. +type internalError string + +func (e internalError) Error() string { return "gcimporter: " + string(e) } + +// TODO(adonovan): make this call panic, so that it's symmetric with errorf. +// Otherwise it's easy to forget to do anything with the error. +// +// TODO(adonovan): also, consider switching the names "errorf" and +// "internalErrorf" as the former is used for bugs, whose cause is +// internal inconsistency, whereas the latter is used for ordinary +// situations like bad input, whose cause is external. +func internalErrorf(format string, args ...interface{}) error { + return internalError(fmt.Sprintf(format, args...)) +} + +// aliasRHS removes exactly one Alias constructor. +func aliasRHS(alias *aliases.Alias) types.Type { + // TODO(adonovan): if proposal #66559 is accepted, this will + // become Alias.RHS(alias). In the meantime, we must punch + // through the drywall. + type go123Alias struct { + _ *types.TypeName + _ *types.TypeParamList + RHS types.Type + _ types.Type + } + var raw *go123Alias + *(**aliases.Alias)(unsafe.Pointer(&raw)) = alias + return raw.RHS +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go new file mode 100644 index 00000000..2732121b --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go @@ -0,0 +1,1098 @@ +// 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. + +// Indexed package import. +// See cmd/compile/internal/gc/iexport.go for the export data format. + +// This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go. + +package gcimporter + +import ( + "bytes" + "encoding/binary" + "fmt" + "go/constant" + "go/token" + "go/types" + "io" + "math/big" + "sort" + "strings" + + "golang.org/x/tools/go/types/objectpath" + "golang.org/x/tools/internal/aliases" + "golang.org/x/tools/internal/typesinternal" +) + +type intReader struct { + *bytes.Reader + path string +} + +func (r *intReader) int64() int64 { + i, err := binary.ReadVarint(r.Reader) + if err != nil { + errorf("import %q: read varint error: %v", r.path, err) + } + return i +} + +func (r *intReader) uint64() uint64 { + i, err := binary.ReadUvarint(r.Reader) + if err != nil { + errorf("import %q: read varint error: %v", r.path, err) + } + return i +} + +// Keep this in sync with constants in iexport.go. +const ( + iexportVersionGo1_11 = 0 + iexportVersionPosCol = 1 + iexportVersionGo1_18 = 2 + iexportVersionGenerics = 2 + + iexportVersionCurrent = 2 +) + +type ident struct { + pkg *types.Package + name string +} + +const predeclReserved = 32 + +type itag uint64 + +const ( + // Types + definedType itag = iota + pointerType + sliceType + arrayType + chanType + mapType + signatureType + structType + interfaceType + typeParamType + instanceType + unionType + aliasType +) + +// Object tags +const ( + varTag = 'V' + funcTag = 'F' + genericFuncTag = 'G' + constTag = 'C' + aliasTag = 'A' + genericAliasTag = 'B' + typeParamTag = 'P' + typeTag = 'T' + genericTypeTag = 'U' +) + +// IImportData imports a package from the serialized package data +// and returns 0 and a reference to the package. +// If the export data version is not recognized or the format is otherwise +// compromised, an error is returned. +func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) { + pkgs, err := iimportCommon(fset, GetPackagesFromMap(imports), data, false, path, false, nil) + if err != nil { + return 0, nil, err + } + return 0, pkgs[0], nil +} + +// IImportBundle imports a set of packages from the serialized package bundle. +func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) { + return iimportCommon(fset, GetPackagesFromMap(imports), data, true, "", false, nil) +} + +// A GetPackagesFunc function obtains the non-nil symbols for a set of +// packages, creating and recursively importing them as needed. An +// implementation should store each package symbol is in the Pkg +// field of the items array. +// +// Any error causes importing to fail. This can be used to quickly read +// the import manifest of an export data file without fully decoding it. +type GetPackagesFunc = func(items []GetPackagesItem) error + +// A GetPackagesItem is a request from the importer for the package +// symbol of the specified name and path. +type GetPackagesItem struct { + Name, Path string + Pkg *types.Package // to be filled in by GetPackagesFunc call + + // private importer state + pathOffset uint64 + nameIndex map[string]uint64 +} + +// GetPackagesFromMap returns a GetPackagesFunc that retrieves +// packages from the given map of package path to package. +// +// The returned function may mutate m: each requested package that is not +// found is created with types.NewPackage and inserted into m. +func GetPackagesFromMap(m map[string]*types.Package) GetPackagesFunc { + return func(items []GetPackagesItem) error { + for i, item := range items { + pkg, ok := m[item.Path] + if !ok { + pkg = types.NewPackage(item.Path, item.Name) + m[item.Path] = pkg + } + items[i].Pkg = pkg + } + return nil + } +} + +func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, bundle bool, path string, shallow bool, reportf ReportFunc) (pkgs []*types.Package, err error) { + const currentVersion = iexportVersionCurrent + version := int64(-1) + if !debug { + defer func() { + if e := recover(); e != nil { + if bundle { + err = fmt.Errorf("%v", e) + } else if version > currentVersion { + err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) + } else { + err = fmt.Errorf("internal error while importing %q (%v); please report an issue", path, e) + } + } + }() + } + + r := &intReader{bytes.NewReader(data), path} + + if bundle { + if v := r.uint64(); v != bundleVersion { + errorf("unknown bundle format version %d", v) + } + } + + version = int64(r.uint64()) + switch version { + case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11: + default: + if version > iexportVersionGo1_18 { + errorf("unstable iexport format version %d, just rebuild compiler and std library", version) + } else { + errorf("unknown iexport format version %d", version) + } + } + + sLen := int64(r.uint64()) + var fLen int64 + var fileOffset []uint64 + if shallow { + // Shallow mode uses a different position encoding. + fLen = int64(r.uint64()) + fileOffset = make([]uint64, r.uint64()) + for i := range fileOffset { + fileOffset[i] = r.uint64() + } + } + dLen := int64(r.uint64()) + + whence, _ := r.Seek(0, io.SeekCurrent) + stringData := data[whence : whence+sLen] + fileData := data[whence+sLen : whence+sLen+fLen] + declData := data[whence+sLen+fLen : whence+sLen+fLen+dLen] + r.Seek(sLen+fLen+dLen, io.SeekCurrent) + + p := iimporter{ + version: int(version), + ipath: path, + shallow: shallow, + reportf: reportf, + + stringData: stringData, + stringCache: make(map[uint64]string), + fileOffset: fileOffset, + fileData: fileData, + fileCache: make([]*token.File, len(fileOffset)), + pkgCache: make(map[uint64]*types.Package), + + declData: declData, + pkgIndex: make(map[*types.Package]map[string]uint64), + typCache: make(map[uint64]types.Type), + // Separate map for typeparams, keyed by their package and unique + // name. + tparamIndex: make(map[ident]types.Type), + + fake: fakeFileSet{ + fset: fset, + files: make(map[string]*fileInfo), + }, + } + defer p.fake.setLines() // set lines for files in fset + + for i, pt := range predeclared() { + p.typCache[uint64(i)] = pt + } + + // Gather the relevant packages from the manifest. + items := make([]GetPackagesItem, r.uint64()) + uniquePkgPaths := make(map[string]bool) + for i := range items { + pkgPathOff := r.uint64() + pkgPath := p.stringAt(pkgPathOff) + pkgName := p.stringAt(r.uint64()) + _ = r.uint64() // package height; unused by go/types + + if pkgPath == "" { + pkgPath = path + } + items[i].Name = pkgName + items[i].Path = pkgPath + items[i].pathOffset = pkgPathOff + + // Read index for package. + nameIndex := make(map[string]uint64) + nSyms := r.uint64() + // In shallow mode, only the current package (i=0) has an index. + assert(!(shallow && i > 0 && nSyms != 0)) + for ; nSyms > 0; nSyms-- { + name := p.stringAt(r.uint64()) + nameIndex[name] = r.uint64() + } + + items[i].nameIndex = nameIndex + + uniquePkgPaths[pkgPath] = true + } + // Debugging #63822; hypothesis: there are duplicate PkgPaths. + if len(uniquePkgPaths) != len(items) { + reportf("found duplicate PkgPaths while reading export data manifest: %v", items) + } + + // Request packages all at once from the client, + // enabling a parallel implementation. + if err := getPackages(items); err != nil { + return nil, err // don't wrap this error + } + + // Check the results and complete the index. + pkgList := make([]*types.Package, len(items)) + for i, item := range items { + pkg := item.Pkg + if pkg == nil { + errorf("internal error: getPackages returned nil package for %q", item.Path) + } else if pkg.Path() != item.Path { + errorf("internal error: getPackages returned wrong path %q, want %q", pkg.Path(), item.Path) + } else if pkg.Name() != item.Name { + errorf("internal error: getPackages returned wrong name %s for package %q, want %s", pkg.Name(), item.Path, item.Name) + } + p.pkgCache[item.pathOffset] = pkg + p.pkgIndex[pkg] = item.nameIndex + pkgList[i] = pkg + } + + if bundle { + pkgs = make([]*types.Package, r.uint64()) + for i := range pkgs { + pkg := p.pkgAt(r.uint64()) + imps := make([]*types.Package, r.uint64()) + for j := range imps { + imps[j] = p.pkgAt(r.uint64()) + } + pkg.SetImports(imps) + pkgs[i] = pkg + } + } else { + if len(pkgList) == 0 { + errorf("no packages found for %s", path) + panic("unreachable") + } + pkgs = pkgList[:1] + + // record all referenced packages as imports + list := append(([]*types.Package)(nil), pkgList[1:]...) + sort.Sort(byPath(list)) + pkgs[0].SetImports(list) + } + + for _, pkg := range pkgs { + if pkg.Complete() { + continue + } + + names := make([]string, 0, len(p.pkgIndex[pkg])) + for name := range p.pkgIndex[pkg] { + names = append(names, name) + } + sort.Strings(names) + for _, name := range names { + p.doDecl(pkg, name) + } + + // package was imported completely and without errors + pkg.MarkComplete() + } + + // SetConstraint can't be called if the constraint type is not yet complete. + // When type params are created in the typeParamTag case of (*importReader).obj(), + // the associated constraint type may not be complete due to recursion. + // Therefore, we defer calling SetConstraint there, and call it here instead + // after all types are complete. + for _, d := range p.later { + d.t.SetConstraint(d.constraint) + } + + for _, typ := range p.interfaceList { + typ.Complete() + } + + // Workaround for golang/go#61561. See the doc for instanceList for details. + for _, typ := range p.instanceList { + if iface, _ := typ.Underlying().(*types.Interface); iface != nil { + iface.Complete() + } + } + + return pkgs, nil +} + +type setConstraintArgs struct { + t *types.TypeParam + constraint types.Type +} + +type iimporter struct { + version int + ipath string + + shallow bool + reportf ReportFunc // if non-nil, used to report bugs + + stringData []byte + stringCache map[uint64]string + fileOffset []uint64 // fileOffset[i] is offset in fileData for info about file encoded as i + fileData []byte + fileCache []*token.File // memoized decoding of file encoded as i + pkgCache map[uint64]*types.Package + + declData []byte + pkgIndex map[*types.Package]map[string]uint64 + typCache map[uint64]types.Type + tparamIndex map[ident]types.Type + + fake fakeFileSet + interfaceList []*types.Interface + + // Workaround for the go/types bug golang/go#61561: instances produced during + // instantiation may contain incomplete interfaces. Here we only complete the + // underlying type of the instance, which is the most common case but doesn't + // handle parameterized interface literals defined deeper in the type. + instanceList []types.Type // instances for later completion (see golang/go#61561) + + // Arguments for calls to SetConstraint that are deferred due to recursive types + later []setConstraintArgs + + indent int // for tracing support +} + +func (p *iimporter) trace(format string, args ...interface{}) { + if !trace { + // Call sites should also be guarded, but having this check here allows + // easily enabling/disabling debug trace statements. + return + } + fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) +} + +func (p *iimporter) doDecl(pkg *types.Package, name string) { + if debug { + p.trace("import decl %s", name) + p.indent++ + defer func() { + p.indent-- + p.trace("=> %s", name) + }() + } + // See if we've already imported this declaration. + if obj := pkg.Scope().Lookup(name); obj != nil { + return + } + + off, ok := p.pkgIndex[pkg][name] + if !ok { + // In deep mode, the index should be complete. In shallow + // mode, we should have already recursively loaded necessary + // dependencies so the above Lookup succeeds. + errorf("%v.%v not in index", pkg, name) + } + + r := &importReader{p: p, currPkg: pkg} + r.declReader.Reset(p.declData[off:]) + + r.obj(name) +} + +func (p *iimporter) stringAt(off uint64) string { + if s, ok := p.stringCache[off]; ok { + return s + } + + slen, n := binary.Uvarint(p.stringData[off:]) + if n <= 0 { + errorf("varint failed") + } + spos := off + uint64(n) + s := string(p.stringData[spos : spos+slen]) + p.stringCache[off] = s + return s +} + +func (p *iimporter) fileAt(index uint64) *token.File { + file := p.fileCache[index] + if file == nil { + off := p.fileOffset[index] + file = p.decodeFile(intReader{bytes.NewReader(p.fileData[off:]), p.ipath}) + p.fileCache[index] = file + } + return file +} + +func (p *iimporter) decodeFile(rd intReader) *token.File { + filename := p.stringAt(rd.uint64()) + size := int(rd.uint64()) + file := p.fake.fset.AddFile(filename, -1, size) + + // SetLines requires a nondecreasing sequence. + // Because it is common for clients to derive the interval + // [start, start+len(name)] from a start position, and we + // want to ensure that the end offset is on the same line, + // we fill in the gaps of the sparse encoding with values + // that strictly increase by the largest possible amount. + // This allows us to avoid having to record the actual end + // offset of each needed line. + + lines := make([]int, int(rd.uint64())) + var index, offset int + for i, n := 0, int(rd.uint64()); i < n; i++ { + index += int(rd.uint64()) + offset += int(rd.uint64()) + lines[index] = offset + + // Ensure monotonicity between points. + for j := index - 1; j > 0 && lines[j] == 0; j-- { + lines[j] = lines[j+1] - 1 + } + } + + // Ensure monotonicity after last point. + for j := len(lines) - 1; j > 0 && lines[j] == 0; j-- { + size-- + lines[j] = size + } + + if !file.SetLines(lines) { + errorf("SetLines failed: %d", lines) // can't happen + } + return file +} + +func (p *iimporter) pkgAt(off uint64) *types.Package { + if pkg, ok := p.pkgCache[off]; ok { + return pkg + } + path := p.stringAt(off) + errorf("missing package %q in %q", path, p.ipath) + return nil +} + +func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { + if t, ok := p.typCache[off]; ok && canReuse(base, t) { + return t + } + + if off < predeclReserved { + errorf("predeclared type missing from cache: %v", off) + } + + r := &importReader{p: p} + r.declReader.Reset(p.declData[off-predeclReserved:]) + t := r.doType(base) + + if canReuse(base, t) { + p.typCache[off] = t + } + return t +} + +// canReuse reports whether the type rhs on the RHS of the declaration for def +// may be re-used. +// +// Specifically, if def is non-nil and rhs is an interface type with methods, it +// may not be re-used because we have a convention of setting the receiver type +// for interface methods to def. +func canReuse(def *types.Named, rhs types.Type) bool { + if def == nil { + return true + } + iface, _ := aliases.Unalias(rhs).(*types.Interface) + if iface == nil { + return true + } + // Don't use iface.Empty() here as iface may not be complete. + return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0 +} + +type importReader struct { + p *iimporter + declReader bytes.Reader + currPkg *types.Package + prevFile string + prevLine int64 + prevColumn int64 +} + +func (r *importReader) obj(name string) { + tag := r.byte() + pos := r.pos() + + switch tag { + case aliasTag: + typ := r.typ() + // TODO(adonovan): support generic aliases: + // if tag == genericAliasTag { + // tparams := r.tparamList() + // alias.SetTypeParams(tparams) + // } + r.declare(aliases.NewAlias(pos, r.currPkg, name, typ)) + + case constTag: + typ, val := r.value() + + r.declare(types.NewConst(pos, r.currPkg, name, typ, val)) + + case funcTag, genericFuncTag: + var tparams []*types.TypeParam + if tag == genericFuncTag { + tparams = r.tparamList() + } + sig := r.signature(nil, nil, tparams) + r.declare(types.NewFunc(pos, r.currPkg, name, sig)) + + case typeTag, genericTypeTag: + // Types can be recursive. We need to setup a stub + // declaration before recursing. + obj := types.NewTypeName(pos, r.currPkg, name, nil) + named := types.NewNamed(obj, nil, nil) + // Declare obj before calling r.tparamList, so the new type name is recognized + // if used in the constraint of one of its own typeparams (see #48280). + r.declare(obj) + if tag == genericTypeTag { + tparams := r.tparamList() + named.SetTypeParams(tparams) + } + + underlying := r.p.typAt(r.uint64(), named).Underlying() + named.SetUnderlying(underlying) + + if !isInterface(underlying) { + for n := r.uint64(); n > 0; n-- { + mpos := r.pos() + mname := r.ident() + recv := r.param() + + // If the receiver has any targs, set those as the + // rparams of the method (since those are the + // typeparams being used in the method sig/body). + _, recvNamed := typesinternal.ReceiverNamed(recv) + targs := recvNamed.TypeArgs() + var rparams []*types.TypeParam + if targs.Len() > 0 { + rparams = make([]*types.TypeParam, targs.Len()) + for i := range rparams { + rparams[i] = aliases.Unalias(targs.At(i)).(*types.TypeParam) + } + } + msig := r.signature(recv, rparams, nil) + + named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig)) + } + } + + case typeParamTag: + // We need to "declare" a typeparam in order to have a name that + // can be referenced recursively (if needed) in the type param's + // bound. + if r.p.version < iexportVersionGenerics { + errorf("unexpected type param type") + } + name0 := tparamName(name) + tn := types.NewTypeName(pos, r.currPkg, name0, nil) + t := types.NewTypeParam(tn, nil) + + // To handle recursive references to the typeparam within its + // bound, save the partial type in tparamIndex before reading the bounds. + id := ident{r.currPkg, name} + r.p.tparamIndex[id] = t + var implicit bool + if r.p.version >= iexportVersionGo1_18 { + implicit = r.bool() + } + constraint := r.typ() + if implicit { + iface, _ := aliases.Unalias(constraint).(*types.Interface) + if iface == nil { + errorf("non-interface constraint marked implicit") + } + iface.MarkImplicit() + } + // The constraint type may not be complete, if we + // are in the middle of a type recursion involving type + // constraints. So, we defer SetConstraint until we have + // completely set up all types in ImportData. + r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint}) + + case varTag: + typ := r.typ() + + r.declare(types.NewVar(pos, r.currPkg, name, typ)) + + default: + errorf("unexpected tag: %v", tag) + } +} + +func (r *importReader) declare(obj types.Object) { + obj.Pkg().Scope().Insert(obj) +} + +func (r *importReader) value() (typ types.Type, val constant.Value) { + typ = r.typ() + if r.p.version >= iexportVersionGo1_18 { + // TODO: add support for using the kind. + _ = constant.Kind(r.int64()) + } + + switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { + case types.IsBoolean: + val = constant.MakeBool(r.bool()) + + case types.IsString: + val = constant.MakeString(r.string()) + + case types.IsInteger: + var x big.Int + r.mpint(&x, b) + val = constant.Make(&x) + + case types.IsFloat: + val = r.mpfloat(b) + + case types.IsComplex: + re := r.mpfloat(b) + im := r.mpfloat(b) + val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) + + default: + if b.Kind() == types.Invalid { + val = constant.MakeUnknown() + return + } + errorf("unexpected type %v", typ) // panics + panic("unreachable") + } + + return +} + +func intSize(b *types.Basic) (signed bool, maxBytes uint) { + if (b.Info() & types.IsUntyped) != 0 { + return true, 64 + } + + switch b.Kind() { + case types.Float32, types.Complex64: + return true, 3 + case types.Float64, types.Complex128: + return true, 7 + } + + signed = (b.Info() & types.IsUnsigned) == 0 + switch b.Kind() { + case types.Int8, types.Uint8: + maxBytes = 1 + case types.Int16, types.Uint16: + maxBytes = 2 + case types.Int32, types.Uint32: + maxBytes = 4 + default: + maxBytes = 8 + } + + return +} + +func (r *importReader) mpint(x *big.Int, typ *types.Basic) { + signed, maxBytes := intSize(typ) + + maxSmall := 256 - maxBytes + if signed { + maxSmall = 256 - 2*maxBytes + } + if maxBytes == 1 { + maxSmall = 256 + } + + n, _ := r.declReader.ReadByte() + if uint(n) < maxSmall { + v := int64(n) + if signed { + v >>= 1 + if n&1 != 0 { + v = ^v + } + } + x.SetInt64(v) + return + } + + v := -n + if signed { + v = -(n &^ 1) >> 1 + } + if v < 1 || uint(v) > maxBytes { + errorf("weird decoding: %v, %v => %v", n, signed, v) + } + b := make([]byte, v) + io.ReadFull(&r.declReader, b) + x.SetBytes(b) + if signed && n&1 != 0 { + x.Neg(x) + } +} + +func (r *importReader) mpfloat(typ *types.Basic) constant.Value { + var mant big.Int + r.mpint(&mant, typ) + var f big.Float + f.SetInt(&mant) + if f.Sign() != 0 { + f.SetMantExp(&f, int(r.int64())) + } + return constant.Make(&f) +} + +func (r *importReader) ident() string { + return r.string() +} + +func (r *importReader) qualifiedIdent() (*types.Package, string) { + name := r.string() + pkg := r.pkg() + return pkg, name +} + +func (r *importReader) pos() token.Pos { + if r.p.shallow { + // precise offsets are encoded only in shallow mode + return r.posv2() + } + if r.p.version >= iexportVersionPosCol { + r.posv1() + } else { + r.posv0() + } + + if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 { + return token.NoPos + } + return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn)) +} + +func (r *importReader) posv0() { + delta := r.int64() + if delta != deltaNewFile { + r.prevLine += delta + } else if l := r.int64(); l == -1 { + r.prevLine += deltaNewFile + } else { + r.prevFile = r.string() + r.prevLine = l + } +} + +func (r *importReader) posv1() { + delta := r.int64() + r.prevColumn += delta >> 1 + if delta&1 != 0 { + delta = r.int64() + r.prevLine += delta >> 1 + if delta&1 != 0 { + r.prevFile = r.string() + } + } +} + +func (r *importReader) posv2() token.Pos { + file := r.uint64() + if file == 0 { + return token.NoPos + } + tf := r.p.fileAt(file - 1) + return tf.Pos(int(r.uint64())) +} + +func (r *importReader) typ() types.Type { + return r.p.typAt(r.uint64(), nil) +} + +func isInterface(t types.Type) bool { + _, ok := aliases.Unalias(t).(*types.Interface) + return ok +} + +func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } +func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } + +func (r *importReader) doType(base *types.Named) (res types.Type) { + k := r.kind() + if debug { + r.p.trace("importing type %d (base: %s)", k, base) + r.p.indent++ + defer func() { + r.p.indent-- + r.p.trace("=> %s", res) + }() + } + switch k { + default: + errorf("unexpected kind tag in %q: %v", r.p.ipath, k) + return nil + + case aliasType, definedType: + pkg, name := r.qualifiedIdent() + r.p.doDecl(pkg, name) + return pkg.Scope().Lookup(name).(*types.TypeName).Type() + case pointerType: + return types.NewPointer(r.typ()) + case sliceType: + return types.NewSlice(r.typ()) + case arrayType: + n := r.uint64() + return types.NewArray(r.typ(), int64(n)) + case chanType: + dir := chanDir(int(r.uint64())) + return types.NewChan(dir, r.typ()) + case mapType: + return types.NewMap(r.typ(), r.typ()) + case signatureType: + r.currPkg = r.pkg() + return r.signature(nil, nil, nil) + + case structType: + r.currPkg = r.pkg() + + fields := make([]*types.Var, r.uint64()) + tags := make([]string, len(fields)) + for i := range fields { + var field *types.Var + if r.p.shallow { + field, _ = r.objectPathObject().(*types.Var) + } + + fpos := r.pos() + fname := r.ident() + ftyp := r.typ() + emb := r.bool() + tag := r.string() + + // Either this is not a shallow import, the field is local, or the + // encoded objectPath failed to produce an object (a bug). + // + // Even in this last, buggy case, fall back on creating a new field. As + // discussed in iexport.go, this is not correct, but mostly works and is + // preferable to failing (for now at least). + if field == nil { + field = types.NewField(fpos, r.currPkg, fname, ftyp, emb) + } + + fields[i] = field + tags[i] = tag + } + return types.NewStruct(fields, tags) + + case interfaceType: + r.currPkg = r.pkg() + + embeddeds := make([]types.Type, r.uint64()) + for i := range embeddeds { + _ = r.pos() + embeddeds[i] = r.typ() + } + + methods := make([]*types.Func, r.uint64()) + for i := range methods { + var method *types.Func + if r.p.shallow { + method, _ = r.objectPathObject().(*types.Func) + } + + mpos := r.pos() + mname := r.ident() + + // TODO(mdempsky): Matches bimport.go, but I + // don't agree with this. + var recv *types.Var + if base != nil { + recv = types.NewVar(token.NoPos, r.currPkg, "", base) + } + msig := r.signature(recv, nil, nil) + + if method == nil { + method = types.NewFunc(mpos, r.currPkg, mname, msig) + } + methods[i] = method + } + + typ := newInterface(methods, embeddeds) + r.p.interfaceList = append(r.p.interfaceList, typ) + return typ + + case typeParamType: + if r.p.version < iexportVersionGenerics { + errorf("unexpected type param type") + } + pkg, name := r.qualifiedIdent() + id := ident{pkg, name} + if t, ok := r.p.tparamIndex[id]; ok { + // We're already in the process of importing this typeparam. + return t + } + // Otherwise, import the definition of the typeparam now. + r.p.doDecl(pkg, name) + return r.p.tparamIndex[id] + + case instanceType: + if r.p.version < iexportVersionGenerics { + errorf("unexpected instantiation type") + } + // pos does not matter for instances: they are positioned on the original + // type. + _ = r.pos() + len := r.uint64() + targs := make([]types.Type, len) + for i := range targs { + targs[i] = r.typ() + } + baseType := r.typ() + // The imported instantiated type doesn't include any methods, so + // we must always use the methods of the base (orig) type. + // TODO provide a non-nil *Environment + t, _ := types.Instantiate(nil, baseType, targs, false) + + // Workaround for golang/go#61561. See the doc for instanceList for details. + r.p.instanceList = append(r.p.instanceList, t) + return t + + case unionType: + if r.p.version < iexportVersionGenerics { + errorf("unexpected instantiation type") + } + terms := make([]*types.Term, r.uint64()) + for i := range terms { + terms[i] = types.NewTerm(r.bool(), r.typ()) + } + return types.NewUnion(terms) + } +} + +func (r *importReader) kind() itag { + return itag(r.uint64()) +} + +// objectPathObject is the inverse of exportWriter.objectPath. +// +// In shallow mode, certain fields and methods may need to be looked up in an +// imported package. See the doc for exportWriter.objectPath for a full +// explanation. +func (r *importReader) objectPathObject() types.Object { + objPath := objectpath.Path(r.string()) + if objPath == "" { + return nil + } + pkg := r.pkg() + obj, err := objectpath.Object(pkg, objPath) + if err != nil { + if r.p.reportf != nil { + r.p.reportf("failed to find object for objectPath %q: %v", objPath, err) + } + } + return obj +} + +func (r *importReader) signature(recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature { + params := r.paramList() + results := r.paramList() + variadic := params.Len() > 0 && r.bool() + return types.NewSignatureType(recv, rparams, tparams, params, results, variadic) +} + +func (r *importReader) tparamList() []*types.TypeParam { + n := r.uint64() + if n == 0 { + return nil + } + xs := make([]*types.TypeParam, n) + for i := range xs { + // Note: the standard library importer is tolerant of nil types here, + // though would panic in SetTypeParams. + xs[i] = aliases.Unalias(r.typ()).(*types.TypeParam) + } + return xs +} + +func (r *importReader) paramList() *types.Tuple { + xs := make([]*types.Var, r.uint64()) + for i := range xs { + xs[i] = r.param() + } + return types.NewTuple(xs...) +} + +func (r *importReader) param() *types.Var { + pos := r.pos() + name := r.ident() + typ := r.typ() + return types.NewParam(pos, r.currPkg, name, typ) +} + +func (r *importReader) bool() bool { + return r.uint64() != 0 +} + +func (r *importReader) int64() int64 { + n, err := binary.ReadVarint(&r.declReader) + if err != nil { + errorf("readVarint: %v", err) + } + return n +} + +func (r *importReader) uint64() uint64 { + n, err := binary.ReadUvarint(&r.declReader) + if err != nil { + errorf("readUvarint: %v", err) + } + return n +} + +func (r *importReader) byte() byte { + x, err := r.declReader.ReadByte() + if err != nil { + errorf("declReader.ReadByte: %v", err) + } + return x +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go b/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go new file mode 100644 index 00000000..8b163e3d --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go @@ -0,0 +1,22 @@ +// 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. + +//go:build !go1.11 +// +build !go1.11 + +package gcimporter + +import "go/types" + +func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { + named := make([]*types.Named, len(embeddeds)) + for i, e := range embeddeds { + var ok bool + named[i], ok = e.(*types.Named) + if !ok { + panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11") + } + } + return types.NewInterface(methods, named) +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go b/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go new file mode 100644 index 00000000..49984f40 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go @@ -0,0 +1,14 @@ +// 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. + +//go:build go1.11 +// +build go1.11 + +package gcimporter + +import "go/types" + +func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { + return types.NewInterfaceType(methods, embeddeds) +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go b/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go new file mode 100644 index 00000000..0cd3b91b --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go @@ -0,0 +1,34 @@ +// 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 gcimporter + +import "go/types" + +const iexportVersion = iexportVersionGenerics + +// additionalPredeclared returns additional predeclared types in go.1.18. +func additionalPredeclared() []types.Type { + return []types.Type{ + // comparable + types.Universe.Lookup("comparable").Type(), + + // any + types.Universe.Lookup("any").Type(), + } +} + +// See cmd/compile/internal/types.SplitVargenSuffix. +func splitVargenSuffix(name string) (base, suffix string) { + i := len(name) + for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' { + i-- + } + const dot = "·" + if i >= len(dot) && name[i-len(dot):i] == dot { + i -= len(dot) + return name[:i], name[i:] + } + return name, "" +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go b/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go new file mode 100644 index 00000000..38b624ca --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go @@ -0,0 +1,10 @@ +// 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. + +//go:build !goexperiment.unified +// +build !goexperiment.unified + +package gcimporter + +const unifiedIR = false diff --git a/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go new file mode 100644 index 00000000..b5118d0b --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go @@ -0,0 +1,10 @@ +// 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. + +//go:build goexperiment.unified +// +build goexperiment.unified + +package gcimporter + +const unifiedIR = true diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go new file mode 100644 index 00000000..b3be452a --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go @@ -0,0 +1,726 @@ +// 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. + +// Derived from go/internal/gcimporter/ureader.go + +package gcimporter + +import ( + "fmt" + "go/token" + "go/types" + "sort" + "strings" + + "golang.org/x/tools/internal/aliases" + "golang.org/x/tools/internal/pkgbits" +) + +// A pkgReader holds the shared state for reading a unified IR package +// description. +type pkgReader struct { + pkgbits.PkgDecoder + + fake fakeFileSet + + ctxt *types.Context + imports map[string]*types.Package // previously imported packages, indexed by path + + // lazily initialized arrays corresponding to the unified IR + // PosBase, Pkg, and Type sections, respectively. + posBases []string // position bases (i.e., file names) + pkgs []*types.Package + typs []types.Type + + // laterFns holds functions that need to be invoked at the end of + // import reading. + laterFns []func() + // laterFors is used in case of 'type A B' to ensure that B is processed before A. + laterFors map[types.Type]int + + // ifaces holds a list of constructed Interfaces, which need to have + // Complete called after importing is done. + ifaces []*types.Interface +} + +// later adds a function to be invoked at the end of import reading. +func (pr *pkgReader) later(fn func()) { + pr.laterFns = append(pr.laterFns, fn) +} + +// See cmd/compile/internal/noder.derivedInfo. +type derivedInfo struct { + idx pkgbits.Index + needed bool +} + +// See cmd/compile/internal/noder.typeInfo. +type typeInfo struct { + idx pkgbits.Index + derived bool +} + +func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + if !debug { + defer func() { + if x := recover(); x != nil { + err = fmt.Errorf("internal error in importing %q (%v); please report an issue", path, x) + } + }() + } + + s := string(data) + s = s[:strings.LastIndex(s, "\n$$\n")] + input := pkgbits.NewPkgDecoder(path, s) + pkg = readUnifiedPackage(fset, nil, imports, input) + return +} + +// laterFor adds a function to be invoked at the end of import reading, and records the type that function is finishing. +func (pr *pkgReader) laterFor(t types.Type, fn func()) { + if pr.laterFors == nil { + pr.laterFors = make(map[types.Type]int) + } + pr.laterFors[t] = len(pr.laterFns) + pr.laterFns = append(pr.laterFns, fn) +} + +// readUnifiedPackage reads a package description from the given +// unified IR export data decoder. +func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package { + pr := pkgReader{ + PkgDecoder: input, + + fake: fakeFileSet{ + fset: fset, + files: make(map[string]*fileInfo), + }, + + ctxt: ctxt, + imports: imports, + + posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)), + pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)), + typs: make([]types.Type, input.NumElems(pkgbits.RelocType)), + } + defer pr.fake.setLines() + + r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) + pkg := r.pkg() + r.Bool() // has init + + for i, n := 0, r.Len(); i < n; i++ { + // As if r.obj(), but avoiding the Scope.Lookup call, + // to avoid eager loading of imports. + r.Sync(pkgbits.SyncObject) + assert(!r.Bool()) + r.p.objIdx(r.Reloc(pkgbits.RelocObj)) + assert(r.Len() == 0) + } + + r.Sync(pkgbits.SyncEOF) + + for _, fn := range pr.laterFns { + fn() + } + + for _, iface := range pr.ifaces { + iface.Complete() + } + + // Imports() of pkg are all of the transitive packages that were loaded. + var imps []*types.Package + for _, imp := range pr.pkgs { + if imp != nil && imp != pkg { + imps = append(imps, imp) + } + } + sort.Sort(byPath(imps)) + pkg.SetImports(imps) + + pkg.MarkComplete() + return pkg +} + +// A reader holds the state for reading a single unified IR element +// within a package. +type reader struct { + pkgbits.Decoder + + p *pkgReader + + dict *readerDict +} + +// A readerDict holds the state for type parameters that parameterize +// the current unified IR element. +type readerDict struct { + // bounds is a slice of typeInfos corresponding to the underlying + // bounds of the element's type parameters. + bounds []typeInfo + + // tparams is a slice of the constructed TypeParams for the element. + tparams []*types.TypeParam + + // devived is a slice of types derived from tparams, which may be + // instantiated while reading the current element. + derived []derivedInfo + derivedTypes []types.Type // lazily instantiated from derived +} + +func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { + return &reader{ + Decoder: pr.NewDecoder(k, idx, marker), + p: pr, + } +} + +func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { + return &reader{ + Decoder: pr.TempDecoder(k, idx, marker), + p: pr, + } +} + +func (pr *pkgReader) retireReader(r *reader) { + pr.RetireDecoder(&r.Decoder) +} + +// @@@ Positions + +func (r *reader) pos() token.Pos { + r.Sync(pkgbits.SyncPos) + if !r.Bool() { + return token.NoPos + } + + // TODO(mdempsky): Delta encoding. + posBase := r.posBase() + line := r.Uint() + col := r.Uint() + return r.p.fake.pos(posBase, int(line), int(col)) +} + +func (r *reader) posBase() string { + return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)) +} + +func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string { + if b := pr.posBases[idx]; b != "" { + return b + } + + var filename string + { + r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase) + + // Within types2, position bases have a lot more details (e.g., + // keeping track of where //line directives appeared exactly). + // + // For go/types, we just track the file name. + + filename = r.String() + + if r.Bool() { // file base + // Was: "b = token.NewTrimmedFileBase(filename, true)" + } else { // line base + pos := r.pos() + line := r.Uint() + col := r.Uint() + + // Was: "b = token.NewLineBase(pos, filename, true, line, col)" + _, _, _ = pos, line, col + } + pr.retireReader(r) + } + b := filename + pr.posBases[idx] = b + return b +} + +// @@@ Packages + +func (r *reader) pkg() *types.Package { + r.Sync(pkgbits.SyncPkg) + return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg)) +} + +func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package { + // TODO(mdempsky): Consider using some non-nil pointer to indicate + // the universe scope, so we don't need to keep re-reading it. + if pkg := pr.pkgs[idx]; pkg != nil { + return pkg + } + + pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg() + pr.pkgs[idx] = pkg + return pkg +} + +func (r *reader) doPkg() *types.Package { + path := r.String() + switch path { + case "": + path = r.p.PkgPath() + case "builtin": + return nil // universe + case "unsafe": + return types.Unsafe + } + + if pkg := r.p.imports[path]; pkg != nil { + return pkg + } + + name := r.String() + + pkg := types.NewPackage(path, name) + r.p.imports[path] = pkg + + return pkg +} + +// @@@ Types + +func (r *reader) typ() types.Type { + return r.p.typIdx(r.typInfo(), r.dict) +} + +func (r *reader) typInfo() typeInfo { + r.Sync(pkgbits.SyncType) + if r.Bool() { + return typeInfo{idx: pkgbits.Index(r.Len()), derived: true} + } + return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false} +} + +func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type { + idx := info.idx + var where *types.Type + if info.derived { + where = &dict.derivedTypes[idx] + idx = dict.derived[idx].idx + } else { + where = &pr.typs[idx] + } + + if typ := *where; typ != nil { + return typ + } + + var typ types.Type + { + r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx) + r.dict = dict + + typ = r.doTyp() + assert(typ != nil) + pr.retireReader(r) + } + // See comment in pkgReader.typIdx explaining how this happens. + if prev := *where; prev != nil { + return prev + } + + *where = typ + return typ +} + +func (r *reader) doTyp() (res types.Type) { + switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag { + default: + errorf("unhandled type tag: %v", tag) + panic("unreachable") + + case pkgbits.TypeBasic: + return types.Typ[r.Len()] + + case pkgbits.TypeNamed: + obj, targs := r.obj() + name := obj.(*types.TypeName) + if len(targs) != 0 { + t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false) + return t + } + return name.Type() + + case pkgbits.TypeTypeParam: + return r.dict.tparams[r.Len()] + + case pkgbits.TypeArray: + len := int64(r.Uint64()) + return types.NewArray(r.typ(), len) + case pkgbits.TypeChan: + dir := types.ChanDir(r.Len()) + return types.NewChan(dir, r.typ()) + case pkgbits.TypeMap: + return types.NewMap(r.typ(), r.typ()) + case pkgbits.TypePointer: + return types.NewPointer(r.typ()) + case pkgbits.TypeSignature: + return r.signature(nil, nil, nil) + case pkgbits.TypeSlice: + return types.NewSlice(r.typ()) + case pkgbits.TypeStruct: + return r.structType() + case pkgbits.TypeInterface: + return r.interfaceType() + case pkgbits.TypeUnion: + return r.unionType() + } +} + +func (r *reader) structType() *types.Struct { + fields := make([]*types.Var, r.Len()) + var tags []string + for i := range fields { + pos := r.pos() + pkg, name := r.selector() + ftyp := r.typ() + tag := r.String() + embedded := r.Bool() + + fields[i] = types.NewField(pos, pkg, name, ftyp, embedded) + if tag != "" { + for len(tags) < i { + tags = append(tags, "") + } + tags = append(tags, tag) + } + } + return types.NewStruct(fields, tags) +} + +func (r *reader) unionType() *types.Union { + terms := make([]*types.Term, r.Len()) + for i := range terms { + terms[i] = types.NewTerm(r.Bool(), r.typ()) + } + return types.NewUnion(terms) +} + +func (r *reader) interfaceType() *types.Interface { + methods := make([]*types.Func, r.Len()) + embeddeds := make([]types.Type, r.Len()) + implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool() + + for i := range methods { + pos := r.pos() + pkg, name := r.selector() + mtyp := r.signature(nil, nil, nil) + methods[i] = types.NewFunc(pos, pkg, name, mtyp) + } + + for i := range embeddeds { + embeddeds[i] = r.typ() + } + + iface := types.NewInterfaceType(methods, embeddeds) + if implicit { + iface.MarkImplicit() + } + + // We need to call iface.Complete(), but if there are any embedded + // defined types, then we may not have set their underlying + // interface type yet. So we need to defer calling Complete until + // after we've called SetUnderlying everywhere. + // + // TODO(mdempsky): After CL 424876 lands, it should be safe to call + // iface.Complete() immediately. + r.p.ifaces = append(r.p.ifaces, iface) + + return iface +} + +func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature { + r.Sync(pkgbits.SyncSignature) + + params := r.params() + results := r.params() + variadic := r.Bool() + + return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic) +} + +func (r *reader) params() *types.Tuple { + r.Sync(pkgbits.SyncParams) + + params := make([]*types.Var, r.Len()) + for i := range params { + params[i] = r.param() + } + + return types.NewTuple(params...) +} + +func (r *reader) param() *types.Var { + r.Sync(pkgbits.SyncParam) + + pos := r.pos() + pkg, name := r.localIdent() + typ := r.typ() + + return types.NewParam(pos, pkg, name, typ) +} + +// @@@ Objects + +func (r *reader) obj() (types.Object, []types.Type) { + r.Sync(pkgbits.SyncObject) + + assert(!r.Bool()) + + pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj)) + obj := pkgScope(pkg).Lookup(name) + + targs := make([]types.Type, r.Len()) + for i := range targs { + targs[i] = r.typ() + } + + return obj, targs +} + +func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { + + var objPkg *types.Package + var objName string + var tag pkgbits.CodeObj + { + rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1) + + objPkg, objName = rname.qualifiedIdent() + assert(objName != "") + + tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj)) + pr.retireReader(rname) + } + + if tag == pkgbits.ObjStub { + assert(objPkg == nil || objPkg == types.Unsafe) + return objPkg, objName + } + + // Ignore local types promoted to global scope (#55110). + if _, suffix := splitVargenSuffix(objName); suffix != "" { + return objPkg, objName + } + + if objPkg.Scope().Lookup(objName) == nil { + dict := pr.objDictIdx(idx) + + r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1) + r.dict = dict + + declare := func(obj types.Object) { + objPkg.Scope().Insert(obj) + } + + switch tag { + default: + panic("weird") + + case pkgbits.ObjAlias: + pos := r.pos() + typ := r.typ() + declare(aliases.NewAlias(pos, objPkg, objName, typ)) + + case pkgbits.ObjConst: + pos := r.pos() + typ := r.typ() + val := r.Value() + declare(types.NewConst(pos, objPkg, objName, typ, val)) + + case pkgbits.ObjFunc: + pos := r.pos() + tparams := r.typeParamNames() + sig := r.signature(nil, nil, tparams) + declare(types.NewFunc(pos, objPkg, objName, sig)) + + case pkgbits.ObjType: + pos := r.pos() + + obj := types.NewTypeName(pos, objPkg, objName, nil) + named := types.NewNamed(obj, nil, nil) + declare(obj) + + named.SetTypeParams(r.typeParamNames()) + + setUnderlying := func(underlying types.Type) { + // If the underlying type is an interface, we need to + // duplicate its methods so we can replace the receiver + // parameter's type (#49906). + if iface, ok := aliases.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 { + methods := make([]*types.Func, iface.NumExplicitMethods()) + for i := range methods { + fn := iface.ExplicitMethod(i) + sig := fn.Type().(*types.Signature) + + recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named) + methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic())) + } + + embeds := make([]types.Type, iface.NumEmbeddeds()) + for i := range embeds { + embeds[i] = iface.EmbeddedType(i) + } + + newIface := types.NewInterfaceType(methods, embeds) + r.p.ifaces = append(r.p.ifaces, newIface) + underlying = newIface + } + + named.SetUnderlying(underlying) + } + + // Since go.dev/cl/455279, we can assume rhs.Underlying() will + // always be non-nil. However, to temporarily support users of + // older snapshot releases, we continue to fallback to the old + // behavior for now. + // + // TODO(mdempsky): Remove fallback code and simplify after + // allowing time for snapshot users to upgrade. + rhs := r.typ() + if underlying := rhs.Underlying(); underlying != nil { + setUnderlying(underlying) + } else { + pk := r.p + pk.laterFor(named, func() { + // First be sure that the rhs is initialized, if it needs to be initialized. + delete(pk.laterFors, named) // prevent cycles + if i, ok := pk.laterFors[rhs]; ok { + f := pk.laterFns[i] + pk.laterFns[i] = func() {} // function is running now, so replace it with a no-op + f() // initialize RHS + } + setUnderlying(rhs.Underlying()) + }) + } + + for i, n := 0, r.Len(); i < n; i++ { + named.AddMethod(r.method()) + } + + case pkgbits.ObjVar: + pos := r.pos() + typ := r.typ() + declare(types.NewVar(pos, objPkg, objName, typ)) + } + } + + return objPkg, objName +} + +func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { + + var dict readerDict + + { + r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1) + if implicits := r.Len(); implicits != 0 { + errorf("unexpected object with %v implicit type parameter(s)", implicits) + } + + dict.bounds = make([]typeInfo, r.Len()) + for i := range dict.bounds { + dict.bounds[i] = r.typInfo() + } + + dict.derived = make([]derivedInfo, r.Len()) + dict.derivedTypes = make([]types.Type, len(dict.derived)) + for i := range dict.derived { + dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()} + } + + pr.retireReader(r) + } + // function references follow, but reader doesn't need those + + return &dict +} + +func (r *reader) typeParamNames() []*types.TypeParam { + r.Sync(pkgbits.SyncTypeParamNames) + + // Note: This code assumes it only processes objects without + // implement type parameters. This is currently fine, because + // reader is only used to read in exported declarations, which are + // always package scoped. + + if len(r.dict.bounds) == 0 { + return nil + } + + // Careful: Type parameter lists may have cycles. To allow for this, + // we construct the type parameter list in two passes: first we + // create all the TypeNames and TypeParams, then we construct and + // set the bound type. + + r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds)) + for i := range r.dict.bounds { + pos := r.pos() + pkg, name := r.localIdent() + + tname := types.NewTypeName(pos, pkg, name, nil) + r.dict.tparams[i] = types.NewTypeParam(tname, nil) + } + + typs := make([]types.Type, len(r.dict.bounds)) + for i, bound := range r.dict.bounds { + typs[i] = r.p.typIdx(bound, r.dict) + } + + // TODO(mdempsky): This is subtle, elaborate further. + // + // We have to save tparams outside of the closure, because + // typeParamNames() can be called multiple times with the same + // dictionary instance. + // + // Also, this needs to happen later to make sure SetUnderlying has + // been called. + // + // TODO(mdempsky): Is it safe to have a single "later" slice or do + // we need to have multiple passes? See comments on CL 386002 and + // go.dev/issue/52104. + tparams := r.dict.tparams + r.p.later(func() { + for i, typ := range typs { + tparams[i].SetConstraint(typ) + } + }) + + return r.dict.tparams +} + +func (r *reader) method() *types.Func { + r.Sync(pkgbits.SyncMethod) + pos := r.pos() + pkg, name := r.selector() + + rparams := r.typeParamNames() + sig := r.signature(r.param(), rparams, nil) + + _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go. + return types.NewFunc(pos, pkg, name, sig) +} + +func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) } +func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) } +func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) } + +func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) { + r.Sync(marker) + return r.pkg(), r.String() +} + +// pkgScope returns pkg.Scope(). +// If pkg is nil, it returns types.Universe instead. +// +// TODO(mdempsky): Remove after x/tools can depend on Go 1.19. +func pkgScope(pkg *types.Package) *types.Scope { + if pkg != nil { + return pkg.Scope() + } + return types.Universe +} diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go new file mode 100644 index 00000000..f7de3c82 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go @@ -0,0 +1,468 @@ +// 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 gocommand is a helper for calling the go command. +package gocommand + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "log" + "os" + "os/exec" + "reflect" + "regexp" + "runtime" + "strconv" + "strings" + "sync" + "time" + + "golang.org/x/tools/internal/event" + "golang.org/x/tools/internal/event/keys" + "golang.org/x/tools/internal/event/label" + "golang.org/x/tools/internal/event/tag" +) + +// An Runner will run go command invocations and serialize +// them if it sees a concurrency error. +type Runner struct { + // once guards the runner initialization. + once sync.Once + + // inFlight tracks available workers. + inFlight chan struct{} + + // serialized guards the ability to run a go command serially, + // to avoid deadlocks when claiming workers. + serialized chan struct{} +} + +const maxInFlight = 10 + +func (runner *Runner) initialize() { + runner.once.Do(func() { + runner.inFlight = make(chan struct{}, maxInFlight) + runner.serialized = make(chan struct{}, 1) + }) +} + +// 1.13: go: updates to go.mod needed, but contents have changed +// 1.14: go: updating go.mod: existing contents have changed since last read +var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`) + +// verb is an event label for the go command verb. +var verb = keys.NewString("verb", "go command verb") + +func invLabels(inv Invocation) []label.Label { + return []label.Label{verb.Of(inv.Verb), tag.Directory.Of(inv.WorkingDir)} +} + +// Run is a convenience wrapper around RunRaw. +// It returns only stdout and a "friendly" error. +func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) { + ctx, done := event.Start(ctx, "gocommand.Runner.Run", invLabels(inv)...) + defer done() + + stdout, _, friendly, _ := runner.RunRaw(ctx, inv) + return stdout, friendly +} + +// RunPiped runs the invocation serially, always waiting for any concurrent +// invocations to complete first. +func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) error { + ctx, done := event.Start(ctx, "gocommand.Runner.RunPiped", invLabels(inv)...) + defer done() + + _, err := runner.runPiped(ctx, inv, stdout, stderr) + return err +} + +// RunRaw runs the invocation, serializing requests only if they fight over +// go.mod changes. +// Postcondition: both error results have same nilness. +func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { + ctx, done := event.Start(ctx, "gocommand.Runner.RunRaw", invLabels(inv)...) + defer done() + // Make sure the runner is always initialized. + runner.initialize() + + // First, try to run the go command concurrently. + stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv) + + // If we encounter a load concurrency error, we need to retry serially. + if friendlyErr != nil && modConcurrencyError.MatchString(friendlyErr.Error()) { + event.Error(ctx, "Load concurrency error, will retry serially", err) + + // Run serially by calling runPiped. + stdout.Reset() + stderr.Reset() + friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr) + } + + return stdout, stderr, friendlyErr, err +} + +// Postcondition: both error results have same nilness. +func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { + // Wait for 1 worker to become available. + select { + case <-ctx.Done(): + return nil, nil, ctx.Err(), ctx.Err() + case runner.inFlight <- struct{}{}: + defer func() { <-runner.inFlight }() + } + + stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{} + friendlyErr, err := inv.runWithFriendlyError(ctx, stdout, stderr) + return stdout, stderr, friendlyErr, err +} + +// Postcondition: both error results have same nilness. +func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) { + // Make sure the runner is always initialized. + runner.initialize() + + // Acquire the serialization lock. This avoids deadlocks between two + // runPiped commands. + select { + case <-ctx.Done(): + return ctx.Err(), ctx.Err() + case runner.serialized <- struct{}{}: + defer func() { <-runner.serialized }() + } + + // Wait for all in-progress go commands to return before proceeding, + // to avoid load concurrency errors. + for i := 0; i < maxInFlight; i++ { + select { + case <-ctx.Done(): + return ctx.Err(), ctx.Err() + case runner.inFlight <- struct{}{}: + // Make sure we always "return" any workers we took. + defer func() { <-runner.inFlight }() + } + } + + return inv.runWithFriendlyError(ctx, stdout, stderr) +} + +// An Invocation represents a call to the go command. +type Invocation struct { + Verb string + Args []string + BuildFlags []string + + // If ModFlag is set, the go command is invoked with -mod=ModFlag. + // TODO(rfindley): remove, in favor of Args. + ModFlag string + + // If ModFile is set, the go command is invoked with -modfile=ModFile. + // TODO(rfindley): remove, in favor of Args. + ModFile string + + // If Overlay is set, the go command is invoked with -overlay=Overlay. + // TODO(rfindley): remove, in favor of Args. + Overlay string + + // If CleanEnv is set, the invocation will run only with the environment + // in Env, not starting with os.Environ. + CleanEnv bool + Env []string + WorkingDir string + Logf func(format string, args ...interface{}) +} + +// Postcondition: both error results have same nilness. +func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) { + rawError = i.run(ctx, stdout, stderr) + if rawError != nil { + friendlyError = rawError + // Check for 'go' executable not being found. + if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound { + friendlyError = fmt.Errorf("go command required, not found: %v", ee) + } + if ctx.Err() != nil { + friendlyError = ctx.Err() + } + friendlyError = fmt.Errorf("err: %v: stderr: %s", friendlyError, stderr) + } + return +} + +func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { + log := i.Logf + if log == nil { + log = func(string, ...interface{}) {} + } + + goArgs := []string{i.Verb} + + appendModFile := func() { + if i.ModFile != "" { + goArgs = append(goArgs, "-modfile="+i.ModFile) + } + } + appendModFlag := func() { + if i.ModFlag != "" { + goArgs = append(goArgs, "-mod="+i.ModFlag) + } + } + appendOverlayFlag := func() { + if i.Overlay != "" { + goArgs = append(goArgs, "-overlay="+i.Overlay) + } + } + + switch i.Verb { + case "env", "version": + goArgs = append(goArgs, i.Args...) + case "mod": + // mod needs the sub-verb before flags. + goArgs = append(goArgs, i.Args[0]) + appendModFile() + goArgs = append(goArgs, i.Args[1:]...) + case "get": + goArgs = append(goArgs, i.BuildFlags...) + appendModFile() + goArgs = append(goArgs, i.Args...) + + default: // notably list and build. + goArgs = append(goArgs, i.BuildFlags...) + appendModFile() + appendModFlag() + appendOverlayFlag() + goArgs = append(goArgs, i.Args...) + } + cmd := exec.Command("go", goArgs...) + cmd.Stdout = stdout + cmd.Stderr = stderr + + // cmd.WaitDelay was added only in go1.20 (see #50436). + if waitDelay := reflect.ValueOf(cmd).Elem().FieldByName("WaitDelay"); waitDelay.IsValid() { + // https://go.dev/issue/59541: don't wait forever copying stderr + // after the command has exited. + // After CL 484741 we copy stdout manually, so we we'll stop reading that as + // soon as ctx is done. However, we also don't want to wait around forever + // for stderr. Give a much-longer-than-reasonable delay and then assume that + // something has wedged in the kernel or runtime. + waitDelay.Set(reflect.ValueOf(30 * time.Second)) + } + + // On darwin the cwd gets resolved to the real path, which breaks anything that + // expects the working directory to keep the original path, including the + // go command when dealing with modules. + // The Go stdlib has a special feature where if the cwd and the PWD are the + // same node then it trusts the PWD, so by setting it in the env for the child + // process we fix up all the paths returned by the go command. + if !i.CleanEnv { + cmd.Env = os.Environ() + } + cmd.Env = append(cmd.Env, i.Env...) + if i.WorkingDir != "" { + cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir) + cmd.Dir = i.WorkingDir + } + + defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now()) + + return runCmdContext(ctx, cmd) +} + +// DebugHangingGoCommands may be set by tests to enable additional +// instrumentation (including panics) for debugging hanging Go commands. +// +// See golang/go#54461 for details. +var DebugHangingGoCommands = false + +// runCmdContext is like exec.CommandContext except it sends os.Interrupt +// before os.Kill. +func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) { + // If cmd.Stdout is not an *os.File, the exec package will create a pipe and + // copy it to the Writer in a goroutine until the process has finished and + // either the pipe reaches EOF or command's WaitDelay expires. + // + // However, the output from 'go list' can be quite large, and we don't want to + // keep reading (and allocating buffers) if we've already decided we don't + // care about the output. We don't want to wait for the process to finish, and + // we don't wait to wait for the WaitDelay to expire either. + // + // Instead, if cmd.Stdout requires a copying goroutine we explicitly replace + // it with a pipe (which is an *os.File), which we can close in order to stop + // copying output as soon as we realize we don't care about it. + var stdoutW *os.File + if cmd.Stdout != nil { + if _, ok := cmd.Stdout.(*os.File); !ok { + var stdoutR *os.File + stdoutR, stdoutW, err = os.Pipe() + if err != nil { + return err + } + prevStdout := cmd.Stdout + cmd.Stdout = stdoutW + + stdoutErr := make(chan error, 1) + go func() { + _, err := io.Copy(prevStdout, stdoutR) + if err != nil { + err = fmt.Errorf("copying stdout: %w", err) + } + stdoutErr <- err + }() + defer func() { + // We started a goroutine to copy a stdout pipe. + // Wait for it to finish, or terminate it if need be. + var err2 error + select { + case err2 = <-stdoutErr: + stdoutR.Close() + case <-ctx.Done(): + stdoutR.Close() + // Per https://pkg.go.dev/os#File.Close, the call to stdoutR.Close + // should cause the Read call in io.Copy to unblock and return + // immediately, but we still need to receive from stdoutErr to confirm + // that it has happened. + <-stdoutErr + err2 = ctx.Err() + } + if err == nil { + err = err2 + } + }() + + // Per https://pkg.go.dev/os/exec#Cmd, “If Stdout and Stderr are the + // same writer, and have a type that can be compared with ==, at most + // one goroutine at a time will call Write.” + // + // Since we're starting a goroutine that writes to cmd.Stdout, we must + // also update cmd.Stderr so that it still holds. + func() { + defer func() { recover() }() + if cmd.Stderr == prevStdout { + cmd.Stderr = cmd.Stdout + } + }() + } + } + + err = cmd.Start() + if stdoutW != nil { + // The child process has inherited the pipe file, + // so close the copy held in this process. + stdoutW.Close() + stdoutW = nil + } + if err != nil { + return err + } + + resChan := make(chan error, 1) + go func() { + resChan <- cmd.Wait() + }() + + // If we're interested in debugging hanging Go commands, stop waiting after a + // minute and panic with interesting information. + debug := DebugHangingGoCommands + if debug { + timer := time.NewTimer(1 * time.Minute) + defer timer.Stop() + select { + case err := <-resChan: + return err + case <-timer.C: + HandleHangingGoCommand(cmd.Process) + case <-ctx.Done(): + } + } else { + select { + case err := <-resChan: + return err + case <-ctx.Done(): + } + } + + // Cancelled. Interrupt and see if it ends voluntarily. + if err := cmd.Process.Signal(os.Interrupt); err == nil { + // (We used to wait only 1s but this proved + // fragile on loaded builder machines.) + timer := time.NewTimer(5 * time.Second) + defer timer.Stop() + select { + case err := <-resChan: + return err + case <-timer.C: + } + } + + // Didn't shut down in response to interrupt. Kill it hard. + // TODO(rfindley): per advice from bcmills@, it may be better to send SIGQUIT + // on certain platforms, such as unix. + if err := cmd.Process.Kill(); err != nil && !errors.Is(err, os.ErrProcessDone) && debug { + log.Printf("error killing the Go command: %v", err) + } + + return <-resChan +} + +func HandleHangingGoCommand(proc *os.Process) { + switch runtime.GOOS { + case "linux", "darwin", "freebsd", "netbsd": + fmt.Fprintln(os.Stderr, `DETECTED A HANGING GO COMMAND + +The gopls test runner has detected a hanging go command. In order to debug +this, the output of ps and lsof/fstat is printed below. + +See golang/go#54461 for more details.`) + + fmt.Fprintln(os.Stderr, "\nps axo ppid,pid,command:") + fmt.Fprintln(os.Stderr, "-------------------------") + psCmd := exec.Command("ps", "axo", "ppid,pid,command") + psCmd.Stdout = os.Stderr + psCmd.Stderr = os.Stderr + if err := psCmd.Run(); err != nil { + panic(fmt.Sprintf("running ps: %v", err)) + } + + listFiles := "lsof" + if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" { + listFiles = "fstat" + } + + fmt.Fprintln(os.Stderr, "\n"+listFiles+":") + fmt.Fprintln(os.Stderr, "-----") + listFilesCmd := exec.Command(listFiles) + listFilesCmd.Stdout = os.Stderr + listFilesCmd.Stderr = os.Stderr + if err := listFilesCmd.Run(); err != nil { + panic(fmt.Sprintf("running %s: %v", listFiles, err)) + } + } + panic(fmt.Sprintf("detected hanging go command (pid %d): see golang/go#54461 for more details", proc.Pid)) +} + +func cmdDebugStr(cmd *exec.Cmd) string { + env := make(map[string]string) + for _, kv := range cmd.Env { + split := strings.SplitN(kv, "=", 2) + if len(split) == 2 { + k, v := split[0], split[1] + env[k] = v + } + } + + var args []string + for _, arg := range cmd.Args { + quoted := strconv.Quote(arg) + if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { + args = append(args, quoted) + } else { + args = append(args, arg) + } + } + return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) +} diff --git a/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/vendor/golang.org/x/tools/internal/gocommand/vendor.go new file mode 100644 index 00000000..2d3d408c --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gocommand/vendor.go @@ -0,0 +1,109 @@ +// 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 gocommand + +import ( + "bytes" + "context" + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + "time" + + "golang.org/x/mod/semver" +) + +// ModuleJSON holds information about a module. +type ModuleJSON struct { + Path string // module path + Version string // module version + Versions []string // available module versions (with -versions) + Replace *ModuleJSON // replaced by this module + Time *time.Time // time version was created + Update *ModuleJSON // available update, if any (with -u) + Main bool // is this the main module? + Indirect bool // is this module only an indirect dependency of main module? + Dir string // directory holding files for this module, if any + GoMod string // path to go.mod file used when loading this module, if any + GoVersion string // go version used in module +} + +var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`) + +// VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands +// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, +// of which only Verb and Args are modified to run the appropriate Go command. +// Inspired by setDefaultBuildMod in modload/init.go +func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, *ModuleJSON, error) { + mainMod, go114, err := getMainModuleAnd114(ctx, inv, r) + if err != nil { + return false, nil, err + } + + // We check the GOFLAGS to see if there is anything overridden or not. + inv.Verb = "env" + inv.Args = []string{"GOFLAGS"} + stdout, err := r.Run(ctx, inv) + if err != nil { + return false, nil, err + } + goflags := string(bytes.TrimSpace(stdout.Bytes())) + matches := modFlagRegexp.FindStringSubmatch(goflags) + var modFlag string + if len(matches) != 0 { + modFlag = matches[1] + } + // Don't override an explicit '-mod=' argument. + if modFlag == "vendor" { + return true, mainMod, nil + } else if modFlag != "" { + return false, nil, nil + } + if mainMod == nil || !go114 { + return false, nil, nil + } + // Check 1.14's automatic vendor mode. + if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() { + if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 { + // The Go version is at least 1.14, and a vendor directory exists. + // Set -mod=vendor by default. + return true, mainMod, nil + } + } + return false, nil, nil +} + +// getMainModuleAnd114 gets one of the main modules' information and whether the +// go command in use is 1.14+. This is the information needed to figure out +// if vendoring should be enabled. +func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { + const format = `{{.Path}} +{{.Dir}} +{{.GoMod}} +{{.GoVersion}} +{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}} +` + inv.Verb = "list" + inv.Args = []string{"-m", "-f", format} + stdout, err := r.Run(ctx, inv) + if err != nil { + return nil, false, err + } + + lines := strings.Split(stdout.String(), "\n") + if len(lines) < 5 { + return nil, false, fmt.Errorf("unexpected stdout: %q", stdout.String()) + } + mod := &ModuleJSON{ + Path: lines[0], + Dir: lines[1], + GoMod: lines[2], + GoVersion: lines[3], + Main: true, + } + return mod, lines[4] == "go1.14", nil +} diff --git a/vendor/golang.org/x/tools/internal/gocommand/version.go b/vendor/golang.org/x/tools/internal/gocommand/version.go new file mode 100644 index 00000000..446c5846 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gocommand/version.go @@ -0,0 +1,71 @@ +// 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 gocommand + +import ( + "context" + "fmt" + "regexp" + "strings" +) + +// GoVersion reports the minor version number of the highest release +// tag built into the go command on the PATH. +// +// Note that this may be higher than the version of the go tool used +// to build this application, and thus the versions of the standard +// go/{scanner,parser,ast,types} packages that are linked into it. +// In that case, callers should either downgrade to the version of +// go used to build the application, or report an error that the +// application is too old to use the go command on the PATH. +func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) { + inv.Verb = "list" + inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`, `--`, `unsafe`} + inv.BuildFlags = nil // This is not a build command. + inv.ModFlag = "" + inv.ModFile = "" + inv.Env = append(inv.Env[:len(inv.Env):len(inv.Env)], "GO111MODULE=off") + + stdoutBytes, err := r.Run(ctx, inv) + if err != nil { + return 0, err + } + stdout := stdoutBytes.String() + if len(stdout) < 3 { + return 0, fmt.Errorf("bad ReleaseTags output: %q", stdout) + } + // Split up "[go1.1 go1.15]" and return highest go1.X value. + tags := strings.Fields(stdout[1 : len(stdout)-2]) + for i := len(tags) - 1; i >= 0; i-- { + var version int + if _, err := fmt.Sscanf(tags[i], "go1.%d", &version); err != nil { + continue + } + return version, nil + } + return 0, fmt.Errorf("no parseable ReleaseTags in %v", tags) +} + +// GoVersionOutput returns the complete output of the go version command. +func GoVersionOutput(ctx context.Context, inv Invocation, r *Runner) (string, error) { + inv.Verb = "version" + goVersion, err := r.Run(ctx, inv) + if err != nil { + return "", err + } + return goVersion.String(), nil +} + +// ParseGoVersionOutput extracts the Go version string +// from the output of the "go version" command. +// Given an unrecognized form, it returns an empty string. +func ParseGoVersionOutput(data string) string { + re := regexp.MustCompile(`^go version (go\S+|devel \S+)`) + m := re.FindStringSubmatch(data) + if len(m) != 2 { + return "" // unrecognized version + } + return m[1] +} diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go new file mode 100644 index 00000000..44719de1 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go @@ -0,0 +1,22 @@ +// 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 packagesinternal exposes internal-only fields from go/packages. +package packagesinternal + +var GetForTest = func(p interface{}) string { return "" } +var GetDepsErrors = func(p interface{}) []*PackageError { return nil } + +type PackageError struct { + ImportStack []string // shortest path from package named on command line to this one + Pos string // position of error (if present, file:line:col) + Err string // the error itself +} + +var TypecheckCgo int +var DepsErrors int // must be set as a LoadMode to call GetDepsErrors +var ForTest int // must be set as a LoadMode to call GetForTest + +var SetModFlag = func(config interface{}, value string) {} +var SetModFile = func(config interface{}, value string) {} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/codes.go b/vendor/golang.org/x/tools/internal/pkgbits/codes.go new file mode 100644 index 00000000..f0cabde9 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/codes.go @@ -0,0 +1,77 @@ +// 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 pkgbits + +// A Code is an enum value that can be encoded into bitstreams. +// +// Code types are preferable for enum types, because they allow +// Decoder to detect desyncs. +type Code interface { + // Marker returns the SyncMarker for the Code's dynamic type. + Marker() SyncMarker + + // Value returns the Code's ordinal value. + Value() int +} + +// A CodeVal distinguishes among go/constant.Value encodings. +type CodeVal int + +func (c CodeVal) Marker() SyncMarker { return SyncVal } +func (c CodeVal) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + ValBool CodeVal = iota + ValString + ValInt64 + ValBigInt + ValBigRat + ValBigFloat +) + +// A CodeType distinguishes among go/types.Type encodings. +type CodeType int + +func (c CodeType) Marker() SyncMarker { return SyncType } +func (c CodeType) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + TypeBasic CodeType = iota + TypeNamed + TypePointer + TypeSlice + TypeArray + TypeChan + TypeMap + TypeSignature + TypeStruct + TypeInterface + TypeUnion + TypeTypeParam +) + +// A CodeObj distinguishes among go/types.Object encodings. +type CodeObj int + +func (c CodeObj) Marker() SyncMarker { return SyncCodeObj } +func (c CodeObj) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + ObjAlias CodeObj = iota + ObjConst + ObjType + ObjFunc + ObjVar + ObjStub +) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go new file mode 100644 index 00000000..b92e8e6e --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go @@ -0,0 +1,517 @@ +// 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 pkgbits + +import ( + "encoding/binary" + "errors" + "fmt" + "go/constant" + "go/token" + "io" + "math/big" + "os" + "runtime" + "strings" +) + +// A PkgDecoder provides methods for decoding a package's Unified IR +// export data. +type PkgDecoder struct { + // version is the file format version. + version uint32 + + // sync indicates whether the file uses sync markers. + sync bool + + // pkgPath is the package path for the package to be decoded. + // + // TODO(mdempsky): Remove; unneeded since CL 391014. + pkgPath string + + // elemData is the full data payload of the encoded package. + // Elements are densely and contiguously packed together. + // + // The last 8 bytes of elemData are the package fingerprint. + elemData string + + // elemEnds stores the byte-offset end positions of element + // bitstreams within elemData. + // + // For example, element I's bitstream data starts at elemEnds[I-1] + // (or 0, if I==0) and ends at elemEnds[I]. + // + // Note: elemEnds is indexed by absolute indices, not + // section-relative indices. + elemEnds []uint32 + + // elemEndsEnds stores the index-offset end positions of relocation + // sections within elemEnds. + // + // For example, section K's end positions start at elemEndsEnds[K-1] + // (or 0, if K==0) and end at elemEndsEnds[K]. + elemEndsEnds [numRelocs]uint32 + + scratchRelocEnt []RelocEnt +} + +// PkgPath returns the package path for the package +// +// TODO(mdempsky): Remove; unneeded since CL 391014. +func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath } + +// SyncMarkers reports whether pr uses sync markers. +func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync } + +// NewPkgDecoder returns a PkgDecoder initialized to read the Unified +// IR export data from input. pkgPath is the package path for the +// compilation unit that produced the export data. +// +// TODO(mdempsky): Remove pkgPath parameter; unneeded since CL 391014. +func NewPkgDecoder(pkgPath, input string) PkgDecoder { + pr := PkgDecoder{ + pkgPath: pkgPath, + } + + // TODO(mdempsky): Implement direct indexing of input string to + // avoid copying the position information. + + r := strings.NewReader(input) + + assert(binary.Read(r, binary.LittleEndian, &pr.version) == nil) + + switch pr.version { + default: + panic(fmt.Errorf("unsupported version: %v", pr.version)) + case 0: + // no flags + case 1: + var flags uint32 + assert(binary.Read(r, binary.LittleEndian, &flags) == nil) + pr.sync = flags&flagSyncMarkers != 0 + } + + assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil) + + pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1]) + assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil) + + pos, err := r.Seek(0, io.SeekCurrent) + assert(err == nil) + + pr.elemData = input[pos:] + assert(len(pr.elemData)-8 == int(pr.elemEnds[len(pr.elemEnds)-1])) + + return pr +} + +// NumElems returns the number of elements in section k. +func (pr *PkgDecoder) NumElems(k RelocKind) int { + count := int(pr.elemEndsEnds[k]) + if k > 0 { + count -= int(pr.elemEndsEnds[k-1]) + } + return count +} + +// TotalElems returns the total number of elements across all sections. +func (pr *PkgDecoder) TotalElems() int { + return len(pr.elemEnds) +} + +// Fingerprint returns the package fingerprint. +func (pr *PkgDecoder) Fingerprint() [8]byte { + var fp [8]byte + copy(fp[:], pr.elemData[len(pr.elemData)-8:]) + return fp +} + +// AbsIdx returns the absolute index for the given (section, index) +// pair. +func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int { + absIdx := int(idx) + if k > 0 { + absIdx += int(pr.elemEndsEnds[k-1]) + } + if absIdx >= int(pr.elemEndsEnds[k]) { + errorf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds) + } + return absIdx +} + +// DataIdx returns the raw element bitstream for the given (section, +// index) pair. +func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string { + absIdx := pr.AbsIdx(k, idx) + + var start uint32 + if absIdx > 0 { + start = pr.elemEnds[absIdx-1] + } + end := pr.elemEnds[absIdx] + + return pr.elemData[start:end] +} + +// StringIdx returns the string value for the given string index. +func (pr *PkgDecoder) StringIdx(idx Index) string { + return pr.DataIdx(RelocString, idx) +} + +// NewDecoder returns a Decoder for the given (section, index) pair, +// and decodes the given SyncMarker from the element bitstream. +func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder { + r := pr.NewDecoderRaw(k, idx) + r.Sync(marker) + return r +} + +// TempDecoder returns a Decoder for the given (section, index) pair, +// and decodes the given SyncMarker from the element bitstream. +// If possible the Decoder should be RetireDecoder'd when it is no longer +// needed, this will avoid heap allocations. +func (pr *PkgDecoder) TempDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder { + r := pr.TempDecoderRaw(k, idx) + r.Sync(marker) + return r +} + +func (pr *PkgDecoder) RetireDecoder(d *Decoder) { + pr.scratchRelocEnt = d.Relocs + d.Relocs = nil +} + +// NewDecoderRaw returns a Decoder for the given (section, index) pair. +// +// Most callers should use NewDecoder instead. +func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder { + r := Decoder{ + common: pr, + k: k, + Idx: idx, + } + + // TODO(mdempsky) r.data.Reset(...) after #44505 is resolved. + r.Data = *strings.NewReader(pr.DataIdx(k, idx)) + + r.Sync(SyncRelocs) + r.Relocs = make([]RelocEnt, r.Len()) + for i := range r.Relocs { + r.Sync(SyncReloc) + r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())} + } + + return r +} + +func (pr *PkgDecoder) TempDecoderRaw(k RelocKind, idx Index) Decoder { + r := Decoder{ + common: pr, + k: k, + Idx: idx, + } + + r.Data.Reset(pr.DataIdx(k, idx)) + r.Sync(SyncRelocs) + l := r.Len() + if cap(pr.scratchRelocEnt) >= l { + r.Relocs = pr.scratchRelocEnt[:l] + pr.scratchRelocEnt = nil + } else { + r.Relocs = make([]RelocEnt, l) + } + for i := range r.Relocs { + r.Sync(SyncReloc) + r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())} + } + + return r +} + +// A Decoder provides methods for decoding an individual element's +// bitstream data. +type Decoder struct { + common *PkgDecoder + + Relocs []RelocEnt + Data strings.Reader + + k RelocKind + Idx Index +} + +func (r *Decoder) checkErr(err error) { + if err != nil { + errorf("unexpected decoding error: %w", err) + } +} + +func (r *Decoder) rawUvarint() uint64 { + x, err := readUvarint(&r.Data) + r.checkErr(err) + return x +} + +// readUvarint is a type-specialized copy of encoding/binary.ReadUvarint. +// This avoids the interface conversion and thus has better escape properties, +// which flows up the stack. +func readUvarint(r *strings.Reader) (uint64, error) { + var x uint64 + var s uint + for i := 0; i < binary.MaxVarintLen64; i++ { + b, err := r.ReadByte() + if err != nil { + if i > 0 && err == io.EOF { + err = io.ErrUnexpectedEOF + } + return x, err + } + if b < 0x80 { + if i == binary.MaxVarintLen64-1 && b > 1 { + return x, overflow + } + return x | uint64(b)<> 1) + if ux&1 != 0 { + x = ^x + } + return x +} + +func (r *Decoder) rawReloc(k RelocKind, idx int) Index { + e := r.Relocs[idx] + assert(e.Kind == k) + return e.Idx +} + +// Sync decodes a sync marker from the element bitstream and asserts +// that it matches the expected marker. +// +// If r.common.sync is false, then Sync is a no-op. +func (r *Decoder) Sync(mWant SyncMarker) { + if !r.common.sync { + return + } + + pos, _ := r.Data.Seek(0, io.SeekCurrent) + mHave := SyncMarker(r.rawUvarint()) + writerPCs := make([]int, r.rawUvarint()) + for i := range writerPCs { + writerPCs[i] = int(r.rawUvarint()) + } + + if mHave == mWant { + return + } + + // There's some tension here between printing: + // + // (1) full file paths that tools can recognize (e.g., so emacs + // hyperlinks the "file:line" text for easy navigation), or + // + // (2) short file paths that are easier for humans to read (e.g., by + // omitting redundant or irrelevant details, so it's easier to + // focus on the useful bits that remain). + // + // The current formatting favors the former, as it seems more + // helpful in practice. But perhaps the formatting could be improved + // to better address both concerns. For example, use relative file + // paths if they would be shorter, or rewrite file paths to contain + // "$GOROOT" (like objabi.AbsFile does) if tools can be taught how + // to reliably expand that again. + + fmt.Printf("export data desync: package %q, section %v, index %v, offset %v\n", r.common.pkgPath, r.k, r.Idx, pos) + + fmt.Printf("\nfound %v, written at:\n", mHave) + if len(writerPCs) == 0 { + fmt.Printf("\t[stack trace unavailable; recompile package %q with -d=syncframes]\n", r.common.pkgPath) + } + for _, pc := range writerPCs { + fmt.Printf("\t%s\n", r.common.StringIdx(r.rawReloc(RelocString, pc))) + } + + fmt.Printf("\nexpected %v, reading at:\n", mWant) + var readerPCs [32]uintptr // TODO(mdempsky): Dynamically size? + n := runtime.Callers(2, readerPCs[:]) + for _, pc := range fmtFrames(readerPCs[:n]...) { + fmt.Printf("\t%s\n", pc) + } + + // We already printed a stack trace for the reader, so now we can + // simply exit. Printing a second one with panic or base.Fatalf + // would just be noise. + os.Exit(1) +} + +// Bool decodes and returns a bool value from the element bitstream. +func (r *Decoder) Bool() bool { + r.Sync(SyncBool) + x, err := r.Data.ReadByte() + r.checkErr(err) + assert(x < 2) + return x != 0 +} + +// Int64 decodes and returns an int64 value from the element bitstream. +func (r *Decoder) Int64() int64 { + r.Sync(SyncInt64) + return r.rawVarint() +} + +// Uint64 decodes and returns a uint64 value from the element bitstream. +func (r *Decoder) Uint64() uint64 { + r.Sync(SyncUint64) + return r.rawUvarint() +} + +// Len decodes and returns a non-negative int value from the element bitstream. +func (r *Decoder) Len() int { x := r.Uint64(); v := int(x); assert(uint64(v) == x); return v } + +// Int decodes and returns an int value from the element bitstream. +func (r *Decoder) Int() int { x := r.Int64(); v := int(x); assert(int64(v) == x); return v } + +// Uint decodes and returns a uint value from the element bitstream. +func (r *Decoder) Uint() uint { x := r.Uint64(); v := uint(x); assert(uint64(v) == x); return v } + +// Code decodes a Code value from the element bitstream and returns +// its ordinal value. It's the caller's responsibility to convert the +// result to an appropriate Code type. +// +// TODO(mdempsky): Ideally this method would have signature "Code[T +// Code] T" instead, but we don't allow generic methods and the +// compiler can't depend on generics yet anyway. +func (r *Decoder) Code(mark SyncMarker) int { + r.Sync(mark) + return r.Len() +} + +// Reloc decodes a relocation of expected section k from the element +// bitstream and returns an index to the referenced element. +func (r *Decoder) Reloc(k RelocKind) Index { + r.Sync(SyncUseReloc) + return r.rawReloc(k, r.Len()) +} + +// String decodes and returns a string value from the element +// bitstream. +func (r *Decoder) String() string { + r.Sync(SyncString) + return r.common.StringIdx(r.Reloc(RelocString)) +} + +// Strings decodes and returns a variable-length slice of strings from +// the element bitstream. +func (r *Decoder) Strings() []string { + res := make([]string, r.Len()) + for i := range res { + res[i] = r.String() + } + return res +} + +// Value decodes and returns a constant.Value from the element +// bitstream. +func (r *Decoder) Value() constant.Value { + r.Sync(SyncValue) + isComplex := r.Bool() + val := r.scalar() + if isComplex { + val = constant.BinaryOp(val, token.ADD, constant.MakeImag(r.scalar())) + } + return val +} + +func (r *Decoder) scalar() constant.Value { + switch tag := CodeVal(r.Code(SyncVal)); tag { + default: + panic(fmt.Errorf("unexpected scalar tag: %v", tag)) + + case ValBool: + return constant.MakeBool(r.Bool()) + case ValString: + return constant.MakeString(r.String()) + case ValInt64: + return constant.MakeInt64(r.Int64()) + case ValBigInt: + return constant.Make(r.bigInt()) + case ValBigRat: + num := r.bigInt() + denom := r.bigInt() + return constant.Make(new(big.Rat).SetFrac(num, denom)) + case ValBigFloat: + return constant.Make(r.bigFloat()) + } +} + +func (r *Decoder) bigInt() *big.Int { + v := new(big.Int).SetBytes([]byte(r.String())) + if r.Bool() { + v.Neg(v) + } + return v +} + +func (r *Decoder) bigFloat() *big.Float { + v := new(big.Float).SetPrec(512) + assert(v.UnmarshalText([]byte(r.String())) == nil) + return v +} + +// @@@ Helpers + +// TODO(mdempsky): These should probably be removed. I think they're a +// smell that the export data format is not yet quite right. + +// PeekPkgPath returns the package path for the specified package +// index. +func (pr *PkgDecoder) PeekPkgPath(idx Index) string { + var path string + { + r := pr.TempDecoder(RelocPkg, idx, SyncPkgDef) + path = r.String() + pr.RetireDecoder(&r) + } + if path == "" { + path = pr.pkgPath + } + return path +} + +// PeekObj returns the package path, object name, and CodeObj for the +// specified object index. +func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) { + var ridx Index + var name string + var rcode int + { + r := pr.TempDecoder(RelocName, idx, SyncObject1) + r.Sync(SyncSym) + r.Sync(SyncPkg) + ridx = r.Reloc(RelocPkg) + name = r.String() + rcode = r.Code(SyncCodeObj) + pr.RetireDecoder(&r) + } + + path := pr.PeekPkgPath(ridx) + assert(name != "") + + tag := CodeObj(rcode) + + return path, name, tag +} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/doc.go b/vendor/golang.org/x/tools/internal/pkgbits/doc.go new file mode 100644 index 00000000..c8a2796b --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/doc.go @@ -0,0 +1,32 @@ +// 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 pkgbits implements low-level coding abstractions for +// Unified IR's export data format. +// +// At a low-level, a package is a collection of bitstream elements. +// Each element has a "kind" and a dense, non-negative index. +// Elements can be randomly accessed given their kind and index. +// +// Individual elements are sequences of variable-length values (e.g., +// integers, booleans, strings, go/constant values, cross-references +// to other elements). Package pkgbits provides APIs for encoding and +// decoding these low-level values, but the details of mapping +// higher-level Go constructs into elements is left to higher-level +// abstractions. +// +// Elements may cross-reference each other with "relocations." For +// example, an element representing a pointer type has a relocation +// referring to the element type. +// +// Go constructs may be composed as a constellation of multiple +// elements. For example, a declared function may have one element to +// describe the object (e.g., its name, type, position), and a +// separate element to describe its function body. This allows readers +// some flexibility in efficiently seeking or re-reading data (e.g., +// inlining requires re-reading the function body for each inlined +// call, without needing to re-read the object-level details). +// +// This is a copy of internal/pkgbits in the Go implementation. +package pkgbits diff --git a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go new file mode 100644 index 00000000..6482617a --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go @@ -0,0 +1,383 @@ +// 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 pkgbits + +import ( + "bytes" + "crypto/md5" + "encoding/binary" + "go/constant" + "io" + "math/big" + "runtime" +) + +// currentVersion is the current version number. +// +// - v0: initial prototype +// +// - v1: adds the flags uint32 word +const currentVersion uint32 = 1 + +// A PkgEncoder provides methods for encoding a package's Unified IR +// export data. +type PkgEncoder struct { + // elems holds the bitstream for previously encoded elements. + elems [numRelocs][]string + + // stringsIdx maps previously encoded strings to their index within + // the RelocString section, to allow deduplication. That is, + // elems[RelocString][stringsIdx[s]] == s (if present). + stringsIdx map[string]Index + + // syncFrames is the number of frames to write at each sync + // marker. A negative value means sync markers are omitted. + syncFrames int +} + +// SyncMarkers reports whether pw uses sync markers. +func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 } + +// NewPkgEncoder returns an initialized PkgEncoder. +// +// syncFrames is the number of caller frames that should be serialized +// at Sync points. Serializing additional frames results in larger +// export data files, but can help diagnosing desync errors in +// higher-level Unified IR reader/writer code. If syncFrames is +// negative, then sync markers are omitted entirely. +func NewPkgEncoder(syncFrames int) PkgEncoder { + return PkgEncoder{ + stringsIdx: make(map[string]Index), + syncFrames: syncFrames, + } +} + +// DumpTo writes the package's encoded data to out0 and returns the +// package fingerprint. +func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) { + h := md5.New() + out := io.MultiWriter(out0, h) + + writeUint32 := func(x uint32) { + assert(binary.Write(out, binary.LittleEndian, x) == nil) + } + + writeUint32(currentVersion) + + var flags uint32 + if pw.SyncMarkers() { + flags |= flagSyncMarkers + } + writeUint32(flags) + + // Write elemEndsEnds. + var sum uint32 + for _, elems := range &pw.elems { + sum += uint32(len(elems)) + writeUint32(sum) + } + + // Write elemEnds. + sum = 0 + for _, elems := range &pw.elems { + for _, elem := range elems { + sum += uint32(len(elem)) + writeUint32(sum) + } + } + + // Write elemData. + for _, elems := range &pw.elems { + for _, elem := range elems { + _, err := io.WriteString(out, elem) + assert(err == nil) + } + } + + // Write fingerprint. + copy(fingerprint[:], h.Sum(nil)) + _, err := out0.Write(fingerprint[:]) + assert(err == nil) + + return +} + +// StringIdx adds a string value to the strings section, if not +// already present, and returns its index. +func (pw *PkgEncoder) StringIdx(s string) Index { + if idx, ok := pw.stringsIdx[s]; ok { + assert(pw.elems[RelocString][idx] == s) + return idx + } + + idx := Index(len(pw.elems[RelocString])) + pw.elems[RelocString] = append(pw.elems[RelocString], s) + pw.stringsIdx[s] = idx + return idx +} + +// NewEncoder returns an Encoder for a new element within the given +// section, and encodes the given SyncMarker as the start of the +// element bitstream. +func (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder { + e := pw.NewEncoderRaw(k) + e.Sync(marker) + return e +} + +// NewEncoderRaw returns an Encoder for a new element within the given +// section. +// +// Most callers should use NewEncoder instead. +func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder { + idx := Index(len(pw.elems[k])) + pw.elems[k] = append(pw.elems[k], "") // placeholder + + return Encoder{ + p: pw, + k: k, + Idx: idx, + } +} + +// An Encoder provides methods for encoding an individual element's +// bitstream data. +type Encoder struct { + p *PkgEncoder + + Relocs []RelocEnt + RelocMap map[RelocEnt]uint32 + Data bytes.Buffer // accumulated element bitstream data + + encodingRelocHeader bool + + k RelocKind + Idx Index // index within relocation section +} + +// Flush finalizes the element's bitstream and returns its Index. +func (w *Encoder) Flush() Index { + var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved + + // Backup the data so we write the relocations at the front. + var tmp bytes.Buffer + io.Copy(&tmp, &w.Data) + + // TODO(mdempsky): Consider writing these out separately so they're + // easier to strip, along with function bodies, so that we can prune + // down to just the data that's relevant to go/types. + if w.encodingRelocHeader { + panic("encodingRelocHeader already true; recursive flush?") + } + w.encodingRelocHeader = true + w.Sync(SyncRelocs) + w.Len(len(w.Relocs)) + for _, rEnt := range w.Relocs { + w.Sync(SyncReloc) + w.Len(int(rEnt.Kind)) + w.Len(int(rEnt.Idx)) + } + + io.Copy(&sb, &w.Data) + io.Copy(&sb, &tmp) + w.p.elems[w.k][w.Idx] = sb.String() + + return w.Idx +} + +func (w *Encoder) checkErr(err error) { + if err != nil { + errorf("unexpected encoding error: %v", err) + } +} + +func (w *Encoder) rawUvarint(x uint64) { + var buf [binary.MaxVarintLen64]byte + n := binary.PutUvarint(buf[:], x) + _, err := w.Data.Write(buf[:n]) + w.checkErr(err) +} + +func (w *Encoder) rawVarint(x int64) { + // Zig-zag encode. + ux := uint64(x) << 1 + if x < 0 { + ux = ^ux + } + + w.rawUvarint(ux) +} + +func (w *Encoder) rawReloc(r RelocKind, idx Index) int { + e := RelocEnt{r, idx} + if w.RelocMap != nil { + if i, ok := w.RelocMap[e]; ok { + return int(i) + } + } else { + w.RelocMap = make(map[RelocEnt]uint32) + } + + i := len(w.Relocs) + w.RelocMap[e] = uint32(i) + w.Relocs = append(w.Relocs, e) + return i +} + +func (w *Encoder) Sync(m SyncMarker) { + if !w.p.SyncMarkers() { + return + } + + // Writing out stack frame string references requires working + // relocations, but writing out the relocations themselves involves + // sync markers. To prevent infinite recursion, we simply trim the + // stack frame for sync markers within the relocation header. + var frames []string + if !w.encodingRelocHeader && w.p.syncFrames > 0 { + pcs := make([]uintptr, w.p.syncFrames) + n := runtime.Callers(2, pcs) + frames = fmtFrames(pcs[:n]...) + } + + // TODO(mdempsky): Save space by writing out stack frames as a + // linked list so we can share common stack frames. + w.rawUvarint(uint64(m)) + w.rawUvarint(uint64(len(frames))) + for _, frame := range frames { + w.rawUvarint(uint64(w.rawReloc(RelocString, w.p.StringIdx(frame)))) + } +} + +// Bool encodes and writes a bool value into the element bitstream, +// and then returns the bool value. +// +// For simple, 2-alternative encodings, the idiomatic way to call Bool +// is something like: +// +// if w.Bool(x != 0) { +// // alternative #1 +// } else { +// // alternative #2 +// } +// +// For multi-alternative encodings, use Code instead. +func (w *Encoder) Bool(b bool) bool { + w.Sync(SyncBool) + var x byte + if b { + x = 1 + } + err := w.Data.WriteByte(x) + w.checkErr(err) + return b +} + +// Int64 encodes and writes an int64 value into the element bitstream. +func (w *Encoder) Int64(x int64) { + w.Sync(SyncInt64) + w.rawVarint(x) +} + +// Uint64 encodes and writes a uint64 value into the element bitstream. +func (w *Encoder) Uint64(x uint64) { + w.Sync(SyncUint64) + w.rawUvarint(x) +} + +// Len encodes and writes a non-negative int value into the element bitstream. +func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) } + +// Int encodes and writes an int value into the element bitstream. +func (w *Encoder) Int(x int) { w.Int64(int64(x)) } + +// Uint encodes and writes a uint value into the element bitstream. +func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) } + +// Reloc encodes and writes a relocation for the given (section, +// index) pair into the element bitstream. +// +// Note: Only the index is formally written into the element +// bitstream, so bitstream decoders must know from context which +// section an encoded relocation refers to. +func (w *Encoder) Reloc(r RelocKind, idx Index) { + w.Sync(SyncUseReloc) + w.Len(w.rawReloc(r, idx)) +} + +// Code encodes and writes a Code value into the element bitstream. +func (w *Encoder) Code(c Code) { + w.Sync(c.Marker()) + w.Len(c.Value()) +} + +// String encodes and writes a string value into the element +// bitstream. +// +// Internally, strings are deduplicated by adding them to the strings +// section (if not already present), and then writing a relocation +// into the element bitstream. +func (w *Encoder) String(s string) { + w.Sync(SyncString) + w.Reloc(RelocString, w.p.StringIdx(s)) +} + +// Strings encodes and writes a variable-length slice of strings into +// the element bitstream. +func (w *Encoder) Strings(ss []string) { + w.Len(len(ss)) + for _, s := range ss { + w.String(s) + } +} + +// Value encodes and writes a constant.Value into the element +// bitstream. +func (w *Encoder) Value(val constant.Value) { + w.Sync(SyncValue) + if w.Bool(val.Kind() == constant.Complex) { + w.scalar(constant.Real(val)) + w.scalar(constant.Imag(val)) + } else { + w.scalar(val) + } +} + +func (w *Encoder) scalar(val constant.Value) { + switch v := constant.Val(val).(type) { + default: + errorf("unhandled %v (%v)", val, val.Kind()) + case bool: + w.Code(ValBool) + w.Bool(v) + case string: + w.Code(ValString) + w.String(v) + case int64: + w.Code(ValInt64) + w.Int64(v) + case *big.Int: + w.Code(ValBigInt) + w.bigInt(v) + case *big.Rat: + w.Code(ValBigRat) + w.bigInt(v.Num()) + w.bigInt(v.Denom()) + case *big.Float: + w.Code(ValBigFloat) + w.bigFloat(v) + } +} + +func (w *Encoder) bigInt(v *big.Int) { + b := v.Bytes() + w.String(string(b)) // TODO: More efficient encoding. + w.Bool(v.Sign() < 0) +} + +func (w *Encoder) bigFloat(v *big.Float) { + b := v.Append(nil, 'p', -1) + w.String(string(b)) // TODO: More efficient encoding. +} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/flags.go b/vendor/golang.org/x/tools/internal/pkgbits/flags.go new file mode 100644 index 00000000..65422274 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/flags.go @@ -0,0 +1,9 @@ +// 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 pkgbits + +const ( + flagSyncMarkers = 1 << iota // file format contains sync markers +) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go b/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go new file mode 100644 index 00000000..5294f6a6 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go @@ -0,0 +1,21 @@ +// 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. + +//go:build !go1.7 +// +build !go1.7 + +// TODO(mdempsky): Remove after #44505 is resolved + +package pkgbits + +import "runtime" + +func walkFrames(pcs []uintptr, visit frameVisitor) { + for _, pc := range pcs { + fn := runtime.FuncForPC(pc) + file, line := fn.FileLine(pc) + + visit(file, line, fn.Name(), pc-fn.Entry()) + } +} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go b/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go new file mode 100644 index 00000000..2324ae7a --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go @@ -0,0 +1,28 @@ +// 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. + +//go:build go1.7 +// +build go1.7 + +package pkgbits + +import "runtime" + +// walkFrames calls visit for each call frame represented by pcs. +// +// pcs should be a slice of PCs, as returned by runtime.Callers. +func walkFrames(pcs []uintptr, visit frameVisitor) { + if len(pcs) == 0 { + return + } + + frames := runtime.CallersFrames(pcs) + for { + frame, more := frames.Next() + visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry) + if !more { + return + } + } +} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/reloc.go b/vendor/golang.org/x/tools/internal/pkgbits/reloc.go new file mode 100644 index 00000000..fcdfb97c --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/reloc.go @@ -0,0 +1,42 @@ +// 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 pkgbits + +// A RelocKind indicates a particular section within a unified IR export. +type RelocKind int32 + +// An Index represents a bitstream element index within a particular +// section. +type Index int32 + +// A relocEnt (relocation entry) is an entry in an element's local +// reference table. +// +// TODO(mdempsky): Rename this too. +type RelocEnt struct { + Kind RelocKind + Idx Index +} + +// Reserved indices within the meta relocation section. +const ( + PublicRootIdx Index = 0 + PrivateRootIdx Index = 1 +) + +const ( + RelocString RelocKind = iota + RelocMeta + RelocPosBase + RelocPkg + RelocName + RelocType + RelocObj + RelocObjExt + RelocObjDict + RelocBody + + numRelocs = iota +) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/support.go b/vendor/golang.org/x/tools/internal/pkgbits/support.go new file mode 100644 index 00000000..ad26d3b2 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/support.go @@ -0,0 +1,17 @@ +// 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 pkgbits + +import "fmt" + +func assert(b bool) { + if !b { + panic("assertion failed") + } +} + +func errorf(format string, args ...interface{}) { + panic(fmt.Errorf(format, args...)) +} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/sync.go b/vendor/golang.org/x/tools/internal/pkgbits/sync.go new file mode 100644 index 00000000..5bd51ef7 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/sync.go @@ -0,0 +1,113 @@ +// 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 pkgbits + +import ( + "fmt" + "strings" +) + +// fmtFrames formats a backtrace for reporting reader/writer desyncs. +func fmtFrames(pcs ...uintptr) []string { + res := make([]string, 0, len(pcs)) + walkFrames(pcs, func(file string, line int, name string, offset uintptr) { + // Trim package from function name. It's just redundant noise. + name = strings.TrimPrefix(name, "cmd/compile/internal/noder.") + + res = append(res, fmt.Sprintf("%s:%v: %s +0x%v", file, line, name, offset)) + }) + return res +} + +type frameVisitor func(file string, line int, name string, offset uintptr) + +// SyncMarker is an enum type that represents markers that may be +// written to export data to ensure the reader and writer stay +// synchronized. +type SyncMarker int + +//go:generate stringer -type=SyncMarker -trimprefix=Sync + +const ( + _ SyncMarker = iota + + // Public markers (known to go/types importers). + + // Low-level coding markers. + SyncEOF + SyncBool + SyncInt64 + SyncUint64 + SyncString + SyncValue + SyncVal + SyncRelocs + SyncReloc + SyncUseReloc + + // Higher-level object and type markers. + SyncPublic + SyncPos + SyncPosBase + SyncObject + SyncObject1 + SyncPkg + SyncPkgDef + SyncMethod + SyncType + SyncTypeIdx + SyncTypeParamNames + SyncSignature + SyncParams + SyncParam + SyncCodeObj + SyncSym + SyncLocalIdent + SyncSelector + + // Private markers (only known to cmd/compile). + SyncPrivate + + SyncFuncExt + SyncVarExt + SyncTypeExt + SyncPragma + + SyncExprList + SyncExprs + SyncExpr + SyncExprType + SyncAssign + SyncOp + SyncFuncLit + SyncCompLit + + SyncDecl + SyncFuncBody + SyncOpenScope + SyncCloseScope + SyncCloseAnotherScope + SyncDeclNames + SyncDeclName + + SyncStmts + SyncBlockStmt + SyncIfStmt + SyncForStmt + SyncSwitchStmt + SyncRangeStmt + SyncCaseClause + SyncCommClause + SyncSelectStmt + SyncDecls + SyncLabeledStmt + SyncUseObjLocal + SyncAddLocal + SyncLinkname + SyncStmt1 + SyncStmtsEnd + SyncLabel + SyncOptLabel +) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go new file mode 100644 index 00000000..4a5b0ca5 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go @@ -0,0 +1,89 @@ +// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT. + +package pkgbits + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[SyncEOF-1] + _ = x[SyncBool-2] + _ = x[SyncInt64-3] + _ = x[SyncUint64-4] + _ = x[SyncString-5] + _ = x[SyncValue-6] + _ = x[SyncVal-7] + _ = x[SyncRelocs-8] + _ = x[SyncReloc-9] + _ = x[SyncUseReloc-10] + _ = x[SyncPublic-11] + _ = x[SyncPos-12] + _ = x[SyncPosBase-13] + _ = x[SyncObject-14] + _ = x[SyncObject1-15] + _ = x[SyncPkg-16] + _ = x[SyncPkgDef-17] + _ = x[SyncMethod-18] + _ = x[SyncType-19] + _ = x[SyncTypeIdx-20] + _ = x[SyncTypeParamNames-21] + _ = x[SyncSignature-22] + _ = x[SyncParams-23] + _ = x[SyncParam-24] + _ = x[SyncCodeObj-25] + _ = x[SyncSym-26] + _ = x[SyncLocalIdent-27] + _ = x[SyncSelector-28] + _ = x[SyncPrivate-29] + _ = x[SyncFuncExt-30] + _ = x[SyncVarExt-31] + _ = x[SyncTypeExt-32] + _ = x[SyncPragma-33] + _ = x[SyncExprList-34] + _ = x[SyncExprs-35] + _ = x[SyncExpr-36] + _ = x[SyncExprType-37] + _ = x[SyncAssign-38] + _ = x[SyncOp-39] + _ = x[SyncFuncLit-40] + _ = x[SyncCompLit-41] + _ = x[SyncDecl-42] + _ = x[SyncFuncBody-43] + _ = x[SyncOpenScope-44] + _ = x[SyncCloseScope-45] + _ = x[SyncCloseAnotherScope-46] + _ = x[SyncDeclNames-47] + _ = x[SyncDeclName-48] + _ = x[SyncStmts-49] + _ = x[SyncBlockStmt-50] + _ = x[SyncIfStmt-51] + _ = x[SyncForStmt-52] + _ = x[SyncSwitchStmt-53] + _ = x[SyncRangeStmt-54] + _ = x[SyncCaseClause-55] + _ = x[SyncCommClause-56] + _ = x[SyncSelectStmt-57] + _ = x[SyncDecls-58] + _ = x[SyncLabeledStmt-59] + _ = x[SyncUseObjLocal-60] + _ = x[SyncAddLocal-61] + _ = x[SyncLinkname-62] + _ = x[SyncStmt1-63] + _ = x[SyncStmtsEnd-64] + _ = x[SyncLabel-65] + _ = x[SyncOptLabel-66] +} + +const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel" + +var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458} + +func (i SyncMarker) String() string { + i -= 1 + if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) { + return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")" + } + return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]] +} diff --git a/vendor/golang.org/x/tools/internal/stdlib/manifest.go b/vendor/golang.org/x/tools/internal/stdlib/manifest.go new file mode 100644 index 00000000..fd689207 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/stdlib/manifest.go @@ -0,0 +1,17320 @@ +// 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. + +// Code generated by generate.go. DO NOT EDIT. + +package stdlib + +var PackageSymbols = map[string][]Symbol{ + "archive/tar": { + {"(*Header).FileInfo", Method, 1}, + {"(*Reader).Next", Method, 0}, + {"(*Reader).Read", Method, 0}, + {"(*Writer).AddFS", Method, 22}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).Flush", Method, 0}, + {"(*Writer).Write", Method, 0}, + {"(*Writer).WriteHeader", Method, 0}, + {"(Format).String", Method, 10}, + {"ErrFieldTooLong", Var, 0}, + {"ErrHeader", Var, 0}, + {"ErrInsecurePath", Var, 20}, + {"ErrWriteAfterClose", Var, 0}, + {"ErrWriteTooLong", Var, 0}, + {"FileInfoHeader", Func, 1}, + {"Format", Type, 10}, + {"FormatGNU", Const, 10}, + {"FormatPAX", Const, 10}, + {"FormatUSTAR", Const, 10}, + {"FormatUnknown", Const, 10}, + {"Header", Type, 0}, + {"Header.AccessTime", Field, 0}, + {"Header.ChangeTime", Field, 0}, + {"Header.Devmajor", Field, 0}, + {"Header.Devminor", Field, 0}, + {"Header.Format", Field, 10}, + {"Header.Gid", Field, 0}, + {"Header.Gname", Field, 0}, + {"Header.Linkname", Field, 0}, + {"Header.ModTime", Field, 0}, + {"Header.Mode", Field, 0}, + {"Header.Name", Field, 0}, + {"Header.PAXRecords", Field, 10}, + {"Header.Size", Field, 0}, + {"Header.Typeflag", Field, 0}, + {"Header.Uid", Field, 0}, + {"Header.Uname", Field, 0}, + {"Header.Xattrs", Field, 3}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"Reader", Type, 0}, + {"TypeBlock", Const, 0}, + {"TypeChar", Const, 0}, + {"TypeCont", Const, 0}, + {"TypeDir", Const, 0}, + {"TypeFifo", Const, 0}, + {"TypeGNULongLink", Const, 1}, + {"TypeGNULongName", Const, 1}, + {"TypeGNUSparse", Const, 3}, + {"TypeLink", Const, 0}, + {"TypeReg", Const, 0}, + {"TypeRegA", Const, 0}, + {"TypeSymlink", Const, 0}, + {"TypeXGlobalHeader", Const, 0}, + {"TypeXHeader", Const, 0}, + {"Writer", Type, 0}, + }, + "archive/zip": { + {"(*File).DataOffset", Method, 2}, + {"(*File).FileInfo", Method, 0}, + {"(*File).ModTime", Method, 0}, + {"(*File).Mode", Method, 0}, + {"(*File).Open", Method, 0}, + {"(*File).OpenRaw", Method, 17}, + {"(*File).SetModTime", Method, 0}, + {"(*File).SetMode", Method, 0}, + {"(*FileHeader).FileInfo", Method, 0}, + {"(*FileHeader).ModTime", Method, 0}, + {"(*FileHeader).Mode", Method, 0}, + {"(*FileHeader).SetModTime", Method, 0}, + {"(*FileHeader).SetMode", Method, 0}, + {"(*ReadCloser).Close", Method, 0}, + {"(*ReadCloser).Open", Method, 16}, + {"(*ReadCloser).RegisterDecompressor", Method, 6}, + {"(*Reader).Open", Method, 16}, + {"(*Reader).RegisterDecompressor", Method, 6}, + {"(*Writer).AddFS", Method, 22}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).Copy", Method, 17}, + {"(*Writer).Create", Method, 0}, + {"(*Writer).CreateHeader", Method, 0}, + {"(*Writer).CreateRaw", Method, 17}, + {"(*Writer).Flush", Method, 4}, + {"(*Writer).RegisterCompressor", Method, 6}, + {"(*Writer).SetComment", Method, 10}, + {"(*Writer).SetOffset", Method, 5}, + {"Compressor", Type, 2}, + {"Decompressor", Type, 2}, + {"Deflate", Const, 0}, + {"ErrAlgorithm", Var, 0}, + {"ErrChecksum", Var, 0}, + {"ErrFormat", Var, 0}, + {"ErrInsecurePath", Var, 20}, + {"File", Type, 0}, + {"File.FileHeader", Field, 0}, + {"FileHeader", Type, 0}, + {"FileHeader.CRC32", Field, 0}, + {"FileHeader.Comment", Field, 0}, + {"FileHeader.CompressedSize", Field, 0}, + {"FileHeader.CompressedSize64", Field, 1}, + {"FileHeader.CreatorVersion", Field, 0}, + {"FileHeader.ExternalAttrs", Field, 0}, + {"FileHeader.Extra", Field, 0}, + {"FileHeader.Flags", Field, 0}, + {"FileHeader.Method", Field, 0}, + {"FileHeader.Modified", Field, 10}, + {"FileHeader.ModifiedDate", Field, 0}, + {"FileHeader.ModifiedTime", Field, 0}, + {"FileHeader.Name", Field, 0}, + {"FileHeader.NonUTF8", Field, 10}, + {"FileHeader.ReaderVersion", Field, 0}, + {"FileHeader.UncompressedSize", Field, 0}, + {"FileHeader.UncompressedSize64", Field, 1}, + {"FileInfoHeader", Func, 0}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"OpenReader", Func, 0}, + {"ReadCloser", Type, 0}, + {"ReadCloser.Reader", Field, 0}, + {"Reader", Type, 0}, + {"Reader.Comment", Field, 0}, + {"Reader.File", Field, 0}, + {"RegisterCompressor", Func, 2}, + {"RegisterDecompressor", Func, 2}, + {"Store", Const, 0}, + {"Writer", Type, 0}, + }, + "bufio": { + {"(*Reader).Buffered", Method, 0}, + {"(*Reader).Discard", Method, 5}, + {"(*Reader).Peek", Method, 0}, + {"(*Reader).Read", Method, 0}, + {"(*Reader).ReadByte", Method, 0}, + {"(*Reader).ReadBytes", Method, 0}, + {"(*Reader).ReadLine", Method, 0}, + {"(*Reader).ReadRune", Method, 0}, + {"(*Reader).ReadSlice", Method, 0}, + {"(*Reader).ReadString", Method, 0}, + {"(*Reader).Reset", Method, 2}, + {"(*Reader).Size", Method, 10}, + {"(*Reader).UnreadByte", Method, 0}, + {"(*Reader).UnreadRune", Method, 0}, + {"(*Reader).WriteTo", Method, 1}, + {"(*Scanner).Buffer", Method, 6}, + {"(*Scanner).Bytes", Method, 1}, + {"(*Scanner).Err", Method, 1}, + {"(*Scanner).Scan", Method, 1}, + {"(*Scanner).Split", Method, 1}, + {"(*Scanner).Text", Method, 1}, + {"(*Writer).Available", Method, 0}, + {"(*Writer).AvailableBuffer", Method, 18}, + {"(*Writer).Buffered", Method, 0}, + {"(*Writer).Flush", Method, 0}, + {"(*Writer).ReadFrom", Method, 1}, + {"(*Writer).Reset", Method, 2}, + {"(*Writer).Size", Method, 10}, + {"(*Writer).Write", Method, 0}, + {"(*Writer).WriteByte", Method, 0}, + {"(*Writer).WriteRune", Method, 0}, + {"(*Writer).WriteString", Method, 0}, + {"(ReadWriter).Available", Method, 0}, + {"(ReadWriter).AvailableBuffer", Method, 18}, + {"(ReadWriter).Discard", Method, 5}, + {"(ReadWriter).Flush", Method, 0}, + {"(ReadWriter).Peek", Method, 0}, + {"(ReadWriter).Read", Method, 0}, + {"(ReadWriter).ReadByte", Method, 0}, + {"(ReadWriter).ReadBytes", Method, 0}, + {"(ReadWriter).ReadFrom", Method, 1}, + {"(ReadWriter).ReadLine", Method, 0}, + {"(ReadWriter).ReadRune", Method, 0}, + {"(ReadWriter).ReadSlice", Method, 0}, + {"(ReadWriter).ReadString", Method, 0}, + {"(ReadWriter).UnreadByte", Method, 0}, + {"(ReadWriter).UnreadRune", Method, 0}, + {"(ReadWriter).Write", Method, 0}, + {"(ReadWriter).WriteByte", Method, 0}, + {"(ReadWriter).WriteRune", Method, 0}, + {"(ReadWriter).WriteString", Method, 0}, + {"(ReadWriter).WriteTo", Method, 1}, + {"ErrAdvanceTooFar", Var, 1}, + {"ErrBadReadCount", Var, 15}, + {"ErrBufferFull", Var, 0}, + {"ErrFinalToken", Var, 6}, + {"ErrInvalidUnreadByte", Var, 0}, + {"ErrInvalidUnreadRune", Var, 0}, + {"ErrNegativeAdvance", Var, 1}, + {"ErrNegativeCount", Var, 0}, + {"ErrTooLong", Var, 1}, + {"MaxScanTokenSize", Const, 1}, + {"NewReadWriter", Func, 0}, + {"NewReader", Func, 0}, + {"NewReaderSize", Func, 0}, + {"NewScanner", Func, 1}, + {"NewWriter", Func, 0}, + {"NewWriterSize", Func, 0}, + {"ReadWriter", Type, 0}, + {"ReadWriter.Reader", Field, 0}, + {"ReadWriter.Writer", Field, 0}, + {"Reader", Type, 0}, + {"ScanBytes", Func, 1}, + {"ScanLines", Func, 1}, + {"ScanRunes", Func, 1}, + {"ScanWords", Func, 1}, + {"Scanner", Type, 1}, + {"SplitFunc", Type, 1}, + {"Writer", Type, 0}, + }, + "bytes": { + {"(*Buffer).Available", Method, 21}, + {"(*Buffer).AvailableBuffer", Method, 21}, + {"(*Buffer).Bytes", Method, 0}, + {"(*Buffer).Cap", Method, 5}, + {"(*Buffer).Grow", Method, 1}, + {"(*Buffer).Len", Method, 0}, + {"(*Buffer).Next", Method, 0}, + {"(*Buffer).Read", Method, 0}, + {"(*Buffer).ReadByte", Method, 0}, + {"(*Buffer).ReadBytes", Method, 0}, + {"(*Buffer).ReadFrom", Method, 0}, + {"(*Buffer).ReadRune", Method, 0}, + {"(*Buffer).ReadString", Method, 0}, + {"(*Buffer).Reset", Method, 0}, + {"(*Buffer).String", Method, 0}, + {"(*Buffer).Truncate", Method, 0}, + {"(*Buffer).UnreadByte", Method, 0}, + {"(*Buffer).UnreadRune", Method, 0}, + {"(*Buffer).Write", Method, 0}, + {"(*Buffer).WriteByte", Method, 0}, + {"(*Buffer).WriteRune", Method, 0}, + {"(*Buffer).WriteString", Method, 0}, + {"(*Buffer).WriteTo", Method, 0}, + {"(*Reader).Len", Method, 0}, + {"(*Reader).Read", Method, 0}, + {"(*Reader).ReadAt", Method, 0}, + {"(*Reader).ReadByte", Method, 0}, + {"(*Reader).ReadRune", Method, 0}, + {"(*Reader).Reset", Method, 7}, + {"(*Reader).Seek", Method, 0}, + {"(*Reader).Size", Method, 5}, + {"(*Reader).UnreadByte", Method, 0}, + {"(*Reader).UnreadRune", Method, 0}, + {"(*Reader).WriteTo", Method, 1}, + {"Buffer", Type, 0}, + {"Clone", Func, 20}, + {"Compare", Func, 0}, + {"Contains", Func, 0}, + {"ContainsAny", Func, 7}, + {"ContainsFunc", Func, 21}, + {"ContainsRune", Func, 7}, + {"Count", Func, 0}, + {"Cut", Func, 18}, + {"CutPrefix", Func, 20}, + {"CutSuffix", Func, 20}, + {"Equal", Func, 0}, + {"EqualFold", Func, 0}, + {"ErrTooLarge", Var, 0}, + {"Fields", Func, 0}, + {"FieldsFunc", Func, 0}, + {"HasPrefix", Func, 0}, + {"HasSuffix", Func, 0}, + {"Index", Func, 0}, + {"IndexAny", Func, 0}, + {"IndexByte", Func, 0}, + {"IndexFunc", Func, 0}, + {"IndexRune", Func, 0}, + {"Join", Func, 0}, + {"LastIndex", Func, 0}, + {"LastIndexAny", Func, 0}, + {"LastIndexByte", Func, 5}, + {"LastIndexFunc", Func, 0}, + {"Map", Func, 0}, + {"MinRead", Const, 0}, + {"NewBuffer", Func, 0}, + {"NewBufferString", Func, 0}, + {"NewReader", Func, 0}, + {"Reader", Type, 0}, + {"Repeat", Func, 0}, + {"Replace", Func, 0}, + {"ReplaceAll", Func, 12}, + {"Runes", Func, 0}, + {"Split", Func, 0}, + {"SplitAfter", Func, 0}, + {"SplitAfterN", Func, 0}, + {"SplitN", Func, 0}, + {"Title", Func, 0}, + {"ToLower", Func, 0}, + {"ToLowerSpecial", Func, 0}, + {"ToTitle", Func, 0}, + {"ToTitleSpecial", Func, 0}, + {"ToUpper", Func, 0}, + {"ToUpperSpecial", Func, 0}, + {"ToValidUTF8", Func, 13}, + {"Trim", Func, 0}, + {"TrimFunc", Func, 0}, + {"TrimLeft", Func, 0}, + {"TrimLeftFunc", Func, 0}, + {"TrimPrefix", Func, 1}, + {"TrimRight", Func, 0}, + {"TrimRightFunc", Func, 0}, + {"TrimSpace", Func, 0}, + {"TrimSuffix", Func, 1}, + }, + "cmp": { + {"Compare", Func, 21}, + {"Less", Func, 21}, + {"Or", Func, 22}, + {"Ordered", Type, 21}, + }, + "compress/bzip2": { + {"(StructuralError).Error", Method, 0}, + {"NewReader", Func, 0}, + {"StructuralError", Type, 0}, + }, + "compress/flate": { + {"(*ReadError).Error", Method, 0}, + {"(*WriteError).Error", Method, 0}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).Flush", Method, 0}, + {"(*Writer).Reset", Method, 2}, + {"(*Writer).Write", Method, 0}, + {"(CorruptInputError).Error", Method, 0}, + {"(InternalError).Error", Method, 0}, + {"BestCompression", Const, 0}, + {"BestSpeed", Const, 0}, + {"CorruptInputError", Type, 0}, + {"DefaultCompression", Const, 0}, + {"HuffmanOnly", Const, 7}, + {"InternalError", Type, 0}, + {"NewReader", Func, 0}, + {"NewReaderDict", Func, 0}, + {"NewWriter", Func, 0}, + {"NewWriterDict", Func, 0}, + {"NoCompression", Const, 0}, + {"ReadError", Type, 0}, + {"ReadError.Err", Field, 0}, + {"ReadError.Offset", Field, 0}, + {"Reader", Type, 0}, + {"Resetter", Type, 4}, + {"WriteError", Type, 0}, + {"WriteError.Err", Field, 0}, + {"WriteError.Offset", Field, 0}, + {"Writer", Type, 0}, + }, + "compress/gzip": { + {"(*Reader).Close", Method, 0}, + {"(*Reader).Multistream", Method, 4}, + {"(*Reader).Read", Method, 0}, + {"(*Reader).Reset", Method, 3}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).Flush", Method, 1}, + {"(*Writer).Reset", Method, 2}, + {"(*Writer).Write", Method, 0}, + {"BestCompression", Const, 0}, + {"BestSpeed", Const, 0}, + {"DefaultCompression", Const, 0}, + {"ErrChecksum", Var, 0}, + {"ErrHeader", Var, 0}, + {"Header", Type, 0}, + {"Header.Comment", Field, 0}, + {"Header.Extra", Field, 0}, + {"Header.ModTime", Field, 0}, + {"Header.Name", Field, 0}, + {"Header.OS", Field, 0}, + {"HuffmanOnly", Const, 8}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"NewWriterLevel", Func, 0}, + {"NoCompression", Const, 0}, + {"Reader", Type, 0}, + {"Reader.Header", Field, 0}, + {"Writer", Type, 0}, + {"Writer.Header", Field, 0}, + }, + "compress/lzw": { + {"(*Reader).Close", Method, 17}, + {"(*Reader).Read", Method, 17}, + {"(*Reader).Reset", Method, 17}, + {"(*Writer).Close", Method, 17}, + {"(*Writer).Reset", Method, 17}, + {"(*Writer).Write", Method, 17}, + {"LSB", Const, 0}, + {"MSB", Const, 0}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"Order", Type, 0}, + {"Reader", Type, 17}, + {"Writer", Type, 17}, + }, + "compress/zlib": { + {"(*Writer).Close", Method, 0}, + {"(*Writer).Flush", Method, 0}, + {"(*Writer).Reset", Method, 2}, + {"(*Writer).Write", Method, 0}, + {"BestCompression", Const, 0}, + {"BestSpeed", Const, 0}, + {"DefaultCompression", Const, 0}, + {"ErrChecksum", Var, 0}, + {"ErrDictionary", Var, 0}, + {"ErrHeader", Var, 0}, + {"HuffmanOnly", Const, 8}, + {"NewReader", Func, 0}, + {"NewReaderDict", Func, 0}, + {"NewWriter", Func, 0}, + {"NewWriterLevel", Func, 0}, + {"NewWriterLevelDict", Func, 0}, + {"NoCompression", Const, 0}, + {"Resetter", Type, 4}, + {"Writer", Type, 0}, + }, + "container/heap": { + {"Fix", Func, 2}, + {"Init", Func, 0}, + {"Interface", Type, 0}, + {"Pop", Func, 0}, + {"Push", Func, 0}, + {"Remove", Func, 0}, + }, + "container/list": { + {"(*Element).Next", Method, 0}, + {"(*Element).Prev", Method, 0}, + {"(*List).Back", Method, 0}, + {"(*List).Front", Method, 0}, + {"(*List).Init", Method, 0}, + {"(*List).InsertAfter", Method, 0}, + {"(*List).InsertBefore", Method, 0}, + {"(*List).Len", Method, 0}, + {"(*List).MoveAfter", Method, 2}, + {"(*List).MoveBefore", Method, 2}, + {"(*List).MoveToBack", Method, 0}, + {"(*List).MoveToFront", Method, 0}, + {"(*List).PushBack", Method, 0}, + {"(*List).PushBackList", Method, 0}, + {"(*List).PushFront", Method, 0}, + {"(*List).PushFrontList", Method, 0}, + {"(*List).Remove", Method, 0}, + {"Element", Type, 0}, + {"Element.Value", Field, 0}, + {"List", Type, 0}, + {"New", Func, 0}, + }, + "container/ring": { + {"(*Ring).Do", Method, 0}, + {"(*Ring).Len", Method, 0}, + {"(*Ring).Link", Method, 0}, + {"(*Ring).Move", Method, 0}, + {"(*Ring).Next", Method, 0}, + {"(*Ring).Prev", Method, 0}, + {"(*Ring).Unlink", Method, 0}, + {"New", Func, 0}, + {"Ring", Type, 0}, + {"Ring.Value", Field, 0}, + }, + "context": { + {"AfterFunc", Func, 21}, + {"Background", Func, 7}, + {"CancelCauseFunc", Type, 20}, + {"CancelFunc", Type, 7}, + {"Canceled", Var, 7}, + {"Cause", Func, 20}, + {"Context", Type, 7}, + {"DeadlineExceeded", Var, 7}, + {"TODO", Func, 7}, + {"WithCancel", Func, 7}, + {"WithCancelCause", Func, 20}, + {"WithDeadline", Func, 7}, + {"WithDeadlineCause", Func, 21}, + {"WithTimeout", Func, 7}, + {"WithTimeoutCause", Func, 21}, + {"WithValue", Func, 7}, + {"WithoutCancel", Func, 21}, + }, + "crypto": { + {"(Hash).Available", Method, 0}, + {"(Hash).HashFunc", Method, 4}, + {"(Hash).New", Method, 0}, + {"(Hash).Size", Method, 0}, + {"(Hash).String", Method, 15}, + {"BLAKE2b_256", Const, 9}, + {"BLAKE2b_384", Const, 9}, + {"BLAKE2b_512", Const, 9}, + {"BLAKE2s_256", Const, 9}, + {"Decrypter", Type, 5}, + {"DecrypterOpts", Type, 5}, + {"Hash", Type, 0}, + {"MD4", Const, 0}, + {"MD5", Const, 0}, + {"MD5SHA1", Const, 0}, + {"PrivateKey", Type, 0}, + {"PublicKey", Type, 2}, + {"RIPEMD160", Const, 0}, + {"RegisterHash", Func, 0}, + {"SHA1", Const, 0}, + {"SHA224", Const, 0}, + {"SHA256", Const, 0}, + {"SHA384", Const, 0}, + {"SHA3_224", Const, 4}, + {"SHA3_256", Const, 4}, + {"SHA3_384", Const, 4}, + {"SHA3_512", Const, 4}, + {"SHA512", Const, 0}, + {"SHA512_224", Const, 5}, + {"SHA512_256", Const, 5}, + {"Signer", Type, 4}, + {"SignerOpts", Type, 4}, + }, + "crypto/aes": { + {"(KeySizeError).Error", Method, 0}, + {"BlockSize", Const, 0}, + {"KeySizeError", Type, 0}, + {"NewCipher", Func, 0}, + }, + "crypto/cipher": { + {"(StreamReader).Read", Method, 0}, + {"(StreamWriter).Close", Method, 0}, + {"(StreamWriter).Write", Method, 0}, + {"AEAD", Type, 2}, + {"Block", Type, 0}, + {"BlockMode", Type, 0}, + {"NewCBCDecrypter", Func, 0}, + {"NewCBCEncrypter", Func, 0}, + {"NewCFBDecrypter", Func, 0}, + {"NewCFBEncrypter", Func, 0}, + {"NewCTR", Func, 0}, + {"NewGCM", Func, 2}, + {"NewGCMWithNonceSize", Func, 5}, + {"NewGCMWithTagSize", Func, 11}, + {"NewOFB", Func, 0}, + {"Stream", Type, 0}, + {"StreamReader", Type, 0}, + {"StreamReader.R", Field, 0}, + {"StreamReader.S", Field, 0}, + {"StreamWriter", Type, 0}, + {"StreamWriter.Err", Field, 0}, + {"StreamWriter.S", Field, 0}, + {"StreamWriter.W", Field, 0}, + }, + "crypto/des": { + {"(KeySizeError).Error", Method, 0}, + {"BlockSize", Const, 0}, + {"KeySizeError", Type, 0}, + {"NewCipher", Func, 0}, + {"NewTripleDESCipher", Func, 0}, + }, + "crypto/dsa": { + {"ErrInvalidPublicKey", Var, 0}, + {"GenerateKey", Func, 0}, + {"GenerateParameters", Func, 0}, + {"L1024N160", Const, 0}, + {"L2048N224", Const, 0}, + {"L2048N256", Const, 0}, + {"L3072N256", Const, 0}, + {"ParameterSizes", Type, 0}, + {"Parameters", Type, 0}, + {"Parameters.G", Field, 0}, + {"Parameters.P", Field, 0}, + {"Parameters.Q", Field, 0}, + {"PrivateKey", Type, 0}, + {"PrivateKey.PublicKey", Field, 0}, + {"PrivateKey.X", Field, 0}, + {"PublicKey", Type, 0}, + {"PublicKey.Parameters", Field, 0}, + {"PublicKey.Y", Field, 0}, + {"Sign", Func, 0}, + {"Verify", Func, 0}, + }, + "crypto/ecdh": { + {"(*PrivateKey).Bytes", Method, 20}, + {"(*PrivateKey).Curve", Method, 20}, + {"(*PrivateKey).ECDH", Method, 20}, + {"(*PrivateKey).Equal", Method, 20}, + {"(*PrivateKey).Public", Method, 20}, + {"(*PrivateKey).PublicKey", Method, 20}, + {"(*PublicKey).Bytes", Method, 20}, + {"(*PublicKey).Curve", Method, 20}, + {"(*PublicKey).Equal", Method, 20}, + {"Curve", Type, 20}, + {"P256", Func, 20}, + {"P384", Func, 20}, + {"P521", Func, 20}, + {"PrivateKey", Type, 20}, + {"PublicKey", Type, 20}, + {"X25519", Func, 20}, + }, + "crypto/ecdsa": { + {"(*PrivateKey).ECDH", Method, 20}, + {"(*PrivateKey).Equal", Method, 15}, + {"(*PrivateKey).Public", Method, 4}, + {"(*PrivateKey).Sign", Method, 4}, + {"(*PublicKey).ECDH", Method, 20}, + {"(*PublicKey).Equal", Method, 15}, + {"(PrivateKey).Add", Method, 0}, + {"(PrivateKey).Double", Method, 0}, + {"(PrivateKey).IsOnCurve", Method, 0}, + {"(PrivateKey).Params", Method, 0}, + {"(PrivateKey).ScalarBaseMult", Method, 0}, + {"(PrivateKey).ScalarMult", Method, 0}, + {"(PublicKey).Add", Method, 0}, + {"(PublicKey).Double", Method, 0}, + {"(PublicKey).IsOnCurve", Method, 0}, + {"(PublicKey).Params", Method, 0}, + {"(PublicKey).ScalarBaseMult", Method, 0}, + {"(PublicKey).ScalarMult", Method, 0}, + {"GenerateKey", Func, 0}, + {"PrivateKey", Type, 0}, + {"PrivateKey.D", Field, 0}, + {"PrivateKey.PublicKey", Field, 0}, + {"PublicKey", Type, 0}, + {"PublicKey.Curve", Field, 0}, + {"PublicKey.X", Field, 0}, + {"PublicKey.Y", Field, 0}, + {"Sign", Func, 0}, + {"SignASN1", Func, 15}, + {"Verify", Func, 0}, + {"VerifyASN1", Func, 15}, + }, + "crypto/ed25519": { + {"(*Options).HashFunc", Method, 20}, + {"(PrivateKey).Equal", Method, 15}, + {"(PrivateKey).Public", Method, 13}, + {"(PrivateKey).Seed", Method, 13}, + {"(PrivateKey).Sign", Method, 13}, + {"(PublicKey).Equal", Method, 15}, + {"GenerateKey", Func, 13}, + {"NewKeyFromSeed", Func, 13}, + {"Options", Type, 20}, + {"Options.Context", Field, 20}, + {"Options.Hash", Field, 20}, + {"PrivateKey", Type, 13}, + {"PrivateKeySize", Const, 13}, + {"PublicKey", Type, 13}, + {"PublicKeySize", Const, 13}, + {"SeedSize", Const, 13}, + {"Sign", Func, 13}, + {"SignatureSize", Const, 13}, + {"Verify", Func, 13}, + {"VerifyWithOptions", Func, 20}, + }, + "crypto/elliptic": { + {"(*CurveParams).Add", Method, 0}, + {"(*CurveParams).Double", Method, 0}, + {"(*CurveParams).IsOnCurve", Method, 0}, + {"(*CurveParams).Params", Method, 0}, + {"(*CurveParams).ScalarBaseMult", Method, 0}, + {"(*CurveParams).ScalarMult", Method, 0}, + {"Curve", Type, 0}, + {"CurveParams", Type, 0}, + {"CurveParams.B", Field, 0}, + {"CurveParams.BitSize", Field, 0}, + {"CurveParams.Gx", Field, 0}, + {"CurveParams.Gy", Field, 0}, + {"CurveParams.N", Field, 0}, + {"CurveParams.Name", Field, 5}, + {"CurveParams.P", Field, 0}, + {"GenerateKey", Func, 0}, + {"Marshal", Func, 0}, + {"MarshalCompressed", Func, 15}, + {"P224", Func, 0}, + {"P256", Func, 0}, + {"P384", Func, 0}, + {"P521", Func, 0}, + {"Unmarshal", Func, 0}, + {"UnmarshalCompressed", Func, 15}, + }, + "crypto/hmac": { + {"Equal", Func, 1}, + {"New", Func, 0}, + }, + "crypto/md5": { + {"BlockSize", Const, 0}, + {"New", Func, 0}, + {"Size", Const, 0}, + {"Sum", Func, 2}, + }, + "crypto/rand": { + {"Int", Func, 0}, + {"Prime", Func, 0}, + {"Read", Func, 0}, + {"Reader", Var, 0}, + }, + "crypto/rc4": { + {"(*Cipher).Reset", Method, 0}, + {"(*Cipher).XORKeyStream", Method, 0}, + {"(KeySizeError).Error", Method, 0}, + {"Cipher", Type, 0}, + {"KeySizeError", Type, 0}, + {"NewCipher", Func, 0}, + }, + "crypto/rsa": { + {"(*PSSOptions).HashFunc", Method, 4}, + {"(*PrivateKey).Decrypt", Method, 5}, + {"(*PrivateKey).Equal", Method, 15}, + {"(*PrivateKey).Precompute", Method, 0}, + {"(*PrivateKey).Public", Method, 4}, + {"(*PrivateKey).Sign", Method, 4}, + {"(*PrivateKey).Size", Method, 11}, + {"(*PrivateKey).Validate", Method, 0}, + {"(*PublicKey).Equal", Method, 15}, + {"(*PublicKey).Size", Method, 11}, + {"CRTValue", Type, 0}, + {"CRTValue.Coeff", Field, 0}, + {"CRTValue.Exp", Field, 0}, + {"CRTValue.R", Field, 0}, + {"DecryptOAEP", Func, 0}, + {"DecryptPKCS1v15", Func, 0}, + {"DecryptPKCS1v15SessionKey", Func, 0}, + {"EncryptOAEP", Func, 0}, + {"EncryptPKCS1v15", Func, 0}, + {"ErrDecryption", Var, 0}, + {"ErrMessageTooLong", Var, 0}, + {"ErrVerification", Var, 0}, + {"GenerateKey", Func, 0}, + {"GenerateMultiPrimeKey", Func, 0}, + {"OAEPOptions", Type, 5}, + {"OAEPOptions.Hash", Field, 5}, + {"OAEPOptions.Label", Field, 5}, + {"OAEPOptions.MGFHash", Field, 20}, + {"PKCS1v15DecryptOptions", Type, 5}, + {"PKCS1v15DecryptOptions.SessionKeyLen", Field, 5}, + {"PSSOptions", Type, 2}, + {"PSSOptions.Hash", Field, 4}, + {"PSSOptions.SaltLength", Field, 2}, + {"PSSSaltLengthAuto", Const, 2}, + {"PSSSaltLengthEqualsHash", Const, 2}, + {"PrecomputedValues", Type, 0}, + {"PrecomputedValues.CRTValues", Field, 0}, + {"PrecomputedValues.Dp", Field, 0}, + {"PrecomputedValues.Dq", Field, 0}, + {"PrecomputedValues.Qinv", Field, 0}, + {"PrivateKey", Type, 0}, + {"PrivateKey.D", Field, 0}, + {"PrivateKey.Precomputed", Field, 0}, + {"PrivateKey.Primes", Field, 0}, + {"PrivateKey.PublicKey", Field, 0}, + {"PublicKey", Type, 0}, + {"PublicKey.E", Field, 0}, + {"PublicKey.N", Field, 0}, + {"SignPKCS1v15", Func, 0}, + {"SignPSS", Func, 2}, + {"VerifyPKCS1v15", Func, 0}, + {"VerifyPSS", Func, 2}, + }, + "crypto/sha1": { + {"BlockSize", Const, 0}, + {"New", Func, 0}, + {"Size", Const, 0}, + {"Sum", Func, 2}, + }, + "crypto/sha256": { + {"BlockSize", Const, 0}, + {"New", Func, 0}, + {"New224", Func, 0}, + {"Size", Const, 0}, + {"Size224", Const, 0}, + {"Sum224", Func, 2}, + {"Sum256", Func, 2}, + }, + "crypto/sha512": { + {"BlockSize", Const, 0}, + {"New", Func, 0}, + {"New384", Func, 0}, + {"New512_224", Func, 5}, + {"New512_256", Func, 5}, + {"Size", Const, 0}, + {"Size224", Const, 5}, + {"Size256", Const, 5}, + {"Size384", Const, 0}, + {"Sum384", Func, 2}, + {"Sum512", Func, 2}, + {"Sum512_224", Func, 5}, + {"Sum512_256", Func, 5}, + }, + "crypto/subtle": { + {"ConstantTimeByteEq", Func, 0}, + {"ConstantTimeCompare", Func, 0}, + {"ConstantTimeCopy", Func, 0}, + {"ConstantTimeEq", Func, 0}, + {"ConstantTimeLessOrEq", Func, 2}, + {"ConstantTimeSelect", Func, 0}, + {"XORBytes", Func, 20}, + }, + "crypto/tls": { + {"(*CertificateRequestInfo).Context", Method, 17}, + {"(*CertificateRequestInfo).SupportsCertificate", Method, 14}, + {"(*CertificateVerificationError).Error", Method, 20}, + {"(*CertificateVerificationError).Unwrap", Method, 20}, + {"(*ClientHelloInfo).Context", Method, 17}, + {"(*ClientHelloInfo).SupportsCertificate", Method, 14}, + {"(*ClientSessionState).ResumptionState", Method, 21}, + {"(*Config).BuildNameToCertificate", Method, 0}, + {"(*Config).Clone", Method, 8}, + {"(*Config).DecryptTicket", Method, 21}, + {"(*Config).EncryptTicket", Method, 21}, + {"(*Config).SetSessionTicketKeys", Method, 5}, + {"(*Conn).Close", Method, 0}, + {"(*Conn).CloseWrite", Method, 8}, + {"(*Conn).ConnectionState", Method, 0}, + {"(*Conn).Handshake", Method, 0}, + {"(*Conn).HandshakeContext", Method, 17}, + {"(*Conn).LocalAddr", Method, 0}, + {"(*Conn).NetConn", Method, 18}, + {"(*Conn).OCSPResponse", Method, 0}, + {"(*Conn).Read", Method, 0}, + {"(*Conn).RemoteAddr", Method, 0}, + {"(*Conn).SetDeadline", Method, 0}, + {"(*Conn).SetReadDeadline", Method, 0}, + {"(*Conn).SetWriteDeadline", Method, 0}, + {"(*Conn).VerifyHostname", Method, 0}, + {"(*Conn).Write", Method, 0}, + {"(*ConnectionState).ExportKeyingMaterial", Method, 11}, + {"(*Dialer).Dial", Method, 15}, + {"(*Dialer).DialContext", Method, 15}, + {"(*QUICConn).Close", Method, 21}, + {"(*QUICConn).ConnectionState", Method, 21}, + {"(*QUICConn).HandleData", Method, 21}, + {"(*QUICConn).NextEvent", Method, 21}, + {"(*QUICConn).SendSessionTicket", Method, 21}, + {"(*QUICConn).SetTransportParameters", Method, 21}, + {"(*QUICConn).Start", Method, 21}, + {"(*SessionState).Bytes", Method, 21}, + {"(AlertError).Error", Method, 21}, + {"(ClientAuthType).String", Method, 15}, + {"(CurveID).String", Method, 15}, + {"(QUICEncryptionLevel).String", Method, 21}, + {"(RecordHeaderError).Error", Method, 6}, + {"(SignatureScheme).String", Method, 15}, + {"AlertError", Type, 21}, + {"Certificate", Type, 0}, + {"Certificate.Certificate", Field, 0}, + {"Certificate.Leaf", Field, 0}, + {"Certificate.OCSPStaple", Field, 0}, + {"Certificate.PrivateKey", Field, 0}, + {"Certificate.SignedCertificateTimestamps", Field, 5}, + {"Certificate.SupportedSignatureAlgorithms", Field, 14}, + {"CertificateRequestInfo", Type, 8}, + {"CertificateRequestInfo.AcceptableCAs", Field, 8}, + {"CertificateRequestInfo.SignatureSchemes", Field, 8}, + {"CertificateRequestInfo.Version", Field, 14}, + {"CertificateVerificationError", Type, 20}, + {"CertificateVerificationError.Err", Field, 20}, + {"CertificateVerificationError.UnverifiedCertificates", Field, 20}, + {"CipherSuite", Type, 14}, + {"CipherSuite.ID", Field, 14}, + {"CipherSuite.Insecure", Field, 14}, + {"CipherSuite.Name", Field, 14}, + {"CipherSuite.SupportedVersions", Field, 14}, + {"CipherSuiteName", Func, 14}, + {"CipherSuites", Func, 14}, + {"Client", Func, 0}, + {"ClientAuthType", Type, 0}, + {"ClientHelloInfo", Type, 4}, + {"ClientHelloInfo.CipherSuites", Field, 4}, + {"ClientHelloInfo.Conn", Field, 8}, + {"ClientHelloInfo.ServerName", Field, 4}, + {"ClientHelloInfo.SignatureSchemes", Field, 8}, + {"ClientHelloInfo.SupportedCurves", Field, 4}, + {"ClientHelloInfo.SupportedPoints", Field, 4}, + {"ClientHelloInfo.SupportedProtos", Field, 8}, + {"ClientHelloInfo.SupportedVersions", Field, 8}, + {"ClientSessionCache", Type, 3}, + {"ClientSessionState", Type, 3}, + {"Config", Type, 0}, + {"Config.Certificates", Field, 0}, + {"Config.CipherSuites", Field, 0}, + {"Config.ClientAuth", Field, 0}, + {"Config.ClientCAs", Field, 0}, + {"Config.ClientSessionCache", Field, 3}, + {"Config.CurvePreferences", Field, 3}, + {"Config.DynamicRecordSizingDisabled", Field, 7}, + {"Config.GetCertificate", Field, 4}, + {"Config.GetClientCertificate", Field, 8}, + {"Config.GetConfigForClient", Field, 8}, + {"Config.InsecureSkipVerify", Field, 0}, + {"Config.KeyLogWriter", Field, 8}, + {"Config.MaxVersion", Field, 2}, + {"Config.MinVersion", Field, 2}, + {"Config.NameToCertificate", Field, 0}, + {"Config.NextProtos", Field, 0}, + {"Config.PreferServerCipherSuites", Field, 1}, + {"Config.Rand", Field, 0}, + {"Config.Renegotiation", Field, 7}, + {"Config.RootCAs", Field, 0}, + {"Config.ServerName", Field, 0}, + {"Config.SessionTicketKey", Field, 1}, + {"Config.SessionTicketsDisabled", Field, 1}, + {"Config.Time", Field, 0}, + {"Config.UnwrapSession", Field, 21}, + {"Config.VerifyConnection", Field, 15}, + {"Config.VerifyPeerCertificate", Field, 8}, + {"Config.WrapSession", Field, 21}, + {"Conn", Type, 0}, + {"ConnectionState", Type, 0}, + {"ConnectionState.CipherSuite", Field, 0}, + {"ConnectionState.DidResume", Field, 1}, + {"ConnectionState.HandshakeComplete", Field, 0}, + {"ConnectionState.NegotiatedProtocol", Field, 0}, + {"ConnectionState.NegotiatedProtocolIsMutual", Field, 0}, + {"ConnectionState.OCSPResponse", Field, 5}, + {"ConnectionState.PeerCertificates", Field, 0}, + {"ConnectionState.ServerName", Field, 0}, + {"ConnectionState.SignedCertificateTimestamps", Field, 5}, + {"ConnectionState.TLSUnique", Field, 4}, + {"ConnectionState.VerifiedChains", Field, 0}, + {"ConnectionState.Version", Field, 3}, + {"CurveID", Type, 3}, + {"CurveP256", Const, 3}, + {"CurveP384", Const, 3}, + {"CurveP521", Const, 3}, + {"Dial", Func, 0}, + {"DialWithDialer", Func, 3}, + {"Dialer", Type, 15}, + {"Dialer.Config", Field, 15}, + {"Dialer.NetDialer", Field, 15}, + {"ECDSAWithP256AndSHA256", Const, 8}, + {"ECDSAWithP384AndSHA384", Const, 8}, + {"ECDSAWithP521AndSHA512", Const, 8}, + {"ECDSAWithSHA1", Const, 10}, + {"Ed25519", Const, 13}, + {"InsecureCipherSuites", Func, 14}, + {"Listen", Func, 0}, + {"LoadX509KeyPair", Func, 0}, + {"NewLRUClientSessionCache", Func, 3}, + {"NewListener", Func, 0}, + {"NewResumptionState", Func, 21}, + {"NoClientCert", Const, 0}, + {"PKCS1WithSHA1", Const, 8}, + {"PKCS1WithSHA256", Const, 8}, + {"PKCS1WithSHA384", Const, 8}, + {"PKCS1WithSHA512", Const, 8}, + {"PSSWithSHA256", Const, 8}, + {"PSSWithSHA384", Const, 8}, + {"PSSWithSHA512", Const, 8}, + {"ParseSessionState", Func, 21}, + {"QUICClient", Func, 21}, + {"QUICConfig", Type, 21}, + {"QUICConfig.TLSConfig", Field, 21}, + {"QUICConn", Type, 21}, + {"QUICEncryptionLevel", Type, 21}, + {"QUICEncryptionLevelApplication", Const, 21}, + {"QUICEncryptionLevelEarly", Const, 21}, + {"QUICEncryptionLevelHandshake", Const, 21}, + {"QUICEncryptionLevelInitial", Const, 21}, + {"QUICEvent", Type, 21}, + {"QUICEvent.Data", Field, 21}, + {"QUICEvent.Kind", Field, 21}, + {"QUICEvent.Level", Field, 21}, + {"QUICEvent.Suite", Field, 21}, + {"QUICEventKind", Type, 21}, + {"QUICHandshakeDone", Const, 21}, + {"QUICNoEvent", Const, 21}, + {"QUICRejectedEarlyData", Const, 21}, + {"QUICServer", Func, 21}, + {"QUICSessionTicketOptions", Type, 21}, + {"QUICSessionTicketOptions.EarlyData", Field, 21}, + {"QUICSetReadSecret", Const, 21}, + {"QUICSetWriteSecret", Const, 21}, + {"QUICTransportParameters", Const, 21}, + {"QUICTransportParametersRequired", Const, 21}, + {"QUICWriteData", Const, 21}, + {"RecordHeaderError", Type, 6}, + {"RecordHeaderError.Conn", Field, 12}, + {"RecordHeaderError.Msg", Field, 6}, + {"RecordHeaderError.RecordHeader", Field, 6}, + {"RenegotiateFreelyAsClient", Const, 7}, + {"RenegotiateNever", Const, 7}, + {"RenegotiateOnceAsClient", Const, 7}, + {"RenegotiationSupport", Type, 7}, + {"RequestClientCert", Const, 0}, + {"RequireAndVerifyClientCert", Const, 0}, + {"RequireAnyClientCert", Const, 0}, + {"Server", Func, 0}, + {"SessionState", Type, 21}, + {"SessionState.EarlyData", Field, 21}, + {"SessionState.Extra", Field, 21}, + {"SignatureScheme", Type, 8}, + {"TLS_AES_128_GCM_SHA256", Const, 12}, + {"TLS_AES_256_GCM_SHA384", Const, 12}, + {"TLS_CHACHA20_POLY1305_SHA256", Const, 12}, + {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", Const, 2}, + {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", Const, 8}, + {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", Const, 2}, + {"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", Const, 2}, + {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", Const, 5}, + {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", Const, 8}, + {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14}, + {"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", Const, 2}, + {"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0}, + {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", Const, 0}, + {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", Const, 8}, + {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", Const, 2}, + {"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", Const, 1}, + {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", Const, 5}, + {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", Const, 8}, + {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14}, + {"TLS_ECDHE_RSA_WITH_RC4_128_SHA", Const, 0}, + {"TLS_FALLBACK_SCSV", Const, 4}, + {"TLS_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0}, + {"TLS_RSA_WITH_AES_128_CBC_SHA", Const, 0}, + {"TLS_RSA_WITH_AES_128_CBC_SHA256", Const, 8}, + {"TLS_RSA_WITH_AES_128_GCM_SHA256", Const, 6}, + {"TLS_RSA_WITH_AES_256_CBC_SHA", Const, 1}, + {"TLS_RSA_WITH_AES_256_GCM_SHA384", Const, 6}, + {"TLS_RSA_WITH_RC4_128_SHA", Const, 0}, + {"VerifyClientCertIfGiven", Const, 0}, + {"VersionName", Func, 21}, + {"VersionSSL30", Const, 2}, + {"VersionTLS10", Const, 2}, + {"VersionTLS11", Const, 2}, + {"VersionTLS12", Const, 2}, + {"VersionTLS13", Const, 12}, + {"X25519", Const, 8}, + {"X509KeyPair", Func, 0}, + }, + "crypto/x509": { + {"(*CertPool).AddCert", Method, 0}, + {"(*CertPool).AddCertWithConstraint", Method, 22}, + {"(*CertPool).AppendCertsFromPEM", Method, 0}, + {"(*CertPool).Clone", Method, 19}, + {"(*CertPool).Equal", Method, 19}, + {"(*CertPool).Subjects", Method, 0}, + {"(*Certificate).CheckCRLSignature", Method, 0}, + {"(*Certificate).CheckSignature", Method, 0}, + {"(*Certificate).CheckSignatureFrom", Method, 0}, + {"(*Certificate).CreateCRL", Method, 0}, + {"(*Certificate).Equal", Method, 0}, + {"(*Certificate).Verify", Method, 0}, + {"(*Certificate).VerifyHostname", Method, 0}, + {"(*CertificateRequest).CheckSignature", Method, 5}, + {"(*RevocationList).CheckSignatureFrom", Method, 19}, + {"(CertificateInvalidError).Error", Method, 0}, + {"(ConstraintViolationError).Error", Method, 0}, + {"(HostnameError).Error", Method, 0}, + {"(InsecureAlgorithmError).Error", Method, 6}, + {"(OID).Equal", Method, 22}, + {"(OID).EqualASN1OID", Method, 22}, + {"(OID).String", Method, 22}, + {"(PublicKeyAlgorithm).String", Method, 10}, + {"(SignatureAlgorithm).String", Method, 6}, + {"(SystemRootsError).Error", Method, 1}, + {"(SystemRootsError).Unwrap", Method, 16}, + {"(UnhandledCriticalExtension).Error", Method, 0}, + {"(UnknownAuthorityError).Error", Method, 0}, + {"CANotAuthorizedForExtKeyUsage", Const, 10}, + {"CANotAuthorizedForThisName", Const, 0}, + {"CertPool", Type, 0}, + {"Certificate", Type, 0}, + {"Certificate.AuthorityKeyId", Field, 0}, + {"Certificate.BasicConstraintsValid", Field, 0}, + {"Certificate.CRLDistributionPoints", Field, 2}, + {"Certificate.DNSNames", Field, 0}, + {"Certificate.EmailAddresses", Field, 0}, + {"Certificate.ExcludedDNSDomains", Field, 9}, + {"Certificate.ExcludedEmailAddresses", Field, 10}, + {"Certificate.ExcludedIPRanges", Field, 10}, + {"Certificate.ExcludedURIDomains", Field, 10}, + {"Certificate.ExtKeyUsage", Field, 0}, + {"Certificate.Extensions", Field, 2}, + {"Certificate.ExtraExtensions", Field, 2}, + {"Certificate.IPAddresses", Field, 1}, + {"Certificate.IsCA", Field, 0}, + {"Certificate.Issuer", Field, 0}, + {"Certificate.IssuingCertificateURL", Field, 2}, + {"Certificate.KeyUsage", Field, 0}, + {"Certificate.MaxPathLen", Field, 0}, + {"Certificate.MaxPathLenZero", Field, 4}, + {"Certificate.NotAfter", Field, 0}, + {"Certificate.NotBefore", Field, 0}, + {"Certificate.OCSPServer", Field, 2}, + {"Certificate.PermittedDNSDomains", Field, 0}, + {"Certificate.PermittedDNSDomainsCritical", Field, 0}, + {"Certificate.PermittedEmailAddresses", Field, 10}, + {"Certificate.PermittedIPRanges", Field, 10}, + {"Certificate.PermittedURIDomains", Field, 10}, + {"Certificate.Policies", Field, 22}, + {"Certificate.PolicyIdentifiers", Field, 0}, + {"Certificate.PublicKey", Field, 0}, + {"Certificate.PublicKeyAlgorithm", Field, 0}, + {"Certificate.Raw", Field, 0}, + {"Certificate.RawIssuer", Field, 0}, + {"Certificate.RawSubject", Field, 0}, + {"Certificate.RawSubjectPublicKeyInfo", Field, 0}, + {"Certificate.RawTBSCertificate", Field, 0}, + {"Certificate.SerialNumber", Field, 0}, + {"Certificate.Signature", Field, 0}, + {"Certificate.SignatureAlgorithm", Field, 0}, + {"Certificate.Subject", Field, 0}, + {"Certificate.SubjectKeyId", Field, 0}, + {"Certificate.URIs", Field, 10}, + {"Certificate.UnhandledCriticalExtensions", Field, 5}, + {"Certificate.UnknownExtKeyUsage", Field, 0}, + {"Certificate.Version", Field, 0}, + {"CertificateInvalidError", Type, 0}, + {"CertificateInvalidError.Cert", Field, 0}, + {"CertificateInvalidError.Detail", Field, 10}, + {"CertificateInvalidError.Reason", Field, 0}, + {"CertificateRequest", Type, 3}, + {"CertificateRequest.Attributes", Field, 3}, + {"CertificateRequest.DNSNames", Field, 3}, + {"CertificateRequest.EmailAddresses", Field, 3}, + {"CertificateRequest.Extensions", Field, 3}, + {"CertificateRequest.ExtraExtensions", Field, 3}, + {"CertificateRequest.IPAddresses", Field, 3}, + {"CertificateRequest.PublicKey", Field, 3}, + {"CertificateRequest.PublicKeyAlgorithm", Field, 3}, + {"CertificateRequest.Raw", Field, 3}, + {"CertificateRequest.RawSubject", Field, 3}, + {"CertificateRequest.RawSubjectPublicKeyInfo", Field, 3}, + {"CertificateRequest.RawTBSCertificateRequest", Field, 3}, + {"CertificateRequest.Signature", Field, 3}, + {"CertificateRequest.SignatureAlgorithm", Field, 3}, + {"CertificateRequest.Subject", Field, 3}, + {"CertificateRequest.URIs", Field, 10}, + {"CertificateRequest.Version", Field, 3}, + {"ConstraintViolationError", Type, 0}, + {"CreateCertificate", Func, 0}, + {"CreateCertificateRequest", Func, 3}, + {"CreateRevocationList", Func, 15}, + {"DSA", Const, 0}, + {"DSAWithSHA1", Const, 0}, + {"DSAWithSHA256", Const, 0}, + {"DecryptPEMBlock", Func, 1}, + {"ECDSA", Const, 1}, + {"ECDSAWithSHA1", Const, 1}, + {"ECDSAWithSHA256", Const, 1}, + {"ECDSAWithSHA384", Const, 1}, + {"ECDSAWithSHA512", Const, 1}, + {"Ed25519", Const, 13}, + {"EncryptPEMBlock", Func, 1}, + {"ErrUnsupportedAlgorithm", Var, 0}, + {"Expired", Const, 0}, + {"ExtKeyUsage", Type, 0}, + {"ExtKeyUsageAny", Const, 0}, + {"ExtKeyUsageClientAuth", Const, 0}, + {"ExtKeyUsageCodeSigning", Const, 0}, + {"ExtKeyUsageEmailProtection", Const, 0}, + {"ExtKeyUsageIPSECEndSystem", Const, 1}, + {"ExtKeyUsageIPSECTunnel", Const, 1}, + {"ExtKeyUsageIPSECUser", Const, 1}, + {"ExtKeyUsageMicrosoftCommercialCodeSigning", Const, 10}, + {"ExtKeyUsageMicrosoftKernelCodeSigning", Const, 10}, + {"ExtKeyUsageMicrosoftServerGatedCrypto", Const, 1}, + {"ExtKeyUsageNetscapeServerGatedCrypto", Const, 1}, + {"ExtKeyUsageOCSPSigning", Const, 0}, + {"ExtKeyUsageServerAuth", Const, 0}, + {"ExtKeyUsageTimeStamping", Const, 0}, + {"HostnameError", Type, 0}, + {"HostnameError.Certificate", Field, 0}, + {"HostnameError.Host", Field, 0}, + {"IncompatibleUsage", Const, 1}, + {"IncorrectPasswordError", Var, 1}, + {"InsecureAlgorithmError", Type, 6}, + {"InvalidReason", Type, 0}, + {"IsEncryptedPEMBlock", Func, 1}, + {"KeyUsage", Type, 0}, + {"KeyUsageCRLSign", Const, 0}, + {"KeyUsageCertSign", Const, 0}, + {"KeyUsageContentCommitment", Const, 0}, + {"KeyUsageDataEncipherment", Const, 0}, + {"KeyUsageDecipherOnly", Const, 0}, + {"KeyUsageDigitalSignature", Const, 0}, + {"KeyUsageEncipherOnly", Const, 0}, + {"KeyUsageKeyAgreement", Const, 0}, + {"KeyUsageKeyEncipherment", Const, 0}, + {"MD2WithRSA", Const, 0}, + {"MD5WithRSA", Const, 0}, + {"MarshalECPrivateKey", Func, 2}, + {"MarshalPKCS1PrivateKey", Func, 0}, + {"MarshalPKCS1PublicKey", Func, 10}, + {"MarshalPKCS8PrivateKey", Func, 10}, + {"MarshalPKIXPublicKey", Func, 0}, + {"NameConstraintsWithoutSANs", Const, 10}, + {"NameMismatch", Const, 8}, + {"NewCertPool", Func, 0}, + {"NotAuthorizedToSign", Const, 0}, + {"OID", Type, 22}, + {"OIDFromInts", Func, 22}, + {"PEMCipher", Type, 1}, + {"PEMCipher3DES", Const, 1}, + {"PEMCipherAES128", Const, 1}, + {"PEMCipherAES192", Const, 1}, + {"PEMCipherAES256", Const, 1}, + {"PEMCipherDES", Const, 1}, + {"ParseCRL", Func, 0}, + {"ParseCertificate", Func, 0}, + {"ParseCertificateRequest", Func, 3}, + {"ParseCertificates", Func, 0}, + {"ParseDERCRL", Func, 0}, + {"ParseECPrivateKey", Func, 1}, + {"ParsePKCS1PrivateKey", Func, 0}, + {"ParsePKCS1PublicKey", Func, 10}, + {"ParsePKCS8PrivateKey", Func, 0}, + {"ParsePKIXPublicKey", Func, 0}, + {"ParseRevocationList", Func, 19}, + {"PublicKeyAlgorithm", Type, 0}, + {"PureEd25519", Const, 13}, + {"RSA", Const, 0}, + {"RevocationList", Type, 15}, + {"RevocationList.AuthorityKeyId", Field, 19}, + {"RevocationList.Extensions", Field, 19}, + {"RevocationList.ExtraExtensions", Field, 15}, + {"RevocationList.Issuer", Field, 19}, + {"RevocationList.NextUpdate", Field, 15}, + {"RevocationList.Number", Field, 15}, + {"RevocationList.Raw", Field, 19}, + {"RevocationList.RawIssuer", Field, 19}, + {"RevocationList.RawTBSRevocationList", Field, 19}, + {"RevocationList.RevokedCertificateEntries", Field, 21}, + {"RevocationList.RevokedCertificates", Field, 15}, + {"RevocationList.Signature", Field, 19}, + {"RevocationList.SignatureAlgorithm", Field, 15}, + {"RevocationList.ThisUpdate", Field, 15}, + {"RevocationListEntry", Type, 21}, + {"RevocationListEntry.Extensions", Field, 21}, + {"RevocationListEntry.ExtraExtensions", Field, 21}, + {"RevocationListEntry.Raw", Field, 21}, + {"RevocationListEntry.ReasonCode", Field, 21}, + {"RevocationListEntry.RevocationTime", Field, 21}, + {"RevocationListEntry.SerialNumber", Field, 21}, + {"SHA1WithRSA", Const, 0}, + {"SHA256WithRSA", Const, 0}, + {"SHA256WithRSAPSS", Const, 8}, + {"SHA384WithRSA", Const, 0}, + {"SHA384WithRSAPSS", Const, 8}, + {"SHA512WithRSA", Const, 0}, + {"SHA512WithRSAPSS", Const, 8}, + {"SetFallbackRoots", Func, 20}, + {"SignatureAlgorithm", Type, 0}, + {"SystemCertPool", Func, 7}, + {"SystemRootsError", Type, 1}, + {"SystemRootsError.Err", Field, 7}, + {"TooManyConstraints", Const, 10}, + {"TooManyIntermediates", Const, 0}, + {"UnconstrainedName", Const, 10}, + {"UnhandledCriticalExtension", Type, 0}, + {"UnknownAuthorityError", Type, 0}, + {"UnknownAuthorityError.Cert", Field, 8}, + {"UnknownPublicKeyAlgorithm", Const, 0}, + {"UnknownSignatureAlgorithm", Const, 0}, + {"VerifyOptions", Type, 0}, + {"VerifyOptions.CurrentTime", Field, 0}, + {"VerifyOptions.DNSName", Field, 0}, + {"VerifyOptions.Intermediates", Field, 0}, + {"VerifyOptions.KeyUsages", Field, 1}, + {"VerifyOptions.MaxConstraintComparisions", Field, 10}, + {"VerifyOptions.Roots", Field, 0}, + }, + "crypto/x509/pkix": { + {"(*CertificateList).HasExpired", Method, 0}, + {"(*Name).FillFromRDNSequence", Method, 0}, + {"(Name).String", Method, 10}, + {"(Name).ToRDNSequence", Method, 0}, + {"(RDNSequence).String", Method, 10}, + {"AlgorithmIdentifier", Type, 0}, + {"AlgorithmIdentifier.Algorithm", Field, 0}, + {"AlgorithmIdentifier.Parameters", Field, 0}, + {"AttributeTypeAndValue", Type, 0}, + {"AttributeTypeAndValue.Type", Field, 0}, + {"AttributeTypeAndValue.Value", Field, 0}, + {"AttributeTypeAndValueSET", Type, 3}, + {"AttributeTypeAndValueSET.Type", Field, 3}, + {"AttributeTypeAndValueSET.Value", Field, 3}, + {"CertificateList", Type, 0}, + {"CertificateList.SignatureAlgorithm", Field, 0}, + {"CertificateList.SignatureValue", Field, 0}, + {"CertificateList.TBSCertList", Field, 0}, + {"Extension", Type, 0}, + {"Extension.Critical", Field, 0}, + {"Extension.Id", Field, 0}, + {"Extension.Value", Field, 0}, + {"Name", Type, 0}, + {"Name.CommonName", Field, 0}, + {"Name.Country", Field, 0}, + {"Name.ExtraNames", Field, 5}, + {"Name.Locality", Field, 0}, + {"Name.Names", Field, 0}, + {"Name.Organization", Field, 0}, + {"Name.OrganizationalUnit", Field, 0}, + {"Name.PostalCode", Field, 0}, + {"Name.Province", Field, 0}, + {"Name.SerialNumber", Field, 0}, + {"Name.StreetAddress", Field, 0}, + {"RDNSequence", Type, 0}, + {"RelativeDistinguishedNameSET", Type, 0}, + {"RevokedCertificate", Type, 0}, + {"RevokedCertificate.Extensions", Field, 0}, + {"RevokedCertificate.RevocationTime", Field, 0}, + {"RevokedCertificate.SerialNumber", Field, 0}, + {"TBSCertificateList", Type, 0}, + {"TBSCertificateList.Extensions", Field, 0}, + {"TBSCertificateList.Issuer", Field, 0}, + {"TBSCertificateList.NextUpdate", Field, 0}, + {"TBSCertificateList.Raw", Field, 0}, + {"TBSCertificateList.RevokedCertificates", Field, 0}, + {"TBSCertificateList.Signature", Field, 0}, + {"TBSCertificateList.ThisUpdate", Field, 0}, + {"TBSCertificateList.Version", Field, 0}, + }, + "database/sql": { + {"(*ColumnType).DatabaseTypeName", Method, 8}, + {"(*ColumnType).DecimalSize", Method, 8}, + {"(*ColumnType).Length", Method, 8}, + {"(*ColumnType).Name", Method, 8}, + {"(*ColumnType).Nullable", Method, 8}, + {"(*ColumnType).ScanType", Method, 8}, + {"(*Conn).BeginTx", Method, 9}, + {"(*Conn).Close", Method, 9}, + {"(*Conn).ExecContext", Method, 9}, + {"(*Conn).PingContext", Method, 9}, + {"(*Conn).PrepareContext", Method, 9}, + {"(*Conn).QueryContext", Method, 9}, + {"(*Conn).QueryRowContext", Method, 9}, + {"(*Conn).Raw", Method, 13}, + {"(*DB).Begin", Method, 0}, + {"(*DB).BeginTx", Method, 8}, + {"(*DB).Close", Method, 0}, + {"(*DB).Conn", Method, 9}, + {"(*DB).Driver", Method, 0}, + {"(*DB).Exec", Method, 0}, + {"(*DB).ExecContext", Method, 8}, + {"(*DB).Ping", Method, 1}, + {"(*DB).PingContext", Method, 8}, + {"(*DB).Prepare", Method, 0}, + {"(*DB).PrepareContext", Method, 8}, + {"(*DB).Query", Method, 0}, + {"(*DB).QueryContext", Method, 8}, + {"(*DB).QueryRow", Method, 0}, + {"(*DB).QueryRowContext", Method, 8}, + {"(*DB).SetConnMaxIdleTime", Method, 15}, + {"(*DB).SetConnMaxLifetime", Method, 6}, + {"(*DB).SetMaxIdleConns", Method, 1}, + {"(*DB).SetMaxOpenConns", Method, 2}, + {"(*DB).Stats", Method, 5}, + {"(*Null).Scan", Method, 22}, + {"(*NullBool).Scan", Method, 0}, + {"(*NullByte).Scan", Method, 17}, + {"(*NullFloat64).Scan", Method, 0}, + {"(*NullInt16).Scan", Method, 17}, + {"(*NullInt32).Scan", Method, 13}, + {"(*NullInt64).Scan", Method, 0}, + {"(*NullString).Scan", Method, 0}, + {"(*NullTime).Scan", Method, 13}, + {"(*Row).Err", Method, 15}, + {"(*Row).Scan", Method, 0}, + {"(*Rows).Close", Method, 0}, + {"(*Rows).ColumnTypes", Method, 8}, + {"(*Rows).Columns", Method, 0}, + {"(*Rows).Err", Method, 0}, + {"(*Rows).Next", Method, 0}, + {"(*Rows).NextResultSet", Method, 8}, + {"(*Rows).Scan", Method, 0}, + {"(*Stmt).Close", Method, 0}, + {"(*Stmt).Exec", Method, 0}, + {"(*Stmt).ExecContext", Method, 8}, + {"(*Stmt).Query", Method, 0}, + {"(*Stmt).QueryContext", Method, 8}, + {"(*Stmt).QueryRow", Method, 0}, + {"(*Stmt).QueryRowContext", Method, 8}, + {"(*Tx).Commit", Method, 0}, + {"(*Tx).Exec", Method, 0}, + {"(*Tx).ExecContext", Method, 8}, + {"(*Tx).Prepare", Method, 0}, + {"(*Tx).PrepareContext", Method, 8}, + {"(*Tx).Query", Method, 0}, + {"(*Tx).QueryContext", Method, 8}, + {"(*Tx).QueryRow", Method, 0}, + {"(*Tx).QueryRowContext", Method, 8}, + {"(*Tx).Rollback", Method, 0}, + {"(*Tx).Stmt", Method, 0}, + {"(*Tx).StmtContext", Method, 8}, + {"(IsolationLevel).String", Method, 11}, + {"(Null).Value", Method, 22}, + {"(NullBool).Value", Method, 0}, + {"(NullByte).Value", Method, 17}, + {"(NullFloat64).Value", Method, 0}, + {"(NullInt16).Value", Method, 17}, + {"(NullInt32).Value", Method, 13}, + {"(NullInt64).Value", Method, 0}, + {"(NullString).Value", Method, 0}, + {"(NullTime).Value", Method, 13}, + {"ColumnType", Type, 8}, + {"Conn", Type, 9}, + {"DB", Type, 0}, + {"DBStats", Type, 5}, + {"DBStats.Idle", Field, 11}, + {"DBStats.InUse", Field, 11}, + {"DBStats.MaxIdleClosed", Field, 11}, + {"DBStats.MaxIdleTimeClosed", Field, 15}, + {"DBStats.MaxLifetimeClosed", Field, 11}, + {"DBStats.MaxOpenConnections", Field, 11}, + {"DBStats.OpenConnections", Field, 5}, + {"DBStats.WaitCount", Field, 11}, + {"DBStats.WaitDuration", Field, 11}, + {"Drivers", Func, 4}, + {"ErrConnDone", Var, 9}, + {"ErrNoRows", Var, 0}, + {"ErrTxDone", Var, 0}, + {"IsolationLevel", Type, 8}, + {"LevelDefault", Const, 8}, + {"LevelLinearizable", Const, 8}, + {"LevelReadCommitted", Const, 8}, + {"LevelReadUncommitted", Const, 8}, + {"LevelRepeatableRead", Const, 8}, + {"LevelSerializable", Const, 8}, + {"LevelSnapshot", Const, 8}, + {"LevelWriteCommitted", Const, 8}, + {"Named", Func, 8}, + {"NamedArg", Type, 8}, + {"NamedArg.Name", Field, 8}, + {"NamedArg.Value", Field, 8}, + {"Null", Type, 22}, + {"Null.V", Field, 22}, + {"Null.Valid", Field, 22}, + {"NullBool", Type, 0}, + {"NullBool.Bool", Field, 0}, + {"NullBool.Valid", Field, 0}, + {"NullByte", Type, 17}, + {"NullByte.Byte", Field, 17}, + {"NullByte.Valid", Field, 17}, + {"NullFloat64", Type, 0}, + {"NullFloat64.Float64", Field, 0}, + {"NullFloat64.Valid", Field, 0}, + {"NullInt16", Type, 17}, + {"NullInt16.Int16", Field, 17}, + {"NullInt16.Valid", Field, 17}, + {"NullInt32", Type, 13}, + {"NullInt32.Int32", Field, 13}, + {"NullInt32.Valid", Field, 13}, + {"NullInt64", Type, 0}, + {"NullInt64.Int64", Field, 0}, + {"NullInt64.Valid", Field, 0}, + {"NullString", Type, 0}, + {"NullString.String", Field, 0}, + {"NullString.Valid", Field, 0}, + {"NullTime", Type, 13}, + {"NullTime.Time", Field, 13}, + {"NullTime.Valid", Field, 13}, + {"Open", Func, 0}, + {"OpenDB", Func, 10}, + {"Out", Type, 9}, + {"Out.Dest", Field, 9}, + {"Out.In", Field, 9}, + {"RawBytes", Type, 0}, + {"Register", Func, 0}, + {"Result", Type, 0}, + {"Row", Type, 0}, + {"Rows", Type, 0}, + {"Scanner", Type, 0}, + {"Stmt", Type, 0}, + {"Tx", Type, 0}, + {"TxOptions", Type, 8}, + {"TxOptions.Isolation", Field, 8}, + {"TxOptions.ReadOnly", Field, 8}, + }, + "database/sql/driver": { + {"(NotNull).ConvertValue", Method, 0}, + {"(Null).ConvertValue", Method, 0}, + {"(RowsAffected).LastInsertId", Method, 0}, + {"(RowsAffected).RowsAffected", Method, 0}, + {"Bool", Var, 0}, + {"ColumnConverter", Type, 0}, + {"Conn", Type, 0}, + {"ConnBeginTx", Type, 8}, + {"ConnPrepareContext", Type, 8}, + {"Connector", Type, 10}, + {"DefaultParameterConverter", Var, 0}, + {"Driver", Type, 0}, + {"DriverContext", Type, 10}, + {"ErrBadConn", Var, 0}, + {"ErrRemoveArgument", Var, 9}, + {"ErrSkip", Var, 0}, + {"Execer", Type, 0}, + {"ExecerContext", Type, 8}, + {"Int32", Var, 0}, + {"IsScanValue", Func, 0}, + {"IsValue", Func, 0}, + {"IsolationLevel", Type, 8}, + {"NamedValue", Type, 8}, + {"NamedValue.Name", Field, 8}, + {"NamedValue.Ordinal", Field, 8}, + {"NamedValue.Value", Field, 8}, + {"NamedValueChecker", Type, 9}, + {"NotNull", Type, 0}, + {"NotNull.Converter", Field, 0}, + {"Null", Type, 0}, + {"Null.Converter", Field, 0}, + {"Pinger", Type, 8}, + {"Queryer", Type, 1}, + {"QueryerContext", Type, 8}, + {"Result", Type, 0}, + {"ResultNoRows", Var, 0}, + {"Rows", Type, 0}, + {"RowsAffected", Type, 0}, + {"RowsColumnTypeDatabaseTypeName", Type, 8}, + {"RowsColumnTypeLength", Type, 8}, + {"RowsColumnTypeNullable", Type, 8}, + {"RowsColumnTypePrecisionScale", Type, 8}, + {"RowsColumnTypeScanType", Type, 8}, + {"RowsNextResultSet", Type, 8}, + {"SessionResetter", Type, 10}, + {"Stmt", Type, 0}, + {"StmtExecContext", Type, 8}, + {"StmtQueryContext", Type, 8}, + {"String", Var, 0}, + {"Tx", Type, 0}, + {"TxOptions", Type, 8}, + {"TxOptions.Isolation", Field, 8}, + {"TxOptions.ReadOnly", Field, 8}, + {"Validator", Type, 15}, + {"Value", Type, 0}, + {"ValueConverter", Type, 0}, + {"Valuer", Type, 0}, + }, + "debug/buildinfo": { + {"BuildInfo", Type, 18}, + {"Read", Func, 18}, + {"ReadFile", Func, 18}, + }, + "debug/dwarf": { + {"(*AddrType).Basic", Method, 0}, + {"(*AddrType).Common", Method, 0}, + {"(*AddrType).Size", Method, 0}, + {"(*AddrType).String", Method, 0}, + {"(*ArrayType).Common", Method, 0}, + {"(*ArrayType).Size", Method, 0}, + {"(*ArrayType).String", Method, 0}, + {"(*BasicType).Basic", Method, 0}, + {"(*BasicType).Common", Method, 0}, + {"(*BasicType).Size", Method, 0}, + {"(*BasicType).String", Method, 0}, + {"(*BoolType).Basic", Method, 0}, + {"(*BoolType).Common", Method, 0}, + {"(*BoolType).Size", Method, 0}, + {"(*BoolType).String", Method, 0}, + {"(*CharType).Basic", Method, 0}, + {"(*CharType).Common", Method, 0}, + {"(*CharType).Size", Method, 0}, + {"(*CharType).String", Method, 0}, + {"(*CommonType).Common", Method, 0}, + {"(*CommonType).Size", Method, 0}, + {"(*ComplexType).Basic", Method, 0}, + {"(*ComplexType).Common", Method, 0}, + {"(*ComplexType).Size", Method, 0}, + {"(*ComplexType).String", Method, 0}, + {"(*Data).AddSection", Method, 14}, + {"(*Data).AddTypes", Method, 3}, + {"(*Data).LineReader", Method, 5}, + {"(*Data).Ranges", Method, 7}, + {"(*Data).Reader", Method, 0}, + {"(*Data).Type", Method, 0}, + {"(*DotDotDotType).Common", Method, 0}, + {"(*DotDotDotType).Size", Method, 0}, + {"(*DotDotDotType).String", Method, 0}, + {"(*Entry).AttrField", Method, 5}, + {"(*Entry).Val", Method, 0}, + {"(*EnumType).Common", Method, 0}, + {"(*EnumType).Size", Method, 0}, + {"(*EnumType).String", Method, 0}, + {"(*FloatType).Basic", Method, 0}, + {"(*FloatType).Common", Method, 0}, + {"(*FloatType).Size", Method, 0}, + {"(*FloatType).String", Method, 0}, + {"(*FuncType).Common", Method, 0}, + {"(*FuncType).Size", Method, 0}, + {"(*FuncType).String", Method, 0}, + {"(*IntType).Basic", Method, 0}, + {"(*IntType).Common", Method, 0}, + {"(*IntType).Size", Method, 0}, + {"(*IntType).String", Method, 0}, + {"(*LineReader).Files", Method, 14}, + {"(*LineReader).Next", Method, 5}, + {"(*LineReader).Reset", Method, 5}, + {"(*LineReader).Seek", Method, 5}, + {"(*LineReader).SeekPC", Method, 5}, + {"(*LineReader).Tell", Method, 5}, + {"(*PtrType).Common", Method, 0}, + {"(*PtrType).Size", Method, 0}, + {"(*PtrType).String", Method, 0}, + {"(*QualType).Common", Method, 0}, + {"(*QualType).Size", Method, 0}, + {"(*QualType).String", Method, 0}, + {"(*Reader).AddressSize", Method, 5}, + {"(*Reader).ByteOrder", Method, 14}, + {"(*Reader).Next", Method, 0}, + {"(*Reader).Seek", Method, 0}, + {"(*Reader).SeekPC", Method, 7}, + {"(*Reader).SkipChildren", Method, 0}, + {"(*StructType).Common", Method, 0}, + {"(*StructType).Defn", Method, 0}, + {"(*StructType).Size", Method, 0}, + {"(*StructType).String", Method, 0}, + {"(*TypedefType).Common", Method, 0}, + {"(*TypedefType).Size", Method, 0}, + {"(*TypedefType).String", Method, 0}, + {"(*UcharType).Basic", Method, 0}, + {"(*UcharType).Common", Method, 0}, + {"(*UcharType).Size", Method, 0}, + {"(*UcharType).String", Method, 0}, + {"(*UintType).Basic", Method, 0}, + {"(*UintType).Common", Method, 0}, + {"(*UintType).Size", Method, 0}, + {"(*UintType).String", Method, 0}, + {"(*UnspecifiedType).Basic", Method, 4}, + {"(*UnspecifiedType).Common", Method, 4}, + {"(*UnspecifiedType).Size", Method, 4}, + {"(*UnspecifiedType).String", Method, 4}, + {"(*UnsupportedType).Common", Method, 13}, + {"(*UnsupportedType).Size", Method, 13}, + {"(*UnsupportedType).String", Method, 13}, + {"(*VoidType).Common", Method, 0}, + {"(*VoidType).Size", Method, 0}, + {"(*VoidType).String", Method, 0}, + {"(Attr).GoString", Method, 0}, + {"(Attr).String", Method, 0}, + {"(Class).GoString", Method, 5}, + {"(Class).String", Method, 5}, + {"(DecodeError).Error", Method, 0}, + {"(Tag).GoString", Method, 0}, + {"(Tag).String", Method, 0}, + {"AddrType", Type, 0}, + {"AddrType.BasicType", Field, 0}, + {"ArrayType", Type, 0}, + {"ArrayType.CommonType", Field, 0}, + {"ArrayType.Count", Field, 0}, + {"ArrayType.StrideBitSize", Field, 0}, + {"ArrayType.Type", Field, 0}, + {"Attr", Type, 0}, + {"AttrAbstractOrigin", Const, 0}, + {"AttrAccessibility", Const, 0}, + {"AttrAddrBase", Const, 14}, + {"AttrAddrClass", Const, 0}, + {"AttrAlignment", Const, 14}, + {"AttrAllocated", Const, 0}, + {"AttrArtificial", Const, 0}, + {"AttrAssociated", Const, 0}, + {"AttrBaseTypes", Const, 0}, + {"AttrBinaryScale", Const, 14}, + {"AttrBitOffset", Const, 0}, + {"AttrBitSize", Const, 0}, + {"AttrByteSize", Const, 0}, + {"AttrCallAllCalls", Const, 14}, + {"AttrCallAllSourceCalls", Const, 14}, + {"AttrCallAllTailCalls", Const, 14}, + {"AttrCallColumn", Const, 0}, + {"AttrCallDataLocation", Const, 14}, + {"AttrCallDataValue", Const, 14}, + {"AttrCallFile", Const, 0}, + {"AttrCallLine", Const, 0}, + {"AttrCallOrigin", Const, 14}, + {"AttrCallPC", Const, 14}, + {"AttrCallParameter", Const, 14}, + {"AttrCallReturnPC", Const, 14}, + {"AttrCallTailCall", Const, 14}, + {"AttrCallTarget", Const, 14}, + {"AttrCallTargetClobbered", Const, 14}, + {"AttrCallValue", Const, 14}, + {"AttrCalling", Const, 0}, + {"AttrCommonRef", Const, 0}, + {"AttrCompDir", Const, 0}, + {"AttrConstExpr", Const, 14}, + {"AttrConstValue", Const, 0}, + {"AttrContainingType", Const, 0}, + {"AttrCount", Const, 0}, + {"AttrDataBitOffset", Const, 14}, + {"AttrDataLocation", Const, 0}, + {"AttrDataMemberLoc", Const, 0}, + {"AttrDecimalScale", Const, 14}, + {"AttrDecimalSign", Const, 14}, + {"AttrDeclColumn", Const, 0}, + {"AttrDeclFile", Const, 0}, + {"AttrDeclLine", Const, 0}, + {"AttrDeclaration", Const, 0}, + {"AttrDefaultValue", Const, 0}, + {"AttrDefaulted", Const, 14}, + {"AttrDeleted", Const, 14}, + {"AttrDescription", Const, 0}, + {"AttrDigitCount", Const, 14}, + {"AttrDiscr", Const, 0}, + {"AttrDiscrList", Const, 0}, + {"AttrDiscrValue", Const, 0}, + {"AttrDwoName", Const, 14}, + {"AttrElemental", Const, 14}, + {"AttrEncoding", Const, 0}, + {"AttrEndianity", Const, 14}, + {"AttrEntrypc", Const, 0}, + {"AttrEnumClass", Const, 14}, + {"AttrExplicit", Const, 14}, + {"AttrExportSymbols", Const, 14}, + {"AttrExtension", Const, 0}, + {"AttrExternal", Const, 0}, + {"AttrFrameBase", Const, 0}, + {"AttrFriend", Const, 0}, + {"AttrHighpc", Const, 0}, + {"AttrIdentifierCase", Const, 0}, + {"AttrImport", Const, 0}, + {"AttrInline", Const, 0}, + {"AttrIsOptional", Const, 0}, + {"AttrLanguage", Const, 0}, + {"AttrLinkageName", Const, 14}, + {"AttrLocation", Const, 0}, + {"AttrLoclistsBase", Const, 14}, + {"AttrLowerBound", Const, 0}, + {"AttrLowpc", Const, 0}, + {"AttrMacroInfo", Const, 0}, + {"AttrMacros", Const, 14}, + {"AttrMainSubprogram", Const, 14}, + {"AttrMutable", Const, 14}, + {"AttrName", Const, 0}, + {"AttrNamelistItem", Const, 0}, + {"AttrNoreturn", Const, 14}, + {"AttrObjectPointer", Const, 14}, + {"AttrOrdering", Const, 0}, + {"AttrPictureString", Const, 14}, + {"AttrPriority", Const, 0}, + {"AttrProducer", Const, 0}, + {"AttrPrototyped", Const, 0}, + {"AttrPure", Const, 14}, + {"AttrRanges", Const, 0}, + {"AttrRank", Const, 14}, + {"AttrRecursive", Const, 14}, + {"AttrReference", Const, 14}, + {"AttrReturnAddr", Const, 0}, + {"AttrRnglistsBase", Const, 14}, + {"AttrRvalueReference", Const, 14}, + {"AttrSegment", Const, 0}, + {"AttrSibling", Const, 0}, + {"AttrSignature", Const, 14}, + {"AttrSmall", Const, 14}, + {"AttrSpecification", Const, 0}, + {"AttrStartScope", Const, 0}, + {"AttrStaticLink", Const, 0}, + {"AttrStmtList", Const, 0}, + {"AttrStrOffsetsBase", Const, 14}, + {"AttrStride", Const, 0}, + {"AttrStrideSize", Const, 0}, + {"AttrStringLength", Const, 0}, + {"AttrStringLengthBitSize", Const, 14}, + {"AttrStringLengthByteSize", Const, 14}, + {"AttrThreadsScaled", Const, 14}, + {"AttrTrampoline", Const, 0}, + {"AttrType", Const, 0}, + {"AttrUpperBound", Const, 0}, + {"AttrUseLocation", Const, 0}, + {"AttrUseUTF8", Const, 0}, + {"AttrVarParam", Const, 0}, + {"AttrVirtuality", Const, 0}, + {"AttrVisibility", Const, 0}, + {"AttrVtableElemLoc", Const, 0}, + {"BasicType", Type, 0}, + {"BasicType.BitOffset", Field, 0}, + {"BasicType.BitSize", Field, 0}, + {"BasicType.CommonType", Field, 0}, + {"BasicType.DataBitOffset", Field, 18}, + {"BoolType", Type, 0}, + {"BoolType.BasicType", Field, 0}, + {"CharType", Type, 0}, + {"CharType.BasicType", Field, 0}, + {"Class", Type, 5}, + {"ClassAddrPtr", Const, 14}, + {"ClassAddress", Const, 5}, + {"ClassBlock", Const, 5}, + {"ClassConstant", Const, 5}, + {"ClassExprLoc", Const, 5}, + {"ClassFlag", Const, 5}, + {"ClassLinePtr", Const, 5}, + {"ClassLocList", Const, 14}, + {"ClassLocListPtr", Const, 5}, + {"ClassMacPtr", Const, 5}, + {"ClassRangeListPtr", Const, 5}, + {"ClassReference", Const, 5}, + {"ClassReferenceAlt", Const, 5}, + {"ClassReferenceSig", Const, 5}, + {"ClassRngList", Const, 14}, + {"ClassRngListsPtr", Const, 14}, + {"ClassStrOffsetsPtr", Const, 14}, + {"ClassString", Const, 5}, + {"ClassStringAlt", Const, 5}, + {"ClassUnknown", Const, 6}, + {"CommonType", Type, 0}, + {"CommonType.ByteSize", Field, 0}, + {"CommonType.Name", Field, 0}, + {"ComplexType", Type, 0}, + {"ComplexType.BasicType", Field, 0}, + {"Data", Type, 0}, + {"DecodeError", Type, 0}, + {"DecodeError.Err", Field, 0}, + {"DecodeError.Name", Field, 0}, + {"DecodeError.Offset", Field, 0}, + {"DotDotDotType", Type, 0}, + {"DotDotDotType.CommonType", Field, 0}, + {"Entry", Type, 0}, + {"Entry.Children", Field, 0}, + {"Entry.Field", Field, 0}, + {"Entry.Offset", Field, 0}, + {"Entry.Tag", Field, 0}, + {"EnumType", Type, 0}, + {"EnumType.CommonType", Field, 0}, + {"EnumType.EnumName", Field, 0}, + {"EnumType.Val", Field, 0}, + {"EnumValue", Type, 0}, + {"EnumValue.Name", Field, 0}, + {"EnumValue.Val", Field, 0}, + {"ErrUnknownPC", Var, 5}, + {"Field", Type, 0}, + {"Field.Attr", Field, 0}, + {"Field.Class", Field, 5}, + {"Field.Val", Field, 0}, + {"FloatType", Type, 0}, + {"FloatType.BasicType", Field, 0}, + {"FuncType", Type, 0}, + {"FuncType.CommonType", Field, 0}, + {"FuncType.ParamType", Field, 0}, + {"FuncType.ReturnType", Field, 0}, + {"IntType", Type, 0}, + {"IntType.BasicType", Field, 0}, + {"LineEntry", Type, 5}, + {"LineEntry.Address", Field, 5}, + {"LineEntry.BasicBlock", Field, 5}, + {"LineEntry.Column", Field, 5}, + {"LineEntry.Discriminator", Field, 5}, + {"LineEntry.EndSequence", Field, 5}, + {"LineEntry.EpilogueBegin", Field, 5}, + {"LineEntry.File", Field, 5}, + {"LineEntry.ISA", Field, 5}, + {"LineEntry.IsStmt", Field, 5}, + {"LineEntry.Line", Field, 5}, + {"LineEntry.OpIndex", Field, 5}, + {"LineEntry.PrologueEnd", Field, 5}, + {"LineFile", Type, 5}, + {"LineFile.Length", Field, 5}, + {"LineFile.Mtime", Field, 5}, + {"LineFile.Name", Field, 5}, + {"LineReader", Type, 5}, + {"LineReaderPos", Type, 5}, + {"New", Func, 0}, + {"Offset", Type, 0}, + {"PtrType", Type, 0}, + {"PtrType.CommonType", Field, 0}, + {"PtrType.Type", Field, 0}, + {"QualType", Type, 0}, + {"QualType.CommonType", Field, 0}, + {"QualType.Qual", Field, 0}, + {"QualType.Type", Field, 0}, + {"Reader", Type, 0}, + {"StructField", Type, 0}, + {"StructField.BitOffset", Field, 0}, + {"StructField.BitSize", Field, 0}, + {"StructField.ByteOffset", Field, 0}, + {"StructField.ByteSize", Field, 0}, + {"StructField.DataBitOffset", Field, 18}, + {"StructField.Name", Field, 0}, + {"StructField.Type", Field, 0}, + {"StructType", Type, 0}, + {"StructType.CommonType", Field, 0}, + {"StructType.Field", Field, 0}, + {"StructType.Incomplete", Field, 0}, + {"StructType.Kind", Field, 0}, + {"StructType.StructName", Field, 0}, + {"Tag", Type, 0}, + {"TagAccessDeclaration", Const, 0}, + {"TagArrayType", Const, 0}, + {"TagAtomicType", Const, 14}, + {"TagBaseType", Const, 0}, + {"TagCallSite", Const, 14}, + {"TagCallSiteParameter", Const, 14}, + {"TagCatchDwarfBlock", Const, 0}, + {"TagClassType", Const, 0}, + {"TagCoarrayType", Const, 14}, + {"TagCommonDwarfBlock", Const, 0}, + {"TagCommonInclusion", Const, 0}, + {"TagCompileUnit", Const, 0}, + {"TagCondition", Const, 3}, + {"TagConstType", Const, 0}, + {"TagConstant", Const, 0}, + {"TagDwarfProcedure", Const, 0}, + {"TagDynamicType", Const, 14}, + {"TagEntryPoint", Const, 0}, + {"TagEnumerationType", Const, 0}, + {"TagEnumerator", Const, 0}, + {"TagFileType", Const, 0}, + {"TagFormalParameter", Const, 0}, + {"TagFriend", Const, 0}, + {"TagGenericSubrange", Const, 14}, + {"TagImmutableType", Const, 14}, + {"TagImportedDeclaration", Const, 0}, + {"TagImportedModule", Const, 0}, + {"TagImportedUnit", Const, 0}, + {"TagInheritance", Const, 0}, + {"TagInlinedSubroutine", Const, 0}, + {"TagInterfaceType", Const, 0}, + {"TagLabel", Const, 0}, + {"TagLexDwarfBlock", Const, 0}, + {"TagMember", Const, 0}, + {"TagModule", Const, 0}, + {"TagMutableType", Const, 0}, + {"TagNamelist", Const, 0}, + {"TagNamelistItem", Const, 0}, + {"TagNamespace", Const, 0}, + {"TagPackedType", Const, 0}, + {"TagPartialUnit", Const, 0}, + {"TagPointerType", Const, 0}, + {"TagPtrToMemberType", Const, 0}, + {"TagReferenceType", Const, 0}, + {"TagRestrictType", Const, 0}, + {"TagRvalueReferenceType", Const, 3}, + {"TagSetType", Const, 0}, + {"TagSharedType", Const, 3}, + {"TagSkeletonUnit", Const, 14}, + {"TagStringType", Const, 0}, + {"TagStructType", Const, 0}, + {"TagSubprogram", Const, 0}, + {"TagSubrangeType", Const, 0}, + {"TagSubroutineType", Const, 0}, + {"TagTemplateAlias", Const, 3}, + {"TagTemplateTypeParameter", Const, 0}, + {"TagTemplateValueParameter", Const, 0}, + {"TagThrownType", Const, 0}, + {"TagTryDwarfBlock", Const, 0}, + {"TagTypeUnit", Const, 3}, + {"TagTypedef", Const, 0}, + {"TagUnionType", Const, 0}, + {"TagUnspecifiedParameters", Const, 0}, + {"TagUnspecifiedType", Const, 0}, + {"TagVariable", Const, 0}, + {"TagVariant", Const, 0}, + {"TagVariantPart", Const, 0}, + {"TagVolatileType", Const, 0}, + {"TagWithStmt", Const, 0}, + {"Type", Type, 0}, + {"TypedefType", Type, 0}, + {"TypedefType.CommonType", Field, 0}, + {"TypedefType.Type", Field, 0}, + {"UcharType", Type, 0}, + {"UcharType.BasicType", Field, 0}, + {"UintType", Type, 0}, + {"UintType.BasicType", Field, 0}, + {"UnspecifiedType", Type, 4}, + {"UnspecifiedType.BasicType", Field, 4}, + {"UnsupportedType", Type, 13}, + {"UnsupportedType.CommonType", Field, 13}, + {"UnsupportedType.Tag", Field, 13}, + {"VoidType", Type, 0}, + {"VoidType.CommonType", Field, 0}, + }, + "debug/elf": { + {"(*File).Close", Method, 0}, + {"(*File).DWARF", Method, 0}, + {"(*File).DynString", Method, 1}, + {"(*File).DynValue", Method, 21}, + {"(*File).DynamicSymbols", Method, 4}, + {"(*File).ImportedLibraries", Method, 0}, + {"(*File).ImportedSymbols", Method, 0}, + {"(*File).Section", Method, 0}, + {"(*File).SectionByType", Method, 0}, + {"(*File).Symbols", Method, 0}, + {"(*FormatError).Error", Method, 0}, + {"(*Prog).Open", Method, 0}, + {"(*Section).Data", Method, 0}, + {"(*Section).Open", Method, 0}, + {"(Class).GoString", Method, 0}, + {"(Class).String", Method, 0}, + {"(CompressionType).GoString", Method, 6}, + {"(CompressionType).String", Method, 6}, + {"(Data).GoString", Method, 0}, + {"(Data).String", Method, 0}, + {"(DynFlag).GoString", Method, 0}, + {"(DynFlag).String", Method, 0}, + {"(DynFlag1).GoString", Method, 21}, + {"(DynFlag1).String", Method, 21}, + {"(DynTag).GoString", Method, 0}, + {"(DynTag).String", Method, 0}, + {"(Machine).GoString", Method, 0}, + {"(Machine).String", Method, 0}, + {"(NType).GoString", Method, 0}, + {"(NType).String", Method, 0}, + {"(OSABI).GoString", Method, 0}, + {"(OSABI).String", Method, 0}, + {"(Prog).ReadAt", Method, 0}, + {"(ProgFlag).GoString", Method, 0}, + {"(ProgFlag).String", Method, 0}, + {"(ProgType).GoString", Method, 0}, + {"(ProgType).String", Method, 0}, + {"(R_386).GoString", Method, 0}, + {"(R_386).String", Method, 0}, + {"(R_390).GoString", Method, 7}, + {"(R_390).String", Method, 7}, + {"(R_AARCH64).GoString", Method, 4}, + {"(R_AARCH64).String", Method, 4}, + {"(R_ALPHA).GoString", Method, 0}, + {"(R_ALPHA).String", Method, 0}, + {"(R_ARM).GoString", Method, 0}, + {"(R_ARM).String", Method, 0}, + {"(R_LARCH).GoString", Method, 19}, + {"(R_LARCH).String", Method, 19}, + {"(R_MIPS).GoString", Method, 6}, + {"(R_MIPS).String", Method, 6}, + {"(R_PPC).GoString", Method, 0}, + {"(R_PPC).String", Method, 0}, + {"(R_PPC64).GoString", Method, 5}, + {"(R_PPC64).String", Method, 5}, + {"(R_RISCV).GoString", Method, 11}, + {"(R_RISCV).String", Method, 11}, + {"(R_SPARC).GoString", Method, 0}, + {"(R_SPARC).String", Method, 0}, + {"(R_X86_64).GoString", Method, 0}, + {"(R_X86_64).String", Method, 0}, + {"(Section).ReadAt", Method, 0}, + {"(SectionFlag).GoString", Method, 0}, + {"(SectionFlag).String", Method, 0}, + {"(SectionIndex).GoString", Method, 0}, + {"(SectionIndex).String", Method, 0}, + {"(SectionType).GoString", Method, 0}, + {"(SectionType).String", Method, 0}, + {"(SymBind).GoString", Method, 0}, + {"(SymBind).String", Method, 0}, + {"(SymType).GoString", Method, 0}, + {"(SymType).String", Method, 0}, + {"(SymVis).GoString", Method, 0}, + {"(SymVis).String", Method, 0}, + {"(Type).GoString", Method, 0}, + {"(Type).String", Method, 0}, + {"(Version).GoString", Method, 0}, + {"(Version).String", Method, 0}, + {"ARM_MAGIC_TRAMP_NUMBER", Const, 0}, + {"COMPRESS_HIOS", Const, 6}, + {"COMPRESS_HIPROC", Const, 6}, + {"COMPRESS_LOOS", Const, 6}, + {"COMPRESS_LOPROC", Const, 6}, + {"COMPRESS_ZLIB", Const, 6}, + {"COMPRESS_ZSTD", Const, 21}, + {"Chdr32", Type, 6}, + {"Chdr32.Addralign", Field, 6}, + {"Chdr32.Size", Field, 6}, + {"Chdr32.Type", Field, 6}, + {"Chdr64", Type, 6}, + {"Chdr64.Addralign", Field, 6}, + {"Chdr64.Size", Field, 6}, + {"Chdr64.Type", Field, 6}, + {"Class", Type, 0}, + {"CompressionType", Type, 6}, + {"DF_1_CONFALT", Const, 21}, + {"DF_1_DIRECT", Const, 21}, + {"DF_1_DISPRELDNE", Const, 21}, + {"DF_1_DISPRELPND", Const, 21}, + {"DF_1_EDITED", Const, 21}, + {"DF_1_ENDFILTEE", Const, 21}, + {"DF_1_GLOBAL", Const, 21}, + {"DF_1_GLOBAUDIT", Const, 21}, + {"DF_1_GROUP", Const, 21}, + {"DF_1_IGNMULDEF", Const, 21}, + {"DF_1_INITFIRST", Const, 21}, + {"DF_1_INTERPOSE", Const, 21}, + {"DF_1_KMOD", Const, 21}, + {"DF_1_LOADFLTR", Const, 21}, + {"DF_1_NOCOMMON", Const, 21}, + {"DF_1_NODEFLIB", Const, 21}, + {"DF_1_NODELETE", Const, 21}, + {"DF_1_NODIRECT", Const, 21}, + {"DF_1_NODUMP", Const, 21}, + {"DF_1_NOHDR", Const, 21}, + {"DF_1_NOKSYMS", Const, 21}, + {"DF_1_NOOPEN", Const, 21}, + {"DF_1_NORELOC", Const, 21}, + {"DF_1_NOW", Const, 21}, + {"DF_1_ORIGIN", Const, 21}, + {"DF_1_PIE", Const, 21}, + {"DF_1_SINGLETON", Const, 21}, + {"DF_1_STUB", Const, 21}, + {"DF_1_SYMINTPOSE", Const, 21}, + {"DF_1_TRANS", Const, 21}, + {"DF_1_WEAKFILTER", Const, 21}, + {"DF_BIND_NOW", Const, 0}, + {"DF_ORIGIN", Const, 0}, + {"DF_STATIC_TLS", Const, 0}, + {"DF_SYMBOLIC", Const, 0}, + {"DF_TEXTREL", Const, 0}, + {"DT_ADDRRNGHI", Const, 16}, + {"DT_ADDRRNGLO", Const, 16}, + {"DT_AUDIT", Const, 16}, + {"DT_AUXILIARY", Const, 16}, + {"DT_BIND_NOW", Const, 0}, + {"DT_CHECKSUM", Const, 16}, + {"DT_CONFIG", Const, 16}, + {"DT_DEBUG", Const, 0}, + {"DT_DEPAUDIT", Const, 16}, + {"DT_ENCODING", Const, 0}, + {"DT_FEATURE", Const, 16}, + {"DT_FILTER", Const, 16}, + {"DT_FINI", Const, 0}, + {"DT_FINI_ARRAY", Const, 0}, + {"DT_FINI_ARRAYSZ", Const, 0}, + {"DT_FLAGS", Const, 0}, + {"DT_FLAGS_1", Const, 16}, + {"DT_GNU_CONFLICT", Const, 16}, + {"DT_GNU_CONFLICTSZ", Const, 16}, + {"DT_GNU_HASH", Const, 16}, + {"DT_GNU_LIBLIST", Const, 16}, + {"DT_GNU_LIBLISTSZ", Const, 16}, + {"DT_GNU_PRELINKED", Const, 16}, + {"DT_HASH", Const, 0}, + {"DT_HIOS", Const, 0}, + {"DT_HIPROC", Const, 0}, + {"DT_INIT", Const, 0}, + {"DT_INIT_ARRAY", Const, 0}, + {"DT_INIT_ARRAYSZ", Const, 0}, + {"DT_JMPREL", Const, 0}, + {"DT_LOOS", Const, 0}, + {"DT_LOPROC", Const, 0}, + {"DT_MIPS_AUX_DYNAMIC", Const, 16}, + {"DT_MIPS_BASE_ADDRESS", Const, 16}, + {"DT_MIPS_COMPACT_SIZE", Const, 16}, + {"DT_MIPS_CONFLICT", Const, 16}, + {"DT_MIPS_CONFLICTNO", Const, 16}, + {"DT_MIPS_CXX_FLAGS", Const, 16}, + {"DT_MIPS_DELTA_CLASS", Const, 16}, + {"DT_MIPS_DELTA_CLASSSYM", Const, 16}, + {"DT_MIPS_DELTA_CLASSSYM_NO", Const, 16}, + {"DT_MIPS_DELTA_CLASS_NO", Const, 16}, + {"DT_MIPS_DELTA_INSTANCE", Const, 16}, + {"DT_MIPS_DELTA_INSTANCE_NO", Const, 16}, + {"DT_MIPS_DELTA_RELOC", Const, 16}, + {"DT_MIPS_DELTA_RELOC_NO", Const, 16}, + {"DT_MIPS_DELTA_SYM", Const, 16}, + {"DT_MIPS_DELTA_SYM_NO", Const, 16}, + {"DT_MIPS_DYNSTR_ALIGN", Const, 16}, + {"DT_MIPS_FLAGS", Const, 16}, + {"DT_MIPS_GOTSYM", Const, 16}, + {"DT_MIPS_GP_VALUE", Const, 16}, + {"DT_MIPS_HIDDEN_GOTIDX", Const, 16}, + {"DT_MIPS_HIPAGENO", Const, 16}, + {"DT_MIPS_ICHECKSUM", Const, 16}, + {"DT_MIPS_INTERFACE", Const, 16}, + {"DT_MIPS_INTERFACE_SIZE", Const, 16}, + {"DT_MIPS_IVERSION", Const, 16}, + {"DT_MIPS_LIBLIST", Const, 16}, + {"DT_MIPS_LIBLISTNO", Const, 16}, + {"DT_MIPS_LOCALPAGE_GOTIDX", Const, 16}, + {"DT_MIPS_LOCAL_GOTIDX", Const, 16}, + {"DT_MIPS_LOCAL_GOTNO", Const, 16}, + {"DT_MIPS_MSYM", Const, 16}, + {"DT_MIPS_OPTIONS", Const, 16}, + {"DT_MIPS_PERF_SUFFIX", Const, 16}, + {"DT_MIPS_PIXIE_INIT", Const, 16}, + {"DT_MIPS_PLTGOT", Const, 16}, + {"DT_MIPS_PROTECTED_GOTIDX", Const, 16}, + {"DT_MIPS_RLD_MAP", Const, 16}, + {"DT_MIPS_RLD_MAP_REL", Const, 16}, + {"DT_MIPS_RLD_TEXT_RESOLVE_ADDR", Const, 16}, + {"DT_MIPS_RLD_VERSION", Const, 16}, + {"DT_MIPS_RWPLT", Const, 16}, + {"DT_MIPS_SYMBOL_LIB", Const, 16}, + {"DT_MIPS_SYMTABNO", Const, 16}, + {"DT_MIPS_TIME_STAMP", Const, 16}, + {"DT_MIPS_UNREFEXTNO", Const, 16}, + {"DT_MOVEENT", Const, 16}, + {"DT_MOVESZ", Const, 16}, + {"DT_MOVETAB", Const, 16}, + {"DT_NEEDED", Const, 0}, + {"DT_NULL", Const, 0}, + {"DT_PLTGOT", Const, 0}, + {"DT_PLTPAD", Const, 16}, + {"DT_PLTPADSZ", Const, 16}, + {"DT_PLTREL", Const, 0}, + {"DT_PLTRELSZ", Const, 0}, + {"DT_POSFLAG_1", Const, 16}, + {"DT_PPC64_GLINK", Const, 16}, + {"DT_PPC64_OPD", Const, 16}, + {"DT_PPC64_OPDSZ", Const, 16}, + {"DT_PPC64_OPT", Const, 16}, + {"DT_PPC_GOT", Const, 16}, + {"DT_PPC_OPT", Const, 16}, + {"DT_PREINIT_ARRAY", Const, 0}, + {"DT_PREINIT_ARRAYSZ", Const, 0}, + {"DT_REL", Const, 0}, + {"DT_RELA", Const, 0}, + {"DT_RELACOUNT", Const, 16}, + {"DT_RELAENT", Const, 0}, + {"DT_RELASZ", Const, 0}, + {"DT_RELCOUNT", Const, 16}, + {"DT_RELENT", Const, 0}, + {"DT_RELSZ", Const, 0}, + {"DT_RPATH", Const, 0}, + {"DT_RUNPATH", Const, 0}, + {"DT_SONAME", Const, 0}, + {"DT_SPARC_REGISTER", Const, 16}, + {"DT_STRSZ", Const, 0}, + {"DT_STRTAB", Const, 0}, + {"DT_SYMBOLIC", Const, 0}, + {"DT_SYMENT", Const, 0}, + {"DT_SYMINENT", Const, 16}, + {"DT_SYMINFO", Const, 16}, + {"DT_SYMINSZ", Const, 16}, + {"DT_SYMTAB", Const, 0}, + {"DT_SYMTAB_SHNDX", Const, 16}, + {"DT_TEXTREL", Const, 0}, + {"DT_TLSDESC_GOT", Const, 16}, + {"DT_TLSDESC_PLT", Const, 16}, + {"DT_USED", Const, 16}, + {"DT_VALRNGHI", Const, 16}, + {"DT_VALRNGLO", Const, 16}, + {"DT_VERDEF", Const, 16}, + {"DT_VERDEFNUM", Const, 16}, + {"DT_VERNEED", Const, 0}, + {"DT_VERNEEDNUM", Const, 0}, + {"DT_VERSYM", Const, 0}, + {"Data", Type, 0}, + {"Dyn32", Type, 0}, + {"Dyn32.Tag", Field, 0}, + {"Dyn32.Val", Field, 0}, + {"Dyn64", Type, 0}, + {"Dyn64.Tag", Field, 0}, + {"Dyn64.Val", Field, 0}, + {"DynFlag", Type, 0}, + {"DynFlag1", Type, 21}, + {"DynTag", Type, 0}, + {"EI_ABIVERSION", Const, 0}, + {"EI_CLASS", Const, 0}, + {"EI_DATA", Const, 0}, + {"EI_NIDENT", Const, 0}, + {"EI_OSABI", Const, 0}, + {"EI_PAD", Const, 0}, + {"EI_VERSION", Const, 0}, + {"ELFCLASS32", Const, 0}, + {"ELFCLASS64", Const, 0}, + {"ELFCLASSNONE", Const, 0}, + {"ELFDATA2LSB", Const, 0}, + {"ELFDATA2MSB", Const, 0}, + {"ELFDATANONE", Const, 0}, + {"ELFMAG", Const, 0}, + {"ELFOSABI_86OPEN", Const, 0}, + {"ELFOSABI_AIX", Const, 0}, + {"ELFOSABI_ARM", Const, 0}, + {"ELFOSABI_AROS", Const, 11}, + {"ELFOSABI_CLOUDABI", Const, 11}, + {"ELFOSABI_FENIXOS", Const, 11}, + {"ELFOSABI_FREEBSD", Const, 0}, + {"ELFOSABI_HPUX", Const, 0}, + {"ELFOSABI_HURD", Const, 0}, + {"ELFOSABI_IRIX", Const, 0}, + {"ELFOSABI_LINUX", Const, 0}, + {"ELFOSABI_MODESTO", Const, 0}, + {"ELFOSABI_NETBSD", Const, 0}, + {"ELFOSABI_NONE", Const, 0}, + {"ELFOSABI_NSK", Const, 0}, + {"ELFOSABI_OPENBSD", Const, 0}, + {"ELFOSABI_OPENVMS", Const, 0}, + {"ELFOSABI_SOLARIS", Const, 0}, + {"ELFOSABI_STANDALONE", Const, 0}, + {"ELFOSABI_TRU64", Const, 0}, + {"EM_386", Const, 0}, + {"EM_486", Const, 0}, + {"EM_56800EX", Const, 11}, + {"EM_68HC05", Const, 11}, + {"EM_68HC08", Const, 11}, + {"EM_68HC11", Const, 11}, + {"EM_68HC12", Const, 0}, + {"EM_68HC16", Const, 11}, + {"EM_68K", Const, 0}, + {"EM_78KOR", Const, 11}, + {"EM_8051", Const, 11}, + {"EM_860", Const, 0}, + {"EM_88K", Const, 0}, + {"EM_960", Const, 0}, + {"EM_AARCH64", Const, 4}, + {"EM_ALPHA", Const, 0}, + {"EM_ALPHA_STD", Const, 0}, + {"EM_ALTERA_NIOS2", Const, 11}, + {"EM_AMDGPU", Const, 11}, + {"EM_ARC", Const, 0}, + {"EM_ARCA", Const, 11}, + {"EM_ARC_COMPACT", Const, 11}, + {"EM_ARC_COMPACT2", Const, 11}, + {"EM_ARM", Const, 0}, + {"EM_AVR", Const, 11}, + {"EM_AVR32", Const, 11}, + {"EM_BA1", Const, 11}, + {"EM_BA2", Const, 11}, + {"EM_BLACKFIN", Const, 11}, + {"EM_BPF", Const, 11}, + {"EM_C166", Const, 11}, + {"EM_CDP", Const, 11}, + {"EM_CE", Const, 11}, + {"EM_CLOUDSHIELD", Const, 11}, + {"EM_COGE", Const, 11}, + {"EM_COLDFIRE", Const, 0}, + {"EM_COOL", Const, 11}, + {"EM_COREA_1ST", Const, 11}, + {"EM_COREA_2ND", Const, 11}, + {"EM_CR", Const, 11}, + {"EM_CR16", Const, 11}, + {"EM_CRAYNV2", Const, 11}, + {"EM_CRIS", Const, 11}, + {"EM_CRX", Const, 11}, + {"EM_CSR_KALIMBA", Const, 11}, + {"EM_CUDA", Const, 11}, + {"EM_CYPRESS_M8C", Const, 11}, + {"EM_D10V", Const, 11}, + {"EM_D30V", Const, 11}, + {"EM_DSP24", Const, 11}, + {"EM_DSPIC30F", Const, 11}, + {"EM_DXP", Const, 11}, + {"EM_ECOG1", Const, 11}, + {"EM_ECOG16", Const, 11}, + {"EM_ECOG1X", Const, 11}, + {"EM_ECOG2", Const, 11}, + {"EM_ETPU", Const, 11}, + {"EM_EXCESS", Const, 11}, + {"EM_F2MC16", Const, 11}, + {"EM_FIREPATH", Const, 11}, + {"EM_FR20", Const, 0}, + {"EM_FR30", Const, 11}, + {"EM_FT32", Const, 11}, + {"EM_FX66", Const, 11}, + {"EM_H8S", Const, 0}, + {"EM_H8_300", Const, 0}, + {"EM_H8_300H", Const, 0}, + {"EM_H8_500", Const, 0}, + {"EM_HUANY", Const, 11}, + {"EM_IA_64", Const, 0}, + {"EM_INTEL205", Const, 11}, + {"EM_INTEL206", Const, 11}, + {"EM_INTEL207", Const, 11}, + {"EM_INTEL208", Const, 11}, + {"EM_INTEL209", Const, 11}, + {"EM_IP2K", Const, 11}, + {"EM_JAVELIN", Const, 11}, + {"EM_K10M", Const, 11}, + {"EM_KM32", Const, 11}, + {"EM_KMX16", Const, 11}, + {"EM_KMX32", Const, 11}, + {"EM_KMX8", Const, 11}, + {"EM_KVARC", Const, 11}, + {"EM_L10M", Const, 11}, + {"EM_LANAI", Const, 11}, + {"EM_LATTICEMICO32", Const, 11}, + {"EM_LOONGARCH", Const, 19}, + {"EM_M16C", Const, 11}, + {"EM_M32", Const, 0}, + {"EM_M32C", Const, 11}, + {"EM_M32R", Const, 11}, + {"EM_MANIK", Const, 11}, + {"EM_MAX", Const, 11}, + {"EM_MAXQ30", Const, 11}, + {"EM_MCHP_PIC", Const, 11}, + {"EM_MCST_ELBRUS", Const, 11}, + {"EM_ME16", Const, 0}, + {"EM_METAG", Const, 11}, + {"EM_MICROBLAZE", Const, 11}, + {"EM_MIPS", Const, 0}, + {"EM_MIPS_RS3_LE", Const, 0}, + {"EM_MIPS_RS4_BE", Const, 0}, + {"EM_MIPS_X", Const, 0}, + {"EM_MMA", Const, 0}, + {"EM_MMDSP_PLUS", Const, 11}, + {"EM_MMIX", Const, 11}, + {"EM_MN10200", Const, 11}, + {"EM_MN10300", Const, 11}, + {"EM_MOXIE", Const, 11}, + {"EM_MSP430", Const, 11}, + {"EM_NCPU", Const, 0}, + {"EM_NDR1", Const, 0}, + {"EM_NDS32", Const, 11}, + {"EM_NONE", Const, 0}, + {"EM_NORC", Const, 11}, + {"EM_NS32K", Const, 11}, + {"EM_OPEN8", Const, 11}, + {"EM_OPENRISC", Const, 11}, + {"EM_PARISC", Const, 0}, + {"EM_PCP", Const, 0}, + {"EM_PDP10", Const, 11}, + {"EM_PDP11", Const, 11}, + {"EM_PDSP", Const, 11}, + {"EM_PJ", Const, 11}, + {"EM_PPC", Const, 0}, + {"EM_PPC64", Const, 0}, + {"EM_PRISM", Const, 11}, + {"EM_QDSP6", Const, 11}, + {"EM_R32C", Const, 11}, + {"EM_RCE", Const, 0}, + {"EM_RH32", Const, 0}, + {"EM_RISCV", Const, 11}, + {"EM_RL78", Const, 11}, + {"EM_RS08", Const, 11}, + {"EM_RX", Const, 11}, + {"EM_S370", Const, 0}, + {"EM_S390", Const, 0}, + {"EM_SCORE7", Const, 11}, + {"EM_SEP", Const, 11}, + {"EM_SE_C17", Const, 11}, + {"EM_SE_C33", Const, 11}, + {"EM_SH", Const, 0}, + {"EM_SHARC", Const, 11}, + {"EM_SLE9X", Const, 11}, + {"EM_SNP1K", Const, 11}, + {"EM_SPARC", Const, 0}, + {"EM_SPARC32PLUS", Const, 0}, + {"EM_SPARCV9", Const, 0}, + {"EM_ST100", Const, 0}, + {"EM_ST19", Const, 11}, + {"EM_ST200", Const, 11}, + {"EM_ST7", Const, 11}, + {"EM_ST9PLUS", Const, 11}, + {"EM_STARCORE", Const, 0}, + {"EM_STM8", Const, 11}, + {"EM_STXP7X", Const, 11}, + {"EM_SVX", Const, 11}, + {"EM_TILE64", Const, 11}, + {"EM_TILEGX", Const, 11}, + {"EM_TILEPRO", Const, 11}, + {"EM_TINYJ", Const, 0}, + {"EM_TI_ARP32", Const, 11}, + {"EM_TI_C2000", Const, 11}, + {"EM_TI_C5500", Const, 11}, + {"EM_TI_C6000", Const, 11}, + {"EM_TI_PRU", Const, 11}, + {"EM_TMM_GPP", Const, 11}, + {"EM_TPC", Const, 11}, + {"EM_TRICORE", Const, 0}, + {"EM_TRIMEDIA", Const, 11}, + {"EM_TSK3000", Const, 11}, + {"EM_UNICORE", Const, 11}, + {"EM_V800", Const, 0}, + {"EM_V850", Const, 11}, + {"EM_VAX", Const, 11}, + {"EM_VIDEOCORE", Const, 11}, + {"EM_VIDEOCORE3", Const, 11}, + {"EM_VIDEOCORE5", Const, 11}, + {"EM_VISIUM", Const, 11}, + {"EM_VPP500", Const, 0}, + {"EM_X86_64", Const, 0}, + {"EM_XCORE", Const, 11}, + {"EM_XGATE", Const, 11}, + {"EM_XIMO16", Const, 11}, + {"EM_XTENSA", Const, 11}, + {"EM_Z80", Const, 11}, + {"EM_ZSP", Const, 11}, + {"ET_CORE", Const, 0}, + {"ET_DYN", Const, 0}, + {"ET_EXEC", Const, 0}, + {"ET_HIOS", Const, 0}, + {"ET_HIPROC", Const, 0}, + {"ET_LOOS", Const, 0}, + {"ET_LOPROC", Const, 0}, + {"ET_NONE", Const, 0}, + {"ET_REL", Const, 0}, + {"EV_CURRENT", Const, 0}, + {"EV_NONE", Const, 0}, + {"ErrNoSymbols", Var, 4}, + {"File", Type, 0}, + {"File.FileHeader", Field, 0}, + {"File.Progs", Field, 0}, + {"File.Sections", Field, 0}, + {"FileHeader", Type, 0}, + {"FileHeader.ABIVersion", Field, 0}, + {"FileHeader.ByteOrder", Field, 0}, + {"FileHeader.Class", Field, 0}, + {"FileHeader.Data", Field, 0}, + {"FileHeader.Entry", Field, 1}, + {"FileHeader.Machine", Field, 0}, + {"FileHeader.OSABI", Field, 0}, + {"FileHeader.Type", Field, 0}, + {"FileHeader.Version", Field, 0}, + {"FormatError", Type, 0}, + {"Header32", Type, 0}, + {"Header32.Ehsize", Field, 0}, + {"Header32.Entry", Field, 0}, + {"Header32.Flags", Field, 0}, + {"Header32.Ident", Field, 0}, + {"Header32.Machine", Field, 0}, + {"Header32.Phentsize", Field, 0}, + {"Header32.Phnum", Field, 0}, + {"Header32.Phoff", Field, 0}, + {"Header32.Shentsize", Field, 0}, + {"Header32.Shnum", Field, 0}, + {"Header32.Shoff", Field, 0}, + {"Header32.Shstrndx", Field, 0}, + {"Header32.Type", Field, 0}, + {"Header32.Version", Field, 0}, + {"Header64", Type, 0}, + {"Header64.Ehsize", Field, 0}, + {"Header64.Entry", Field, 0}, + {"Header64.Flags", Field, 0}, + {"Header64.Ident", Field, 0}, + {"Header64.Machine", Field, 0}, + {"Header64.Phentsize", Field, 0}, + {"Header64.Phnum", Field, 0}, + {"Header64.Phoff", Field, 0}, + {"Header64.Shentsize", Field, 0}, + {"Header64.Shnum", Field, 0}, + {"Header64.Shoff", Field, 0}, + {"Header64.Shstrndx", Field, 0}, + {"Header64.Type", Field, 0}, + {"Header64.Version", Field, 0}, + {"ImportedSymbol", Type, 0}, + {"ImportedSymbol.Library", Field, 0}, + {"ImportedSymbol.Name", Field, 0}, + {"ImportedSymbol.Version", Field, 0}, + {"Machine", Type, 0}, + {"NT_FPREGSET", Const, 0}, + {"NT_PRPSINFO", Const, 0}, + {"NT_PRSTATUS", Const, 0}, + {"NType", Type, 0}, + {"NewFile", Func, 0}, + {"OSABI", Type, 0}, + {"Open", Func, 0}, + {"PF_MASKOS", Const, 0}, + {"PF_MASKPROC", Const, 0}, + {"PF_R", Const, 0}, + {"PF_W", Const, 0}, + {"PF_X", Const, 0}, + {"PT_AARCH64_ARCHEXT", Const, 16}, + {"PT_AARCH64_UNWIND", Const, 16}, + {"PT_ARM_ARCHEXT", Const, 16}, + {"PT_ARM_EXIDX", Const, 16}, + {"PT_DYNAMIC", Const, 0}, + {"PT_GNU_EH_FRAME", Const, 16}, + {"PT_GNU_MBIND_HI", Const, 16}, + {"PT_GNU_MBIND_LO", Const, 16}, + {"PT_GNU_PROPERTY", Const, 16}, + {"PT_GNU_RELRO", Const, 16}, + {"PT_GNU_STACK", Const, 16}, + {"PT_HIOS", Const, 0}, + {"PT_HIPROC", Const, 0}, + {"PT_INTERP", Const, 0}, + {"PT_LOAD", Const, 0}, + {"PT_LOOS", Const, 0}, + {"PT_LOPROC", Const, 0}, + {"PT_MIPS_ABIFLAGS", Const, 16}, + {"PT_MIPS_OPTIONS", Const, 16}, + {"PT_MIPS_REGINFO", Const, 16}, + {"PT_MIPS_RTPROC", Const, 16}, + {"PT_NOTE", Const, 0}, + {"PT_NULL", Const, 0}, + {"PT_OPENBSD_BOOTDATA", Const, 16}, + {"PT_OPENBSD_RANDOMIZE", Const, 16}, + {"PT_OPENBSD_WXNEEDED", Const, 16}, + {"PT_PAX_FLAGS", Const, 16}, + {"PT_PHDR", Const, 0}, + {"PT_S390_PGSTE", Const, 16}, + {"PT_SHLIB", Const, 0}, + {"PT_SUNWSTACK", Const, 16}, + {"PT_SUNW_EH_FRAME", Const, 16}, + {"PT_TLS", Const, 0}, + {"Prog", Type, 0}, + {"Prog.ProgHeader", Field, 0}, + {"Prog.ReaderAt", Field, 0}, + {"Prog32", Type, 0}, + {"Prog32.Align", Field, 0}, + {"Prog32.Filesz", Field, 0}, + {"Prog32.Flags", Field, 0}, + {"Prog32.Memsz", Field, 0}, + {"Prog32.Off", Field, 0}, + {"Prog32.Paddr", Field, 0}, + {"Prog32.Type", Field, 0}, + {"Prog32.Vaddr", Field, 0}, + {"Prog64", Type, 0}, + {"Prog64.Align", Field, 0}, + {"Prog64.Filesz", Field, 0}, + {"Prog64.Flags", Field, 0}, + {"Prog64.Memsz", Field, 0}, + {"Prog64.Off", Field, 0}, + {"Prog64.Paddr", Field, 0}, + {"Prog64.Type", Field, 0}, + {"Prog64.Vaddr", Field, 0}, + {"ProgFlag", Type, 0}, + {"ProgHeader", Type, 0}, + {"ProgHeader.Align", Field, 0}, + {"ProgHeader.Filesz", Field, 0}, + {"ProgHeader.Flags", Field, 0}, + {"ProgHeader.Memsz", Field, 0}, + {"ProgHeader.Off", Field, 0}, + {"ProgHeader.Paddr", Field, 0}, + {"ProgHeader.Type", Field, 0}, + {"ProgHeader.Vaddr", Field, 0}, + {"ProgType", Type, 0}, + {"R_386", Type, 0}, + {"R_386_16", Const, 10}, + {"R_386_32", Const, 0}, + {"R_386_32PLT", Const, 10}, + {"R_386_8", Const, 10}, + {"R_386_COPY", Const, 0}, + {"R_386_GLOB_DAT", Const, 0}, + {"R_386_GOT32", Const, 0}, + {"R_386_GOT32X", Const, 10}, + {"R_386_GOTOFF", Const, 0}, + {"R_386_GOTPC", Const, 0}, + {"R_386_IRELATIVE", Const, 10}, + {"R_386_JMP_SLOT", Const, 0}, + {"R_386_NONE", Const, 0}, + {"R_386_PC16", Const, 10}, + {"R_386_PC32", Const, 0}, + {"R_386_PC8", Const, 10}, + {"R_386_PLT32", Const, 0}, + {"R_386_RELATIVE", Const, 0}, + {"R_386_SIZE32", Const, 10}, + {"R_386_TLS_DESC", Const, 10}, + {"R_386_TLS_DESC_CALL", Const, 10}, + {"R_386_TLS_DTPMOD32", Const, 0}, + {"R_386_TLS_DTPOFF32", Const, 0}, + {"R_386_TLS_GD", Const, 0}, + {"R_386_TLS_GD_32", Const, 0}, + {"R_386_TLS_GD_CALL", Const, 0}, + {"R_386_TLS_GD_POP", Const, 0}, + {"R_386_TLS_GD_PUSH", Const, 0}, + {"R_386_TLS_GOTDESC", Const, 10}, + {"R_386_TLS_GOTIE", Const, 0}, + {"R_386_TLS_IE", Const, 0}, + {"R_386_TLS_IE_32", Const, 0}, + {"R_386_TLS_LDM", Const, 0}, + {"R_386_TLS_LDM_32", Const, 0}, + {"R_386_TLS_LDM_CALL", Const, 0}, + {"R_386_TLS_LDM_POP", Const, 0}, + {"R_386_TLS_LDM_PUSH", Const, 0}, + {"R_386_TLS_LDO_32", Const, 0}, + {"R_386_TLS_LE", Const, 0}, + {"R_386_TLS_LE_32", Const, 0}, + {"R_386_TLS_TPOFF", Const, 0}, + {"R_386_TLS_TPOFF32", Const, 0}, + {"R_390", Type, 7}, + {"R_390_12", Const, 7}, + {"R_390_16", Const, 7}, + {"R_390_20", Const, 7}, + {"R_390_32", Const, 7}, + {"R_390_64", Const, 7}, + {"R_390_8", Const, 7}, + {"R_390_COPY", Const, 7}, + {"R_390_GLOB_DAT", Const, 7}, + {"R_390_GOT12", Const, 7}, + {"R_390_GOT16", Const, 7}, + {"R_390_GOT20", Const, 7}, + {"R_390_GOT32", Const, 7}, + {"R_390_GOT64", Const, 7}, + {"R_390_GOTENT", Const, 7}, + {"R_390_GOTOFF", Const, 7}, + {"R_390_GOTOFF16", Const, 7}, + {"R_390_GOTOFF64", Const, 7}, + {"R_390_GOTPC", Const, 7}, + {"R_390_GOTPCDBL", Const, 7}, + {"R_390_GOTPLT12", Const, 7}, + {"R_390_GOTPLT16", Const, 7}, + {"R_390_GOTPLT20", Const, 7}, + {"R_390_GOTPLT32", Const, 7}, + {"R_390_GOTPLT64", Const, 7}, + {"R_390_GOTPLTENT", Const, 7}, + {"R_390_GOTPLTOFF16", Const, 7}, + {"R_390_GOTPLTOFF32", Const, 7}, + {"R_390_GOTPLTOFF64", Const, 7}, + {"R_390_JMP_SLOT", Const, 7}, + {"R_390_NONE", Const, 7}, + {"R_390_PC16", Const, 7}, + {"R_390_PC16DBL", Const, 7}, + {"R_390_PC32", Const, 7}, + {"R_390_PC32DBL", Const, 7}, + {"R_390_PC64", Const, 7}, + {"R_390_PLT16DBL", Const, 7}, + {"R_390_PLT32", Const, 7}, + {"R_390_PLT32DBL", Const, 7}, + {"R_390_PLT64", Const, 7}, + {"R_390_RELATIVE", Const, 7}, + {"R_390_TLS_DTPMOD", Const, 7}, + {"R_390_TLS_DTPOFF", Const, 7}, + {"R_390_TLS_GD32", Const, 7}, + {"R_390_TLS_GD64", Const, 7}, + {"R_390_TLS_GDCALL", Const, 7}, + {"R_390_TLS_GOTIE12", Const, 7}, + {"R_390_TLS_GOTIE20", Const, 7}, + {"R_390_TLS_GOTIE32", Const, 7}, + {"R_390_TLS_GOTIE64", Const, 7}, + {"R_390_TLS_IE32", Const, 7}, + {"R_390_TLS_IE64", Const, 7}, + {"R_390_TLS_IEENT", Const, 7}, + {"R_390_TLS_LDCALL", Const, 7}, + {"R_390_TLS_LDM32", Const, 7}, + {"R_390_TLS_LDM64", Const, 7}, + {"R_390_TLS_LDO32", Const, 7}, + {"R_390_TLS_LDO64", Const, 7}, + {"R_390_TLS_LE32", Const, 7}, + {"R_390_TLS_LE64", Const, 7}, + {"R_390_TLS_LOAD", Const, 7}, + {"R_390_TLS_TPOFF", Const, 7}, + {"R_AARCH64", Type, 4}, + {"R_AARCH64_ABS16", Const, 4}, + {"R_AARCH64_ABS32", Const, 4}, + {"R_AARCH64_ABS64", Const, 4}, + {"R_AARCH64_ADD_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_ADR_GOT_PAGE", Const, 4}, + {"R_AARCH64_ADR_PREL_LO21", Const, 4}, + {"R_AARCH64_ADR_PREL_PG_HI21", Const, 4}, + {"R_AARCH64_ADR_PREL_PG_HI21_NC", Const, 4}, + {"R_AARCH64_CALL26", Const, 4}, + {"R_AARCH64_CONDBR19", Const, 4}, + {"R_AARCH64_COPY", Const, 4}, + {"R_AARCH64_GLOB_DAT", Const, 4}, + {"R_AARCH64_GOT_LD_PREL19", Const, 4}, + {"R_AARCH64_IRELATIVE", Const, 4}, + {"R_AARCH64_JUMP26", Const, 4}, + {"R_AARCH64_JUMP_SLOT", Const, 4}, + {"R_AARCH64_LD64_GOTOFF_LO15", Const, 10}, + {"R_AARCH64_LD64_GOTPAGE_LO15", Const, 10}, + {"R_AARCH64_LD64_GOT_LO12_NC", Const, 4}, + {"R_AARCH64_LDST128_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_LDST16_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_LDST32_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_LDST64_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_LDST8_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_LD_PREL_LO19", Const, 4}, + {"R_AARCH64_MOVW_SABS_G0", Const, 4}, + {"R_AARCH64_MOVW_SABS_G1", Const, 4}, + {"R_AARCH64_MOVW_SABS_G2", Const, 4}, + {"R_AARCH64_MOVW_UABS_G0", Const, 4}, + {"R_AARCH64_MOVW_UABS_G0_NC", Const, 4}, + {"R_AARCH64_MOVW_UABS_G1", Const, 4}, + {"R_AARCH64_MOVW_UABS_G1_NC", Const, 4}, + {"R_AARCH64_MOVW_UABS_G2", Const, 4}, + {"R_AARCH64_MOVW_UABS_G2_NC", Const, 4}, + {"R_AARCH64_MOVW_UABS_G3", Const, 4}, + {"R_AARCH64_NONE", Const, 4}, + {"R_AARCH64_NULL", Const, 4}, + {"R_AARCH64_P32_ABS16", Const, 4}, + {"R_AARCH64_P32_ABS32", Const, 4}, + {"R_AARCH64_P32_ADD_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_ADR_GOT_PAGE", Const, 4}, + {"R_AARCH64_P32_ADR_PREL_LO21", Const, 4}, + {"R_AARCH64_P32_ADR_PREL_PG_HI21", Const, 4}, + {"R_AARCH64_P32_CALL26", Const, 4}, + {"R_AARCH64_P32_CONDBR19", Const, 4}, + {"R_AARCH64_P32_COPY", Const, 4}, + {"R_AARCH64_P32_GLOB_DAT", Const, 4}, + {"R_AARCH64_P32_GOT_LD_PREL19", Const, 4}, + {"R_AARCH64_P32_IRELATIVE", Const, 4}, + {"R_AARCH64_P32_JUMP26", Const, 4}, + {"R_AARCH64_P32_JUMP_SLOT", Const, 4}, + {"R_AARCH64_P32_LD32_GOT_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LDST128_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LDST16_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LDST32_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LDST64_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LDST8_ABS_LO12_NC", Const, 4}, + {"R_AARCH64_P32_LD_PREL_LO19", Const, 4}, + {"R_AARCH64_P32_MOVW_SABS_G0", Const, 4}, + {"R_AARCH64_P32_MOVW_UABS_G0", Const, 4}, + {"R_AARCH64_P32_MOVW_UABS_G0_NC", Const, 4}, + {"R_AARCH64_P32_MOVW_UABS_G1", Const, 4}, + {"R_AARCH64_P32_PREL16", Const, 4}, + {"R_AARCH64_P32_PREL32", Const, 4}, + {"R_AARCH64_P32_RELATIVE", Const, 4}, + {"R_AARCH64_P32_TLSDESC", Const, 4}, + {"R_AARCH64_P32_TLSDESC_ADD_LO12_NC", Const, 4}, + {"R_AARCH64_P32_TLSDESC_ADR_PAGE21", Const, 4}, + {"R_AARCH64_P32_TLSDESC_ADR_PREL21", Const, 4}, + {"R_AARCH64_P32_TLSDESC_CALL", Const, 4}, + {"R_AARCH64_P32_TLSDESC_LD32_LO12_NC", Const, 4}, + {"R_AARCH64_P32_TLSDESC_LD_PREL19", Const, 4}, + {"R_AARCH64_P32_TLSGD_ADD_LO12_NC", Const, 4}, + {"R_AARCH64_P32_TLSGD_ADR_PAGE21", Const, 4}, + {"R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4}, + {"R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC", Const, 4}, + {"R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19", Const, 4}, + {"R_AARCH64_P32_TLSLE_ADD_TPREL_HI12", Const, 4}, + {"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12", Const, 4}, + {"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC", Const, 4}, + {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0", Const, 4}, + {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC", Const, 4}, + {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G1", Const, 4}, + {"R_AARCH64_P32_TLS_DTPMOD", Const, 4}, + {"R_AARCH64_P32_TLS_DTPREL", Const, 4}, + {"R_AARCH64_P32_TLS_TPREL", Const, 4}, + {"R_AARCH64_P32_TSTBR14", Const, 4}, + {"R_AARCH64_PREL16", Const, 4}, + {"R_AARCH64_PREL32", Const, 4}, + {"R_AARCH64_PREL64", Const, 4}, + {"R_AARCH64_RELATIVE", Const, 4}, + {"R_AARCH64_TLSDESC", Const, 4}, + {"R_AARCH64_TLSDESC_ADD", Const, 4}, + {"R_AARCH64_TLSDESC_ADD_LO12_NC", Const, 4}, + {"R_AARCH64_TLSDESC_ADR_PAGE21", Const, 4}, + {"R_AARCH64_TLSDESC_ADR_PREL21", Const, 4}, + {"R_AARCH64_TLSDESC_CALL", Const, 4}, + {"R_AARCH64_TLSDESC_LD64_LO12_NC", Const, 4}, + {"R_AARCH64_TLSDESC_LDR", Const, 4}, + {"R_AARCH64_TLSDESC_LD_PREL19", Const, 4}, + {"R_AARCH64_TLSDESC_OFF_G0_NC", Const, 4}, + {"R_AARCH64_TLSDESC_OFF_G1", Const, 4}, + {"R_AARCH64_TLSGD_ADD_LO12_NC", Const, 4}, + {"R_AARCH64_TLSGD_ADR_PAGE21", Const, 4}, + {"R_AARCH64_TLSGD_ADR_PREL21", Const, 10}, + {"R_AARCH64_TLSGD_MOVW_G0_NC", Const, 10}, + {"R_AARCH64_TLSGD_MOVW_G1", Const, 10}, + {"R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4}, + {"R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC", Const, 4}, + {"R_AARCH64_TLSIE_LD_GOTTPREL_PREL19", Const, 4}, + {"R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC", Const, 4}, + {"R_AARCH64_TLSIE_MOVW_GOTTPREL_G1", Const, 4}, + {"R_AARCH64_TLSLD_ADR_PAGE21", Const, 10}, + {"R_AARCH64_TLSLD_ADR_PREL21", Const, 10}, + {"R_AARCH64_TLSLD_LDST128_DTPREL_LO12", Const, 10}, + {"R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC", Const, 10}, + {"R_AARCH64_TLSLE_ADD_TPREL_HI12", Const, 4}, + {"R_AARCH64_TLSLE_ADD_TPREL_LO12", Const, 4}, + {"R_AARCH64_TLSLE_ADD_TPREL_LO12_NC", Const, 4}, + {"R_AARCH64_TLSLE_LDST128_TPREL_LO12", Const, 10}, + {"R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC", Const, 10}, + {"R_AARCH64_TLSLE_MOVW_TPREL_G0", Const, 4}, + {"R_AARCH64_TLSLE_MOVW_TPREL_G0_NC", Const, 4}, + {"R_AARCH64_TLSLE_MOVW_TPREL_G1", Const, 4}, + {"R_AARCH64_TLSLE_MOVW_TPREL_G1_NC", Const, 4}, + {"R_AARCH64_TLSLE_MOVW_TPREL_G2", Const, 4}, + {"R_AARCH64_TLS_DTPMOD64", Const, 4}, + {"R_AARCH64_TLS_DTPREL64", Const, 4}, + {"R_AARCH64_TLS_TPREL64", Const, 4}, + {"R_AARCH64_TSTBR14", Const, 4}, + {"R_ALPHA", Type, 0}, + {"R_ALPHA_BRADDR", Const, 0}, + {"R_ALPHA_COPY", Const, 0}, + {"R_ALPHA_GLOB_DAT", Const, 0}, + {"R_ALPHA_GPDISP", Const, 0}, + {"R_ALPHA_GPREL32", Const, 0}, + {"R_ALPHA_GPRELHIGH", Const, 0}, + {"R_ALPHA_GPRELLOW", Const, 0}, + {"R_ALPHA_GPVALUE", Const, 0}, + {"R_ALPHA_HINT", Const, 0}, + {"R_ALPHA_IMMED_BR_HI32", Const, 0}, + {"R_ALPHA_IMMED_GP_16", Const, 0}, + {"R_ALPHA_IMMED_GP_HI32", Const, 0}, + {"R_ALPHA_IMMED_LO32", Const, 0}, + {"R_ALPHA_IMMED_SCN_HI32", Const, 0}, + {"R_ALPHA_JMP_SLOT", Const, 0}, + {"R_ALPHA_LITERAL", Const, 0}, + {"R_ALPHA_LITUSE", Const, 0}, + {"R_ALPHA_NONE", Const, 0}, + {"R_ALPHA_OP_PRSHIFT", Const, 0}, + {"R_ALPHA_OP_PSUB", Const, 0}, + {"R_ALPHA_OP_PUSH", Const, 0}, + {"R_ALPHA_OP_STORE", Const, 0}, + {"R_ALPHA_REFLONG", Const, 0}, + {"R_ALPHA_REFQUAD", Const, 0}, + {"R_ALPHA_RELATIVE", Const, 0}, + {"R_ALPHA_SREL16", Const, 0}, + {"R_ALPHA_SREL32", Const, 0}, + {"R_ALPHA_SREL64", Const, 0}, + {"R_ARM", Type, 0}, + {"R_ARM_ABS12", Const, 0}, + {"R_ARM_ABS16", Const, 0}, + {"R_ARM_ABS32", Const, 0}, + {"R_ARM_ABS32_NOI", Const, 10}, + {"R_ARM_ABS8", Const, 0}, + {"R_ARM_ALU_PCREL_15_8", Const, 10}, + {"R_ARM_ALU_PCREL_23_15", Const, 10}, + {"R_ARM_ALU_PCREL_7_0", Const, 10}, + {"R_ARM_ALU_PC_G0", Const, 10}, + {"R_ARM_ALU_PC_G0_NC", Const, 10}, + {"R_ARM_ALU_PC_G1", Const, 10}, + {"R_ARM_ALU_PC_G1_NC", Const, 10}, + {"R_ARM_ALU_PC_G2", Const, 10}, + {"R_ARM_ALU_SBREL_19_12_NC", Const, 10}, + {"R_ARM_ALU_SBREL_27_20_CK", Const, 10}, + {"R_ARM_ALU_SB_G0", Const, 10}, + {"R_ARM_ALU_SB_G0_NC", Const, 10}, + {"R_ARM_ALU_SB_G1", Const, 10}, + {"R_ARM_ALU_SB_G1_NC", Const, 10}, + {"R_ARM_ALU_SB_G2", Const, 10}, + {"R_ARM_AMP_VCALL9", Const, 0}, + {"R_ARM_BASE_ABS", Const, 10}, + {"R_ARM_CALL", Const, 10}, + {"R_ARM_COPY", Const, 0}, + {"R_ARM_GLOB_DAT", Const, 0}, + {"R_ARM_GNU_VTENTRY", Const, 0}, + {"R_ARM_GNU_VTINHERIT", Const, 0}, + {"R_ARM_GOT32", Const, 0}, + {"R_ARM_GOTOFF", Const, 0}, + {"R_ARM_GOTOFF12", Const, 10}, + {"R_ARM_GOTPC", Const, 0}, + {"R_ARM_GOTRELAX", Const, 10}, + {"R_ARM_GOT_ABS", Const, 10}, + {"R_ARM_GOT_BREL12", Const, 10}, + {"R_ARM_GOT_PREL", Const, 10}, + {"R_ARM_IRELATIVE", Const, 10}, + {"R_ARM_JUMP24", Const, 10}, + {"R_ARM_JUMP_SLOT", Const, 0}, + {"R_ARM_LDC_PC_G0", Const, 10}, + {"R_ARM_LDC_PC_G1", Const, 10}, + {"R_ARM_LDC_PC_G2", Const, 10}, + {"R_ARM_LDC_SB_G0", Const, 10}, + {"R_ARM_LDC_SB_G1", Const, 10}, + {"R_ARM_LDC_SB_G2", Const, 10}, + {"R_ARM_LDRS_PC_G0", Const, 10}, + {"R_ARM_LDRS_PC_G1", Const, 10}, + {"R_ARM_LDRS_PC_G2", Const, 10}, + {"R_ARM_LDRS_SB_G0", Const, 10}, + {"R_ARM_LDRS_SB_G1", Const, 10}, + {"R_ARM_LDRS_SB_G2", Const, 10}, + {"R_ARM_LDR_PC_G1", Const, 10}, + {"R_ARM_LDR_PC_G2", Const, 10}, + {"R_ARM_LDR_SBREL_11_10_NC", Const, 10}, + {"R_ARM_LDR_SB_G0", Const, 10}, + {"R_ARM_LDR_SB_G1", Const, 10}, + {"R_ARM_LDR_SB_G2", Const, 10}, + {"R_ARM_ME_TOO", Const, 10}, + {"R_ARM_MOVT_ABS", Const, 10}, + {"R_ARM_MOVT_BREL", Const, 10}, + {"R_ARM_MOVT_PREL", Const, 10}, + {"R_ARM_MOVW_ABS_NC", Const, 10}, + {"R_ARM_MOVW_BREL", Const, 10}, + {"R_ARM_MOVW_BREL_NC", Const, 10}, + {"R_ARM_MOVW_PREL_NC", Const, 10}, + {"R_ARM_NONE", Const, 0}, + {"R_ARM_PC13", Const, 0}, + {"R_ARM_PC24", Const, 0}, + {"R_ARM_PLT32", Const, 0}, + {"R_ARM_PLT32_ABS", Const, 10}, + {"R_ARM_PREL31", Const, 10}, + {"R_ARM_PRIVATE_0", Const, 10}, + {"R_ARM_PRIVATE_1", Const, 10}, + {"R_ARM_PRIVATE_10", Const, 10}, + {"R_ARM_PRIVATE_11", Const, 10}, + {"R_ARM_PRIVATE_12", Const, 10}, + {"R_ARM_PRIVATE_13", Const, 10}, + {"R_ARM_PRIVATE_14", Const, 10}, + {"R_ARM_PRIVATE_15", Const, 10}, + {"R_ARM_PRIVATE_2", Const, 10}, + {"R_ARM_PRIVATE_3", Const, 10}, + {"R_ARM_PRIVATE_4", Const, 10}, + {"R_ARM_PRIVATE_5", Const, 10}, + {"R_ARM_PRIVATE_6", Const, 10}, + {"R_ARM_PRIVATE_7", Const, 10}, + {"R_ARM_PRIVATE_8", Const, 10}, + {"R_ARM_PRIVATE_9", Const, 10}, + {"R_ARM_RABS32", Const, 0}, + {"R_ARM_RBASE", Const, 0}, + {"R_ARM_REL32", Const, 0}, + {"R_ARM_REL32_NOI", Const, 10}, + {"R_ARM_RELATIVE", Const, 0}, + {"R_ARM_RPC24", Const, 0}, + {"R_ARM_RREL32", Const, 0}, + {"R_ARM_RSBREL32", Const, 0}, + {"R_ARM_RXPC25", Const, 10}, + {"R_ARM_SBREL31", Const, 10}, + {"R_ARM_SBREL32", Const, 0}, + {"R_ARM_SWI24", Const, 0}, + {"R_ARM_TARGET1", Const, 10}, + {"R_ARM_TARGET2", Const, 10}, + {"R_ARM_THM_ABS5", Const, 0}, + {"R_ARM_THM_ALU_ABS_G0_NC", Const, 10}, + {"R_ARM_THM_ALU_ABS_G1_NC", Const, 10}, + {"R_ARM_THM_ALU_ABS_G2_NC", Const, 10}, + {"R_ARM_THM_ALU_ABS_G3", Const, 10}, + {"R_ARM_THM_ALU_PREL_11_0", Const, 10}, + {"R_ARM_THM_GOT_BREL12", Const, 10}, + {"R_ARM_THM_JUMP11", Const, 10}, + {"R_ARM_THM_JUMP19", Const, 10}, + {"R_ARM_THM_JUMP24", Const, 10}, + {"R_ARM_THM_JUMP6", Const, 10}, + {"R_ARM_THM_JUMP8", Const, 10}, + {"R_ARM_THM_MOVT_ABS", Const, 10}, + {"R_ARM_THM_MOVT_BREL", Const, 10}, + {"R_ARM_THM_MOVT_PREL", Const, 10}, + {"R_ARM_THM_MOVW_ABS_NC", Const, 10}, + {"R_ARM_THM_MOVW_BREL", Const, 10}, + {"R_ARM_THM_MOVW_BREL_NC", Const, 10}, + {"R_ARM_THM_MOVW_PREL_NC", Const, 10}, + {"R_ARM_THM_PC12", Const, 10}, + {"R_ARM_THM_PC22", Const, 0}, + {"R_ARM_THM_PC8", Const, 0}, + {"R_ARM_THM_RPC22", Const, 0}, + {"R_ARM_THM_SWI8", Const, 0}, + {"R_ARM_THM_TLS_CALL", Const, 10}, + {"R_ARM_THM_TLS_DESCSEQ16", Const, 10}, + {"R_ARM_THM_TLS_DESCSEQ32", Const, 10}, + {"R_ARM_THM_XPC22", Const, 0}, + {"R_ARM_TLS_CALL", Const, 10}, + {"R_ARM_TLS_DESCSEQ", Const, 10}, + {"R_ARM_TLS_DTPMOD32", Const, 10}, + {"R_ARM_TLS_DTPOFF32", Const, 10}, + {"R_ARM_TLS_GD32", Const, 10}, + {"R_ARM_TLS_GOTDESC", Const, 10}, + {"R_ARM_TLS_IE12GP", Const, 10}, + {"R_ARM_TLS_IE32", Const, 10}, + {"R_ARM_TLS_LDM32", Const, 10}, + {"R_ARM_TLS_LDO12", Const, 10}, + {"R_ARM_TLS_LDO32", Const, 10}, + {"R_ARM_TLS_LE12", Const, 10}, + {"R_ARM_TLS_LE32", Const, 10}, + {"R_ARM_TLS_TPOFF32", Const, 10}, + {"R_ARM_V4BX", Const, 10}, + {"R_ARM_XPC25", Const, 0}, + {"R_INFO", Func, 0}, + {"R_INFO32", Func, 0}, + {"R_LARCH", Type, 19}, + {"R_LARCH_32", Const, 19}, + {"R_LARCH_32_PCREL", Const, 20}, + {"R_LARCH_64", Const, 19}, + {"R_LARCH_64_PCREL", Const, 22}, + {"R_LARCH_ABS64_HI12", Const, 20}, + {"R_LARCH_ABS64_LO20", Const, 20}, + {"R_LARCH_ABS_HI20", Const, 20}, + {"R_LARCH_ABS_LO12", Const, 20}, + {"R_LARCH_ADD16", Const, 19}, + {"R_LARCH_ADD24", Const, 19}, + {"R_LARCH_ADD32", Const, 19}, + {"R_LARCH_ADD6", Const, 22}, + {"R_LARCH_ADD64", Const, 19}, + {"R_LARCH_ADD8", Const, 19}, + {"R_LARCH_ADD_ULEB128", Const, 22}, + {"R_LARCH_ALIGN", Const, 22}, + {"R_LARCH_B16", Const, 20}, + {"R_LARCH_B21", Const, 20}, + {"R_LARCH_B26", Const, 20}, + {"R_LARCH_CFA", Const, 22}, + {"R_LARCH_COPY", Const, 19}, + {"R_LARCH_DELETE", Const, 22}, + {"R_LARCH_GNU_VTENTRY", Const, 20}, + {"R_LARCH_GNU_VTINHERIT", Const, 20}, + {"R_LARCH_GOT64_HI12", Const, 20}, + {"R_LARCH_GOT64_LO20", Const, 20}, + {"R_LARCH_GOT64_PC_HI12", Const, 20}, + {"R_LARCH_GOT64_PC_LO20", Const, 20}, + {"R_LARCH_GOT_HI20", Const, 20}, + {"R_LARCH_GOT_LO12", Const, 20}, + {"R_LARCH_GOT_PC_HI20", Const, 20}, + {"R_LARCH_GOT_PC_LO12", Const, 20}, + {"R_LARCH_IRELATIVE", Const, 19}, + {"R_LARCH_JUMP_SLOT", Const, 19}, + {"R_LARCH_MARK_LA", Const, 19}, + {"R_LARCH_MARK_PCREL", Const, 19}, + {"R_LARCH_NONE", Const, 19}, + {"R_LARCH_PCALA64_HI12", Const, 20}, + {"R_LARCH_PCALA64_LO20", Const, 20}, + {"R_LARCH_PCALA_HI20", Const, 20}, + {"R_LARCH_PCALA_LO12", Const, 20}, + {"R_LARCH_PCREL20_S2", Const, 22}, + {"R_LARCH_RELATIVE", Const, 19}, + {"R_LARCH_RELAX", Const, 20}, + {"R_LARCH_SOP_ADD", Const, 19}, + {"R_LARCH_SOP_AND", Const, 19}, + {"R_LARCH_SOP_ASSERT", Const, 19}, + {"R_LARCH_SOP_IF_ELSE", Const, 19}, + {"R_LARCH_SOP_NOT", Const, 19}, + {"R_LARCH_SOP_POP_32_S_0_10_10_16_S2", Const, 19}, + {"R_LARCH_SOP_POP_32_S_0_5_10_16_S2", Const, 19}, + {"R_LARCH_SOP_POP_32_S_10_12", Const, 19}, + {"R_LARCH_SOP_POP_32_S_10_16", Const, 19}, + {"R_LARCH_SOP_POP_32_S_10_16_S2", Const, 19}, + {"R_LARCH_SOP_POP_32_S_10_5", Const, 19}, + {"R_LARCH_SOP_POP_32_S_5_20", Const, 19}, + {"R_LARCH_SOP_POP_32_U", Const, 19}, + {"R_LARCH_SOP_POP_32_U_10_12", Const, 19}, + {"R_LARCH_SOP_PUSH_ABSOLUTE", Const, 19}, + {"R_LARCH_SOP_PUSH_DUP", Const, 19}, + {"R_LARCH_SOP_PUSH_GPREL", Const, 19}, + {"R_LARCH_SOP_PUSH_PCREL", Const, 19}, + {"R_LARCH_SOP_PUSH_PLT_PCREL", Const, 19}, + {"R_LARCH_SOP_PUSH_TLS_GD", Const, 19}, + {"R_LARCH_SOP_PUSH_TLS_GOT", Const, 19}, + {"R_LARCH_SOP_PUSH_TLS_TPREL", Const, 19}, + {"R_LARCH_SOP_SL", Const, 19}, + {"R_LARCH_SOP_SR", Const, 19}, + {"R_LARCH_SOP_SUB", Const, 19}, + {"R_LARCH_SUB16", Const, 19}, + {"R_LARCH_SUB24", Const, 19}, + {"R_LARCH_SUB32", Const, 19}, + {"R_LARCH_SUB6", Const, 22}, + {"R_LARCH_SUB64", Const, 19}, + {"R_LARCH_SUB8", Const, 19}, + {"R_LARCH_SUB_ULEB128", Const, 22}, + {"R_LARCH_TLS_DTPMOD32", Const, 19}, + {"R_LARCH_TLS_DTPMOD64", Const, 19}, + {"R_LARCH_TLS_DTPREL32", Const, 19}, + {"R_LARCH_TLS_DTPREL64", Const, 19}, + {"R_LARCH_TLS_GD_HI20", Const, 20}, + {"R_LARCH_TLS_GD_PC_HI20", Const, 20}, + {"R_LARCH_TLS_IE64_HI12", Const, 20}, + {"R_LARCH_TLS_IE64_LO20", Const, 20}, + {"R_LARCH_TLS_IE64_PC_HI12", Const, 20}, + {"R_LARCH_TLS_IE64_PC_LO20", Const, 20}, + {"R_LARCH_TLS_IE_HI20", Const, 20}, + {"R_LARCH_TLS_IE_LO12", Const, 20}, + {"R_LARCH_TLS_IE_PC_HI20", Const, 20}, + {"R_LARCH_TLS_IE_PC_LO12", Const, 20}, + {"R_LARCH_TLS_LD_HI20", Const, 20}, + {"R_LARCH_TLS_LD_PC_HI20", Const, 20}, + {"R_LARCH_TLS_LE64_HI12", Const, 20}, + {"R_LARCH_TLS_LE64_LO20", Const, 20}, + {"R_LARCH_TLS_LE_HI20", Const, 20}, + {"R_LARCH_TLS_LE_LO12", Const, 20}, + {"R_LARCH_TLS_TPREL32", Const, 19}, + {"R_LARCH_TLS_TPREL64", Const, 19}, + {"R_MIPS", Type, 6}, + {"R_MIPS_16", Const, 6}, + {"R_MIPS_26", Const, 6}, + {"R_MIPS_32", Const, 6}, + {"R_MIPS_64", Const, 6}, + {"R_MIPS_ADD_IMMEDIATE", Const, 6}, + {"R_MIPS_CALL16", Const, 6}, + {"R_MIPS_CALL_HI16", Const, 6}, + {"R_MIPS_CALL_LO16", Const, 6}, + {"R_MIPS_DELETE", Const, 6}, + {"R_MIPS_GOT16", Const, 6}, + {"R_MIPS_GOT_DISP", Const, 6}, + {"R_MIPS_GOT_HI16", Const, 6}, + {"R_MIPS_GOT_LO16", Const, 6}, + {"R_MIPS_GOT_OFST", Const, 6}, + {"R_MIPS_GOT_PAGE", Const, 6}, + {"R_MIPS_GPREL16", Const, 6}, + {"R_MIPS_GPREL32", Const, 6}, + {"R_MIPS_HI16", Const, 6}, + {"R_MIPS_HIGHER", Const, 6}, + {"R_MIPS_HIGHEST", Const, 6}, + {"R_MIPS_INSERT_A", Const, 6}, + {"R_MIPS_INSERT_B", Const, 6}, + {"R_MIPS_JALR", Const, 6}, + {"R_MIPS_LITERAL", Const, 6}, + {"R_MIPS_LO16", Const, 6}, + {"R_MIPS_NONE", Const, 6}, + {"R_MIPS_PC16", Const, 6}, + {"R_MIPS_PC32", Const, 22}, + {"R_MIPS_PJUMP", Const, 6}, + {"R_MIPS_REL16", Const, 6}, + {"R_MIPS_REL32", Const, 6}, + {"R_MIPS_RELGOT", Const, 6}, + {"R_MIPS_SCN_DISP", Const, 6}, + {"R_MIPS_SHIFT5", Const, 6}, + {"R_MIPS_SHIFT6", Const, 6}, + {"R_MIPS_SUB", Const, 6}, + {"R_MIPS_TLS_DTPMOD32", Const, 6}, + {"R_MIPS_TLS_DTPMOD64", Const, 6}, + {"R_MIPS_TLS_DTPREL32", Const, 6}, + {"R_MIPS_TLS_DTPREL64", Const, 6}, + {"R_MIPS_TLS_DTPREL_HI16", Const, 6}, + {"R_MIPS_TLS_DTPREL_LO16", Const, 6}, + {"R_MIPS_TLS_GD", Const, 6}, + {"R_MIPS_TLS_GOTTPREL", Const, 6}, + {"R_MIPS_TLS_LDM", Const, 6}, + {"R_MIPS_TLS_TPREL32", Const, 6}, + {"R_MIPS_TLS_TPREL64", Const, 6}, + {"R_MIPS_TLS_TPREL_HI16", Const, 6}, + {"R_MIPS_TLS_TPREL_LO16", Const, 6}, + {"R_PPC", Type, 0}, + {"R_PPC64", Type, 5}, + {"R_PPC64_ADDR14", Const, 5}, + {"R_PPC64_ADDR14_BRNTAKEN", Const, 5}, + {"R_PPC64_ADDR14_BRTAKEN", Const, 5}, + {"R_PPC64_ADDR16", Const, 5}, + {"R_PPC64_ADDR16_DS", Const, 5}, + {"R_PPC64_ADDR16_HA", Const, 5}, + {"R_PPC64_ADDR16_HI", Const, 5}, + {"R_PPC64_ADDR16_HIGH", Const, 10}, + {"R_PPC64_ADDR16_HIGHA", Const, 10}, + {"R_PPC64_ADDR16_HIGHER", Const, 5}, + {"R_PPC64_ADDR16_HIGHER34", Const, 20}, + {"R_PPC64_ADDR16_HIGHERA", Const, 5}, + {"R_PPC64_ADDR16_HIGHERA34", Const, 20}, + {"R_PPC64_ADDR16_HIGHEST", Const, 5}, + {"R_PPC64_ADDR16_HIGHEST34", Const, 20}, + {"R_PPC64_ADDR16_HIGHESTA", Const, 5}, + {"R_PPC64_ADDR16_HIGHESTA34", Const, 20}, + {"R_PPC64_ADDR16_LO", Const, 5}, + {"R_PPC64_ADDR16_LO_DS", Const, 5}, + {"R_PPC64_ADDR24", Const, 5}, + {"R_PPC64_ADDR32", Const, 5}, + {"R_PPC64_ADDR64", Const, 5}, + {"R_PPC64_ADDR64_LOCAL", Const, 10}, + {"R_PPC64_COPY", Const, 20}, + {"R_PPC64_D28", Const, 20}, + {"R_PPC64_D34", Const, 20}, + {"R_PPC64_D34_HA30", Const, 20}, + {"R_PPC64_D34_HI30", Const, 20}, + {"R_PPC64_D34_LO", Const, 20}, + {"R_PPC64_DTPMOD64", Const, 5}, + {"R_PPC64_DTPREL16", Const, 5}, + {"R_PPC64_DTPREL16_DS", Const, 5}, + {"R_PPC64_DTPREL16_HA", Const, 5}, + {"R_PPC64_DTPREL16_HI", Const, 5}, + {"R_PPC64_DTPREL16_HIGH", Const, 10}, + {"R_PPC64_DTPREL16_HIGHA", Const, 10}, + {"R_PPC64_DTPREL16_HIGHER", Const, 5}, + {"R_PPC64_DTPREL16_HIGHERA", Const, 5}, + {"R_PPC64_DTPREL16_HIGHEST", Const, 5}, + {"R_PPC64_DTPREL16_HIGHESTA", Const, 5}, + {"R_PPC64_DTPREL16_LO", Const, 5}, + {"R_PPC64_DTPREL16_LO_DS", Const, 5}, + {"R_PPC64_DTPREL34", Const, 20}, + {"R_PPC64_DTPREL64", Const, 5}, + {"R_PPC64_ENTRY", Const, 10}, + {"R_PPC64_GLOB_DAT", Const, 20}, + {"R_PPC64_GNU_VTENTRY", Const, 20}, + {"R_PPC64_GNU_VTINHERIT", Const, 20}, + {"R_PPC64_GOT16", Const, 5}, + {"R_PPC64_GOT16_DS", Const, 5}, + {"R_PPC64_GOT16_HA", Const, 5}, + {"R_PPC64_GOT16_HI", Const, 5}, + {"R_PPC64_GOT16_LO", Const, 5}, + {"R_PPC64_GOT16_LO_DS", Const, 5}, + {"R_PPC64_GOT_DTPREL16_DS", Const, 5}, + {"R_PPC64_GOT_DTPREL16_HA", Const, 5}, + {"R_PPC64_GOT_DTPREL16_HI", Const, 5}, + {"R_PPC64_GOT_DTPREL16_LO_DS", Const, 5}, + {"R_PPC64_GOT_DTPREL_PCREL34", Const, 20}, + {"R_PPC64_GOT_PCREL34", Const, 20}, + {"R_PPC64_GOT_TLSGD16", Const, 5}, + {"R_PPC64_GOT_TLSGD16_HA", Const, 5}, + {"R_PPC64_GOT_TLSGD16_HI", Const, 5}, + {"R_PPC64_GOT_TLSGD16_LO", Const, 5}, + {"R_PPC64_GOT_TLSGD_PCREL34", Const, 20}, + {"R_PPC64_GOT_TLSLD16", Const, 5}, + {"R_PPC64_GOT_TLSLD16_HA", Const, 5}, + {"R_PPC64_GOT_TLSLD16_HI", Const, 5}, + {"R_PPC64_GOT_TLSLD16_LO", Const, 5}, + {"R_PPC64_GOT_TLSLD_PCREL34", Const, 20}, + {"R_PPC64_GOT_TPREL16_DS", Const, 5}, + {"R_PPC64_GOT_TPREL16_HA", Const, 5}, + {"R_PPC64_GOT_TPREL16_HI", Const, 5}, + {"R_PPC64_GOT_TPREL16_LO_DS", Const, 5}, + {"R_PPC64_GOT_TPREL_PCREL34", Const, 20}, + {"R_PPC64_IRELATIVE", Const, 10}, + {"R_PPC64_JMP_IREL", Const, 10}, + {"R_PPC64_JMP_SLOT", Const, 5}, + {"R_PPC64_NONE", Const, 5}, + {"R_PPC64_PCREL28", Const, 20}, + {"R_PPC64_PCREL34", Const, 20}, + {"R_PPC64_PCREL_OPT", Const, 20}, + {"R_PPC64_PLT16_HA", Const, 20}, + {"R_PPC64_PLT16_HI", Const, 20}, + {"R_PPC64_PLT16_LO", Const, 20}, + {"R_PPC64_PLT16_LO_DS", Const, 10}, + {"R_PPC64_PLT32", Const, 20}, + {"R_PPC64_PLT64", Const, 20}, + {"R_PPC64_PLTCALL", Const, 20}, + {"R_PPC64_PLTCALL_NOTOC", Const, 20}, + {"R_PPC64_PLTGOT16", Const, 10}, + {"R_PPC64_PLTGOT16_DS", Const, 10}, + {"R_PPC64_PLTGOT16_HA", Const, 10}, + {"R_PPC64_PLTGOT16_HI", Const, 10}, + {"R_PPC64_PLTGOT16_LO", Const, 10}, + {"R_PPC64_PLTGOT_LO_DS", Const, 10}, + {"R_PPC64_PLTREL32", Const, 20}, + {"R_PPC64_PLTREL64", Const, 20}, + {"R_PPC64_PLTSEQ", Const, 20}, + {"R_PPC64_PLTSEQ_NOTOC", Const, 20}, + {"R_PPC64_PLT_PCREL34", Const, 20}, + {"R_PPC64_PLT_PCREL34_NOTOC", Const, 20}, + {"R_PPC64_REL14", Const, 5}, + {"R_PPC64_REL14_BRNTAKEN", Const, 5}, + {"R_PPC64_REL14_BRTAKEN", Const, 5}, + {"R_PPC64_REL16", Const, 5}, + {"R_PPC64_REL16DX_HA", Const, 10}, + {"R_PPC64_REL16_HA", Const, 5}, + {"R_PPC64_REL16_HI", Const, 5}, + {"R_PPC64_REL16_HIGH", Const, 20}, + {"R_PPC64_REL16_HIGHA", Const, 20}, + {"R_PPC64_REL16_HIGHER", Const, 20}, + {"R_PPC64_REL16_HIGHER34", Const, 20}, + {"R_PPC64_REL16_HIGHERA", Const, 20}, + {"R_PPC64_REL16_HIGHERA34", Const, 20}, + {"R_PPC64_REL16_HIGHEST", Const, 20}, + {"R_PPC64_REL16_HIGHEST34", Const, 20}, + {"R_PPC64_REL16_HIGHESTA", Const, 20}, + {"R_PPC64_REL16_HIGHESTA34", Const, 20}, + {"R_PPC64_REL16_LO", Const, 5}, + {"R_PPC64_REL24", Const, 5}, + {"R_PPC64_REL24_NOTOC", Const, 10}, + {"R_PPC64_REL24_P9NOTOC", Const, 21}, + {"R_PPC64_REL30", Const, 20}, + {"R_PPC64_REL32", Const, 5}, + {"R_PPC64_REL64", Const, 5}, + {"R_PPC64_RELATIVE", Const, 18}, + {"R_PPC64_SECTOFF", Const, 20}, + {"R_PPC64_SECTOFF_DS", Const, 10}, + {"R_PPC64_SECTOFF_HA", Const, 20}, + {"R_PPC64_SECTOFF_HI", Const, 20}, + {"R_PPC64_SECTOFF_LO", Const, 20}, + {"R_PPC64_SECTOFF_LO_DS", Const, 10}, + {"R_PPC64_TLS", Const, 5}, + {"R_PPC64_TLSGD", Const, 5}, + {"R_PPC64_TLSLD", Const, 5}, + {"R_PPC64_TOC", Const, 5}, + {"R_PPC64_TOC16", Const, 5}, + {"R_PPC64_TOC16_DS", Const, 5}, + {"R_PPC64_TOC16_HA", Const, 5}, + {"R_PPC64_TOC16_HI", Const, 5}, + {"R_PPC64_TOC16_LO", Const, 5}, + {"R_PPC64_TOC16_LO_DS", Const, 5}, + {"R_PPC64_TOCSAVE", Const, 10}, + {"R_PPC64_TPREL16", Const, 5}, + {"R_PPC64_TPREL16_DS", Const, 5}, + {"R_PPC64_TPREL16_HA", Const, 5}, + {"R_PPC64_TPREL16_HI", Const, 5}, + {"R_PPC64_TPREL16_HIGH", Const, 10}, + {"R_PPC64_TPREL16_HIGHA", Const, 10}, + {"R_PPC64_TPREL16_HIGHER", Const, 5}, + {"R_PPC64_TPREL16_HIGHERA", Const, 5}, + {"R_PPC64_TPREL16_HIGHEST", Const, 5}, + {"R_PPC64_TPREL16_HIGHESTA", Const, 5}, + {"R_PPC64_TPREL16_LO", Const, 5}, + {"R_PPC64_TPREL16_LO_DS", Const, 5}, + {"R_PPC64_TPREL34", Const, 20}, + {"R_PPC64_TPREL64", Const, 5}, + {"R_PPC64_UADDR16", Const, 20}, + {"R_PPC64_UADDR32", Const, 20}, + {"R_PPC64_UADDR64", Const, 20}, + {"R_PPC_ADDR14", Const, 0}, + {"R_PPC_ADDR14_BRNTAKEN", Const, 0}, + {"R_PPC_ADDR14_BRTAKEN", Const, 0}, + {"R_PPC_ADDR16", Const, 0}, + {"R_PPC_ADDR16_HA", Const, 0}, + {"R_PPC_ADDR16_HI", Const, 0}, + {"R_PPC_ADDR16_LO", Const, 0}, + {"R_PPC_ADDR24", Const, 0}, + {"R_PPC_ADDR32", Const, 0}, + {"R_PPC_COPY", Const, 0}, + {"R_PPC_DTPMOD32", Const, 0}, + {"R_PPC_DTPREL16", Const, 0}, + {"R_PPC_DTPREL16_HA", Const, 0}, + {"R_PPC_DTPREL16_HI", Const, 0}, + {"R_PPC_DTPREL16_LO", Const, 0}, + {"R_PPC_DTPREL32", Const, 0}, + {"R_PPC_EMB_BIT_FLD", Const, 0}, + {"R_PPC_EMB_MRKREF", Const, 0}, + {"R_PPC_EMB_NADDR16", Const, 0}, + {"R_PPC_EMB_NADDR16_HA", Const, 0}, + {"R_PPC_EMB_NADDR16_HI", Const, 0}, + {"R_PPC_EMB_NADDR16_LO", Const, 0}, + {"R_PPC_EMB_NADDR32", Const, 0}, + {"R_PPC_EMB_RELSDA", Const, 0}, + {"R_PPC_EMB_RELSEC16", Const, 0}, + {"R_PPC_EMB_RELST_HA", Const, 0}, + {"R_PPC_EMB_RELST_HI", Const, 0}, + {"R_PPC_EMB_RELST_LO", Const, 0}, + {"R_PPC_EMB_SDA21", Const, 0}, + {"R_PPC_EMB_SDA2I16", Const, 0}, + {"R_PPC_EMB_SDA2REL", Const, 0}, + {"R_PPC_EMB_SDAI16", Const, 0}, + {"R_PPC_GLOB_DAT", Const, 0}, + {"R_PPC_GOT16", Const, 0}, + {"R_PPC_GOT16_HA", Const, 0}, + {"R_PPC_GOT16_HI", Const, 0}, + {"R_PPC_GOT16_LO", Const, 0}, + {"R_PPC_GOT_TLSGD16", Const, 0}, + {"R_PPC_GOT_TLSGD16_HA", Const, 0}, + {"R_PPC_GOT_TLSGD16_HI", Const, 0}, + {"R_PPC_GOT_TLSGD16_LO", Const, 0}, + {"R_PPC_GOT_TLSLD16", Const, 0}, + {"R_PPC_GOT_TLSLD16_HA", Const, 0}, + {"R_PPC_GOT_TLSLD16_HI", Const, 0}, + {"R_PPC_GOT_TLSLD16_LO", Const, 0}, + {"R_PPC_GOT_TPREL16", Const, 0}, + {"R_PPC_GOT_TPREL16_HA", Const, 0}, + {"R_PPC_GOT_TPREL16_HI", Const, 0}, + {"R_PPC_GOT_TPREL16_LO", Const, 0}, + {"R_PPC_JMP_SLOT", Const, 0}, + {"R_PPC_LOCAL24PC", Const, 0}, + {"R_PPC_NONE", Const, 0}, + {"R_PPC_PLT16_HA", Const, 0}, + {"R_PPC_PLT16_HI", Const, 0}, + {"R_PPC_PLT16_LO", Const, 0}, + {"R_PPC_PLT32", Const, 0}, + {"R_PPC_PLTREL24", Const, 0}, + {"R_PPC_PLTREL32", Const, 0}, + {"R_PPC_REL14", Const, 0}, + {"R_PPC_REL14_BRNTAKEN", Const, 0}, + {"R_PPC_REL14_BRTAKEN", Const, 0}, + {"R_PPC_REL24", Const, 0}, + {"R_PPC_REL32", Const, 0}, + {"R_PPC_RELATIVE", Const, 0}, + {"R_PPC_SDAREL16", Const, 0}, + {"R_PPC_SECTOFF", Const, 0}, + {"R_PPC_SECTOFF_HA", Const, 0}, + {"R_PPC_SECTOFF_HI", Const, 0}, + {"R_PPC_SECTOFF_LO", Const, 0}, + {"R_PPC_TLS", Const, 0}, + {"R_PPC_TPREL16", Const, 0}, + {"R_PPC_TPREL16_HA", Const, 0}, + {"R_PPC_TPREL16_HI", Const, 0}, + {"R_PPC_TPREL16_LO", Const, 0}, + {"R_PPC_TPREL32", Const, 0}, + {"R_PPC_UADDR16", Const, 0}, + {"R_PPC_UADDR32", Const, 0}, + {"R_RISCV", Type, 11}, + {"R_RISCV_32", Const, 11}, + {"R_RISCV_32_PCREL", Const, 12}, + {"R_RISCV_64", Const, 11}, + {"R_RISCV_ADD16", Const, 11}, + {"R_RISCV_ADD32", Const, 11}, + {"R_RISCV_ADD64", Const, 11}, + {"R_RISCV_ADD8", Const, 11}, + {"R_RISCV_ALIGN", Const, 11}, + {"R_RISCV_BRANCH", Const, 11}, + {"R_RISCV_CALL", Const, 11}, + {"R_RISCV_CALL_PLT", Const, 11}, + {"R_RISCV_COPY", Const, 11}, + {"R_RISCV_GNU_VTENTRY", Const, 11}, + {"R_RISCV_GNU_VTINHERIT", Const, 11}, + {"R_RISCV_GOT_HI20", Const, 11}, + {"R_RISCV_GPREL_I", Const, 11}, + {"R_RISCV_GPREL_S", Const, 11}, + {"R_RISCV_HI20", Const, 11}, + {"R_RISCV_JAL", Const, 11}, + {"R_RISCV_JUMP_SLOT", Const, 11}, + {"R_RISCV_LO12_I", Const, 11}, + {"R_RISCV_LO12_S", Const, 11}, + {"R_RISCV_NONE", Const, 11}, + {"R_RISCV_PCREL_HI20", Const, 11}, + {"R_RISCV_PCREL_LO12_I", Const, 11}, + {"R_RISCV_PCREL_LO12_S", Const, 11}, + {"R_RISCV_RELATIVE", Const, 11}, + {"R_RISCV_RELAX", Const, 11}, + {"R_RISCV_RVC_BRANCH", Const, 11}, + {"R_RISCV_RVC_JUMP", Const, 11}, + {"R_RISCV_RVC_LUI", Const, 11}, + {"R_RISCV_SET16", Const, 11}, + {"R_RISCV_SET32", Const, 11}, + {"R_RISCV_SET6", Const, 11}, + {"R_RISCV_SET8", Const, 11}, + {"R_RISCV_SUB16", Const, 11}, + {"R_RISCV_SUB32", Const, 11}, + {"R_RISCV_SUB6", Const, 11}, + {"R_RISCV_SUB64", Const, 11}, + {"R_RISCV_SUB8", Const, 11}, + {"R_RISCV_TLS_DTPMOD32", Const, 11}, + {"R_RISCV_TLS_DTPMOD64", Const, 11}, + {"R_RISCV_TLS_DTPREL32", Const, 11}, + {"R_RISCV_TLS_DTPREL64", Const, 11}, + {"R_RISCV_TLS_GD_HI20", Const, 11}, + {"R_RISCV_TLS_GOT_HI20", Const, 11}, + {"R_RISCV_TLS_TPREL32", Const, 11}, + {"R_RISCV_TLS_TPREL64", Const, 11}, + {"R_RISCV_TPREL_ADD", Const, 11}, + {"R_RISCV_TPREL_HI20", Const, 11}, + {"R_RISCV_TPREL_I", Const, 11}, + {"R_RISCV_TPREL_LO12_I", Const, 11}, + {"R_RISCV_TPREL_LO12_S", Const, 11}, + {"R_RISCV_TPREL_S", Const, 11}, + {"R_SPARC", Type, 0}, + {"R_SPARC_10", Const, 0}, + {"R_SPARC_11", Const, 0}, + {"R_SPARC_13", Const, 0}, + {"R_SPARC_16", Const, 0}, + {"R_SPARC_22", Const, 0}, + {"R_SPARC_32", Const, 0}, + {"R_SPARC_5", Const, 0}, + {"R_SPARC_6", Const, 0}, + {"R_SPARC_64", Const, 0}, + {"R_SPARC_7", Const, 0}, + {"R_SPARC_8", Const, 0}, + {"R_SPARC_COPY", Const, 0}, + {"R_SPARC_DISP16", Const, 0}, + {"R_SPARC_DISP32", Const, 0}, + {"R_SPARC_DISP64", Const, 0}, + {"R_SPARC_DISP8", Const, 0}, + {"R_SPARC_GLOB_DAT", Const, 0}, + {"R_SPARC_GLOB_JMP", Const, 0}, + {"R_SPARC_GOT10", Const, 0}, + {"R_SPARC_GOT13", Const, 0}, + {"R_SPARC_GOT22", Const, 0}, + {"R_SPARC_H44", Const, 0}, + {"R_SPARC_HH22", Const, 0}, + {"R_SPARC_HI22", Const, 0}, + {"R_SPARC_HIPLT22", Const, 0}, + {"R_SPARC_HIX22", Const, 0}, + {"R_SPARC_HM10", Const, 0}, + {"R_SPARC_JMP_SLOT", Const, 0}, + {"R_SPARC_L44", Const, 0}, + {"R_SPARC_LM22", Const, 0}, + {"R_SPARC_LO10", Const, 0}, + {"R_SPARC_LOPLT10", Const, 0}, + {"R_SPARC_LOX10", Const, 0}, + {"R_SPARC_M44", Const, 0}, + {"R_SPARC_NONE", Const, 0}, + {"R_SPARC_OLO10", Const, 0}, + {"R_SPARC_PC10", Const, 0}, + {"R_SPARC_PC22", Const, 0}, + {"R_SPARC_PCPLT10", Const, 0}, + {"R_SPARC_PCPLT22", Const, 0}, + {"R_SPARC_PCPLT32", Const, 0}, + {"R_SPARC_PC_HH22", Const, 0}, + {"R_SPARC_PC_HM10", Const, 0}, + {"R_SPARC_PC_LM22", Const, 0}, + {"R_SPARC_PLT32", Const, 0}, + {"R_SPARC_PLT64", Const, 0}, + {"R_SPARC_REGISTER", Const, 0}, + {"R_SPARC_RELATIVE", Const, 0}, + {"R_SPARC_UA16", Const, 0}, + {"R_SPARC_UA32", Const, 0}, + {"R_SPARC_UA64", Const, 0}, + {"R_SPARC_WDISP16", Const, 0}, + {"R_SPARC_WDISP19", Const, 0}, + {"R_SPARC_WDISP22", Const, 0}, + {"R_SPARC_WDISP30", Const, 0}, + {"R_SPARC_WPLT30", Const, 0}, + {"R_SYM32", Func, 0}, + {"R_SYM64", Func, 0}, + {"R_TYPE32", Func, 0}, + {"R_TYPE64", Func, 0}, + {"R_X86_64", Type, 0}, + {"R_X86_64_16", Const, 0}, + {"R_X86_64_32", Const, 0}, + {"R_X86_64_32S", Const, 0}, + {"R_X86_64_64", Const, 0}, + {"R_X86_64_8", Const, 0}, + {"R_X86_64_COPY", Const, 0}, + {"R_X86_64_DTPMOD64", Const, 0}, + {"R_X86_64_DTPOFF32", Const, 0}, + {"R_X86_64_DTPOFF64", Const, 0}, + {"R_X86_64_GLOB_DAT", Const, 0}, + {"R_X86_64_GOT32", Const, 0}, + {"R_X86_64_GOT64", Const, 10}, + {"R_X86_64_GOTOFF64", Const, 10}, + {"R_X86_64_GOTPC32", Const, 10}, + {"R_X86_64_GOTPC32_TLSDESC", Const, 10}, + {"R_X86_64_GOTPC64", Const, 10}, + {"R_X86_64_GOTPCREL", Const, 0}, + {"R_X86_64_GOTPCREL64", Const, 10}, + {"R_X86_64_GOTPCRELX", Const, 10}, + {"R_X86_64_GOTPLT64", Const, 10}, + {"R_X86_64_GOTTPOFF", Const, 0}, + {"R_X86_64_IRELATIVE", Const, 10}, + {"R_X86_64_JMP_SLOT", Const, 0}, + {"R_X86_64_NONE", Const, 0}, + {"R_X86_64_PC16", Const, 0}, + {"R_X86_64_PC32", Const, 0}, + {"R_X86_64_PC32_BND", Const, 10}, + {"R_X86_64_PC64", Const, 10}, + {"R_X86_64_PC8", Const, 0}, + {"R_X86_64_PLT32", Const, 0}, + {"R_X86_64_PLT32_BND", Const, 10}, + {"R_X86_64_PLTOFF64", Const, 10}, + {"R_X86_64_RELATIVE", Const, 0}, + {"R_X86_64_RELATIVE64", Const, 10}, + {"R_X86_64_REX_GOTPCRELX", Const, 10}, + {"R_X86_64_SIZE32", Const, 10}, + {"R_X86_64_SIZE64", Const, 10}, + {"R_X86_64_TLSDESC", Const, 10}, + {"R_X86_64_TLSDESC_CALL", Const, 10}, + {"R_X86_64_TLSGD", Const, 0}, + {"R_X86_64_TLSLD", Const, 0}, + {"R_X86_64_TPOFF32", Const, 0}, + {"R_X86_64_TPOFF64", Const, 0}, + {"Rel32", Type, 0}, + {"Rel32.Info", Field, 0}, + {"Rel32.Off", Field, 0}, + {"Rel64", Type, 0}, + {"Rel64.Info", Field, 0}, + {"Rel64.Off", Field, 0}, + {"Rela32", Type, 0}, + {"Rela32.Addend", Field, 0}, + {"Rela32.Info", Field, 0}, + {"Rela32.Off", Field, 0}, + {"Rela64", Type, 0}, + {"Rela64.Addend", Field, 0}, + {"Rela64.Info", Field, 0}, + {"Rela64.Off", Field, 0}, + {"SHF_ALLOC", Const, 0}, + {"SHF_COMPRESSED", Const, 6}, + {"SHF_EXECINSTR", Const, 0}, + {"SHF_GROUP", Const, 0}, + {"SHF_INFO_LINK", Const, 0}, + {"SHF_LINK_ORDER", Const, 0}, + {"SHF_MASKOS", Const, 0}, + {"SHF_MASKPROC", Const, 0}, + {"SHF_MERGE", Const, 0}, + {"SHF_OS_NONCONFORMING", Const, 0}, + {"SHF_STRINGS", Const, 0}, + {"SHF_TLS", Const, 0}, + {"SHF_WRITE", Const, 0}, + {"SHN_ABS", Const, 0}, + {"SHN_COMMON", Const, 0}, + {"SHN_HIOS", Const, 0}, + {"SHN_HIPROC", Const, 0}, + {"SHN_HIRESERVE", Const, 0}, + {"SHN_LOOS", Const, 0}, + {"SHN_LOPROC", Const, 0}, + {"SHN_LORESERVE", Const, 0}, + {"SHN_UNDEF", Const, 0}, + {"SHN_XINDEX", Const, 0}, + {"SHT_DYNAMIC", Const, 0}, + {"SHT_DYNSYM", Const, 0}, + {"SHT_FINI_ARRAY", Const, 0}, + {"SHT_GNU_ATTRIBUTES", Const, 0}, + {"SHT_GNU_HASH", Const, 0}, + {"SHT_GNU_LIBLIST", Const, 0}, + {"SHT_GNU_VERDEF", Const, 0}, + {"SHT_GNU_VERNEED", Const, 0}, + {"SHT_GNU_VERSYM", Const, 0}, + {"SHT_GROUP", Const, 0}, + {"SHT_HASH", Const, 0}, + {"SHT_HIOS", Const, 0}, + {"SHT_HIPROC", Const, 0}, + {"SHT_HIUSER", Const, 0}, + {"SHT_INIT_ARRAY", Const, 0}, + {"SHT_LOOS", Const, 0}, + {"SHT_LOPROC", Const, 0}, + {"SHT_LOUSER", Const, 0}, + {"SHT_MIPS_ABIFLAGS", Const, 17}, + {"SHT_NOBITS", Const, 0}, + {"SHT_NOTE", Const, 0}, + {"SHT_NULL", Const, 0}, + {"SHT_PREINIT_ARRAY", Const, 0}, + {"SHT_PROGBITS", Const, 0}, + {"SHT_REL", Const, 0}, + {"SHT_RELA", Const, 0}, + {"SHT_SHLIB", Const, 0}, + {"SHT_STRTAB", Const, 0}, + {"SHT_SYMTAB", Const, 0}, + {"SHT_SYMTAB_SHNDX", Const, 0}, + {"STB_GLOBAL", Const, 0}, + {"STB_HIOS", Const, 0}, + {"STB_HIPROC", Const, 0}, + {"STB_LOCAL", Const, 0}, + {"STB_LOOS", Const, 0}, + {"STB_LOPROC", Const, 0}, + {"STB_WEAK", Const, 0}, + {"STT_COMMON", Const, 0}, + {"STT_FILE", Const, 0}, + {"STT_FUNC", Const, 0}, + {"STT_HIOS", Const, 0}, + {"STT_HIPROC", Const, 0}, + {"STT_LOOS", Const, 0}, + {"STT_LOPROC", Const, 0}, + {"STT_NOTYPE", Const, 0}, + {"STT_OBJECT", Const, 0}, + {"STT_SECTION", Const, 0}, + {"STT_TLS", Const, 0}, + {"STV_DEFAULT", Const, 0}, + {"STV_HIDDEN", Const, 0}, + {"STV_INTERNAL", Const, 0}, + {"STV_PROTECTED", Const, 0}, + {"ST_BIND", Func, 0}, + {"ST_INFO", Func, 0}, + {"ST_TYPE", Func, 0}, + {"ST_VISIBILITY", Func, 0}, + {"Section", Type, 0}, + {"Section.ReaderAt", Field, 0}, + {"Section.SectionHeader", Field, 0}, + {"Section32", Type, 0}, + {"Section32.Addr", Field, 0}, + {"Section32.Addralign", Field, 0}, + {"Section32.Entsize", Field, 0}, + {"Section32.Flags", Field, 0}, + {"Section32.Info", Field, 0}, + {"Section32.Link", Field, 0}, + {"Section32.Name", Field, 0}, + {"Section32.Off", Field, 0}, + {"Section32.Size", Field, 0}, + {"Section32.Type", Field, 0}, + {"Section64", Type, 0}, + {"Section64.Addr", Field, 0}, + {"Section64.Addralign", Field, 0}, + {"Section64.Entsize", Field, 0}, + {"Section64.Flags", Field, 0}, + {"Section64.Info", Field, 0}, + {"Section64.Link", Field, 0}, + {"Section64.Name", Field, 0}, + {"Section64.Off", Field, 0}, + {"Section64.Size", Field, 0}, + {"Section64.Type", Field, 0}, + {"SectionFlag", Type, 0}, + {"SectionHeader", Type, 0}, + {"SectionHeader.Addr", Field, 0}, + {"SectionHeader.Addralign", Field, 0}, + {"SectionHeader.Entsize", Field, 0}, + {"SectionHeader.FileSize", Field, 6}, + {"SectionHeader.Flags", Field, 0}, + {"SectionHeader.Info", Field, 0}, + {"SectionHeader.Link", Field, 0}, + {"SectionHeader.Name", Field, 0}, + {"SectionHeader.Offset", Field, 0}, + {"SectionHeader.Size", Field, 0}, + {"SectionHeader.Type", Field, 0}, + {"SectionIndex", Type, 0}, + {"SectionType", Type, 0}, + {"Sym32", Type, 0}, + {"Sym32.Info", Field, 0}, + {"Sym32.Name", Field, 0}, + {"Sym32.Other", Field, 0}, + {"Sym32.Shndx", Field, 0}, + {"Sym32.Size", Field, 0}, + {"Sym32.Value", Field, 0}, + {"Sym32Size", Const, 0}, + {"Sym64", Type, 0}, + {"Sym64.Info", Field, 0}, + {"Sym64.Name", Field, 0}, + {"Sym64.Other", Field, 0}, + {"Sym64.Shndx", Field, 0}, + {"Sym64.Size", Field, 0}, + {"Sym64.Value", Field, 0}, + {"Sym64Size", Const, 0}, + {"SymBind", Type, 0}, + {"SymType", Type, 0}, + {"SymVis", Type, 0}, + {"Symbol", Type, 0}, + {"Symbol.Info", Field, 0}, + {"Symbol.Library", Field, 13}, + {"Symbol.Name", Field, 0}, + {"Symbol.Other", Field, 0}, + {"Symbol.Section", Field, 0}, + {"Symbol.Size", Field, 0}, + {"Symbol.Value", Field, 0}, + {"Symbol.Version", Field, 13}, + {"Type", Type, 0}, + {"Version", Type, 0}, + }, + "debug/gosym": { + {"(*DecodingError).Error", Method, 0}, + {"(*LineTable).LineToPC", Method, 0}, + {"(*LineTable).PCToLine", Method, 0}, + {"(*Sym).BaseName", Method, 0}, + {"(*Sym).PackageName", Method, 0}, + {"(*Sym).ReceiverName", Method, 0}, + {"(*Sym).Static", Method, 0}, + {"(*Table).LineToPC", Method, 0}, + {"(*Table).LookupFunc", Method, 0}, + {"(*Table).LookupSym", Method, 0}, + {"(*Table).PCToFunc", Method, 0}, + {"(*Table).PCToLine", Method, 0}, + {"(*Table).SymByAddr", Method, 0}, + {"(*UnknownLineError).Error", Method, 0}, + {"(Func).BaseName", Method, 0}, + {"(Func).PackageName", Method, 0}, + {"(Func).ReceiverName", Method, 0}, + {"(Func).Static", Method, 0}, + {"(UnknownFileError).Error", Method, 0}, + {"DecodingError", Type, 0}, + {"Func", Type, 0}, + {"Func.End", Field, 0}, + {"Func.Entry", Field, 0}, + {"Func.FrameSize", Field, 0}, + {"Func.LineTable", Field, 0}, + {"Func.Locals", Field, 0}, + {"Func.Obj", Field, 0}, + {"Func.Params", Field, 0}, + {"Func.Sym", Field, 0}, + {"LineTable", Type, 0}, + {"LineTable.Data", Field, 0}, + {"LineTable.Line", Field, 0}, + {"LineTable.PC", Field, 0}, + {"NewLineTable", Func, 0}, + {"NewTable", Func, 0}, + {"Obj", Type, 0}, + {"Obj.Funcs", Field, 0}, + {"Obj.Paths", Field, 0}, + {"Sym", Type, 0}, + {"Sym.Func", Field, 0}, + {"Sym.GoType", Field, 0}, + {"Sym.Name", Field, 0}, + {"Sym.Type", Field, 0}, + {"Sym.Value", Field, 0}, + {"Table", Type, 0}, + {"Table.Files", Field, 0}, + {"Table.Funcs", Field, 0}, + {"Table.Objs", Field, 0}, + {"Table.Syms", Field, 0}, + {"UnknownFileError", Type, 0}, + {"UnknownLineError", Type, 0}, + {"UnknownLineError.File", Field, 0}, + {"UnknownLineError.Line", Field, 0}, + }, + "debug/macho": { + {"(*FatFile).Close", Method, 3}, + {"(*File).Close", Method, 0}, + {"(*File).DWARF", Method, 0}, + {"(*File).ImportedLibraries", Method, 0}, + {"(*File).ImportedSymbols", Method, 0}, + {"(*File).Section", Method, 0}, + {"(*File).Segment", Method, 0}, + {"(*FormatError).Error", Method, 0}, + {"(*Section).Data", Method, 0}, + {"(*Section).Open", Method, 0}, + {"(*Segment).Data", Method, 0}, + {"(*Segment).Open", Method, 0}, + {"(Cpu).GoString", Method, 0}, + {"(Cpu).String", Method, 0}, + {"(Dylib).Raw", Method, 0}, + {"(Dysymtab).Raw", Method, 0}, + {"(FatArch).Close", Method, 3}, + {"(FatArch).DWARF", Method, 3}, + {"(FatArch).ImportedLibraries", Method, 3}, + {"(FatArch).ImportedSymbols", Method, 3}, + {"(FatArch).Section", Method, 3}, + {"(FatArch).Segment", Method, 3}, + {"(LoadBytes).Raw", Method, 0}, + {"(LoadCmd).GoString", Method, 0}, + {"(LoadCmd).String", Method, 0}, + {"(RelocTypeARM).GoString", Method, 10}, + {"(RelocTypeARM).String", Method, 10}, + {"(RelocTypeARM64).GoString", Method, 10}, + {"(RelocTypeARM64).String", Method, 10}, + {"(RelocTypeGeneric).GoString", Method, 10}, + {"(RelocTypeGeneric).String", Method, 10}, + {"(RelocTypeX86_64).GoString", Method, 10}, + {"(RelocTypeX86_64).String", Method, 10}, + {"(Rpath).Raw", Method, 10}, + {"(Section).ReadAt", Method, 0}, + {"(Segment).Raw", Method, 0}, + {"(Segment).ReadAt", Method, 0}, + {"(Symtab).Raw", Method, 0}, + {"(Type).GoString", Method, 10}, + {"(Type).String", Method, 10}, + {"ARM64_RELOC_ADDEND", Const, 10}, + {"ARM64_RELOC_BRANCH26", Const, 10}, + {"ARM64_RELOC_GOT_LOAD_PAGE21", Const, 10}, + {"ARM64_RELOC_GOT_LOAD_PAGEOFF12", Const, 10}, + {"ARM64_RELOC_PAGE21", Const, 10}, + {"ARM64_RELOC_PAGEOFF12", Const, 10}, + {"ARM64_RELOC_POINTER_TO_GOT", Const, 10}, + {"ARM64_RELOC_SUBTRACTOR", Const, 10}, + {"ARM64_RELOC_TLVP_LOAD_PAGE21", Const, 10}, + {"ARM64_RELOC_TLVP_LOAD_PAGEOFF12", Const, 10}, + {"ARM64_RELOC_UNSIGNED", Const, 10}, + {"ARM_RELOC_BR24", Const, 10}, + {"ARM_RELOC_HALF", Const, 10}, + {"ARM_RELOC_HALF_SECTDIFF", Const, 10}, + {"ARM_RELOC_LOCAL_SECTDIFF", Const, 10}, + {"ARM_RELOC_PAIR", Const, 10}, + {"ARM_RELOC_PB_LA_PTR", Const, 10}, + {"ARM_RELOC_SECTDIFF", Const, 10}, + {"ARM_RELOC_VANILLA", Const, 10}, + {"ARM_THUMB_32BIT_BRANCH", Const, 10}, + {"ARM_THUMB_RELOC_BR22", Const, 10}, + {"Cpu", Type, 0}, + {"Cpu386", Const, 0}, + {"CpuAmd64", Const, 0}, + {"CpuArm", Const, 3}, + {"CpuArm64", Const, 11}, + {"CpuPpc", Const, 3}, + {"CpuPpc64", Const, 3}, + {"Dylib", Type, 0}, + {"Dylib.CompatVersion", Field, 0}, + {"Dylib.CurrentVersion", Field, 0}, + {"Dylib.LoadBytes", Field, 0}, + {"Dylib.Name", Field, 0}, + {"Dylib.Time", Field, 0}, + {"DylibCmd", Type, 0}, + {"DylibCmd.Cmd", Field, 0}, + {"DylibCmd.CompatVersion", Field, 0}, + {"DylibCmd.CurrentVersion", Field, 0}, + {"DylibCmd.Len", Field, 0}, + {"DylibCmd.Name", Field, 0}, + {"DylibCmd.Time", Field, 0}, + {"Dysymtab", Type, 0}, + {"Dysymtab.DysymtabCmd", Field, 0}, + {"Dysymtab.IndirectSyms", Field, 0}, + {"Dysymtab.LoadBytes", Field, 0}, + {"DysymtabCmd", Type, 0}, + {"DysymtabCmd.Cmd", Field, 0}, + {"DysymtabCmd.Extrefsymoff", Field, 0}, + {"DysymtabCmd.Extreloff", Field, 0}, + {"DysymtabCmd.Iextdefsym", Field, 0}, + {"DysymtabCmd.Ilocalsym", Field, 0}, + {"DysymtabCmd.Indirectsymoff", Field, 0}, + {"DysymtabCmd.Iundefsym", Field, 0}, + {"DysymtabCmd.Len", Field, 0}, + {"DysymtabCmd.Locreloff", Field, 0}, + {"DysymtabCmd.Modtaboff", Field, 0}, + {"DysymtabCmd.Nextdefsym", Field, 0}, + {"DysymtabCmd.Nextrefsyms", Field, 0}, + {"DysymtabCmd.Nextrel", Field, 0}, + {"DysymtabCmd.Nindirectsyms", Field, 0}, + {"DysymtabCmd.Nlocalsym", Field, 0}, + {"DysymtabCmd.Nlocrel", Field, 0}, + {"DysymtabCmd.Nmodtab", Field, 0}, + {"DysymtabCmd.Ntoc", Field, 0}, + {"DysymtabCmd.Nundefsym", Field, 0}, + {"DysymtabCmd.Tocoffset", Field, 0}, + {"ErrNotFat", Var, 3}, + {"FatArch", Type, 3}, + {"FatArch.FatArchHeader", Field, 3}, + {"FatArch.File", Field, 3}, + {"FatArchHeader", Type, 3}, + {"FatArchHeader.Align", Field, 3}, + {"FatArchHeader.Cpu", Field, 3}, + {"FatArchHeader.Offset", Field, 3}, + {"FatArchHeader.Size", Field, 3}, + {"FatArchHeader.SubCpu", Field, 3}, + {"FatFile", Type, 3}, + {"FatFile.Arches", Field, 3}, + {"FatFile.Magic", Field, 3}, + {"File", Type, 0}, + {"File.ByteOrder", Field, 0}, + {"File.Dysymtab", Field, 0}, + {"File.FileHeader", Field, 0}, + {"File.Loads", Field, 0}, + {"File.Sections", Field, 0}, + {"File.Symtab", Field, 0}, + {"FileHeader", Type, 0}, + {"FileHeader.Cmdsz", Field, 0}, + {"FileHeader.Cpu", Field, 0}, + {"FileHeader.Flags", Field, 0}, + {"FileHeader.Magic", Field, 0}, + {"FileHeader.Ncmd", Field, 0}, + {"FileHeader.SubCpu", Field, 0}, + {"FileHeader.Type", Field, 0}, + {"FlagAllModsBound", Const, 10}, + {"FlagAllowStackExecution", Const, 10}, + {"FlagAppExtensionSafe", Const, 10}, + {"FlagBindAtLoad", Const, 10}, + {"FlagBindsToWeak", Const, 10}, + {"FlagCanonical", Const, 10}, + {"FlagDeadStrippableDylib", Const, 10}, + {"FlagDyldLink", Const, 10}, + {"FlagForceFlat", Const, 10}, + {"FlagHasTLVDescriptors", Const, 10}, + {"FlagIncrLink", Const, 10}, + {"FlagLazyInit", Const, 10}, + {"FlagNoFixPrebinding", Const, 10}, + {"FlagNoHeapExecution", Const, 10}, + {"FlagNoMultiDefs", Const, 10}, + {"FlagNoReexportedDylibs", Const, 10}, + {"FlagNoUndefs", Const, 10}, + {"FlagPIE", Const, 10}, + {"FlagPrebindable", Const, 10}, + {"FlagPrebound", Const, 10}, + {"FlagRootSafe", Const, 10}, + {"FlagSetuidSafe", Const, 10}, + {"FlagSplitSegs", Const, 10}, + {"FlagSubsectionsViaSymbols", Const, 10}, + {"FlagTwoLevel", Const, 10}, + {"FlagWeakDefines", Const, 10}, + {"FormatError", Type, 0}, + {"GENERIC_RELOC_LOCAL_SECTDIFF", Const, 10}, + {"GENERIC_RELOC_PAIR", Const, 10}, + {"GENERIC_RELOC_PB_LA_PTR", Const, 10}, + {"GENERIC_RELOC_SECTDIFF", Const, 10}, + {"GENERIC_RELOC_TLV", Const, 10}, + {"GENERIC_RELOC_VANILLA", Const, 10}, + {"Load", Type, 0}, + {"LoadBytes", Type, 0}, + {"LoadCmd", Type, 0}, + {"LoadCmdDylib", Const, 0}, + {"LoadCmdDylinker", Const, 0}, + {"LoadCmdDysymtab", Const, 0}, + {"LoadCmdRpath", Const, 10}, + {"LoadCmdSegment", Const, 0}, + {"LoadCmdSegment64", Const, 0}, + {"LoadCmdSymtab", Const, 0}, + {"LoadCmdThread", Const, 0}, + {"LoadCmdUnixThread", Const, 0}, + {"Magic32", Const, 0}, + {"Magic64", Const, 0}, + {"MagicFat", Const, 3}, + {"NewFatFile", Func, 3}, + {"NewFile", Func, 0}, + {"Nlist32", Type, 0}, + {"Nlist32.Desc", Field, 0}, + {"Nlist32.Name", Field, 0}, + {"Nlist32.Sect", Field, 0}, + {"Nlist32.Type", Field, 0}, + {"Nlist32.Value", Field, 0}, + {"Nlist64", Type, 0}, + {"Nlist64.Desc", Field, 0}, + {"Nlist64.Name", Field, 0}, + {"Nlist64.Sect", Field, 0}, + {"Nlist64.Type", Field, 0}, + {"Nlist64.Value", Field, 0}, + {"Open", Func, 0}, + {"OpenFat", Func, 3}, + {"Regs386", Type, 0}, + {"Regs386.AX", Field, 0}, + {"Regs386.BP", Field, 0}, + {"Regs386.BX", Field, 0}, + {"Regs386.CS", Field, 0}, + {"Regs386.CX", Field, 0}, + {"Regs386.DI", Field, 0}, + {"Regs386.DS", Field, 0}, + {"Regs386.DX", Field, 0}, + {"Regs386.ES", Field, 0}, + {"Regs386.FLAGS", Field, 0}, + {"Regs386.FS", Field, 0}, + {"Regs386.GS", Field, 0}, + {"Regs386.IP", Field, 0}, + {"Regs386.SI", Field, 0}, + {"Regs386.SP", Field, 0}, + {"Regs386.SS", Field, 0}, + {"RegsAMD64", Type, 0}, + {"RegsAMD64.AX", Field, 0}, + {"RegsAMD64.BP", Field, 0}, + {"RegsAMD64.BX", Field, 0}, + {"RegsAMD64.CS", Field, 0}, + {"RegsAMD64.CX", Field, 0}, + {"RegsAMD64.DI", Field, 0}, + {"RegsAMD64.DX", Field, 0}, + {"RegsAMD64.FLAGS", Field, 0}, + {"RegsAMD64.FS", Field, 0}, + {"RegsAMD64.GS", Field, 0}, + {"RegsAMD64.IP", Field, 0}, + {"RegsAMD64.R10", Field, 0}, + {"RegsAMD64.R11", Field, 0}, + {"RegsAMD64.R12", Field, 0}, + {"RegsAMD64.R13", Field, 0}, + {"RegsAMD64.R14", Field, 0}, + {"RegsAMD64.R15", Field, 0}, + {"RegsAMD64.R8", Field, 0}, + {"RegsAMD64.R9", Field, 0}, + {"RegsAMD64.SI", Field, 0}, + {"RegsAMD64.SP", Field, 0}, + {"Reloc", Type, 10}, + {"Reloc.Addr", Field, 10}, + {"Reloc.Extern", Field, 10}, + {"Reloc.Len", Field, 10}, + {"Reloc.Pcrel", Field, 10}, + {"Reloc.Scattered", Field, 10}, + {"Reloc.Type", Field, 10}, + {"Reloc.Value", Field, 10}, + {"RelocTypeARM", Type, 10}, + {"RelocTypeARM64", Type, 10}, + {"RelocTypeGeneric", Type, 10}, + {"RelocTypeX86_64", Type, 10}, + {"Rpath", Type, 10}, + {"Rpath.LoadBytes", Field, 10}, + {"Rpath.Path", Field, 10}, + {"RpathCmd", Type, 10}, + {"RpathCmd.Cmd", Field, 10}, + {"RpathCmd.Len", Field, 10}, + {"RpathCmd.Path", Field, 10}, + {"Section", Type, 0}, + {"Section.ReaderAt", Field, 0}, + {"Section.Relocs", Field, 10}, + {"Section.SectionHeader", Field, 0}, + {"Section32", Type, 0}, + {"Section32.Addr", Field, 0}, + {"Section32.Align", Field, 0}, + {"Section32.Flags", Field, 0}, + {"Section32.Name", Field, 0}, + {"Section32.Nreloc", Field, 0}, + {"Section32.Offset", Field, 0}, + {"Section32.Reloff", Field, 0}, + {"Section32.Reserve1", Field, 0}, + {"Section32.Reserve2", Field, 0}, + {"Section32.Seg", Field, 0}, + {"Section32.Size", Field, 0}, + {"Section64", Type, 0}, + {"Section64.Addr", Field, 0}, + {"Section64.Align", Field, 0}, + {"Section64.Flags", Field, 0}, + {"Section64.Name", Field, 0}, + {"Section64.Nreloc", Field, 0}, + {"Section64.Offset", Field, 0}, + {"Section64.Reloff", Field, 0}, + {"Section64.Reserve1", Field, 0}, + {"Section64.Reserve2", Field, 0}, + {"Section64.Reserve3", Field, 0}, + {"Section64.Seg", Field, 0}, + {"Section64.Size", Field, 0}, + {"SectionHeader", Type, 0}, + {"SectionHeader.Addr", Field, 0}, + {"SectionHeader.Align", Field, 0}, + {"SectionHeader.Flags", Field, 0}, + {"SectionHeader.Name", Field, 0}, + {"SectionHeader.Nreloc", Field, 0}, + {"SectionHeader.Offset", Field, 0}, + {"SectionHeader.Reloff", Field, 0}, + {"SectionHeader.Seg", Field, 0}, + {"SectionHeader.Size", Field, 0}, + {"Segment", Type, 0}, + {"Segment.LoadBytes", Field, 0}, + {"Segment.ReaderAt", Field, 0}, + {"Segment.SegmentHeader", Field, 0}, + {"Segment32", Type, 0}, + {"Segment32.Addr", Field, 0}, + {"Segment32.Cmd", Field, 0}, + {"Segment32.Filesz", Field, 0}, + {"Segment32.Flag", Field, 0}, + {"Segment32.Len", Field, 0}, + {"Segment32.Maxprot", Field, 0}, + {"Segment32.Memsz", Field, 0}, + {"Segment32.Name", Field, 0}, + {"Segment32.Nsect", Field, 0}, + {"Segment32.Offset", Field, 0}, + {"Segment32.Prot", Field, 0}, + {"Segment64", Type, 0}, + {"Segment64.Addr", Field, 0}, + {"Segment64.Cmd", Field, 0}, + {"Segment64.Filesz", Field, 0}, + {"Segment64.Flag", Field, 0}, + {"Segment64.Len", Field, 0}, + {"Segment64.Maxprot", Field, 0}, + {"Segment64.Memsz", Field, 0}, + {"Segment64.Name", Field, 0}, + {"Segment64.Nsect", Field, 0}, + {"Segment64.Offset", Field, 0}, + {"Segment64.Prot", Field, 0}, + {"SegmentHeader", Type, 0}, + {"SegmentHeader.Addr", Field, 0}, + {"SegmentHeader.Cmd", Field, 0}, + {"SegmentHeader.Filesz", Field, 0}, + {"SegmentHeader.Flag", Field, 0}, + {"SegmentHeader.Len", Field, 0}, + {"SegmentHeader.Maxprot", Field, 0}, + {"SegmentHeader.Memsz", Field, 0}, + {"SegmentHeader.Name", Field, 0}, + {"SegmentHeader.Nsect", Field, 0}, + {"SegmentHeader.Offset", Field, 0}, + {"SegmentHeader.Prot", Field, 0}, + {"Symbol", Type, 0}, + {"Symbol.Desc", Field, 0}, + {"Symbol.Name", Field, 0}, + {"Symbol.Sect", Field, 0}, + {"Symbol.Type", Field, 0}, + {"Symbol.Value", Field, 0}, + {"Symtab", Type, 0}, + {"Symtab.LoadBytes", Field, 0}, + {"Symtab.Syms", Field, 0}, + {"Symtab.SymtabCmd", Field, 0}, + {"SymtabCmd", Type, 0}, + {"SymtabCmd.Cmd", Field, 0}, + {"SymtabCmd.Len", Field, 0}, + {"SymtabCmd.Nsyms", Field, 0}, + {"SymtabCmd.Stroff", Field, 0}, + {"SymtabCmd.Strsize", Field, 0}, + {"SymtabCmd.Symoff", Field, 0}, + {"Thread", Type, 0}, + {"Thread.Cmd", Field, 0}, + {"Thread.Data", Field, 0}, + {"Thread.Len", Field, 0}, + {"Thread.Type", Field, 0}, + {"Type", Type, 0}, + {"TypeBundle", Const, 3}, + {"TypeDylib", Const, 3}, + {"TypeExec", Const, 0}, + {"TypeObj", Const, 0}, + {"X86_64_RELOC_BRANCH", Const, 10}, + {"X86_64_RELOC_GOT", Const, 10}, + {"X86_64_RELOC_GOT_LOAD", Const, 10}, + {"X86_64_RELOC_SIGNED", Const, 10}, + {"X86_64_RELOC_SIGNED_1", Const, 10}, + {"X86_64_RELOC_SIGNED_2", Const, 10}, + {"X86_64_RELOC_SIGNED_4", Const, 10}, + {"X86_64_RELOC_SUBTRACTOR", Const, 10}, + {"X86_64_RELOC_TLV", Const, 10}, + {"X86_64_RELOC_UNSIGNED", Const, 10}, + }, + "debug/pe": { + {"(*COFFSymbol).FullName", Method, 8}, + {"(*File).COFFSymbolReadSectionDefAux", Method, 19}, + {"(*File).Close", Method, 0}, + {"(*File).DWARF", Method, 0}, + {"(*File).ImportedLibraries", Method, 0}, + {"(*File).ImportedSymbols", Method, 0}, + {"(*File).Section", Method, 0}, + {"(*FormatError).Error", Method, 0}, + {"(*Section).Data", Method, 0}, + {"(*Section).Open", Method, 0}, + {"(Section).ReadAt", Method, 0}, + {"(StringTable).String", Method, 8}, + {"COFFSymbol", Type, 1}, + {"COFFSymbol.Name", Field, 1}, + {"COFFSymbol.NumberOfAuxSymbols", Field, 1}, + {"COFFSymbol.SectionNumber", Field, 1}, + {"COFFSymbol.StorageClass", Field, 1}, + {"COFFSymbol.Type", Field, 1}, + {"COFFSymbol.Value", Field, 1}, + {"COFFSymbolAuxFormat5", Type, 19}, + {"COFFSymbolAuxFormat5.Checksum", Field, 19}, + {"COFFSymbolAuxFormat5.NumLineNumbers", Field, 19}, + {"COFFSymbolAuxFormat5.NumRelocs", Field, 19}, + {"COFFSymbolAuxFormat5.SecNum", Field, 19}, + {"COFFSymbolAuxFormat5.Selection", Field, 19}, + {"COFFSymbolAuxFormat5.Size", Field, 19}, + {"COFFSymbolSize", Const, 1}, + {"DataDirectory", Type, 3}, + {"DataDirectory.Size", Field, 3}, + {"DataDirectory.VirtualAddress", Field, 3}, + {"File", Type, 0}, + {"File.COFFSymbols", Field, 8}, + {"File.FileHeader", Field, 0}, + {"File.OptionalHeader", Field, 3}, + {"File.Sections", Field, 0}, + {"File.StringTable", Field, 8}, + {"File.Symbols", Field, 1}, + {"FileHeader", Type, 0}, + {"FileHeader.Characteristics", Field, 0}, + {"FileHeader.Machine", Field, 0}, + {"FileHeader.NumberOfSections", Field, 0}, + {"FileHeader.NumberOfSymbols", Field, 0}, + {"FileHeader.PointerToSymbolTable", Field, 0}, + {"FileHeader.SizeOfOptionalHeader", Field, 0}, + {"FileHeader.TimeDateStamp", Field, 0}, + {"FormatError", Type, 0}, + {"IMAGE_COMDAT_SELECT_ANY", Const, 19}, + {"IMAGE_COMDAT_SELECT_ASSOCIATIVE", Const, 19}, + {"IMAGE_COMDAT_SELECT_EXACT_MATCH", Const, 19}, + {"IMAGE_COMDAT_SELECT_LARGEST", Const, 19}, + {"IMAGE_COMDAT_SELECT_NODUPLICATES", Const, 19}, + {"IMAGE_COMDAT_SELECT_SAME_SIZE", Const, 19}, + {"IMAGE_DIRECTORY_ENTRY_ARCHITECTURE", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_BASERELOC", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_DEBUG", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_EXCEPTION", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_EXPORT", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_GLOBALPTR", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_IAT", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_IMPORT", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_RESOURCE", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_SECURITY", Const, 11}, + {"IMAGE_DIRECTORY_ENTRY_TLS", Const, 11}, + {"IMAGE_DLLCHARACTERISTICS_APPCONTAINER", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_GUARD_CF", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_NO_BIND", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_NO_ISOLATION", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_NO_SEH", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_NX_COMPAT", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE", Const, 15}, + {"IMAGE_DLLCHARACTERISTICS_WDM_DRIVER", Const, 15}, + {"IMAGE_FILE_32BIT_MACHINE", Const, 15}, + {"IMAGE_FILE_AGGRESIVE_WS_TRIM", Const, 15}, + {"IMAGE_FILE_BYTES_REVERSED_HI", Const, 15}, + {"IMAGE_FILE_BYTES_REVERSED_LO", Const, 15}, + {"IMAGE_FILE_DEBUG_STRIPPED", Const, 15}, + {"IMAGE_FILE_DLL", Const, 15}, + {"IMAGE_FILE_EXECUTABLE_IMAGE", Const, 15}, + {"IMAGE_FILE_LARGE_ADDRESS_AWARE", Const, 15}, + {"IMAGE_FILE_LINE_NUMS_STRIPPED", Const, 15}, + {"IMAGE_FILE_LOCAL_SYMS_STRIPPED", Const, 15}, + {"IMAGE_FILE_MACHINE_AM33", Const, 0}, + {"IMAGE_FILE_MACHINE_AMD64", Const, 0}, + {"IMAGE_FILE_MACHINE_ARM", Const, 0}, + {"IMAGE_FILE_MACHINE_ARM64", Const, 11}, + {"IMAGE_FILE_MACHINE_ARMNT", Const, 12}, + {"IMAGE_FILE_MACHINE_EBC", Const, 0}, + {"IMAGE_FILE_MACHINE_I386", Const, 0}, + {"IMAGE_FILE_MACHINE_IA64", Const, 0}, + {"IMAGE_FILE_MACHINE_LOONGARCH32", Const, 19}, + {"IMAGE_FILE_MACHINE_LOONGARCH64", Const, 19}, + {"IMAGE_FILE_MACHINE_M32R", Const, 0}, + {"IMAGE_FILE_MACHINE_MIPS16", Const, 0}, + {"IMAGE_FILE_MACHINE_MIPSFPU", Const, 0}, + {"IMAGE_FILE_MACHINE_MIPSFPU16", Const, 0}, + {"IMAGE_FILE_MACHINE_POWERPC", Const, 0}, + {"IMAGE_FILE_MACHINE_POWERPCFP", Const, 0}, + {"IMAGE_FILE_MACHINE_R4000", Const, 0}, + {"IMAGE_FILE_MACHINE_RISCV128", Const, 20}, + {"IMAGE_FILE_MACHINE_RISCV32", Const, 20}, + {"IMAGE_FILE_MACHINE_RISCV64", Const, 20}, + {"IMAGE_FILE_MACHINE_SH3", Const, 0}, + {"IMAGE_FILE_MACHINE_SH3DSP", Const, 0}, + {"IMAGE_FILE_MACHINE_SH4", Const, 0}, + {"IMAGE_FILE_MACHINE_SH5", Const, 0}, + {"IMAGE_FILE_MACHINE_THUMB", Const, 0}, + {"IMAGE_FILE_MACHINE_UNKNOWN", Const, 0}, + {"IMAGE_FILE_MACHINE_WCEMIPSV2", Const, 0}, + {"IMAGE_FILE_NET_RUN_FROM_SWAP", Const, 15}, + {"IMAGE_FILE_RELOCS_STRIPPED", Const, 15}, + {"IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP", Const, 15}, + {"IMAGE_FILE_SYSTEM", Const, 15}, + {"IMAGE_FILE_UP_SYSTEM_ONLY", Const, 15}, + {"IMAGE_SCN_CNT_CODE", Const, 19}, + {"IMAGE_SCN_CNT_INITIALIZED_DATA", Const, 19}, + {"IMAGE_SCN_CNT_UNINITIALIZED_DATA", Const, 19}, + {"IMAGE_SCN_LNK_COMDAT", Const, 19}, + {"IMAGE_SCN_MEM_DISCARDABLE", Const, 19}, + {"IMAGE_SCN_MEM_EXECUTE", Const, 19}, + {"IMAGE_SCN_MEM_READ", Const, 19}, + {"IMAGE_SCN_MEM_WRITE", Const, 19}, + {"IMAGE_SUBSYSTEM_EFI_APPLICATION", Const, 15}, + {"IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER", Const, 15}, + {"IMAGE_SUBSYSTEM_EFI_ROM", Const, 15}, + {"IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER", Const, 15}, + {"IMAGE_SUBSYSTEM_NATIVE", Const, 15}, + {"IMAGE_SUBSYSTEM_NATIVE_WINDOWS", Const, 15}, + {"IMAGE_SUBSYSTEM_OS2_CUI", Const, 15}, + {"IMAGE_SUBSYSTEM_POSIX_CUI", Const, 15}, + {"IMAGE_SUBSYSTEM_UNKNOWN", Const, 15}, + {"IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION", Const, 15}, + {"IMAGE_SUBSYSTEM_WINDOWS_CE_GUI", Const, 15}, + {"IMAGE_SUBSYSTEM_WINDOWS_CUI", Const, 15}, + {"IMAGE_SUBSYSTEM_WINDOWS_GUI", Const, 15}, + {"IMAGE_SUBSYSTEM_XBOX", Const, 15}, + {"ImportDirectory", Type, 0}, + {"ImportDirectory.FirstThunk", Field, 0}, + {"ImportDirectory.ForwarderChain", Field, 0}, + {"ImportDirectory.Name", Field, 0}, + {"ImportDirectory.OriginalFirstThunk", Field, 0}, + {"ImportDirectory.TimeDateStamp", Field, 0}, + {"NewFile", Func, 0}, + {"Open", Func, 0}, + {"OptionalHeader32", Type, 3}, + {"OptionalHeader32.AddressOfEntryPoint", Field, 3}, + {"OptionalHeader32.BaseOfCode", Field, 3}, + {"OptionalHeader32.BaseOfData", Field, 3}, + {"OptionalHeader32.CheckSum", Field, 3}, + {"OptionalHeader32.DataDirectory", Field, 3}, + {"OptionalHeader32.DllCharacteristics", Field, 3}, + {"OptionalHeader32.FileAlignment", Field, 3}, + {"OptionalHeader32.ImageBase", Field, 3}, + {"OptionalHeader32.LoaderFlags", Field, 3}, + {"OptionalHeader32.Magic", Field, 3}, + {"OptionalHeader32.MajorImageVersion", Field, 3}, + {"OptionalHeader32.MajorLinkerVersion", Field, 3}, + {"OptionalHeader32.MajorOperatingSystemVersion", Field, 3}, + {"OptionalHeader32.MajorSubsystemVersion", Field, 3}, + {"OptionalHeader32.MinorImageVersion", Field, 3}, + {"OptionalHeader32.MinorLinkerVersion", Field, 3}, + {"OptionalHeader32.MinorOperatingSystemVersion", Field, 3}, + {"OptionalHeader32.MinorSubsystemVersion", Field, 3}, + {"OptionalHeader32.NumberOfRvaAndSizes", Field, 3}, + {"OptionalHeader32.SectionAlignment", Field, 3}, + {"OptionalHeader32.SizeOfCode", Field, 3}, + {"OptionalHeader32.SizeOfHeaders", Field, 3}, + {"OptionalHeader32.SizeOfHeapCommit", Field, 3}, + {"OptionalHeader32.SizeOfHeapReserve", Field, 3}, + {"OptionalHeader32.SizeOfImage", Field, 3}, + {"OptionalHeader32.SizeOfInitializedData", Field, 3}, + {"OptionalHeader32.SizeOfStackCommit", Field, 3}, + {"OptionalHeader32.SizeOfStackReserve", Field, 3}, + {"OptionalHeader32.SizeOfUninitializedData", Field, 3}, + {"OptionalHeader32.Subsystem", Field, 3}, + {"OptionalHeader32.Win32VersionValue", Field, 3}, + {"OptionalHeader64", Type, 3}, + {"OptionalHeader64.AddressOfEntryPoint", Field, 3}, + {"OptionalHeader64.BaseOfCode", Field, 3}, + {"OptionalHeader64.CheckSum", Field, 3}, + {"OptionalHeader64.DataDirectory", Field, 3}, + {"OptionalHeader64.DllCharacteristics", Field, 3}, + {"OptionalHeader64.FileAlignment", Field, 3}, + {"OptionalHeader64.ImageBase", Field, 3}, + {"OptionalHeader64.LoaderFlags", Field, 3}, + {"OptionalHeader64.Magic", Field, 3}, + {"OptionalHeader64.MajorImageVersion", Field, 3}, + {"OptionalHeader64.MajorLinkerVersion", Field, 3}, + {"OptionalHeader64.MajorOperatingSystemVersion", Field, 3}, + {"OptionalHeader64.MajorSubsystemVersion", Field, 3}, + {"OptionalHeader64.MinorImageVersion", Field, 3}, + {"OptionalHeader64.MinorLinkerVersion", Field, 3}, + {"OptionalHeader64.MinorOperatingSystemVersion", Field, 3}, + {"OptionalHeader64.MinorSubsystemVersion", Field, 3}, + {"OptionalHeader64.NumberOfRvaAndSizes", Field, 3}, + {"OptionalHeader64.SectionAlignment", Field, 3}, + {"OptionalHeader64.SizeOfCode", Field, 3}, + {"OptionalHeader64.SizeOfHeaders", Field, 3}, + {"OptionalHeader64.SizeOfHeapCommit", Field, 3}, + {"OptionalHeader64.SizeOfHeapReserve", Field, 3}, + {"OptionalHeader64.SizeOfImage", Field, 3}, + {"OptionalHeader64.SizeOfInitializedData", Field, 3}, + {"OptionalHeader64.SizeOfStackCommit", Field, 3}, + {"OptionalHeader64.SizeOfStackReserve", Field, 3}, + {"OptionalHeader64.SizeOfUninitializedData", Field, 3}, + {"OptionalHeader64.Subsystem", Field, 3}, + {"OptionalHeader64.Win32VersionValue", Field, 3}, + {"Reloc", Type, 8}, + {"Reloc.SymbolTableIndex", Field, 8}, + {"Reloc.Type", Field, 8}, + {"Reloc.VirtualAddress", Field, 8}, + {"Section", Type, 0}, + {"Section.ReaderAt", Field, 0}, + {"Section.Relocs", Field, 8}, + {"Section.SectionHeader", Field, 0}, + {"SectionHeader", Type, 0}, + {"SectionHeader.Characteristics", Field, 0}, + {"SectionHeader.Name", Field, 0}, + {"SectionHeader.NumberOfLineNumbers", Field, 0}, + {"SectionHeader.NumberOfRelocations", Field, 0}, + {"SectionHeader.Offset", Field, 0}, + {"SectionHeader.PointerToLineNumbers", Field, 0}, + {"SectionHeader.PointerToRelocations", Field, 0}, + {"SectionHeader.Size", Field, 0}, + {"SectionHeader.VirtualAddress", Field, 0}, + {"SectionHeader.VirtualSize", Field, 0}, + {"SectionHeader32", Type, 0}, + {"SectionHeader32.Characteristics", Field, 0}, + {"SectionHeader32.Name", Field, 0}, + {"SectionHeader32.NumberOfLineNumbers", Field, 0}, + {"SectionHeader32.NumberOfRelocations", Field, 0}, + {"SectionHeader32.PointerToLineNumbers", Field, 0}, + {"SectionHeader32.PointerToRawData", Field, 0}, + {"SectionHeader32.PointerToRelocations", Field, 0}, + {"SectionHeader32.SizeOfRawData", Field, 0}, + {"SectionHeader32.VirtualAddress", Field, 0}, + {"SectionHeader32.VirtualSize", Field, 0}, + {"StringTable", Type, 8}, + {"Symbol", Type, 1}, + {"Symbol.Name", Field, 1}, + {"Symbol.SectionNumber", Field, 1}, + {"Symbol.StorageClass", Field, 1}, + {"Symbol.Type", Field, 1}, + {"Symbol.Value", Field, 1}, + }, + "debug/plan9obj": { + {"(*File).Close", Method, 3}, + {"(*File).Section", Method, 3}, + {"(*File).Symbols", Method, 3}, + {"(*Section).Data", Method, 3}, + {"(*Section).Open", Method, 3}, + {"(Section).ReadAt", Method, 3}, + {"ErrNoSymbols", Var, 18}, + {"File", Type, 3}, + {"File.FileHeader", Field, 3}, + {"File.Sections", Field, 3}, + {"FileHeader", Type, 3}, + {"FileHeader.Bss", Field, 3}, + {"FileHeader.Entry", Field, 3}, + {"FileHeader.HdrSize", Field, 4}, + {"FileHeader.LoadAddress", Field, 4}, + {"FileHeader.Magic", Field, 3}, + {"FileHeader.PtrSize", Field, 3}, + {"Magic386", Const, 3}, + {"Magic64", Const, 3}, + {"MagicAMD64", Const, 3}, + {"MagicARM", Const, 3}, + {"NewFile", Func, 3}, + {"Open", Func, 3}, + {"Section", Type, 3}, + {"Section.ReaderAt", Field, 3}, + {"Section.SectionHeader", Field, 3}, + {"SectionHeader", Type, 3}, + {"SectionHeader.Name", Field, 3}, + {"SectionHeader.Offset", Field, 3}, + {"SectionHeader.Size", Field, 3}, + {"Sym", Type, 3}, + {"Sym.Name", Field, 3}, + {"Sym.Type", Field, 3}, + {"Sym.Value", Field, 3}, + }, + "embed": { + {"(FS).Open", Method, 16}, + {"(FS).ReadDir", Method, 16}, + {"(FS).ReadFile", Method, 16}, + {"FS", Type, 16}, + }, + "encoding": { + {"BinaryMarshaler", Type, 2}, + {"BinaryUnmarshaler", Type, 2}, + {"TextMarshaler", Type, 2}, + {"TextUnmarshaler", Type, 2}, + }, + "encoding/ascii85": { + {"(CorruptInputError).Error", Method, 0}, + {"CorruptInputError", Type, 0}, + {"Decode", Func, 0}, + {"Encode", Func, 0}, + {"MaxEncodedLen", Func, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + }, + "encoding/asn1": { + {"(BitString).At", Method, 0}, + {"(BitString).RightAlign", Method, 0}, + {"(ObjectIdentifier).Equal", Method, 0}, + {"(ObjectIdentifier).String", Method, 3}, + {"(StructuralError).Error", Method, 0}, + {"(SyntaxError).Error", Method, 0}, + {"BitString", Type, 0}, + {"BitString.BitLength", Field, 0}, + {"BitString.Bytes", Field, 0}, + {"ClassApplication", Const, 6}, + {"ClassContextSpecific", Const, 6}, + {"ClassPrivate", Const, 6}, + {"ClassUniversal", Const, 6}, + {"Enumerated", Type, 0}, + {"Flag", Type, 0}, + {"Marshal", Func, 0}, + {"MarshalWithParams", Func, 10}, + {"NullBytes", Var, 9}, + {"NullRawValue", Var, 9}, + {"ObjectIdentifier", Type, 0}, + {"RawContent", Type, 0}, + {"RawValue", Type, 0}, + {"RawValue.Bytes", Field, 0}, + {"RawValue.Class", Field, 0}, + {"RawValue.FullBytes", Field, 0}, + {"RawValue.IsCompound", Field, 0}, + {"RawValue.Tag", Field, 0}, + {"StructuralError", Type, 0}, + {"StructuralError.Msg", Field, 0}, + {"SyntaxError", Type, 0}, + {"SyntaxError.Msg", Field, 0}, + {"TagBMPString", Const, 14}, + {"TagBitString", Const, 6}, + {"TagBoolean", Const, 6}, + {"TagEnum", Const, 6}, + {"TagGeneralString", Const, 6}, + {"TagGeneralizedTime", Const, 6}, + {"TagIA5String", Const, 6}, + {"TagInteger", Const, 6}, + {"TagNull", Const, 9}, + {"TagNumericString", Const, 10}, + {"TagOID", Const, 6}, + {"TagOctetString", Const, 6}, + {"TagPrintableString", Const, 6}, + {"TagSequence", Const, 6}, + {"TagSet", Const, 6}, + {"TagT61String", Const, 6}, + {"TagUTCTime", Const, 6}, + {"TagUTF8String", Const, 6}, + {"Unmarshal", Func, 0}, + {"UnmarshalWithParams", Func, 0}, + }, + "encoding/base32": { + {"(*Encoding).AppendDecode", Method, 22}, + {"(*Encoding).AppendEncode", Method, 22}, + {"(*Encoding).Decode", Method, 0}, + {"(*Encoding).DecodeString", Method, 0}, + {"(*Encoding).DecodedLen", Method, 0}, + {"(*Encoding).Encode", Method, 0}, + {"(*Encoding).EncodeToString", Method, 0}, + {"(*Encoding).EncodedLen", Method, 0}, + {"(CorruptInputError).Error", Method, 0}, + {"(Encoding).WithPadding", Method, 9}, + {"CorruptInputError", Type, 0}, + {"Encoding", Type, 0}, + {"HexEncoding", Var, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + {"NewEncoding", Func, 0}, + {"NoPadding", Const, 9}, + {"StdEncoding", Var, 0}, + {"StdPadding", Const, 9}, + }, + "encoding/base64": { + {"(*Encoding).AppendDecode", Method, 22}, + {"(*Encoding).AppendEncode", Method, 22}, + {"(*Encoding).Decode", Method, 0}, + {"(*Encoding).DecodeString", Method, 0}, + {"(*Encoding).DecodedLen", Method, 0}, + {"(*Encoding).Encode", Method, 0}, + {"(*Encoding).EncodeToString", Method, 0}, + {"(*Encoding).EncodedLen", Method, 0}, + {"(CorruptInputError).Error", Method, 0}, + {"(Encoding).Strict", Method, 8}, + {"(Encoding).WithPadding", Method, 5}, + {"CorruptInputError", Type, 0}, + {"Encoding", Type, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + {"NewEncoding", Func, 0}, + {"NoPadding", Const, 5}, + {"RawStdEncoding", Var, 5}, + {"RawURLEncoding", Var, 5}, + {"StdEncoding", Var, 0}, + {"StdPadding", Const, 5}, + {"URLEncoding", Var, 0}, + }, + "encoding/binary": { + {"AppendByteOrder", Type, 19}, + {"AppendUvarint", Func, 19}, + {"AppendVarint", Func, 19}, + {"BigEndian", Var, 0}, + {"ByteOrder", Type, 0}, + {"LittleEndian", Var, 0}, + {"MaxVarintLen16", Const, 0}, + {"MaxVarintLen32", Const, 0}, + {"MaxVarintLen64", Const, 0}, + {"NativeEndian", Var, 21}, + {"PutUvarint", Func, 0}, + {"PutVarint", Func, 0}, + {"Read", Func, 0}, + {"ReadUvarint", Func, 0}, + {"ReadVarint", Func, 0}, + {"Size", Func, 0}, + {"Uvarint", Func, 0}, + {"Varint", Func, 0}, + {"Write", Func, 0}, + }, + "encoding/csv": { + {"(*ParseError).Error", Method, 0}, + {"(*ParseError).Unwrap", Method, 13}, + {"(*Reader).FieldPos", Method, 17}, + {"(*Reader).InputOffset", Method, 19}, + {"(*Reader).Read", Method, 0}, + {"(*Reader).ReadAll", Method, 0}, + {"(*Writer).Error", Method, 1}, + {"(*Writer).Flush", Method, 0}, + {"(*Writer).Write", Method, 0}, + {"(*Writer).WriteAll", Method, 0}, + {"ErrBareQuote", Var, 0}, + {"ErrFieldCount", Var, 0}, + {"ErrQuote", Var, 0}, + {"ErrTrailingComma", Var, 0}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"ParseError", Type, 0}, + {"ParseError.Column", Field, 0}, + {"ParseError.Err", Field, 0}, + {"ParseError.Line", Field, 0}, + {"ParseError.StartLine", Field, 10}, + {"Reader", Type, 0}, + {"Reader.Comma", Field, 0}, + {"Reader.Comment", Field, 0}, + {"Reader.FieldsPerRecord", Field, 0}, + {"Reader.LazyQuotes", Field, 0}, + {"Reader.ReuseRecord", Field, 9}, + {"Reader.TrailingComma", Field, 0}, + {"Reader.TrimLeadingSpace", Field, 0}, + {"Writer", Type, 0}, + {"Writer.Comma", Field, 0}, + {"Writer.UseCRLF", Field, 0}, + }, + "encoding/gob": { + {"(*Decoder).Decode", Method, 0}, + {"(*Decoder).DecodeValue", Method, 0}, + {"(*Encoder).Encode", Method, 0}, + {"(*Encoder).EncodeValue", Method, 0}, + {"CommonType", Type, 0}, + {"CommonType.Id", Field, 0}, + {"CommonType.Name", Field, 0}, + {"Decoder", Type, 0}, + {"Encoder", Type, 0}, + {"GobDecoder", Type, 0}, + {"GobEncoder", Type, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + {"Register", Func, 0}, + {"RegisterName", Func, 0}, + }, + "encoding/hex": { + {"(InvalidByteError).Error", Method, 0}, + {"AppendDecode", Func, 22}, + {"AppendEncode", Func, 22}, + {"Decode", Func, 0}, + {"DecodeString", Func, 0}, + {"DecodedLen", Func, 0}, + {"Dump", Func, 0}, + {"Dumper", Func, 0}, + {"Encode", Func, 0}, + {"EncodeToString", Func, 0}, + {"EncodedLen", Func, 0}, + {"ErrLength", Var, 0}, + {"InvalidByteError", Type, 0}, + {"NewDecoder", Func, 10}, + {"NewEncoder", Func, 10}, + }, + "encoding/json": { + {"(*Decoder).Buffered", Method, 1}, + {"(*Decoder).Decode", Method, 0}, + {"(*Decoder).DisallowUnknownFields", Method, 10}, + {"(*Decoder).InputOffset", Method, 14}, + {"(*Decoder).More", Method, 5}, + {"(*Decoder).Token", Method, 5}, + {"(*Decoder).UseNumber", Method, 1}, + {"(*Encoder).Encode", Method, 0}, + {"(*Encoder).SetEscapeHTML", Method, 7}, + {"(*Encoder).SetIndent", Method, 7}, + {"(*InvalidUTF8Error).Error", Method, 0}, + {"(*InvalidUnmarshalError).Error", Method, 0}, + {"(*MarshalerError).Error", Method, 0}, + {"(*MarshalerError).Unwrap", Method, 13}, + {"(*RawMessage).MarshalJSON", Method, 0}, + {"(*RawMessage).UnmarshalJSON", Method, 0}, + {"(*SyntaxError).Error", Method, 0}, + {"(*UnmarshalFieldError).Error", Method, 0}, + {"(*UnmarshalTypeError).Error", Method, 0}, + {"(*UnsupportedTypeError).Error", Method, 0}, + {"(*UnsupportedValueError).Error", Method, 0}, + {"(Delim).String", Method, 5}, + {"(Number).Float64", Method, 1}, + {"(Number).Int64", Method, 1}, + {"(Number).String", Method, 1}, + {"(RawMessage).MarshalJSON", Method, 8}, + {"Compact", Func, 0}, + {"Decoder", Type, 0}, + {"Delim", Type, 5}, + {"Encoder", Type, 0}, + {"HTMLEscape", Func, 0}, + {"Indent", Func, 0}, + {"InvalidUTF8Error", Type, 0}, + {"InvalidUTF8Error.S", Field, 0}, + {"InvalidUnmarshalError", Type, 0}, + {"InvalidUnmarshalError.Type", Field, 0}, + {"Marshal", Func, 0}, + {"MarshalIndent", Func, 0}, + {"Marshaler", Type, 0}, + {"MarshalerError", Type, 0}, + {"MarshalerError.Err", Field, 0}, + {"MarshalerError.Type", Field, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + {"Number", Type, 1}, + {"RawMessage", Type, 0}, + {"SyntaxError", Type, 0}, + {"SyntaxError.Offset", Field, 0}, + {"Token", Type, 5}, + {"Unmarshal", Func, 0}, + {"UnmarshalFieldError", Type, 0}, + {"UnmarshalFieldError.Field", Field, 0}, + {"UnmarshalFieldError.Key", Field, 0}, + {"UnmarshalFieldError.Type", Field, 0}, + {"UnmarshalTypeError", Type, 0}, + {"UnmarshalTypeError.Field", Field, 8}, + {"UnmarshalTypeError.Offset", Field, 5}, + {"UnmarshalTypeError.Struct", Field, 8}, + {"UnmarshalTypeError.Type", Field, 0}, + {"UnmarshalTypeError.Value", Field, 0}, + {"Unmarshaler", Type, 0}, + {"UnsupportedTypeError", Type, 0}, + {"UnsupportedTypeError.Type", Field, 0}, + {"UnsupportedValueError", Type, 0}, + {"UnsupportedValueError.Str", Field, 0}, + {"UnsupportedValueError.Value", Field, 0}, + {"Valid", Func, 9}, + }, + "encoding/pem": { + {"Block", Type, 0}, + {"Block.Bytes", Field, 0}, + {"Block.Headers", Field, 0}, + {"Block.Type", Field, 0}, + {"Decode", Func, 0}, + {"Encode", Func, 0}, + {"EncodeToMemory", Func, 0}, + }, + "encoding/xml": { + {"(*Decoder).Decode", Method, 0}, + {"(*Decoder).DecodeElement", Method, 0}, + {"(*Decoder).InputOffset", Method, 4}, + {"(*Decoder).InputPos", Method, 19}, + {"(*Decoder).RawToken", Method, 0}, + {"(*Decoder).Skip", Method, 0}, + {"(*Decoder).Token", Method, 0}, + {"(*Encoder).Close", Method, 20}, + {"(*Encoder).Encode", Method, 0}, + {"(*Encoder).EncodeElement", Method, 2}, + {"(*Encoder).EncodeToken", Method, 2}, + {"(*Encoder).Flush", Method, 2}, + {"(*Encoder).Indent", Method, 1}, + {"(*SyntaxError).Error", Method, 0}, + {"(*TagPathError).Error", Method, 0}, + {"(*UnsupportedTypeError).Error", Method, 0}, + {"(CharData).Copy", Method, 0}, + {"(Comment).Copy", Method, 0}, + {"(Directive).Copy", Method, 0}, + {"(ProcInst).Copy", Method, 0}, + {"(StartElement).Copy", Method, 0}, + {"(StartElement).End", Method, 2}, + {"(UnmarshalError).Error", Method, 0}, + {"Attr", Type, 0}, + {"Attr.Name", Field, 0}, + {"Attr.Value", Field, 0}, + {"CharData", Type, 0}, + {"Comment", Type, 0}, + {"CopyToken", Func, 0}, + {"Decoder", Type, 0}, + {"Decoder.AutoClose", Field, 0}, + {"Decoder.CharsetReader", Field, 0}, + {"Decoder.DefaultSpace", Field, 1}, + {"Decoder.Entity", Field, 0}, + {"Decoder.Strict", Field, 0}, + {"Directive", Type, 0}, + {"Encoder", Type, 0}, + {"EndElement", Type, 0}, + {"EndElement.Name", Field, 0}, + {"Escape", Func, 0}, + {"EscapeText", Func, 1}, + {"HTMLAutoClose", Var, 0}, + {"HTMLEntity", Var, 0}, + {"Header", Const, 0}, + {"Marshal", Func, 0}, + {"MarshalIndent", Func, 0}, + {"Marshaler", Type, 2}, + {"MarshalerAttr", Type, 2}, + {"Name", Type, 0}, + {"Name.Local", Field, 0}, + {"Name.Space", Field, 0}, + {"NewDecoder", Func, 0}, + {"NewEncoder", Func, 0}, + {"NewTokenDecoder", Func, 10}, + {"ProcInst", Type, 0}, + {"ProcInst.Inst", Field, 0}, + {"ProcInst.Target", Field, 0}, + {"StartElement", Type, 0}, + {"StartElement.Attr", Field, 0}, + {"StartElement.Name", Field, 0}, + {"SyntaxError", Type, 0}, + {"SyntaxError.Line", Field, 0}, + {"SyntaxError.Msg", Field, 0}, + {"TagPathError", Type, 0}, + {"TagPathError.Field1", Field, 0}, + {"TagPathError.Field2", Field, 0}, + {"TagPathError.Struct", Field, 0}, + {"TagPathError.Tag1", Field, 0}, + {"TagPathError.Tag2", Field, 0}, + {"Token", Type, 0}, + {"TokenReader", Type, 10}, + {"Unmarshal", Func, 0}, + {"UnmarshalError", Type, 0}, + {"Unmarshaler", Type, 2}, + {"UnmarshalerAttr", Type, 2}, + {"UnsupportedTypeError", Type, 0}, + {"UnsupportedTypeError.Type", Field, 0}, + }, + "errors": { + {"As", Func, 13}, + {"ErrUnsupported", Var, 21}, + {"Is", Func, 13}, + {"Join", Func, 20}, + {"New", Func, 0}, + {"Unwrap", Func, 13}, + }, + "expvar": { + {"(*Float).Add", Method, 0}, + {"(*Float).Set", Method, 0}, + {"(*Float).String", Method, 0}, + {"(*Float).Value", Method, 8}, + {"(*Int).Add", Method, 0}, + {"(*Int).Set", Method, 0}, + {"(*Int).String", Method, 0}, + {"(*Int).Value", Method, 8}, + {"(*Map).Add", Method, 0}, + {"(*Map).AddFloat", Method, 0}, + {"(*Map).Delete", Method, 12}, + {"(*Map).Do", Method, 0}, + {"(*Map).Get", Method, 0}, + {"(*Map).Init", Method, 0}, + {"(*Map).Set", Method, 0}, + {"(*Map).String", Method, 0}, + {"(*String).Set", Method, 0}, + {"(*String).String", Method, 0}, + {"(*String).Value", Method, 8}, + {"(Func).String", Method, 0}, + {"(Func).Value", Method, 8}, + {"Do", Func, 0}, + {"Float", Type, 0}, + {"Func", Type, 0}, + {"Get", Func, 0}, + {"Handler", Func, 8}, + {"Int", Type, 0}, + {"KeyValue", Type, 0}, + {"KeyValue.Key", Field, 0}, + {"KeyValue.Value", Field, 0}, + {"Map", Type, 0}, + {"NewFloat", Func, 0}, + {"NewInt", Func, 0}, + {"NewMap", Func, 0}, + {"NewString", Func, 0}, + {"Publish", Func, 0}, + {"String", Type, 0}, + {"Var", Type, 0}, + }, + "flag": { + {"(*FlagSet).Arg", Method, 0}, + {"(*FlagSet).Args", Method, 0}, + {"(*FlagSet).Bool", Method, 0}, + {"(*FlagSet).BoolFunc", Method, 21}, + {"(*FlagSet).BoolVar", Method, 0}, + {"(*FlagSet).Duration", Method, 0}, + {"(*FlagSet).DurationVar", Method, 0}, + {"(*FlagSet).ErrorHandling", Method, 10}, + {"(*FlagSet).Float64", Method, 0}, + {"(*FlagSet).Float64Var", Method, 0}, + {"(*FlagSet).Func", Method, 16}, + {"(*FlagSet).Init", Method, 0}, + {"(*FlagSet).Int", Method, 0}, + {"(*FlagSet).Int64", Method, 0}, + {"(*FlagSet).Int64Var", Method, 0}, + {"(*FlagSet).IntVar", Method, 0}, + {"(*FlagSet).Lookup", Method, 0}, + {"(*FlagSet).NArg", Method, 0}, + {"(*FlagSet).NFlag", Method, 0}, + {"(*FlagSet).Name", Method, 10}, + {"(*FlagSet).Output", Method, 10}, + {"(*FlagSet).Parse", Method, 0}, + {"(*FlagSet).Parsed", Method, 0}, + {"(*FlagSet).PrintDefaults", Method, 0}, + {"(*FlagSet).Set", Method, 0}, + {"(*FlagSet).SetOutput", Method, 0}, + {"(*FlagSet).String", Method, 0}, + {"(*FlagSet).StringVar", Method, 0}, + {"(*FlagSet).TextVar", Method, 19}, + {"(*FlagSet).Uint", Method, 0}, + {"(*FlagSet).Uint64", Method, 0}, + {"(*FlagSet).Uint64Var", Method, 0}, + {"(*FlagSet).UintVar", Method, 0}, + {"(*FlagSet).Var", Method, 0}, + {"(*FlagSet).Visit", Method, 0}, + {"(*FlagSet).VisitAll", Method, 0}, + {"Arg", Func, 0}, + {"Args", Func, 0}, + {"Bool", Func, 0}, + {"BoolFunc", Func, 21}, + {"BoolVar", Func, 0}, + {"CommandLine", Var, 2}, + {"ContinueOnError", Const, 0}, + {"Duration", Func, 0}, + {"DurationVar", Func, 0}, + {"ErrHelp", Var, 0}, + {"ErrorHandling", Type, 0}, + {"ExitOnError", Const, 0}, + {"Flag", Type, 0}, + {"Flag.DefValue", Field, 0}, + {"Flag.Name", Field, 0}, + {"Flag.Usage", Field, 0}, + {"Flag.Value", Field, 0}, + {"FlagSet", Type, 0}, + {"FlagSet.Usage", Field, 0}, + {"Float64", Func, 0}, + {"Float64Var", Func, 0}, + {"Func", Func, 16}, + {"Getter", Type, 2}, + {"Int", Func, 0}, + {"Int64", Func, 0}, + {"Int64Var", Func, 0}, + {"IntVar", Func, 0}, + {"Lookup", Func, 0}, + {"NArg", Func, 0}, + {"NFlag", Func, 0}, + {"NewFlagSet", Func, 0}, + {"PanicOnError", Const, 0}, + {"Parse", Func, 0}, + {"Parsed", Func, 0}, + {"PrintDefaults", Func, 0}, + {"Set", Func, 0}, + {"String", Func, 0}, + {"StringVar", Func, 0}, + {"TextVar", Func, 19}, + {"Uint", Func, 0}, + {"Uint64", Func, 0}, + {"Uint64Var", Func, 0}, + {"UintVar", Func, 0}, + {"UnquoteUsage", Func, 5}, + {"Usage", Var, 0}, + {"Value", Type, 0}, + {"Var", Func, 0}, + {"Visit", Func, 0}, + {"VisitAll", Func, 0}, + }, + "fmt": { + {"Append", Func, 19}, + {"Appendf", Func, 19}, + {"Appendln", Func, 19}, + {"Errorf", Func, 0}, + {"FormatString", Func, 20}, + {"Formatter", Type, 0}, + {"Fprint", Func, 0}, + {"Fprintf", Func, 0}, + {"Fprintln", Func, 0}, + {"Fscan", Func, 0}, + {"Fscanf", Func, 0}, + {"Fscanln", Func, 0}, + {"GoStringer", Type, 0}, + {"Print", Func, 0}, + {"Printf", Func, 0}, + {"Println", Func, 0}, + {"Scan", Func, 0}, + {"ScanState", Type, 0}, + {"Scanf", Func, 0}, + {"Scanln", Func, 0}, + {"Scanner", Type, 0}, + {"Sprint", Func, 0}, + {"Sprintf", Func, 0}, + {"Sprintln", Func, 0}, + {"Sscan", Func, 0}, + {"Sscanf", Func, 0}, + {"Sscanln", Func, 0}, + {"State", Type, 0}, + {"Stringer", Type, 0}, + }, + "go/ast": { + {"(*ArrayType).End", Method, 0}, + {"(*ArrayType).Pos", Method, 0}, + {"(*AssignStmt).End", Method, 0}, + {"(*AssignStmt).Pos", Method, 0}, + {"(*BadDecl).End", Method, 0}, + {"(*BadDecl).Pos", Method, 0}, + {"(*BadExpr).End", Method, 0}, + {"(*BadExpr).Pos", Method, 0}, + {"(*BadStmt).End", Method, 0}, + {"(*BadStmt).Pos", Method, 0}, + {"(*BasicLit).End", Method, 0}, + {"(*BasicLit).Pos", Method, 0}, + {"(*BinaryExpr).End", Method, 0}, + {"(*BinaryExpr).Pos", Method, 0}, + {"(*BlockStmt).End", Method, 0}, + {"(*BlockStmt).Pos", Method, 0}, + {"(*BranchStmt).End", Method, 0}, + {"(*BranchStmt).Pos", Method, 0}, + {"(*CallExpr).End", Method, 0}, + {"(*CallExpr).Pos", Method, 0}, + {"(*CaseClause).End", Method, 0}, + {"(*CaseClause).Pos", Method, 0}, + {"(*ChanType).End", Method, 0}, + {"(*ChanType).Pos", Method, 0}, + {"(*CommClause).End", Method, 0}, + {"(*CommClause).Pos", Method, 0}, + {"(*Comment).End", Method, 0}, + {"(*Comment).Pos", Method, 0}, + {"(*CommentGroup).End", Method, 0}, + {"(*CommentGroup).Pos", Method, 0}, + {"(*CommentGroup).Text", Method, 0}, + {"(*CompositeLit).End", Method, 0}, + {"(*CompositeLit).Pos", Method, 0}, + {"(*DeclStmt).End", Method, 0}, + {"(*DeclStmt).Pos", Method, 0}, + {"(*DeferStmt).End", Method, 0}, + {"(*DeferStmt).Pos", Method, 0}, + {"(*Ellipsis).End", Method, 0}, + {"(*Ellipsis).Pos", Method, 0}, + {"(*EmptyStmt).End", Method, 0}, + {"(*EmptyStmt).Pos", Method, 0}, + {"(*ExprStmt).End", Method, 0}, + {"(*ExprStmt).Pos", Method, 0}, + {"(*Field).End", Method, 0}, + {"(*Field).Pos", Method, 0}, + {"(*FieldList).End", Method, 0}, + {"(*FieldList).NumFields", Method, 0}, + {"(*FieldList).Pos", Method, 0}, + {"(*File).End", Method, 0}, + {"(*File).Pos", Method, 0}, + {"(*ForStmt).End", Method, 0}, + {"(*ForStmt).Pos", Method, 0}, + {"(*FuncDecl).End", Method, 0}, + {"(*FuncDecl).Pos", Method, 0}, + {"(*FuncLit).End", Method, 0}, + {"(*FuncLit).Pos", Method, 0}, + {"(*FuncType).End", Method, 0}, + {"(*FuncType).Pos", Method, 0}, + {"(*GenDecl).End", Method, 0}, + {"(*GenDecl).Pos", Method, 0}, + {"(*GoStmt).End", Method, 0}, + {"(*GoStmt).Pos", Method, 0}, + {"(*Ident).End", Method, 0}, + {"(*Ident).IsExported", Method, 0}, + {"(*Ident).Pos", Method, 0}, + {"(*Ident).String", Method, 0}, + {"(*IfStmt).End", Method, 0}, + {"(*IfStmt).Pos", Method, 0}, + {"(*ImportSpec).End", Method, 0}, + {"(*ImportSpec).Pos", Method, 0}, + {"(*IncDecStmt).End", Method, 0}, + {"(*IncDecStmt).Pos", Method, 0}, + {"(*IndexExpr).End", Method, 0}, + {"(*IndexExpr).Pos", Method, 0}, + {"(*IndexListExpr).End", Method, 18}, + {"(*IndexListExpr).Pos", Method, 18}, + {"(*InterfaceType).End", Method, 0}, + {"(*InterfaceType).Pos", Method, 0}, + {"(*KeyValueExpr).End", Method, 0}, + {"(*KeyValueExpr).Pos", Method, 0}, + {"(*LabeledStmt).End", Method, 0}, + {"(*LabeledStmt).Pos", Method, 0}, + {"(*MapType).End", Method, 0}, + {"(*MapType).Pos", Method, 0}, + {"(*Object).Pos", Method, 0}, + {"(*Package).End", Method, 0}, + {"(*Package).Pos", Method, 0}, + {"(*ParenExpr).End", Method, 0}, + {"(*ParenExpr).Pos", Method, 0}, + {"(*RangeStmt).End", Method, 0}, + {"(*RangeStmt).Pos", Method, 0}, + {"(*ReturnStmt).End", Method, 0}, + {"(*ReturnStmt).Pos", Method, 0}, + {"(*Scope).Insert", Method, 0}, + {"(*Scope).Lookup", Method, 0}, + {"(*Scope).String", Method, 0}, + {"(*SelectStmt).End", Method, 0}, + {"(*SelectStmt).Pos", Method, 0}, + {"(*SelectorExpr).End", Method, 0}, + {"(*SelectorExpr).Pos", Method, 0}, + {"(*SendStmt).End", Method, 0}, + {"(*SendStmt).Pos", Method, 0}, + {"(*SliceExpr).End", Method, 0}, + {"(*SliceExpr).Pos", Method, 0}, + {"(*StarExpr).End", Method, 0}, + {"(*StarExpr).Pos", Method, 0}, + {"(*StructType).End", Method, 0}, + {"(*StructType).Pos", Method, 0}, + {"(*SwitchStmt).End", Method, 0}, + {"(*SwitchStmt).Pos", Method, 0}, + {"(*TypeAssertExpr).End", Method, 0}, + {"(*TypeAssertExpr).Pos", Method, 0}, + {"(*TypeSpec).End", Method, 0}, + {"(*TypeSpec).Pos", Method, 0}, + {"(*TypeSwitchStmt).End", Method, 0}, + {"(*TypeSwitchStmt).Pos", Method, 0}, + {"(*UnaryExpr).End", Method, 0}, + {"(*UnaryExpr).Pos", Method, 0}, + {"(*ValueSpec).End", Method, 0}, + {"(*ValueSpec).Pos", Method, 0}, + {"(CommentMap).Comments", Method, 1}, + {"(CommentMap).Filter", Method, 1}, + {"(CommentMap).String", Method, 1}, + {"(CommentMap).Update", Method, 1}, + {"(ObjKind).String", Method, 0}, + {"ArrayType", Type, 0}, + {"ArrayType.Elt", Field, 0}, + {"ArrayType.Lbrack", Field, 0}, + {"ArrayType.Len", Field, 0}, + {"AssignStmt", Type, 0}, + {"AssignStmt.Lhs", Field, 0}, + {"AssignStmt.Rhs", Field, 0}, + {"AssignStmt.Tok", Field, 0}, + {"AssignStmt.TokPos", Field, 0}, + {"Bad", Const, 0}, + {"BadDecl", Type, 0}, + {"BadDecl.From", Field, 0}, + {"BadDecl.To", Field, 0}, + {"BadExpr", Type, 0}, + {"BadExpr.From", Field, 0}, + {"BadExpr.To", Field, 0}, + {"BadStmt", Type, 0}, + {"BadStmt.From", Field, 0}, + {"BadStmt.To", Field, 0}, + {"BasicLit", Type, 0}, + {"BasicLit.Kind", Field, 0}, + {"BasicLit.Value", Field, 0}, + {"BasicLit.ValuePos", Field, 0}, + {"BinaryExpr", Type, 0}, + {"BinaryExpr.Op", Field, 0}, + {"BinaryExpr.OpPos", Field, 0}, + {"BinaryExpr.X", Field, 0}, + {"BinaryExpr.Y", Field, 0}, + {"BlockStmt", Type, 0}, + {"BlockStmt.Lbrace", Field, 0}, + {"BlockStmt.List", Field, 0}, + {"BlockStmt.Rbrace", Field, 0}, + {"BranchStmt", Type, 0}, + {"BranchStmt.Label", Field, 0}, + {"BranchStmt.Tok", Field, 0}, + {"BranchStmt.TokPos", Field, 0}, + {"CallExpr", Type, 0}, + {"CallExpr.Args", Field, 0}, + {"CallExpr.Ellipsis", Field, 0}, + {"CallExpr.Fun", Field, 0}, + {"CallExpr.Lparen", Field, 0}, + {"CallExpr.Rparen", Field, 0}, + {"CaseClause", Type, 0}, + {"CaseClause.Body", Field, 0}, + {"CaseClause.Case", Field, 0}, + {"CaseClause.Colon", Field, 0}, + {"CaseClause.List", Field, 0}, + {"ChanDir", Type, 0}, + {"ChanType", Type, 0}, + {"ChanType.Arrow", Field, 1}, + {"ChanType.Begin", Field, 0}, + {"ChanType.Dir", Field, 0}, + {"ChanType.Value", Field, 0}, + {"CommClause", Type, 0}, + {"CommClause.Body", Field, 0}, + {"CommClause.Case", Field, 0}, + {"CommClause.Colon", Field, 0}, + {"CommClause.Comm", Field, 0}, + {"Comment", Type, 0}, + {"Comment.Slash", Field, 0}, + {"Comment.Text", Field, 0}, + {"CommentGroup", Type, 0}, + {"CommentGroup.List", Field, 0}, + {"CommentMap", Type, 1}, + {"CompositeLit", Type, 0}, + {"CompositeLit.Elts", Field, 0}, + {"CompositeLit.Incomplete", Field, 11}, + {"CompositeLit.Lbrace", Field, 0}, + {"CompositeLit.Rbrace", Field, 0}, + {"CompositeLit.Type", Field, 0}, + {"Con", Const, 0}, + {"Decl", Type, 0}, + {"DeclStmt", Type, 0}, + {"DeclStmt.Decl", Field, 0}, + {"DeferStmt", Type, 0}, + {"DeferStmt.Call", Field, 0}, + {"DeferStmt.Defer", Field, 0}, + {"Ellipsis", Type, 0}, + {"Ellipsis.Ellipsis", Field, 0}, + {"Ellipsis.Elt", Field, 0}, + {"EmptyStmt", Type, 0}, + {"EmptyStmt.Implicit", Field, 5}, + {"EmptyStmt.Semicolon", Field, 0}, + {"Expr", Type, 0}, + {"ExprStmt", Type, 0}, + {"ExprStmt.X", Field, 0}, + {"Field", Type, 0}, + {"Field.Comment", Field, 0}, + {"Field.Doc", Field, 0}, + {"Field.Names", Field, 0}, + {"Field.Tag", Field, 0}, + {"Field.Type", Field, 0}, + {"FieldFilter", Type, 0}, + {"FieldList", Type, 0}, + {"FieldList.Closing", Field, 0}, + {"FieldList.List", Field, 0}, + {"FieldList.Opening", Field, 0}, + {"File", Type, 0}, + {"File.Comments", Field, 0}, + {"File.Decls", Field, 0}, + {"File.Doc", Field, 0}, + {"File.FileEnd", Field, 20}, + {"File.FileStart", Field, 20}, + {"File.GoVersion", Field, 21}, + {"File.Imports", Field, 0}, + {"File.Name", Field, 0}, + {"File.Package", Field, 0}, + {"File.Scope", Field, 0}, + {"File.Unresolved", Field, 0}, + {"FileExports", Func, 0}, + {"Filter", Type, 0}, + {"FilterDecl", Func, 0}, + {"FilterFile", Func, 0}, + {"FilterFuncDuplicates", Const, 0}, + {"FilterImportDuplicates", Const, 0}, + {"FilterPackage", Func, 0}, + {"FilterUnassociatedComments", Const, 0}, + {"ForStmt", Type, 0}, + {"ForStmt.Body", Field, 0}, + {"ForStmt.Cond", Field, 0}, + {"ForStmt.For", Field, 0}, + {"ForStmt.Init", Field, 0}, + {"ForStmt.Post", Field, 0}, + {"Fprint", Func, 0}, + {"Fun", Const, 0}, + {"FuncDecl", Type, 0}, + {"FuncDecl.Body", Field, 0}, + {"FuncDecl.Doc", Field, 0}, + {"FuncDecl.Name", Field, 0}, + {"FuncDecl.Recv", Field, 0}, + {"FuncDecl.Type", Field, 0}, + {"FuncLit", Type, 0}, + {"FuncLit.Body", Field, 0}, + {"FuncLit.Type", Field, 0}, + {"FuncType", Type, 0}, + {"FuncType.Func", Field, 0}, + {"FuncType.Params", Field, 0}, + {"FuncType.Results", Field, 0}, + {"FuncType.TypeParams", Field, 18}, + {"GenDecl", Type, 0}, + {"GenDecl.Doc", Field, 0}, + {"GenDecl.Lparen", Field, 0}, + {"GenDecl.Rparen", Field, 0}, + {"GenDecl.Specs", Field, 0}, + {"GenDecl.Tok", Field, 0}, + {"GenDecl.TokPos", Field, 0}, + {"GoStmt", Type, 0}, + {"GoStmt.Call", Field, 0}, + {"GoStmt.Go", Field, 0}, + {"Ident", Type, 0}, + {"Ident.Name", Field, 0}, + {"Ident.NamePos", Field, 0}, + {"Ident.Obj", Field, 0}, + {"IfStmt", Type, 0}, + {"IfStmt.Body", Field, 0}, + {"IfStmt.Cond", Field, 0}, + {"IfStmt.Else", Field, 0}, + {"IfStmt.If", Field, 0}, + {"IfStmt.Init", Field, 0}, + {"ImportSpec", Type, 0}, + {"ImportSpec.Comment", Field, 0}, + {"ImportSpec.Doc", Field, 0}, + {"ImportSpec.EndPos", Field, 0}, + {"ImportSpec.Name", Field, 0}, + {"ImportSpec.Path", Field, 0}, + {"Importer", Type, 0}, + {"IncDecStmt", Type, 0}, + {"IncDecStmt.Tok", Field, 0}, + {"IncDecStmt.TokPos", Field, 0}, + {"IncDecStmt.X", Field, 0}, + {"IndexExpr", Type, 0}, + {"IndexExpr.Index", Field, 0}, + {"IndexExpr.Lbrack", Field, 0}, + {"IndexExpr.Rbrack", Field, 0}, + {"IndexExpr.X", Field, 0}, + {"IndexListExpr", Type, 18}, + {"IndexListExpr.Indices", Field, 18}, + {"IndexListExpr.Lbrack", Field, 18}, + {"IndexListExpr.Rbrack", Field, 18}, + {"IndexListExpr.X", Field, 18}, + {"Inspect", Func, 0}, + {"InterfaceType", Type, 0}, + {"InterfaceType.Incomplete", Field, 0}, + {"InterfaceType.Interface", Field, 0}, + {"InterfaceType.Methods", Field, 0}, + {"IsExported", Func, 0}, + {"IsGenerated", Func, 21}, + {"KeyValueExpr", Type, 0}, + {"KeyValueExpr.Colon", Field, 0}, + {"KeyValueExpr.Key", Field, 0}, + {"KeyValueExpr.Value", Field, 0}, + {"LabeledStmt", Type, 0}, + {"LabeledStmt.Colon", Field, 0}, + {"LabeledStmt.Label", Field, 0}, + {"LabeledStmt.Stmt", Field, 0}, + {"Lbl", Const, 0}, + {"MapType", Type, 0}, + {"MapType.Key", Field, 0}, + {"MapType.Map", Field, 0}, + {"MapType.Value", Field, 0}, + {"MergeMode", Type, 0}, + {"MergePackageFiles", Func, 0}, + {"NewCommentMap", Func, 1}, + {"NewIdent", Func, 0}, + {"NewObj", Func, 0}, + {"NewPackage", Func, 0}, + {"NewScope", Func, 0}, + {"Node", Type, 0}, + {"NotNilFilter", Func, 0}, + {"ObjKind", Type, 0}, + {"Object", Type, 0}, + {"Object.Data", Field, 0}, + {"Object.Decl", Field, 0}, + {"Object.Kind", Field, 0}, + {"Object.Name", Field, 0}, + {"Object.Type", Field, 0}, + {"Package", Type, 0}, + {"Package.Files", Field, 0}, + {"Package.Imports", Field, 0}, + {"Package.Name", Field, 0}, + {"Package.Scope", Field, 0}, + {"PackageExports", Func, 0}, + {"ParenExpr", Type, 0}, + {"ParenExpr.Lparen", Field, 0}, + {"ParenExpr.Rparen", Field, 0}, + {"ParenExpr.X", Field, 0}, + {"Pkg", Const, 0}, + {"Print", Func, 0}, + {"RECV", Const, 0}, + {"RangeStmt", Type, 0}, + {"RangeStmt.Body", Field, 0}, + {"RangeStmt.For", Field, 0}, + {"RangeStmt.Key", Field, 0}, + {"RangeStmt.Range", Field, 20}, + {"RangeStmt.Tok", Field, 0}, + {"RangeStmt.TokPos", Field, 0}, + {"RangeStmt.Value", Field, 0}, + {"RangeStmt.X", Field, 0}, + {"ReturnStmt", Type, 0}, + {"ReturnStmt.Results", Field, 0}, + {"ReturnStmt.Return", Field, 0}, + {"SEND", Const, 0}, + {"Scope", Type, 0}, + {"Scope.Objects", Field, 0}, + {"Scope.Outer", Field, 0}, + {"SelectStmt", Type, 0}, + {"SelectStmt.Body", Field, 0}, + {"SelectStmt.Select", Field, 0}, + {"SelectorExpr", Type, 0}, + {"SelectorExpr.Sel", Field, 0}, + {"SelectorExpr.X", Field, 0}, + {"SendStmt", Type, 0}, + {"SendStmt.Arrow", Field, 0}, + {"SendStmt.Chan", Field, 0}, + {"SendStmt.Value", Field, 0}, + {"SliceExpr", Type, 0}, + {"SliceExpr.High", Field, 0}, + {"SliceExpr.Lbrack", Field, 0}, + {"SliceExpr.Low", Field, 0}, + {"SliceExpr.Max", Field, 2}, + {"SliceExpr.Rbrack", Field, 0}, + {"SliceExpr.Slice3", Field, 2}, + {"SliceExpr.X", Field, 0}, + {"SortImports", Func, 0}, + {"Spec", Type, 0}, + {"StarExpr", Type, 0}, + {"StarExpr.Star", Field, 0}, + {"StarExpr.X", Field, 0}, + {"Stmt", Type, 0}, + {"StructType", Type, 0}, + {"StructType.Fields", Field, 0}, + {"StructType.Incomplete", Field, 0}, + {"StructType.Struct", Field, 0}, + {"SwitchStmt", Type, 0}, + {"SwitchStmt.Body", Field, 0}, + {"SwitchStmt.Init", Field, 0}, + {"SwitchStmt.Switch", Field, 0}, + {"SwitchStmt.Tag", Field, 0}, + {"Typ", Const, 0}, + {"TypeAssertExpr", Type, 0}, + {"TypeAssertExpr.Lparen", Field, 2}, + {"TypeAssertExpr.Rparen", Field, 2}, + {"TypeAssertExpr.Type", Field, 0}, + {"TypeAssertExpr.X", Field, 0}, + {"TypeSpec", Type, 0}, + {"TypeSpec.Assign", Field, 9}, + {"TypeSpec.Comment", Field, 0}, + {"TypeSpec.Doc", Field, 0}, + {"TypeSpec.Name", Field, 0}, + {"TypeSpec.Type", Field, 0}, + {"TypeSpec.TypeParams", Field, 18}, + {"TypeSwitchStmt", Type, 0}, + {"TypeSwitchStmt.Assign", Field, 0}, + {"TypeSwitchStmt.Body", Field, 0}, + {"TypeSwitchStmt.Init", Field, 0}, + {"TypeSwitchStmt.Switch", Field, 0}, + {"UnaryExpr", Type, 0}, + {"UnaryExpr.Op", Field, 0}, + {"UnaryExpr.OpPos", Field, 0}, + {"UnaryExpr.X", Field, 0}, + {"Unparen", Func, 22}, + {"ValueSpec", Type, 0}, + {"ValueSpec.Comment", Field, 0}, + {"ValueSpec.Doc", Field, 0}, + {"ValueSpec.Names", Field, 0}, + {"ValueSpec.Type", Field, 0}, + {"ValueSpec.Values", Field, 0}, + {"Var", Const, 0}, + {"Visitor", Type, 0}, + {"Walk", Func, 0}, + }, + "go/build": { + {"(*Context).Import", Method, 0}, + {"(*Context).ImportDir", Method, 0}, + {"(*Context).MatchFile", Method, 2}, + {"(*Context).SrcDirs", Method, 0}, + {"(*MultiplePackageError).Error", Method, 4}, + {"(*NoGoError).Error", Method, 0}, + {"(*Package).IsCommand", Method, 0}, + {"AllowBinary", Const, 0}, + {"ArchChar", Func, 0}, + {"Context", Type, 0}, + {"Context.BuildTags", Field, 0}, + {"Context.CgoEnabled", Field, 0}, + {"Context.Compiler", Field, 0}, + {"Context.Dir", Field, 14}, + {"Context.GOARCH", Field, 0}, + {"Context.GOOS", Field, 0}, + {"Context.GOPATH", Field, 0}, + {"Context.GOROOT", Field, 0}, + {"Context.HasSubdir", Field, 0}, + {"Context.InstallSuffix", Field, 1}, + {"Context.IsAbsPath", Field, 0}, + {"Context.IsDir", Field, 0}, + {"Context.JoinPath", Field, 0}, + {"Context.OpenFile", Field, 0}, + {"Context.ReadDir", Field, 0}, + {"Context.ReleaseTags", Field, 1}, + {"Context.SplitPathList", Field, 0}, + {"Context.ToolTags", Field, 17}, + {"Context.UseAllFiles", Field, 0}, + {"Default", Var, 0}, + {"Directive", Type, 21}, + {"Directive.Pos", Field, 21}, + {"Directive.Text", Field, 21}, + {"FindOnly", Const, 0}, + {"IgnoreVendor", Const, 6}, + {"Import", Func, 0}, + {"ImportComment", Const, 4}, + {"ImportDir", Func, 0}, + {"ImportMode", Type, 0}, + {"IsLocalImport", Func, 0}, + {"MultiplePackageError", Type, 4}, + {"MultiplePackageError.Dir", Field, 4}, + {"MultiplePackageError.Files", Field, 4}, + {"MultiplePackageError.Packages", Field, 4}, + {"NoGoError", Type, 0}, + {"NoGoError.Dir", Field, 0}, + {"Package", Type, 0}, + {"Package.AllTags", Field, 2}, + {"Package.BinDir", Field, 0}, + {"Package.BinaryOnly", Field, 7}, + {"Package.CFiles", Field, 0}, + {"Package.CXXFiles", Field, 2}, + {"Package.CgoCFLAGS", Field, 0}, + {"Package.CgoCPPFLAGS", Field, 2}, + {"Package.CgoCXXFLAGS", Field, 2}, + {"Package.CgoFFLAGS", Field, 7}, + {"Package.CgoFiles", Field, 0}, + {"Package.CgoLDFLAGS", Field, 0}, + {"Package.CgoPkgConfig", Field, 0}, + {"Package.ConflictDir", Field, 2}, + {"Package.Dir", Field, 0}, + {"Package.Directives", Field, 21}, + {"Package.Doc", Field, 0}, + {"Package.EmbedPatternPos", Field, 16}, + {"Package.EmbedPatterns", Field, 16}, + {"Package.FFiles", Field, 7}, + {"Package.GoFiles", Field, 0}, + {"Package.Goroot", Field, 0}, + {"Package.HFiles", Field, 0}, + {"Package.IgnoredGoFiles", Field, 1}, + {"Package.IgnoredOtherFiles", Field, 16}, + {"Package.ImportComment", Field, 4}, + {"Package.ImportPath", Field, 0}, + {"Package.ImportPos", Field, 0}, + {"Package.Imports", Field, 0}, + {"Package.InvalidGoFiles", Field, 6}, + {"Package.MFiles", Field, 3}, + {"Package.Name", Field, 0}, + {"Package.PkgObj", Field, 0}, + {"Package.PkgRoot", Field, 0}, + {"Package.PkgTargetRoot", Field, 5}, + {"Package.Root", Field, 0}, + {"Package.SFiles", Field, 0}, + {"Package.SrcRoot", Field, 0}, + {"Package.SwigCXXFiles", Field, 1}, + {"Package.SwigFiles", Field, 1}, + {"Package.SysoFiles", Field, 0}, + {"Package.TestDirectives", Field, 21}, + {"Package.TestEmbedPatternPos", Field, 16}, + {"Package.TestEmbedPatterns", Field, 16}, + {"Package.TestGoFiles", Field, 0}, + {"Package.TestImportPos", Field, 0}, + {"Package.TestImports", Field, 0}, + {"Package.XTestDirectives", Field, 21}, + {"Package.XTestEmbedPatternPos", Field, 16}, + {"Package.XTestEmbedPatterns", Field, 16}, + {"Package.XTestGoFiles", Field, 0}, + {"Package.XTestImportPos", Field, 0}, + {"Package.XTestImports", Field, 0}, + {"ToolDir", Var, 0}, + }, + "go/build/constraint": { + {"(*AndExpr).Eval", Method, 16}, + {"(*AndExpr).String", Method, 16}, + {"(*NotExpr).Eval", Method, 16}, + {"(*NotExpr).String", Method, 16}, + {"(*OrExpr).Eval", Method, 16}, + {"(*OrExpr).String", Method, 16}, + {"(*SyntaxError).Error", Method, 16}, + {"(*TagExpr).Eval", Method, 16}, + {"(*TagExpr).String", Method, 16}, + {"AndExpr", Type, 16}, + {"AndExpr.X", Field, 16}, + {"AndExpr.Y", Field, 16}, + {"Expr", Type, 16}, + {"GoVersion", Func, 21}, + {"IsGoBuild", Func, 16}, + {"IsPlusBuild", Func, 16}, + {"NotExpr", Type, 16}, + {"NotExpr.X", Field, 16}, + {"OrExpr", Type, 16}, + {"OrExpr.X", Field, 16}, + {"OrExpr.Y", Field, 16}, + {"Parse", Func, 16}, + {"PlusBuildLines", Func, 16}, + {"SyntaxError", Type, 16}, + {"SyntaxError.Err", Field, 16}, + {"SyntaxError.Offset", Field, 16}, + {"TagExpr", Type, 16}, + {"TagExpr.Tag", Field, 16}, + }, + "go/constant": { + {"(Kind).String", Method, 18}, + {"BinaryOp", Func, 5}, + {"BitLen", Func, 5}, + {"Bool", Const, 5}, + {"BoolVal", Func, 5}, + {"Bytes", Func, 5}, + {"Compare", Func, 5}, + {"Complex", Const, 5}, + {"Denom", Func, 5}, + {"Float", Const, 5}, + {"Float32Val", Func, 5}, + {"Float64Val", Func, 5}, + {"Imag", Func, 5}, + {"Int", Const, 5}, + {"Int64Val", Func, 5}, + {"Kind", Type, 5}, + {"Make", Func, 13}, + {"MakeBool", Func, 5}, + {"MakeFloat64", Func, 5}, + {"MakeFromBytes", Func, 5}, + {"MakeFromLiteral", Func, 5}, + {"MakeImag", Func, 5}, + {"MakeInt64", Func, 5}, + {"MakeString", Func, 5}, + {"MakeUint64", Func, 5}, + {"MakeUnknown", Func, 5}, + {"Num", Func, 5}, + {"Real", Func, 5}, + {"Shift", Func, 5}, + {"Sign", Func, 5}, + {"String", Const, 5}, + {"StringVal", Func, 5}, + {"ToComplex", Func, 6}, + {"ToFloat", Func, 6}, + {"ToInt", Func, 6}, + {"Uint64Val", Func, 5}, + {"UnaryOp", Func, 5}, + {"Unknown", Const, 5}, + {"Val", Func, 13}, + {"Value", Type, 5}, + }, + "go/doc": { + {"(*Package).Filter", Method, 0}, + {"(*Package).HTML", Method, 19}, + {"(*Package).Markdown", Method, 19}, + {"(*Package).Parser", Method, 19}, + {"(*Package).Printer", Method, 19}, + {"(*Package).Synopsis", Method, 19}, + {"(*Package).Text", Method, 19}, + {"AllDecls", Const, 0}, + {"AllMethods", Const, 0}, + {"Example", Type, 0}, + {"Example.Code", Field, 0}, + {"Example.Comments", Field, 0}, + {"Example.Doc", Field, 0}, + {"Example.EmptyOutput", Field, 1}, + {"Example.Name", Field, 0}, + {"Example.Order", Field, 1}, + {"Example.Output", Field, 0}, + {"Example.Play", Field, 1}, + {"Example.Suffix", Field, 14}, + {"Example.Unordered", Field, 7}, + {"Examples", Func, 0}, + {"Filter", Type, 0}, + {"Func", Type, 0}, + {"Func.Decl", Field, 0}, + {"Func.Doc", Field, 0}, + {"Func.Examples", Field, 14}, + {"Func.Level", Field, 0}, + {"Func.Name", Field, 0}, + {"Func.Orig", Field, 0}, + {"Func.Recv", Field, 0}, + {"IllegalPrefixes", Var, 1}, + {"IsPredeclared", Func, 8}, + {"Mode", Type, 0}, + {"New", Func, 0}, + {"NewFromFiles", Func, 14}, + {"Note", Type, 1}, + {"Note.Body", Field, 1}, + {"Note.End", Field, 1}, + {"Note.Pos", Field, 1}, + {"Note.UID", Field, 1}, + {"Package", Type, 0}, + {"Package.Bugs", Field, 0}, + {"Package.Consts", Field, 0}, + {"Package.Doc", Field, 0}, + {"Package.Examples", Field, 14}, + {"Package.Filenames", Field, 0}, + {"Package.Funcs", Field, 0}, + {"Package.ImportPath", Field, 0}, + {"Package.Imports", Field, 0}, + {"Package.Name", Field, 0}, + {"Package.Notes", Field, 1}, + {"Package.Types", Field, 0}, + {"Package.Vars", Field, 0}, + {"PreserveAST", Const, 12}, + {"Synopsis", Func, 0}, + {"ToHTML", Func, 0}, + {"ToText", Func, 0}, + {"Type", Type, 0}, + {"Type.Consts", Field, 0}, + {"Type.Decl", Field, 0}, + {"Type.Doc", Field, 0}, + {"Type.Examples", Field, 14}, + {"Type.Funcs", Field, 0}, + {"Type.Methods", Field, 0}, + {"Type.Name", Field, 0}, + {"Type.Vars", Field, 0}, + {"Value", Type, 0}, + {"Value.Decl", Field, 0}, + {"Value.Doc", Field, 0}, + {"Value.Names", Field, 0}, + }, + "go/doc/comment": { + {"(*DocLink).DefaultURL", Method, 19}, + {"(*Heading).DefaultID", Method, 19}, + {"(*List).BlankBefore", Method, 19}, + {"(*List).BlankBetween", Method, 19}, + {"(*Parser).Parse", Method, 19}, + {"(*Printer).Comment", Method, 19}, + {"(*Printer).HTML", Method, 19}, + {"(*Printer).Markdown", Method, 19}, + {"(*Printer).Text", Method, 19}, + {"Block", Type, 19}, + {"Code", Type, 19}, + {"Code.Text", Field, 19}, + {"DefaultLookupPackage", Func, 19}, + {"Doc", Type, 19}, + {"Doc.Content", Field, 19}, + {"Doc.Links", Field, 19}, + {"DocLink", Type, 19}, + {"DocLink.ImportPath", Field, 19}, + {"DocLink.Name", Field, 19}, + {"DocLink.Recv", Field, 19}, + {"DocLink.Text", Field, 19}, + {"Heading", Type, 19}, + {"Heading.Text", Field, 19}, + {"Italic", Type, 19}, + {"Link", Type, 19}, + {"Link.Auto", Field, 19}, + {"Link.Text", Field, 19}, + {"Link.URL", Field, 19}, + {"LinkDef", Type, 19}, + {"LinkDef.Text", Field, 19}, + {"LinkDef.URL", Field, 19}, + {"LinkDef.Used", Field, 19}, + {"List", Type, 19}, + {"List.ForceBlankBefore", Field, 19}, + {"List.ForceBlankBetween", Field, 19}, + {"List.Items", Field, 19}, + {"ListItem", Type, 19}, + {"ListItem.Content", Field, 19}, + {"ListItem.Number", Field, 19}, + {"Paragraph", Type, 19}, + {"Paragraph.Text", Field, 19}, + {"Parser", Type, 19}, + {"Parser.LookupPackage", Field, 19}, + {"Parser.LookupSym", Field, 19}, + {"Parser.Words", Field, 19}, + {"Plain", Type, 19}, + {"Printer", Type, 19}, + {"Printer.DocLinkBaseURL", Field, 19}, + {"Printer.DocLinkURL", Field, 19}, + {"Printer.HeadingID", Field, 19}, + {"Printer.HeadingLevel", Field, 19}, + {"Printer.TextCodePrefix", Field, 19}, + {"Printer.TextPrefix", Field, 19}, + {"Printer.TextWidth", Field, 19}, + {"Text", Type, 19}, + }, + "go/format": { + {"Node", Func, 1}, + {"Source", Func, 1}, + }, + "go/importer": { + {"Default", Func, 5}, + {"For", Func, 5}, + {"ForCompiler", Func, 12}, + {"Lookup", Type, 5}, + }, + "go/parser": { + {"AllErrors", Const, 1}, + {"DeclarationErrors", Const, 0}, + {"ImportsOnly", Const, 0}, + {"Mode", Type, 0}, + {"PackageClauseOnly", Const, 0}, + {"ParseComments", Const, 0}, + {"ParseDir", Func, 0}, + {"ParseExpr", Func, 0}, + {"ParseExprFrom", Func, 5}, + {"ParseFile", Func, 0}, + {"SkipObjectResolution", Const, 17}, + {"SpuriousErrors", Const, 0}, + {"Trace", Const, 0}, + }, + "go/printer": { + {"(*Config).Fprint", Method, 0}, + {"CommentedNode", Type, 0}, + {"CommentedNode.Comments", Field, 0}, + {"CommentedNode.Node", Field, 0}, + {"Config", Type, 0}, + {"Config.Indent", Field, 1}, + {"Config.Mode", Field, 0}, + {"Config.Tabwidth", Field, 0}, + {"Fprint", Func, 0}, + {"Mode", Type, 0}, + {"RawFormat", Const, 0}, + {"SourcePos", Const, 0}, + {"TabIndent", Const, 0}, + {"UseSpaces", Const, 0}, + }, + "go/scanner": { + {"(*ErrorList).Add", Method, 0}, + {"(*ErrorList).RemoveMultiples", Method, 0}, + {"(*ErrorList).Reset", Method, 0}, + {"(*Scanner).Init", Method, 0}, + {"(*Scanner).Scan", Method, 0}, + {"(Error).Error", Method, 0}, + {"(ErrorList).Err", Method, 0}, + {"(ErrorList).Error", Method, 0}, + {"(ErrorList).Len", Method, 0}, + {"(ErrorList).Less", Method, 0}, + {"(ErrorList).Sort", Method, 0}, + {"(ErrorList).Swap", Method, 0}, + {"Error", Type, 0}, + {"Error.Msg", Field, 0}, + {"Error.Pos", Field, 0}, + {"ErrorHandler", Type, 0}, + {"ErrorList", Type, 0}, + {"Mode", Type, 0}, + {"PrintError", Func, 0}, + {"ScanComments", Const, 0}, + {"Scanner", Type, 0}, + {"Scanner.ErrorCount", Field, 0}, + }, + "go/token": { + {"(*File).AddLine", Method, 0}, + {"(*File).AddLineColumnInfo", Method, 11}, + {"(*File).AddLineInfo", Method, 0}, + {"(*File).Base", Method, 0}, + {"(*File).Line", Method, 0}, + {"(*File).LineCount", Method, 0}, + {"(*File).LineStart", Method, 12}, + {"(*File).Lines", Method, 21}, + {"(*File).MergeLine", Method, 2}, + {"(*File).Name", Method, 0}, + {"(*File).Offset", Method, 0}, + {"(*File).Pos", Method, 0}, + {"(*File).Position", Method, 0}, + {"(*File).PositionFor", Method, 4}, + {"(*File).SetLines", Method, 0}, + {"(*File).SetLinesForContent", Method, 0}, + {"(*File).Size", Method, 0}, + {"(*FileSet).AddFile", Method, 0}, + {"(*FileSet).Base", Method, 0}, + {"(*FileSet).File", Method, 0}, + {"(*FileSet).Iterate", Method, 0}, + {"(*FileSet).Position", Method, 0}, + {"(*FileSet).PositionFor", Method, 4}, + {"(*FileSet).Read", Method, 0}, + {"(*FileSet).RemoveFile", Method, 20}, + {"(*FileSet).Write", Method, 0}, + {"(*Position).IsValid", Method, 0}, + {"(Pos).IsValid", Method, 0}, + {"(Position).String", Method, 0}, + {"(Token).IsKeyword", Method, 0}, + {"(Token).IsLiteral", Method, 0}, + {"(Token).IsOperator", Method, 0}, + {"(Token).Precedence", Method, 0}, + {"(Token).String", Method, 0}, + {"ADD", Const, 0}, + {"ADD_ASSIGN", Const, 0}, + {"AND", Const, 0}, + {"AND_ASSIGN", Const, 0}, + {"AND_NOT", Const, 0}, + {"AND_NOT_ASSIGN", Const, 0}, + {"ARROW", Const, 0}, + {"ASSIGN", Const, 0}, + {"BREAK", Const, 0}, + {"CASE", Const, 0}, + {"CHAN", Const, 0}, + {"CHAR", Const, 0}, + {"COLON", Const, 0}, + {"COMMA", Const, 0}, + {"COMMENT", Const, 0}, + {"CONST", Const, 0}, + {"CONTINUE", Const, 0}, + {"DEC", Const, 0}, + {"DEFAULT", Const, 0}, + {"DEFER", Const, 0}, + {"DEFINE", Const, 0}, + {"ELLIPSIS", Const, 0}, + {"ELSE", Const, 0}, + {"EOF", Const, 0}, + {"EQL", Const, 0}, + {"FALLTHROUGH", Const, 0}, + {"FLOAT", Const, 0}, + {"FOR", Const, 0}, + {"FUNC", Const, 0}, + {"File", Type, 0}, + {"FileSet", Type, 0}, + {"GEQ", Const, 0}, + {"GO", Const, 0}, + {"GOTO", Const, 0}, + {"GTR", Const, 0}, + {"HighestPrec", Const, 0}, + {"IDENT", Const, 0}, + {"IF", Const, 0}, + {"ILLEGAL", Const, 0}, + {"IMAG", Const, 0}, + {"IMPORT", Const, 0}, + {"INC", Const, 0}, + {"INT", Const, 0}, + {"INTERFACE", Const, 0}, + {"IsExported", Func, 13}, + {"IsIdentifier", Func, 13}, + {"IsKeyword", Func, 13}, + {"LAND", Const, 0}, + {"LBRACE", Const, 0}, + {"LBRACK", Const, 0}, + {"LEQ", Const, 0}, + {"LOR", Const, 0}, + {"LPAREN", Const, 0}, + {"LSS", Const, 0}, + {"Lookup", Func, 0}, + {"LowestPrec", Const, 0}, + {"MAP", Const, 0}, + {"MUL", Const, 0}, + {"MUL_ASSIGN", Const, 0}, + {"NEQ", Const, 0}, + {"NOT", Const, 0}, + {"NewFileSet", Func, 0}, + {"NoPos", Const, 0}, + {"OR", Const, 0}, + {"OR_ASSIGN", Const, 0}, + {"PACKAGE", Const, 0}, + {"PERIOD", Const, 0}, + {"Pos", Type, 0}, + {"Position", Type, 0}, + {"Position.Column", Field, 0}, + {"Position.Filename", Field, 0}, + {"Position.Line", Field, 0}, + {"Position.Offset", Field, 0}, + {"QUO", Const, 0}, + {"QUO_ASSIGN", Const, 0}, + {"RANGE", Const, 0}, + {"RBRACE", Const, 0}, + {"RBRACK", Const, 0}, + {"REM", Const, 0}, + {"REM_ASSIGN", Const, 0}, + {"RETURN", Const, 0}, + {"RPAREN", Const, 0}, + {"SELECT", Const, 0}, + {"SEMICOLON", Const, 0}, + {"SHL", Const, 0}, + {"SHL_ASSIGN", Const, 0}, + {"SHR", Const, 0}, + {"SHR_ASSIGN", Const, 0}, + {"STRING", Const, 0}, + {"STRUCT", Const, 0}, + {"SUB", Const, 0}, + {"SUB_ASSIGN", Const, 0}, + {"SWITCH", Const, 0}, + {"TILDE", Const, 18}, + {"TYPE", Const, 0}, + {"Token", Type, 0}, + {"UnaryPrec", Const, 0}, + {"VAR", Const, 0}, + {"XOR", Const, 0}, + {"XOR_ASSIGN", Const, 0}, + }, + "go/types": { + {"(*Alias).Obj", Method, 22}, + {"(*Alias).String", Method, 22}, + {"(*Alias).Underlying", Method, 22}, + {"(*ArgumentError).Error", Method, 18}, + {"(*ArgumentError).Unwrap", Method, 18}, + {"(*Array).Elem", Method, 5}, + {"(*Array).Len", Method, 5}, + {"(*Array).String", Method, 5}, + {"(*Array).Underlying", Method, 5}, + {"(*Basic).Info", Method, 5}, + {"(*Basic).Kind", Method, 5}, + {"(*Basic).Name", Method, 5}, + {"(*Basic).String", Method, 5}, + {"(*Basic).Underlying", Method, 5}, + {"(*Builtin).Exported", Method, 5}, + {"(*Builtin).Id", Method, 5}, + {"(*Builtin).Name", Method, 5}, + {"(*Builtin).Parent", Method, 5}, + {"(*Builtin).Pkg", Method, 5}, + {"(*Builtin).Pos", Method, 5}, + {"(*Builtin).String", Method, 5}, + {"(*Builtin).Type", Method, 5}, + {"(*Chan).Dir", Method, 5}, + {"(*Chan).Elem", Method, 5}, + {"(*Chan).String", Method, 5}, + {"(*Chan).Underlying", Method, 5}, + {"(*Checker).Files", Method, 5}, + {"(*Config).Check", Method, 5}, + {"(*Const).Exported", Method, 5}, + {"(*Const).Id", Method, 5}, + {"(*Const).Name", Method, 5}, + {"(*Const).Parent", Method, 5}, + {"(*Const).Pkg", Method, 5}, + {"(*Const).Pos", Method, 5}, + {"(*Const).String", Method, 5}, + {"(*Const).Type", Method, 5}, + {"(*Const).Val", Method, 5}, + {"(*Func).Exported", Method, 5}, + {"(*Func).FullName", Method, 5}, + {"(*Func).Id", Method, 5}, + {"(*Func).Name", Method, 5}, + {"(*Func).Origin", Method, 19}, + {"(*Func).Parent", Method, 5}, + {"(*Func).Pkg", Method, 5}, + {"(*Func).Pos", Method, 5}, + {"(*Func).Scope", Method, 5}, + {"(*Func).String", Method, 5}, + {"(*Func).Type", Method, 5}, + {"(*Info).ObjectOf", Method, 5}, + {"(*Info).PkgNameOf", Method, 22}, + {"(*Info).TypeOf", Method, 5}, + {"(*Initializer).String", Method, 5}, + {"(*Interface).Complete", Method, 5}, + {"(*Interface).Embedded", Method, 5}, + {"(*Interface).EmbeddedType", Method, 11}, + {"(*Interface).Empty", Method, 5}, + {"(*Interface).ExplicitMethod", Method, 5}, + {"(*Interface).IsComparable", Method, 18}, + {"(*Interface).IsImplicit", Method, 18}, + {"(*Interface).IsMethodSet", Method, 18}, + {"(*Interface).MarkImplicit", Method, 18}, + {"(*Interface).Method", Method, 5}, + {"(*Interface).NumEmbeddeds", Method, 5}, + {"(*Interface).NumExplicitMethods", Method, 5}, + {"(*Interface).NumMethods", Method, 5}, + {"(*Interface).String", Method, 5}, + {"(*Interface).Underlying", Method, 5}, + {"(*Label).Exported", Method, 5}, + {"(*Label).Id", Method, 5}, + {"(*Label).Name", Method, 5}, + {"(*Label).Parent", Method, 5}, + {"(*Label).Pkg", Method, 5}, + {"(*Label).Pos", Method, 5}, + {"(*Label).String", Method, 5}, + {"(*Label).Type", Method, 5}, + {"(*Map).Elem", Method, 5}, + {"(*Map).Key", Method, 5}, + {"(*Map).String", Method, 5}, + {"(*Map).Underlying", Method, 5}, + {"(*MethodSet).At", Method, 5}, + {"(*MethodSet).Len", Method, 5}, + {"(*MethodSet).Lookup", Method, 5}, + {"(*MethodSet).String", Method, 5}, + {"(*Named).AddMethod", Method, 5}, + {"(*Named).Method", Method, 5}, + {"(*Named).NumMethods", Method, 5}, + {"(*Named).Obj", Method, 5}, + {"(*Named).Origin", Method, 18}, + {"(*Named).SetTypeParams", Method, 18}, + {"(*Named).SetUnderlying", Method, 5}, + {"(*Named).String", Method, 5}, + {"(*Named).TypeArgs", Method, 18}, + {"(*Named).TypeParams", Method, 18}, + {"(*Named).Underlying", Method, 5}, + {"(*Nil).Exported", Method, 5}, + {"(*Nil).Id", Method, 5}, + {"(*Nil).Name", Method, 5}, + {"(*Nil).Parent", Method, 5}, + {"(*Nil).Pkg", Method, 5}, + {"(*Nil).Pos", Method, 5}, + {"(*Nil).String", Method, 5}, + {"(*Nil).Type", Method, 5}, + {"(*Package).Complete", Method, 5}, + {"(*Package).GoVersion", Method, 21}, + {"(*Package).Imports", Method, 5}, + {"(*Package).MarkComplete", Method, 5}, + {"(*Package).Name", Method, 5}, + {"(*Package).Path", Method, 5}, + {"(*Package).Scope", Method, 5}, + {"(*Package).SetImports", Method, 5}, + {"(*Package).SetName", Method, 6}, + {"(*Package).String", Method, 5}, + {"(*PkgName).Exported", Method, 5}, + {"(*PkgName).Id", Method, 5}, + {"(*PkgName).Imported", Method, 5}, + {"(*PkgName).Name", Method, 5}, + {"(*PkgName).Parent", Method, 5}, + {"(*PkgName).Pkg", Method, 5}, + {"(*PkgName).Pos", Method, 5}, + {"(*PkgName).String", Method, 5}, + {"(*PkgName).Type", Method, 5}, + {"(*Pointer).Elem", Method, 5}, + {"(*Pointer).String", Method, 5}, + {"(*Pointer).Underlying", Method, 5}, + {"(*Scope).Child", Method, 5}, + {"(*Scope).Contains", Method, 5}, + {"(*Scope).End", Method, 5}, + {"(*Scope).Innermost", Method, 5}, + {"(*Scope).Insert", Method, 5}, + {"(*Scope).Len", Method, 5}, + {"(*Scope).Lookup", Method, 5}, + {"(*Scope).LookupParent", Method, 5}, + {"(*Scope).Names", Method, 5}, + {"(*Scope).NumChildren", Method, 5}, + {"(*Scope).Parent", Method, 5}, + {"(*Scope).Pos", Method, 5}, + {"(*Scope).String", Method, 5}, + {"(*Scope).WriteTo", Method, 5}, + {"(*Selection).Index", Method, 5}, + {"(*Selection).Indirect", Method, 5}, + {"(*Selection).Kind", Method, 5}, + {"(*Selection).Obj", Method, 5}, + {"(*Selection).Recv", Method, 5}, + {"(*Selection).String", Method, 5}, + {"(*Selection).Type", Method, 5}, + {"(*Signature).Params", Method, 5}, + {"(*Signature).Recv", Method, 5}, + {"(*Signature).RecvTypeParams", Method, 18}, + {"(*Signature).Results", Method, 5}, + {"(*Signature).String", Method, 5}, + {"(*Signature).TypeParams", Method, 18}, + {"(*Signature).Underlying", Method, 5}, + {"(*Signature).Variadic", Method, 5}, + {"(*Slice).Elem", Method, 5}, + {"(*Slice).String", Method, 5}, + {"(*Slice).Underlying", Method, 5}, + {"(*StdSizes).Alignof", Method, 5}, + {"(*StdSizes).Offsetsof", Method, 5}, + {"(*StdSizes).Sizeof", Method, 5}, + {"(*Struct).Field", Method, 5}, + {"(*Struct).NumFields", Method, 5}, + {"(*Struct).String", Method, 5}, + {"(*Struct).Tag", Method, 5}, + {"(*Struct).Underlying", Method, 5}, + {"(*Term).String", Method, 18}, + {"(*Term).Tilde", Method, 18}, + {"(*Term).Type", Method, 18}, + {"(*Tuple).At", Method, 5}, + {"(*Tuple).Len", Method, 5}, + {"(*Tuple).String", Method, 5}, + {"(*Tuple).Underlying", Method, 5}, + {"(*TypeList).At", Method, 18}, + {"(*TypeList).Len", Method, 18}, + {"(*TypeName).Exported", Method, 5}, + {"(*TypeName).Id", Method, 5}, + {"(*TypeName).IsAlias", Method, 9}, + {"(*TypeName).Name", Method, 5}, + {"(*TypeName).Parent", Method, 5}, + {"(*TypeName).Pkg", Method, 5}, + {"(*TypeName).Pos", Method, 5}, + {"(*TypeName).String", Method, 5}, + {"(*TypeName).Type", Method, 5}, + {"(*TypeParam).Constraint", Method, 18}, + {"(*TypeParam).Index", Method, 18}, + {"(*TypeParam).Obj", Method, 18}, + {"(*TypeParam).SetConstraint", Method, 18}, + {"(*TypeParam).String", Method, 18}, + {"(*TypeParam).Underlying", Method, 18}, + {"(*TypeParamList).At", Method, 18}, + {"(*TypeParamList).Len", Method, 18}, + {"(*Union).Len", Method, 18}, + {"(*Union).String", Method, 18}, + {"(*Union).Term", Method, 18}, + {"(*Union).Underlying", Method, 18}, + {"(*Var).Anonymous", Method, 5}, + {"(*Var).Embedded", Method, 11}, + {"(*Var).Exported", Method, 5}, + {"(*Var).Id", Method, 5}, + {"(*Var).IsField", Method, 5}, + {"(*Var).Name", Method, 5}, + {"(*Var).Origin", Method, 19}, + {"(*Var).Parent", Method, 5}, + {"(*Var).Pkg", Method, 5}, + {"(*Var).Pos", Method, 5}, + {"(*Var).String", Method, 5}, + {"(*Var).Type", Method, 5}, + {"(Checker).ObjectOf", Method, 5}, + {"(Checker).PkgNameOf", Method, 22}, + {"(Checker).TypeOf", Method, 5}, + {"(Error).Error", Method, 5}, + {"(TypeAndValue).Addressable", Method, 5}, + {"(TypeAndValue).Assignable", Method, 5}, + {"(TypeAndValue).HasOk", Method, 5}, + {"(TypeAndValue).IsBuiltin", Method, 5}, + {"(TypeAndValue).IsNil", Method, 5}, + {"(TypeAndValue).IsType", Method, 5}, + {"(TypeAndValue).IsValue", Method, 5}, + {"(TypeAndValue).IsVoid", Method, 5}, + {"Alias", Type, 22}, + {"ArgumentError", Type, 18}, + {"ArgumentError.Err", Field, 18}, + {"ArgumentError.Index", Field, 18}, + {"Array", Type, 5}, + {"AssertableTo", Func, 5}, + {"AssignableTo", Func, 5}, + {"Basic", Type, 5}, + {"BasicInfo", Type, 5}, + {"BasicKind", Type, 5}, + {"Bool", Const, 5}, + {"Builtin", Type, 5}, + {"Byte", Const, 5}, + {"Chan", Type, 5}, + {"ChanDir", Type, 5}, + {"CheckExpr", Func, 13}, + {"Checker", Type, 5}, + {"Checker.Info", Field, 5}, + {"Comparable", Func, 5}, + {"Complex128", Const, 5}, + {"Complex64", Const, 5}, + {"Config", Type, 5}, + {"Config.Context", Field, 18}, + {"Config.DisableUnusedImportCheck", Field, 5}, + {"Config.Error", Field, 5}, + {"Config.FakeImportC", Field, 5}, + {"Config.GoVersion", Field, 18}, + {"Config.IgnoreFuncBodies", Field, 5}, + {"Config.Importer", Field, 5}, + {"Config.Sizes", Field, 5}, + {"Const", Type, 5}, + {"Context", Type, 18}, + {"ConvertibleTo", Func, 5}, + {"DefPredeclaredTestFuncs", Func, 5}, + {"Default", Func, 8}, + {"Error", Type, 5}, + {"Error.Fset", Field, 5}, + {"Error.Msg", Field, 5}, + {"Error.Pos", Field, 5}, + {"Error.Soft", Field, 5}, + {"Eval", Func, 5}, + {"ExprString", Func, 5}, + {"FieldVal", Const, 5}, + {"Float32", Const, 5}, + {"Float64", Const, 5}, + {"Func", Type, 5}, + {"Id", Func, 5}, + {"Identical", Func, 5}, + {"IdenticalIgnoreTags", Func, 8}, + {"Implements", Func, 5}, + {"ImportMode", Type, 6}, + {"Importer", Type, 5}, + {"ImporterFrom", Type, 6}, + {"Info", Type, 5}, + {"Info.Defs", Field, 5}, + {"Info.FileVersions", Field, 22}, + {"Info.Implicits", Field, 5}, + {"Info.InitOrder", Field, 5}, + {"Info.Instances", Field, 18}, + {"Info.Scopes", Field, 5}, + {"Info.Selections", Field, 5}, + {"Info.Types", Field, 5}, + {"Info.Uses", Field, 5}, + {"Initializer", Type, 5}, + {"Initializer.Lhs", Field, 5}, + {"Initializer.Rhs", Field, 5}, + {"Instance", Type, 18}, + {"Instance.Type", Field, 18}, + {"Instance.TypeArgs", Field, 18}, + {"Instantiate", Func, 18}, + {"Int", Const, 5}, + {"Int16", Const, 5}, + {"Int32", Const, 5}, + {"Int64", Const, 5}, + {"Int8", Const, 5}, + {"Interface", Type, 5}, + {"Invalid", Const, 5}, + {"IsBoolean", Const, 5}, + {"IsComplex", Const, 5}, + {"IsConstType", Const, 5}, + {"IsFloat", Const, 5}, + {"IsInteger", Const, 5}, + {"IsInterface", Func, 5}, + {"IsNumeric", Const, 5}, + {"IsOrdered", Const, 5}, + {"IsString", Const, 5}, + {"IsUnsigned", Const, 5}, + {"IsUntyped", Const, 5}, + {"Label", Type, 5}, + {"LookupFieldOrMethod", Func, 5}, + {"Map", Type, 5}, + {"MethodExpr", Const, 5}, + {"MethodSet", Type, 5}, + {"MethodVal", Const, 5}, + {"MissingMethod", Func, 5}, + {"Named", Type, 5}, + {"NewAlias", Func, 22}, + {"NewArray", Func, 5}, + {"NewChan", Func, 5}, + {"NewChecker", Func, 5}, + {"NewConst", Func, 5}, + {"NewContext", Func, 18}, + {"NewField", Func, 5}, + {"NewFunc", Func, 5}, + {"NewInterface", Func, 5}, + {"NewInterfaceType", Func, 11}, + {"NewLabel", Func, 5}, + {"NewMap", Func, 5}, + {"NewMethodSet", Func, 5}, + {"NewNamed", Func, 5}, + {"NewPackage", Func, 5}, + {"NewParam", Func, 5}, + {"NewPkgName", Func, 5}, + {"NewPointer", Func, 5}, + {"NewScope", Func, 5}, + {"NewSignature", Func, 5}, + {"NewSignatureType", Func, 18}, + {"NewSlice", Func, 5}, + {"NewStruct", Func, 5}, + {"NewTerm", Func, 18}, + {"NewTuple", Func, 5}, + {"NewTypeName", Func, 5}, + {"NewTypeParam", Func, 18}, + {"NewUnion", Func, 18}, + {"NewVar", Func, 5}, + {"Nil", Type, 5}, + {"Object", Type, 5}, + {"ObjectString", Func, 5}, + {"Package", Type, 5}, + {"PkgName", Type, 5}, + {"Pointer", Type, 5}, + {"Qualifier", Type, 5}, + {"RecvOnly", Const, 5}, + {"RelativeTo", Func, 5}, + {"Rune", Const, 5}, + {"Satisfies", Func, 20}, + {"Scope", Type, 5}, + {"Selection", Type, 5}, + {"SelectionKind", Type, 5}, + {"SelectionString", Func, 5}, + {"SendOnly", Const, 5}, + {"SendRecv", Const, 5}, + {"Signature", Type, 5}, + {"Sizes", Type, 5}, + {"SizesFor", Func, 9}, + {"Slice", Type, 5}, + {"StdSizes", Type, 5}, + {"StdSizes.MaxAlign", Field, 5}, + {"StdSizes.WordSize", Field, 5}, + {"String", Const, 5}, + {"Struct", Type, 5}, + {"Term", Type, 18}, + {"Tuple", Type, 5}, + {"Typ", Var, 5}, + {"Type", Type, 5}, + {"TypeAndValue", Type, 5}, + {"TypeAndValue.Type", Field, 5}, + {"TypeAndValue.Value", Field, 5}, + {"TypeList", Type, 18}, + {"TypeName", Type, 5}, + {"TypeParam", Type, 18}, + {"TypeParamList", Type, 18}, + {"TypeString", Func, 5}, + {"Uint", Const, 5}, + {"Uint16", Const, 5}, + {"Uint32", Const, 5}, + {"Uint64", Const, 5}, + {"Uint8", Const, 5}, + {"Uintptr", Const, 5}, + {"Unalias", Func, 22}, + {"Union", Type, 18}, + {"Universe", Var, 5}, + {"Unsafe", Var, 5}, + {"UnsafePointer", Const, 5}, + {"UntypedBool", Const, 5}, + {"UntypedComplex", Const, 5}, + {"UntypedFloat", Const, 5}, + {"UntypedInt", Const, 5}, + {"UntypedNil", Const, 5}, + {"UntypedRune", Const, 5}, + {"UntypedString", Const, 5}, + {"Var", Type, 5}, + {"WriteExpr", Func, 5}, + {"WriteSignature", Func, 5}, + {"WriteType", Func, 5}, + }, + "go/version": { + {"Compare", Func, 22}, + {"IsValid", Func, 22}, + {"Lang", Func, 22}, + }, + "hash": { + {"Hash", Type, 0}, + {"Hash32", Type, 0}, + {"Hash64", Type, 0}, + }, + "hash/adler32": { + {"Checksum", Func, 0}, + {"New", Func, 0}, + {"Size", Const, 0}, + }, + "hash/crc32": { + {"Castagnoli", Const, 0}, + {"Checksum", Func, 0}, + {"ChecksumIEEE", Func, 0}, + {"IEEE", Const, 0}, + {"IEEETable", Var, 0}, + {"Koopman", Const, 0}, + {"MakeTable", Func, 0}, + {"New", Func, 0}, + {"NewIEEE", Func, 0}, + {"Size", Const, 0}, + {"Table", Type, 0}, + {"Update", Func, 0}, + }, + "hash/crc64": { + {"Checksum", Func, 0}, + {"ECMA", Const, 0}, + {"ISO", Const, 0}, + {"MakeTable", Func, 0}, + {"New", Func, 0}, + {"Size", Const, 0}, + {"Table", Type, 0}, + {"Update", Func, 0}, + }, + "hash/fnv": { + {"New128", Func, 9}, + {"New128a", Func, 9}, + {"New32", Func, 0}, + {"New32a", Func, 0}, + {"New64", Func, 0}, + {"New64a", Func, 0}, + }, + "hash/maphash": { + {"(*Hash).BlockSize", Method, 14}, + {"(*Hash).Reset", Method, 14}, + {"(*Hash).Seed", Method, 14}, + {"(*Hash).SetSeed", Method, 14}, + {"(*Hash).Size", Method, 14}, + {"(*Hash).Sum", Method, 14}, + {"(*Hash).Sum64", Method, 14}, + {"(*Hash).Write", Method, 14}, + {"(*Hash).WriteByte", Method, 14}, + {"(*Hash).WriteString", Method, 14}, + {"Bytes", Func, 19}, + {"Hash", Type, 14}, + {"MakeSeed", Func, 14}, + {"Seed", Type, 14}, + {"String", Func, 19}, + }, + "html": { + {"EscapeString", Func, 0}, + {"UnescapeString", Func, 0}, + }, + "html/template": { + {"(*Error).Error", Method, 0}, + {"(*Template).AddParseTree", Method, 0}, + {"(*Template).Clone", Method, 0}, + {"(*Template).DefinedTemplates", Method, 6}, + {"(*Template).Delims", Method, 0}, + {"(*Template).Execute", Method, 0}, + {"(*Template).ExecuteTemplate", Method, 0}, + {"(*Template).Funcs", Method, 0}, + {"(*Template).Lookup", Method, 0}, + {"(*Template).Name", Method, 0}, + {"(*Template).New", Method, 0}, + {"(*Template).Option", Method, 5}, + {"(*Template).Parse", Method, 0}, + {"(*Template).ParseFS", Method, 16}, + {"(*Template).ParseFiles", Method, 0}, + {"(*Template).ParseGlob", Method, 0}, + {"(*Template).Templates", Method, 0}, + {"CSS", Type, 0}, + {"ErrAmbigContext", Const, 0}, + {"ErrBadHTML", Const, 0}, + {"ErrBranchEnd", Const, 0}, + {"ErrEndContext", Const, 0}, + {"ErrJSTemplate", Const, 21}, + {"ErrNoSuchTemplate", Const, 0}, + {"ErrOutputContext", Const, 0}, + {"ErrPartialCharset", Const, 0}, + {"ErrPartialEscape", Const, 0}, + {"ErrPredefinedEscaper", Const, 9}, + {"ErrRangeLoopReentry", Const, 0}, + {"ErrSlashAmbig", Const, 0}, + {"Error", Type, 0}, + {"Error.Description", Field, 0}, + {"Error.ErrorCode", Field, 0}, + {"Error.Line", Field, 0}, + {"Error.Name", Field, 0}, + {"Error.Node", Field, 4}, + {"ErrorCode", Type, 0}, + {"FuncMap", Type, 0}, + {"HTML", Type, 0}, + {"HTMLAttr", Type, 0}, + {"HTMLEscape", Func, 0}, + {"HTMLEscapeString", Func, 0}, + {"HTMLEscaper", Func, 0}, + {"IsTrue", Func, 6}, + {"JS", Type, 0}, + {"JSEscape", Func, 0}, + {"JSEscapeString", Func, 0}, + {"JSEscaper", Func, 0}, + {"JSStr", Type, 0}, + {"Must", Func, 0}, + {"New", Func, 0}, + {"OK", Const, 0}, + {"ParseFS", Func, 16}, + {"ParseFiles", Func, 0}, + {"ParseGlob", Func, 0}, + {"Srcset", Type, 10}, + {"Template", Type, 0}, + {"Template.Tree", Field, 2}, + {"URL", Type, 0}, + {"URLQueryEscaper", Func, 0}, + }, + "image": { + {"(*Alpha).AlphaAt", Method, 4}, + {"(*Alpha).At", Method, 0}, + {"(*Alpha).Bounds", Method, 0}, + {"(*Alpha).ColorModel", Method, 0}, + {"(*Alpha).Opaque", Method, 0}, + {"(*Alpha).PixOffset", Method, 0}, + {"(*Alpha).RGBA64At", Method, 17}, + {"(*Alpha).Set", Method, 0}, + {"(*Alpha).SetAlpha", Method, 0}, + {"(*Alpha).SetRGBA64", Method, 17}, + {"(*Alpha).SubImage", Method, 0}, + {"(*Alpha16).Alpha16At", Method, 4}, + {"(*Alpha16).At", Method, 0}, + {"(*Alpha16).Bounds", Method, 0}, + {"(*Alpha16).ColorModel", Method, 0}, + {"(*Alpha16).Opaque", Method, 0}, + {"(*Alpha16).PixOffset", Method, 0}, + {"(*Alpha16).RGBA64At", Method, 17}, + {"(*Alpha16).Set", Method, 0}, + {"(*Alpha16).SetAlpha16", Method, 0}, + {"(*Alpha16).SetRGBA64", Method, 17}, + {"(*Alpha16).SubImage", Method, 0}, + {"(*CMYK).At", Method, 5}, + {"(*CMYK).Bounds", Method, 5}, + {"(*CMYK).CMYKAt", Method, 5}, + {"(*CMYK).ColorModel", Method, 5}, + {"(*CMYK).Opaque", Method, 5}, + {"(*CMYK).PixOffset", Method, 5}, + {"(*CMYK).RGBA64At", Method, 17}, + {"(*CMYK).Set", Method, 5}, + {"(*CMYK).SetCMYK", Method, 5}, + {"(*CMYK).SetRGBA64", Method, 17}, + {"(*CMYK).SubImage", Method, 5}, + {"(*Gray).At", Method, 0}, + {"(*Gray).Bounds", Method, 0}, + {"(*Gray).ColorModel", Method, 0}, + {"(*Gray).GrayAt", Method, 4}, + {"(*Gray).Opaque", Method, 0}, + {"(*Gray).PixOffset", Method, 0}, + {"(*Gray).RGBA64At", Method, 17}, + {"(*Gray).Set", Method, 0}, + {"(*Gray).SetGray", Method, 0}, + {"(*Gray).SetRGBA64", Method, 17}, + {"(*Gray).SubImage", Method, 0}, + {"(*Gray16).At", Method, 0}, + {"(*Gray16).Bounds", Method, 0}, + {"(*Gray16).ColorModel", Method, 0}, + {"(*Gray16).Gray16At", Method, 4}, + {"(*Gray16).Opaque", Method, 0}, + {"(*Gray16).PixOffset", Method, 0}, + {"(*Gray16).RGBA64At", Method, 17}, + {"(*Gray16).Set", Method, 0}, + {"(*Gray16).SetGray16", Method, 0}, + {"(*Gray16).SetRGBA64", Method, 17}, + {"(*Gray16).SubImage", Method, 0}, + {"(*NRGBA).At", Method, 0}, + {"(*NRGBA).Bounds", Method, 0}, + {"(*NRGBA).ColorModel", Method, 0}, + {"(*NRGBA).NRGBAAt", Method, 4}, + {"(*NRGBA).Opaque", Method, 0}, + {"(*NRGBA).PixOffset", Method, 0}, + {"(*NRGBA).RGBA64At", Method, 17}, + {"(*NRGBA).Set", Method, 0}, + {"(*NRGBA).SetNRGBA", Method, 0}, + {"(*NRGBA).SetRGBA64", Method, 17}, + {"(*NRGBA).SubImage", Method, 0}, + {"(*NRGBA64).At", Method, 0}, + {"(*NRGBA64).Bounds", Method, 0}, + {"(*NRGBA64).ColorModel", Method, 0}, + {"(*NRGBA64).NRGBA64At", Method, 4}, + {"(*NRGBA64).Opaque", Method, 0}, + {"(*NRGBA64).PixOffset", Method, 0}, + {"(*NRGBA64).RGBA64At", Method, 17}, + {"(*NRGBA64).Set", Method, 0}, + {"(*NRGBA64).SetNRGBA64", Method, 0}, + {"(*NRGBA64).SetRGBA64", Method, 17}, + {"(*NRGBA64).SubImage", Method, 0}, + {"(*NYCbCrA).AOffset", Method, 6}, + {"(*NYCbCrA).At", Method, 6}, + {"(*NYCbCrA).Bounds", Method, 6}, + {"(*NYCbCrA).COffset", Method, 6}, + {"(*NYCbCrA).ColorModel", Method, 6}, + {"(*NYCbCrA).NYCbCrAAt", Method, 6}, + {"(*NYCbCrA).Opaque", Method, 6}, + {"(*NYCbCrA).RGBA64At", Method, 17}, + {"(*NYCbCrA).SubImage", Method, 6}, + {"(*NYCbCrA).YCbCrAt", Method, 6}, + {"(*NYCbCrA).YOffset", Method, 6}, + {"(*Paletted).At", Method, 0}, + {"(*Paletted).Bounds", Method, 0}, + {"(*Paletted).ColorIndexAt", Method, 0}, + {"(*Paletted).ColorModel", Method, 0}, + {"(*Paletted).Opaque", Method, 0}, + {"(*Paletted).PixOffset", Method, 0}, + {"(*Paletted).RGBA64At", Method, 17}, + {"(*Paletted).Set", Method, 0}, + {"(*Paletted).SetColorIndex", Method, 0}, + {"(*Paletted).SetRGBA64", Method, 17}, + {"(*Paletted).SubImage", Method, 0}, + {"(*RGBA).At", Method, 0}, + {"(*RGBA).Bounds", Method, 0}, + {"(*RGBA).ColorModel", Method, 0}, + {"(*RGBA).Opaque", Method, 0}, + {"(*RGBA).PixOffset", Method, 0}, + {"(*RGBA).RGBA64At", Method, 17}, + {"(*RGBA).RGBAAt", Method, 4}, + {"(*RGBA).Set", Method, 0}, + {"(*RGBA).SetRGBA", Method, 0}, + {"(*RGBA).SetRGBA64", Method, 17}, + {"(*RGBA).SubImage", Method, 0}, + {"(*RGBA64).At", Method, 0}, + {"(*RGBA64).Bounds", Method, 0}, + {"(*RGBA64).ColorModel", Method, 0}, + {"(*RGBA64).Opaque", Method, 0}, + {"(*RGBA64).PixOffset", Method, 0}, + {"(*RGBA64).RGBA64At", Method, 4}, + {"(*RGBA64).Set", Method, 0}, + {"(*RGBA64).SetRGBA64", Method, 0}, + {"(*RGBA64).SubImage", Method, 0}, + {"(*Uniform).At", Method, 0}, + {"(*Uniform).Bounds", Method, 0}, + {"(*Uniform).ColorModel", Method, 0}, + {"(*Uniform).Convert", Method, 0}, + {"(*Uniform).Opaque", Method, 0}, + {"(*Uniform).RGBA", Method, 0}, + {"(*Uniform).RGBA64At", Method, 17}, + {"(*YCbCr).At", Method, 0}, + {"(*YCbCr).Bounds", Method, 0}, + {"(*YCbCr).COffset", Method, 0}, + {"(*YCbCr).ColorModel", Method, 0}, + {"(*YCbCr).Opaque", Method, 0}, + {"(*YCbCr).RGBA64At", Method, 17}, + {"(*YCbCr).SubImage", Method, 0}, + {"(*YCbCr).YCbCrAt", Method, 4}, + {"(*YCbCr).YOffset", Method, 0}, + {"(Point).Add", Method, 0}, + {"(Point).Div", Method, 0}, + {"(Point).Eq", Method, 0}, + {"(Point).In", Method, 0}, + {"(Point).Mod", Method, 0}, + {"(Point).Mul", Method, 0}, + {"(Point).String", Method, 0}, + {"(Point).Sub", Method, 0}, + {"(Rectangle).Add", Method, 0}, + {"(Rectangle).At", Method, 5}, + {"(Rectangle).Bounds", Method, 5}, + {"(Rectangle).Canon", Method, 0}, + {"(Rectangle).ColorModel", Method, 5}, + {"(Rectangle).Dx", Method, 0}, + {"(Rectangle).Dy", Method, 0}, + {"(Rectangle).Empty", Method, 0}, + {"(Rectangle).Eq", Method, 0}, + {"(Rectangle).In", Method, 0}, + {"(Rectangle).Inset", Method, 0}, + {"(Rectangle).Intersect", Method, 0}, + {"(Rectangle).Overlaps", Method, 0}, + {"(Rectangle).RGBA64At", Method, 17}, + {"(Rectangle).Size", Method, 0}, + {"(Rectangle).String", Method, 0}, + {"(Rectangle).Sub", Method, 0}, + {"(Rectangle).Union", Method, 0}, + {"(YCbCrSubsampleRatio).String", Method, 0}, + {"Alpha", Type, 0}, + {"Alpha.Pix", Field, 0}, + {"Alpha.Rect", Field, 0}, + {"Alpha.Stride", Field, 0}, + {"Alpha16", Type, 0}, + {"Alpha16.Pix", Field, 0}, + {"Alpha16.Rect", Field, 0}, + {"Alpha16.Stride", Field, 0}, + {"Black", Var, 0}, + {"CMYK", Type, 5}, + {"CMYK.Pix", Field, 5}, + {"CMYK.Rect", Field, 5}, + {"CMYK.Stride", Field, 5}, + {"Config", Type, 0}, + {"Config.ColorModel", Field, 0}, + {"Config.Height", Field, 0}, + {"Config.Width", Field, 0}, + {"Decode", Func, 0}, + {"DecodeConfig", Func, 0}, + {"ErrFormat", Var, 0}, + {"Gray", Type, 0}, + {"Gray.Pix", Field, 0}, + {"Gray.Rect", Field, 0}, + {"Gray.Stride", Field, 0}, + {"Gray16", Type, 0}, + {"Gray16.Pix", Field, 0}, + {"Gray16.Rect", Field, 0}, + {"Gray16.Stride", Field, 0}, + {"Image", Type, 0}, + {"NRGBA", Type, 0}, + {"NRGBA.Pix", Field, 0}, + {"NRGBA.Rect", Field, 0}, + {"NRGBA.Stride", Field, 0}, + {"NRGBA64", Type, 0}, + {"NRGBA64.Pix", Field, 0}, + {"NRGBA64.Rect", Field, 0}, + {"NRGBA64.Stride", Field, 0}, + {"NYCbCrA", Type, 6}, + {"NYCbCrA.A", Field, 6}, + {"NYCbCrA.AStride", Field, 6}, + {"NYCbCrA.YCbCr", Field, 6}, + {"NewAlpha", Func, 0}, + {"NewAlpha16", Func, 0}, + {"NewCMYK", Func, 5}, + {"NewGray", Func, 0}, + {"NewGray16", Func, 0}, + {"NewNRGBA", Func, 0}, + {"NewNRGBA64", Func, 0}, + {"NewNYCbCrA", Func, 6}, + {"NewPaletted", Func, 0}, + {"NewRGBA", Func, 0}, + {"NewRGBA64", Func, 0}, + {"NewUniform", Func, 0}, + {"NewYCbCr", Func, 0}, + {"Opaque", Var, 0}, + {"Paletted", Type, 0}, + {"Paletted.Palette", Field, 0}, + {"Paletted.Pix", Field, 0}, + {"Paletted.Rect", Field, 0}, + {"Paletted.Stride", Field, 0}, + {"PalettedImage", Type, 0}, + {"Point", Type, 0}, + {"Point.X", Field, 0}, + {"Point.Y", Field, 0}, + {"Pt", Func, 0}, + {"RGBA", Type, 0}, + {"RGBA.Pix", Field, 0}, + {"RGBA.Rect", Field, 0}, + {"RGBA.Stride", Field, 0}, + {"RGBA64", Type, 0}, + {"RGBA64.Pix", Field, 0}, + {"RGBA64.Rect", Field, 0}, + {"RGBA64.Stride", Field, 0}, + {"RGBA64Image", Type, 17}, + {"Rect", Func, 0}, + {"Rectangle", Type, 0}, + {"Rectangle.Max", Field, 0}, + {"Rectangle.Min", Field, 0}, + {"RegisterFormat", Func, 0}, + {"Transparent", Var, 0}, + {"Uniform", Type, 0}, + {"Uniform.C", Field, 0}, + {"White", Var, 0}, + {"YCbCr", Type, 0}, + {"YCbCr.CStride", Field, 0}, + {"YCbCr.Cb", Field, 0}, + {"YCbCr.Cr", Field, 0}, + {"YCbCr.Rect", Field, 0}, + {"YCbCr.SubsampleRatio", Field, 0}, + {"YCbCr.Y", Field, 0}, + {"YCbCr.YStride", Field, 0}, + {"YCbCrSubsampleRatio", Type, 0}, + {"YCbCrSubsampleRatio410", Const, 5}, + {"YCbCrSubsampleRatio411", Const, 5}, + {"YCbCrSubsampleRatio420", Const, 0}, + {"YCbCrSubsampleRatio422", Const, 0}, + {"YCbCrSubsampleRatio440", Const, 1}, + {"YCbCrSubsampleRatio444", Const, 0}, + {"ZP", Var, 0}, + {"ZR", Var, 0}, + }, + "image/color": { + {"(Alpha).RGBA", Method, 0}, + {"(Alpha16).RGBA", Method, 0}, + {"(CMYK).RGBA", Method, 5}, + {"(Gray).RGBA", Method, 0}, + {"(Gray16).RGBA", Method, 0}, + {"(NRGBA).RGBA", Method, 0}, + {"(NRGBA64).RGBA", Method, 0}, + {"(NYCbCrA).RGBA", Method, 6}, + {"(Palette).Convert", Method, 0}, + {"(Palette).Index", Method, 0}, + {"(RGBA).RGBA", Method, 0}, + {"(RGBA64).RGBA", Method, 0}, + {"(YCbCr).RGBA", Method, 0}, + {"Alpha", Type, 0}, + {"Alpha.A", Field, 0}, + {"Alpha16", Type, 0}, + {"Alpha16.A", Field, 0}, + {"Alpha16Model", Var, 0}, + {"AlphaModel", Var, 0}, + {"Black", Var, 0}, + {"CMYK", Type, 5}, + {"CMYK.C", Field, 5}, + {"CMYK.K", Field, 5}, + {"CMYK.M", Field, 5}, + {"CMYK.Y", Field, 5}, + {"CMYKModel", Var, 5}, + {"CMYKToRGB", Func, 5}, + {"Color", Type, 0}, + {"Gray", Type, 0}, + {"Gray.Y", Field, 0}, + {"Gray16", Type, 0}, + {"Gray16.Y", Field, 0}, + {"Gray16Model", Var, 0}, + {"GrayModel", Var, 0}, + {"Model", Type, 0}, + {"ModelFunc", Func, 0}, + {"NRGBA", Type, 0}, + {"NRGBA.A", Field, 0}, + {"NRGBA.B", Field, 0}, + {"NRGBA.G", Field, 0}, + {"NRGBA.R", Field, 0}, + {"NRGBA64", Type, 0}, + {"NRGBA64.A", Field, 0}, + {"NRGBA64.B", Field, 0}, + {"NRGBA64.G", Field, 0}, + {"NRGBA64.R", Field, 0}, + {"NRGBA64Model", Var, 0}, + {"NRGBAModel", Var, 0}, + {"NYCbCrA", Type, 6}, + {"NYCbCrA.A", Field, 6}, + {"NYCbCrA.YCbCr", Field, 6}, + {"NYCbCrAModel", Var, 6}, + {"Opaque", Var, 0}, + {"Palette", Type, 0}, + {"RGBA", Type, 0}, + {"RGBA.A", Field, 0}, + {"RGBA.B", Field, 0}, + {"RGBA.G", Field, 0}, + {"RGBA.R", Field, 0}, + {"RGBA64", Type, 0}, + {"RGBA64.A", Field, 0}, + {"RGBA64.B", Field, 0}, + {"RGBA64.G", Field, 0}, + {"RGBA64.R", Field, 0}, + {"RGBA64Model", Var, 0}, + {"RGBAModel", Var, 0}, + {"RGBToCMYK", Func, 5}, + {"RGBToYCbCr", Func, 0}, + {"Transparent", Var, 0}, + {"White", Var, 0}, + {"YCbCr", Type, 0}, + {"YCbCr.Cb", Field, 0}, + {"YCbCr.Cr", Field, 0}, + {"YCbCr.Y", Field, 0}, + {"YCbCrModel", Var, 0}, + {"YCbCrToRGB", Func, 0}, + }, + "image/color/palette": { + {"Plan9", Var, 2}, + {"WebSafe", Var, 2}, + }, + "image/draw": { + {"(Op).Draw", Method, 2}, + {"Draw", Func, 0}, + {"DrawMask", Func, 0}, + {"Drawer", Type, 2}, + {"FloydSteinberg", Var, 2}, + {"Image", Type, 0}, + {"Op", Type, 0}, + {"Over", Const, 0}, + {"Quantizer", Type, 2}, + {"RGBA64Image", Type, 17}, + {"Src", Const, 0}, + }, + "image/gif": { + {"Decode", Func, 0}, + {"DecodeAll", Func, 0}, + {"DecodeConfig", Func, 0}, + {"DisposalBackground", Const, 5}, + {"DisposalNone", Const, 5}, + {"DisposalPrevious", Const, 5}, + {"Encode", Func, 2}, + {"EncodeAll", Func, 2}, + {"GIF", Type, 0}, + {"GIF.BackgroundIndex", Field, 5}, + {"GIF.Config", Field, 5}, + {"GIF.Delay", Field, 0}, + {"GIF.Disposal", Field, 5}, + {"GIF.Image", Field, 0}, + {"GIF.LoopCount", Field, 0}, + {"Options", Type, 2}, + {"Options.Drawer", Field, 2}, + {"Options.NumColors", Field, 2}, + {"Options.Quantizer", Field, 2}, + }, + "image/jpeg": { + {"(FormatError).Error", Method, 0}, + {"(UnsupportedError).Error", Method, 0}, + {"Decode", Func, 0}, + {"DecodeConfig", Func, 0}, + {"DefaultQuality", Const, 0}, + {"Encode", Func, 0}, + {"FormatError", Type, 0}, + {"Options", Type, 0}, + {"Options.Quality", Field, 0}, + {"Reader", Type, 0}, + {"UnsupportedError", Type, 0}, + }, + "image/png": { + {"(*Encoder).Encode", Method, 4}, + {"(FormatError).Error", Method, 0}, + {"(UnsupportedError).Error", Method, 0}, + {"BestCompression", Const, 4}, + {"BestSpeed", Const, 4}, + {"CompressionLevel", Type, 4}, + {"Decode", Func, 0}, + {"DecodeConfig", Func, 0}, + {"DefaultCompression", Const, 4}, + {"Encode", Func, 0}, + {"Encoder", Type, 4}, + {"Encoder.BufferPool", Field, 9}, + {"Encoder.CompressionLevel", Field, 4}, + {"EncoderBuffer", Type, 9}, + {"EncoderBufferPool", Type, 9}, + {"FormatError", Type, 0}, + {"NoCompression", Const, 4}, + {"UnsupportedError", Type, 0}, + }, + "index/suffixarray": { + {"(*Index).Bytes", Method, 0}, + {"(*Index).FindAllIndex", Method, 0}, + {"(*Index).Lookup", Method, 0}, + {"(*Index).Read", Method, 0}, + {"(*Index).Write", Method, 0}, + {"Index", Type, 0}, + {"New", Func, 0}, + }, + "io": { + {"(*LimitedReader).Read", Method, 0}, + {"(*OffsetWriter).Seek", Method, 20}, + {"(*OffsetWriter).Write", Method, 20}, + {"(*OffsetWriter).WriteAt", Method, 20}, + {"(*PipeReader).Close", Method, 0}, + {"(*PipeReader).CloseWithError", Method, 0}, + {"(*PipeReader).Read", Method, 0}, + {"(*PipeWriter).Close", Method, 0}, + {"(*PipeWriter).CloseWithError", Method, 0}, + {"(*PipeWriter).Write", Method, 0}, + {"(*SectionReader).Outer", Method, 22}, + {"(*SectionReader).Read", Method, 0}, + {"(*SectionReader).ReadAt", Method, 0}, + {"(*SectionReader).Seek", Method, 0}, + {"(*SectionReader).Size", Method, 0}, + {"ByteReader", Type, 0}, + {"ByteScanner", Type, 0}, + {"ByteWriter", Type, 1}, + {"Closer", Type, 0}, + {"Copy", Func, 0}, + {"CopyBuffer", Func, 5}, + {"CopyN", Func, 0}, + {"Discard", Var, 16}, + {"EOF", Var, 0}, + {"ErrClosedPipe", Var, 0}, + {"ErrNoProgress", Var, 1}, + {"ErrShortBuffer", Var, 0}, + {"ErrShortWrite", Var, 0}, + {"ErrUnexpectedEOF", Var, 0}, + {"LimitReader", Func, 0}, + {"LimitedReader", Type, 0}, + {"LimitedReader.N", Field, 0}, + {"LimitedReader.R", Field, 0}, + {"MultiReader", Func, 0}, + {"MultiWriter", Func, 0}, + {"NewOffsetWriter", Func, 20}, + {"NewSectionReader", Func, 0}, + {"NopCloser", Func, 16}, + {"OffsetWriter", Type, 20}, + {"Pipe", Func, 0}, + {"PipeReader", Type, 0}, + {"PipeWriter", Type, 0}, + {"ReadAll", Func, 16}, + {"ReadAtLeast", Func, 0}, + {"ReadCloser", Type, 0}, + {"ReadFull", Func, 0}, + {"ReadSeekCloser", Type, 16}, + {"ReadSeeker", Type, 0}, + {"ReadWriteCloser", Type, 0}, + {"ReadWriteSeeker", Type, 0}, + {"ReadWriter", Type, 0}, + {"Reader", Type, 0}, + {"ReaderAt", Type, 0}, + {"ReaderFrom", Type, 0}, + {"RuneReader", Type, 0}, + {"RuneScanner", Type, 0}, + {"SectionReader", Type, 0}, + {"SeekCurrent", Const, 7}, + {"SeekEnd", Const, 7}, + {"SeekStart", Const, 7}, + {"Seeker", Type, 0}, + {"StringWriter", Type, 12}, + {"TeeReader", Func, 0}, + {"WriteCloser", Type, 0}, + {"WriteSeeker", Type, 0}, + {"WriteString", Func, 0}, + {"Writer", Type, 0}, + {"WriterAt", Type, 0}, + {"WriterTo", Type, 0}, + }, + "io/fs": { + {"(*PathError).Error", Method, 16}, + {"(*PathError).Timeout", Method, 16}, + {"(*PathError).Unwrap", Method, 16}, + {"(FileMode).IsDir", Method, 16}, + {"(FileMode).IsRegular", Method, 16}, + {"(FileMode).Perm", Method, 16}, + {"(FileMode).String", Method, 16}, + {"(FileMode).Type", Method, 16}, + {"DirEntry", Type, 16}, + {"ErrClosed", Var, 16}, + {"ErrExist", Var, 16}, + {"ErrInvalid", Var, 16}, + {"ErrNotExist", Var, 16}, + {"ErrPermission", Var, 16}, + {"FS", Type, 16}, + {"File", Type, 16}, + {"FileInfo", Type, 16}, + {"FileInfoToDirEntry", Func, 17}, + {"FileMode", Type, 16}, + {"FormatDirEntry", Func, 21}, + {"FormatFileInfo", Func, 21}, + {"Glob", Func, 16}, + {"GlobFS", Type, 16}, + {"ModeAppend", Const, 16}, + {"ModeCharDevice", Const, 16}, + {"ModeDevice", Const, 16}, + {"ModeDir", Const, 16}, + {"ModeExclusive", Const, 16}, + {"ModeIrregular", Const, 16}, + {"ModeNamedPipe", Const, 16}, + {"ModePerm", Const, 16}, + {"ModeSetgid", Const, 16}, + {"ModeSetuid", Const, 16}, + {"ModeSocket", Const, 16}, + {"ModeSticky", Const, 16}, + {"ModeSymlink", Const, 16}, + {"ModeTemporary", Const, 16}, + {"ModeType", Const, 16}, + {"PathError", Type, 16}, + {"PathError.Err", Field, 16}, + {"PathError.Op", Field, 16}, + {"PathError.Path", Field, 16}, + {"ReadDir", Func, 16}, + {"ReadDirFS", Type, 16}, + {"ReadDirFile", Type, 16}, + {"ReadFile", Func, 16}, + {"ReadFileFS", Type, 16}, + {"SkipAll", Var, 20}, + {"SkipDir", Var, 16}, + {"Stat", Func, 16}, + {"StatFS", Type, 16}, + {"Sub", Func, 16}, + {"SubFS", Type, 16}, + {"ValidPath", Func, 16}, + {"WalkDir", Func, 16}, + {"WalkDirFunc", Type, 16}, + }, + "io/ioutil": { + {"Discard", Var, 0}, + {"NopCloser", Func, 0}, + {"ReadAll", Func, 0}, + {"ReadDir", Func, 0}, + {"ReadFile", Func, 0}, + {"TempDir", Func, 0}, + {"TempFile", Func, 0}, + {"WriteFile", Func, 0}, + }, + "log": { + {"(*Logger).Fatal", Method, 0}, + {"(*Logger).Fatalf", Method, 0}, + {"(*Logger).Fatalln", Method, 0}, + {"(*Logger).Flags", Method, 0}, + {"(*Logger).Output", Method, 0}, + {"(*Logger).Panic", Method, 0}, + {"(*Logger).Panicf", Method, 0}, + {"(*Logger).Panicln", Method, 0}, + {"(*Logger).Prefix", Method, 0}, + {"(*Logger).Print", Method, 0}, + {"(*Logger).Printf", Method, 0}, + {"(*Logger).Println", Method, 0}, + {"(*Logger).SetFlags", Method, 0}, + {"(*Logger).SetOutput", Method, 5}, + {"(*Logger).SetPrefix", Method, 0}, + {"(*Logger).Writer", Method, 12}, + {"Default", Func, 16}, + {"Fatal", Func, 0}, + {"Fatalf", Func, 0}, + {"Fatalln", Func, 0}, + {"Flags", Func, 0}, + {"LUTC", Const, 5}, + {"Ldate", Const, 0}, + {"Llongfile", Const, 0}, + {"Lmicroseconds", Const, 0}, + {"Lmsgprefix", Const, 14}, + {"Logger", Type, 0}, + {"Lshortfile", Const, 0}, + {"LstdFlags", Const, 0}, + {"Ltime", Const, 0}, + {"New", Func, 0}, + {"Output", Func, 5}, + {"Panic", Func, 0}, + {"Panicf", Func, 0}, + {"Panicln", Func, 0}, + {"Prefix", Func, 0}, + {"Print", Func, 0}, + {"Printf", Func, 0}, + {"Println", Func, 0}, + {"SetFlags", Func, 0}, + {"SetOutput", Func, 0}, + {"SetPrefix", Func, 0}, + {"Writer", Func, 13}, + }, + "log/slog": { + {"(*JSONHandler).Enabled", Method, 21}, + {"(*JSONHandler).Handle", Method, 21}, + {"(*JSONHandler).WithAttrs", Method, 21}, + {"(*JSONHandler).WithGroup", Method, 21}, + {"(*Level).UnmarshalJSON", Method, 21}, + {"(*Level).UnmarshalText", Method, 21}, + {"(*LevelVar).Level", Method, 21}, + {"(*LevelVar).MarshalText", Method, 21}, + {"(*LevelVar).Set", Method, 21}, + {"(*LevelVar).String", Method, 21}, + {"(*LevelVar).UnmarshalText", Method, 21}, + {"(*Logger).Debug", Method, 21}, + {"(*Logger).DebugContext", Method, 21}, + {"(*Logger).Enabled", Method, 21}, + {"(*Logger).Error", Method, 21}, + {"(*Logger).ErrorContext", Method, 21}, + {"(*Logger).Handler", Method, 21}, + {"(*Logger).Info", Method, 21}, + {"(*Logger).InfoContext", Method, 21}, + {"(*Logger).Log", Method, 21}, + {"(*Logger).LogAttrs", Method, 21}, + {"(*Logger).Warn", Method, 21}, + {"(*Logger).WarnContext", Method, 21}, + {"(*Logger).With", Method, 21}, + {"(*Logger).WithGroup", Method, 21}, + {"(*Record).Add", Method, 21}, + {"(*Record).AddAttrs", Method, 21}, + {"(*TextHandler).Enabled", Method, 21}, + {"(*TextHandler).Handle", Method, 21}, + {"(*TextHandler).WithAttrs", Method, 21}, + {"(*TextHandler).WithGroup", Method, 21}, + {"(Attr).Equal", Method, 21}, + {"(Attr).String", Method, 21}, + {"(Kind).String", Method, 21}, + {"(Level).Level", Method, 21}, + {"(Level).MarshalJSON", Method, 21}, + {"(Level).MarshalText", Method, 21}, + {"(Level).String", Method, 21}, + {"(Record).Attrs", Method, 21}, + {"(Record).Clone", Method, 21}, + {"(Record).NumAttrs", Method, 21}, + {"(Value).Any", Method, 21}, + {"(Value).Bool", Method, 21}, + {"(Value).Duration", Method, 21}, + {"(Value).Equal", Method, 21}, + {"(Value).Float64", Method, 21}, + {"(Value).Group", Method, 21}, + {"(Value).Int64", Method, 21}, + {"(Value).Kind", Method, 21}, + {"(Value).LogValuer", Method, 21}, + {"(Value).Resolve", Method, 21}, + {"(Value).String", Method, 21}, + {"(Value).Time", Method, 21}, + {"(Value).Uint64", Method, 21}, + {"Any", Func, 21}, + {"AnyValue", Func, 21}, + {"Attr", Type, 21}, + {"Attr.Key", Field, 21}, + {"Attr.Value", Field, 21}, + {"Bool", Func, 21}, + {"BoolValue", Func, 21}, + {"Debug", Func, 21}, + {"DebugContext", Func, 21}, + {"Default", Func, 21}, + {"Duration", Func, 21}, + {"DurationValue", Func, 21}, + {"Error", Func, 21}, + {"ErrorContext", Func, 21}, + {"Float64", Func, 21}, + {"Float64Value", Func, 21}, + {"Group", Func, 21}, + {"GroupValue", Func, 21}, + {"Handler", Type, 21}, + {"HandlerOptions", Type, 21}, + {"HandlerOptions.AddSource", Field, 21}, + {"HandlerOptions.Level", Field, 21}, + {"HandlerOptions.ReplaceAttr", Field, 21}, + {"Info", Func, 21}, + {"InfoContext", Func, 21}, + {"Int", Func, 21}, + {"Int64", Func, 21}, + {"Int64Value", Func, 21}, + {"IntValue", Func, 21}, + {"JSONHandler", Type, 21}, + {"Kind", Type, 21}, + {"KindAny", Const, 21}, + {"KindBool", Const, 21}, + {"KindDuration", Const, 21}, + {"KindFloat64", Const, 21}, + {"KindGroup", Const, 21}, + {"KindInt64", Const, 21}, + {"KindLogValuer", Const, 21}, + {"KindString", Const, 21}, + {"KindTime", Const, 21}, + {"KindUint64", Const, 21}, + {"Level", Type, 21}, + {"LevelDebug", Const, 21}, + {"LevelError", Const, 21}, + {"LevelInfo", Const, 21}, + {"LevelKey", Const, 21}, + {"LevelVar", Type, 21}, + {"LevelWarn", Const, 21}, + {"Leveler", Type, 21}, + {"Log", Func, 21}, + {"LogAttrs", Func, 21}, + {"LogValuer", Type, 21}, + {"Logger", Type, 21}, + {"MessageKey", Const, 21}, + {"New", Func, 21}, + {"NewJSONHandler", Func, 21}, + {"NewLogLogger", Func, 21}, + {"NewRecord", Func, 21}, + {"NewTextHandler", Func, 21}, + {"Record", Type, 21}, + {"Record.Level", Field, 21}, + {"Record.Message", Field, 21}, + {"Record.PC", Field, 21}, + {"Record.Time", Field, 21}, + {"SetDefault", Func, 21}, + {"SetLogLoggerLevel", Func, 22}, + {"Source", Type, 21}, + {"Source.File", Field, 21}, + {"Source.Function", Field, 21}, + {"Source.Line", Field, 21}, + {"SourceKey", Const, 21}, + {"String", Func, 21}, + {"StringValue", Func, 21}, + {"TextHandler", Type, 21}, + {"Time", Func, 21}, + {"TimeKey", Const, 21}, + {"TimeValue", Func, 21}, + {"Uint64", Func, 21}, + {"Uint64Value", Func, 21}, + {"Value", Type, 21}, + {"Warn", Func, 21}, + {"WarnContext", Func, 21}, + {"With", Func, 21}, + }, + "log/syslog": { + {"(*Writer).Alert", Method, 0}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).Crit", Method, 0}, + {"(*Writer).Debug", Method, 0}, + {"(*Writer).Emerg", Method, 0}, + {"(*Writer).Err", Method, 0}, + {"(*Writer).Info", Method, 0}, + {"(*Writer).Notice", Method, 0}, + {"(*Writer).Warning", Method, 0}, + {"(*Writer).Write", Method, 0}, + {"Dial", Func, 0}, + {"LOG_ALERT", Const, 0}, + {"LOG_AUTH", Const, 1}, + {"LOG_AUTHPRIV", Const, 1}, + {"LOG_CRIT", Const, 0}, + {"LOG_CRON", Const, 1}, + {"LOG_DAEMON", Const, 1}, + {"LOG_DEBUG", Const, 0}, + {"LOG_EMERG", Const, 0}, + {"LOG_ERR", Const, 0}, + {"LOG_FTP", Const, 1}, + {"LOG_INFO", Const, 0}, + {"LOG_KERN", Const, 1}, + {"LOG_LOCAL0", Const, 1}, + {"LOG_LOCAL1", Const, 1}, + {"LOG_LOCAL2", Const, 1}, + {"LOG_LOCAL3", Const, 1}, + {"LOG_LOCAL4", Const, 1}, + {"LOG_LOCAL5", Const, 1}, + {"LOG_LOCAL6", Const, 1}, + {"LOG_LOCAL7", Const, 1}, + {"LOG_LPR", Const, 1}, + {"LOG_MAIL", Const, 1}, + {"LOG_NEWS", Const, 1}, + {"LOG_NOTICE", Const, 0}, + {"LOG_SYSLOG", Const, 1}, + {"LOG_USER", Const, 1}, + {"LOG_UUCP", Const, 1}, + {"LOG_WARNING", Const, 0}, + {"New", Func, 0}, + {"NewLogger", Func, 0}, + {"Priority", Type, 0}, + {"Writer", Type, 0}, + }, + "maps": { + {"Clone", Func, 21}, + {"Copy", Func, 21}, + {"DeleteFunc", Func, 21}, + {"Equal", Func, 21}, + {"EqualFunc", Func, 21}, + }, + "math": { + {"Abs", Func, 0}, + {"Acos", Func, 0}, + {"Acosh", Func, 0}, + {"Asin", Func, 0}, + {"Asinh", Func, 0}, + {"Atan", Func, 0}, + {"Atan2", Func, 0}, + {"Atanh", Func, 0}, + {"Cbrt", Func, 0}, + {"Ceil", Func, 0}, + {"Copysign", Func, 0}, + {"Cos", Func, 0}, + {"Cosh", Func, 0}, + {"Dim", Func, 0}, + {"E", Const, 0}, + {"Erf", Func, 0}, + {"Erfc", Func, 0}, + {"Erfcinv", Func, 10}, + {"Erfinv", Func, 10}, + {"Exp", Func, 0}, + {"Exp2", Func, 0}, + {"Expm1", Func, 0}, + {"FMA", Func, 14}, + {"Float32bits", Func, 0}, + {"Float32frombits", Func, 0}, + {"Float64bits", Func, 0}, + {"Float64frombits", Func, 0}, + {"Floor", Func, 0}, + {"Frexp", Func, 0}, + {"Gamma", Func, 0}, + {"Hypot", Func, 0}, + {"Ilogb", Func, 0}, + {"Inf", Func, 0}, + {"IsInf", Func, 0}, + {"IsNaN", Func, 0}, + {"J0", Func, 0}, + {"J1", Func, 0}, + {"Jn", Func, 0}, + {"Ldexp", Func, 0}, + {"Lgamma", Func, 0}, + {"Ln10", Const, 0}, + {"Ln2", Const, 0}, + {"Log", Func, 0}, + {"Log10", Func, 0}, + {"Log10E", Const, 0}, + {"Log1p", Func, 0}, + {"Log2", Func, 0}, + {"Log2E", Const, 0}, + {"Logb", Func, 0}, + {"Max", Func, 0}, + {"MaxFloat32", Const, 0}, + {"MaxFloat64", Const, 0}, + {"MaxInt", Const, 17}, + {"MaxInt16", Const, 0}, + {"MaxInt32", Const, 0}, + {"MaxInt64", Const, 0}, + {"MaxInt8", Const, 0}, + {"MaxUint", Const, 17}, + {"MaxUint16", Const, 0}, + {"MaxUint32", Const, 0}, + {"MaxUint64", Const, 0}, + {"MaxUint8", Const, 0}, + {"Min", Func, 0}, + {"MinInt", Const, 17}, + {"MinInt16", Const, 0}, + {"MinInt32", Const, 0}, + {"MinInt64", Const, 0}, + {"MinInt8", Const, 0}, + {"Mod", Func, 0}, + {"Modf", Func, 0}, + {"NaN", Func, 0}, + {"Nextafter", Func, 0}, + {"Nextafter32", Func, 4}, + {"Phi", Const, 0}, + {"Pi", Const, 0}, + {"Pow", Func, 0}, + {"Pow10", Func, 0}, + {"Remainder", Func, 0}, + {"Round", Func, 10}, + {"RoundToEven", Func, 10}, + {"Signbit", Func, 0}, + {"Sin", Func, 0}, + {"Sincos", Func, 0}, + {"Sinh", Func, 0}, + {"SmallestNonzeroFloat32", Const, 0}, + {"SmallestNonzeroFloat64", Const, 0}, + {"Sqrt", Func, 0}, + {"Sqrt2", Const, 0}, + {"SqrtE", Const, 0}, + {"SqrtPhi", Const, 0}, + {"SqrtPi", Const, 0}, + {"Tan", Func, 0}, + {"Tanh", Func, 0}, + {"Trunc", Func, 0}, + {"Y0", Func, 0}, + {"Y1", Func, 0}, + {"Yn", Func, 0}, + }, + "math/big": { + {"(*Float).Abs", Method, 5}, + {"(*Float).Acc", Method, 5}, + {"(*Float).Add", Method, 5}, + {"(*Float).Append", Method, 5}, + {"(*Float).Cmp", Method, 5}, + {"(*Float).Copy", Method, 5}, + {"(*Float).Float32", Method, 5}, + {"(*Float).Float64", Method, 5}, + {"(*Float).Format", Method, 5}, + {"(*Float).GobDecode", Method, 7}, + {"(*Float).GobEncode", Method, 7}, + {"(*Float).Int", Method, 5}, + {"(*Float).Int64", Method, 5}, + {"(*Float).IsInf", Method, 5}, + {"(*Float).IsInt", Method, 5}, + {"(*Float).MantExp", Method, 5}, + {"(*Float).MarshalText", Method, 6}, + {"(*Float).MinPrec", Method, 5}, + {"(*Float).Mode", Method, 5}, + {"(*Float).Mul", Method, 5}, + {"(*Float).Neg", Method, 5}, + {"(*Float).Parse", Method, 5}, + {"(*Float).Prec", Method, 5}, + {"(*Float).Quo", Method, 5}, + {"(*Float).Rat", Method, 5}, + {"(*Float).Scan", Method, 8}, + {"(*Float).Set", Method, 5}, + {"(*Float).SetFloat64", Method, 5}, + {"(*Float).SetInf", Method, 5}, + {"(*Float).SetInt", Method, 5}, + {"(*Float).SetInt64", Method, 5}, + {"(*Float).SetMantExp", Method, 5}, + {"(*Float).SetMode", Method, 5}, + {"(*Float).SetPrec", Method, 5}, + {"(*Float).SetRat", Method, 5}, + {"(*Float).SetString", Method, 5}, + {"(*Float).SetUint64", Method, 5}, + {"(*Float).Sign", Method, 5}, + {"(*Float).Signbit", Method, 5}, + {"(*Float).Sqrt", Method, 10}, + {"(*Float).String", Method, 5}, + {"(*Float).Sub", Method, 5}, + {"(*Float).Text", Method, 5}, + {"(*Float).Uint64", Method, 5}, + {"(*Float).UnmarshalText", Method, 6}, + {"(*Int).Abs", Method, 0}, + {"(*Int).Add", Method, 0}, + {"(*Int).And", Method, 0}, + {"(*Int).AndNot", Method, 0}, + {"(*Int).Append", Method, 6}, + {"(*Int).Binomial", Method, 0}, + {"(*Int).Bit", Method, 0}, + {"(*Int).BitLen", Method, 0}, + {"(*Int).Bits", Method, 0}, + {"(*Int).Bytes", Method, 0}, + {"(*Int).Cmp", Method, 0}, + {"(*Int).CmpAbs", Method, 10}, + {"(*Int).Div", Method, 0}, + {"(*Int).DivMod", Method, 0}, + {"(*Int).Exp", Method, 0}, + {"(*Int).FillBytes", Method, 15}, + {"(*Int).Float64", Method, 21}, + {"(*Int).Format", Method, 0}, + {"(*Int).GCD", Method, 0}, + {"(*Int).GobDecode", Method, 0}, + {"(*Int).GobEncode", Method, 0}, + {"(*Int).Int64", Method, 0}, + {"(*Int).IsInt64", Method, 9}, + {"(*Int).IsUint64", Method, 9}, + {"(*Int).Lsh", Method, 0}, + {"(*Int).MarshalJSON", Method, 1}, + {"(*Int).MarshalText", Method, 3}, + {"(*Int).Mod", Method, 0}, + {"(*Int).ModInverse", Method, 0}, + {"(*Int).ModSqrt", Method, 5}, + {"(*Int).Mul", Method, 0}, + {"(*Int).MulRange", Method, 0}, + {"(*Int).Neg", Method, 0}, + {"(*Int).Not", Method, 0}, + {"(*Int).Or", Method, 0}, + {"(*Int).ProbablyPrime", Method, 0}, + {"(*Int).Quo", Method, 0}, + {"(*Int).QuoRem", Method, 0}, + {"(*Int).Rand", Method, 0}, + {"(*Int).Rem", Method, 0}, + {"(*Int).Rsh", Method, 0}, + {"(*Int).Scan", Method, 0}, + {"(*Int).Set", Method, 0}, + {"(*Int).SetBit", Method, 0}, + {"(*Int).SetBits", Method, 0}, + {"(*Int).SetBytes", Method, 0}, + {"(*Int).SetInt64", Method, 0}, + {"(*Int).SetString", Method, 0}, + {"(*Int).SetUint64", Method, 1}, + {"(*Int).Sign", Method, 0}, + {"(*Int).Sqrt", Method, 8}, + {"(*Int).String", Method, 0}, + {"(*Int).Sub", Method, 0}, + {"(*Int).Text", Method, 6}, + {"(*Int).TrailingZeroBits", Method, 13}, + {"(*Int).Uint64", Method, 1}, + {"(*Int).UnmarshalJSON", Method, 1}, + {"(*Int).UnmarshalText", Method, 3}, + {"(*Int).Xor", Method, 0}, + {"(*Rat).Abs", Method, 0}, + {"(*Rat).Add", Method, 0}, + {"(*Rat).Cmp", Method, 0}, + {"(*Rat).Denom", Method, 0}, + {"(*Rat).Float32", Method, 4}, + {"(*Rat).Float64", Method, 1}, + {"(*Rat).FloatPrec", Method, 22}, + {"(*Rat).FloatString", Method, 0}, + {"(*Rat).GobDecode", Method, 0}, + {"(*Rat).GobEncode", Method, 0}, + {"(*Rat).Inv", Method, 0}, + {"(*Rat).IsInt", Method, 0}, + {"(*Rat).MarshalText", Method, 3}, + {"(*Rat).Mul", Method, 0}, + {"(*Rat).Neg", Method, 0}, + {"(*Rat).Num", Method, 0}, + {"(*Rat).Quo", Method, 0}, + {"(*Rat).RatString", Method, 0}, + {"(*Rat).Scan", Method, 0}, + {"(*Rat).Set", Method, 0}, + {"(*Rat).SetFloat64", Method, 1}, + {"(*Rat).SetFrac", Method, 0}, + {"(*Rat).SetFrac64", Method, 0}, + {"(*Rat).SetInt", Method, 0}, + {"(*Rat).SetInt64", Method, 0}, + {"(*Rat).SetString", Method, 0}, + {"(*Rat).SetUint64", Method, 13}, + {"(*Rat).Sign", Method, 0}, + {"(*Rat).String", Method, 0}, + {"(*Rat).Sub", Method, 0}, + {"(*Rat).UnmarshalText", Method, 3}, + {"(Accuracy).String", Method, 5}, + {"(ErrNaN).Error", Method, 5}, + {"(RoundingMode).String", Method, 5}, + {"Above", Const, 5}, + {"Accuracy", Type, 5}, + {"AwayFromZero", Const, 5}, + {"Below", Const, 5}, + {"ErrNaN", Type, 5}, + {"Exact", Const, 5}, + {"Float", Type, 5}, + {"Int", Type, 0}, + {"Jacobi", Func, 5}, + {"MaxBase", Const, 0}, + {"MaxExp", Const, 5}, + {"MaxPrec", Const, 5}, + {"MinExp", Const, 5}, + {"NewFloat", Func, 5}, + {"NewInt", Func, 0}, + {"NewRat", Func, 0}, + {"ParseFloat", Func, 5}, + {"Rat", Type, 0}, + {"RoundingMode", Type, 5}, + {"ToNearestAway", Const, 5}, + {"ToNearestEven", Const, 5}, + {"ToNegativeInf", Const, 5}, + {"ToPositiveInf", Const, 5}, + {"ToZero", Const, 5}, + {"Word", Type, 0}, + }, + "math/bits": { + {"Add", Func, 12}, + {"Add32", Func, 12}, + {"Add64", Func, 12}, + {"Div", Func, 12}, + {"Div32", Func, 12}, + {"Div64", Func, 12}, + {"LeadingZeros", Func, 9}, + {"LeadingZeros16", Func, 9}, + {"LeadingZeros32", Func, 9}, + {"LeadingZeros64", Func, 9}, + {"LeadingZeros8", Func, 9}, + {"Len", Func, 9}, + {"Len16", Func, 9}, + {"Len32", Func, 9}, + {"Len64", Func, 9}, + {"Len8", Func, 9}, + {"Mul", Func, 12}, + {"Mul32", Func, 12}, + {"Mul64", Func, 12}, + {"OnesCount", Func, 9}, + {"OnesCount16", Func, 9}, + {"OnesCount32", Func, 9}, + {"OnesCount64", Func, 9}, + {"OnesCount8", Func, 9}, + {"Rem", Func, 14}, + {"Rem32", Func, 14}, + {"Rem64", Func, 14}, + {"Reverse", Func, 9}, + {"Reverse16", Func, 9}, + {"Reverse32", Func, 9}, + {"Reverse64", Func, 9}, + {"Reverse8", Func, 9}, + {"ReverseBytes", Func, 9}, + {"ReverseBytes16", Func, 9}, + {"ReverseBytes32", Func, 9}, + {"ReverseBytes64", Func, 9}, + {"RotateLeft", Func, 9}, + {"RotateLeft16", Func, 9}, + {"RotateLeft32", Func, 9}, + {"RotateLeft64", Func, 9}, + {"RotateLeft8", Func, 9}, + {"Sub", Func, 12}, + {"Sub32", Func, 12}, + {"Sub64", Func, 12}, + {"TrailingZeros", Func, 9}, + {"TrailingZeros16", Func, 9}, + {"TrailingZeros32", Func, 9}, + {"TrailingZeros64", Func, 9}, + {"TrailingZeros8", Func, 9}, + {"UintSize", Const, 9}, + }, + "math/cmplx": { + {"Abs", Func, 0}, + {"Acos", Func, 0}, + {"Acosh", Func, 0}, + {"Asin", Func, 0}, + {"Asinh", Func, 0}, + {"Atan", Func, 0}, + {"Atanh", Func, 0}, + {"Conj", Func, 0}, + {"Cos", Func, 0}, + {"Cosh", Func, 0}, + {"Cot", Func, 0}, + {"Exp", Func, 0}, + {"Inf", Func, 0}, + {"IsInf", Func, 0}, + {"IsNaN", Func, 0}, + {"Log", Func, 0}, + {"Log10", Func, 0}, + {"NaN", Func, 0}, + {"Phase", Func, 0}, + {"Polar", Func, 0}, + {"Pow", Func, 0}, + {"Rect", Func, 0}, + {"Sin", Func, 0}, + {"Sinh", Func, 0}, + {"Sqrt", Func, 0}, + {"Tan", Func, 0}, + {"Tanh", Func, 0}, + }, + "math/rand": { + {"(*Rand).ExpFloat64", Method, 0}, + {"(*Rand).Float32", Method, 0}, + {"(*Rand).Float64", Method, 0}, + {"(*Rand).Int", Method, 0}, + {"(*Rand).Int31", Method, 0}, + {"(*Rand).Int31n", Method, 0}, + {"(*Rand).Int63", Method, 0}, + {"(*Rand).Int63n", Method, 0}, + {"(*Rand).Intn", Method, 0}, + {"(*Rand).NormFloat64", Method, 0}, + {"(*Rand).Perm", Method, 0}, + {"(*Rand).Read", Method, 6}, + {"(*Rand).Seed", Method, 0}, + {"(*Rand).Shuffle", Method, 10}, + {"(*Rand).Uint32", Method, 0}, + {"(*Rand).Uint64", Method, 8}, + {"(*Zipf).Uint64", Method, 0}, + {"ExpFloat64", Func, 0}, + {"Float32", Func, 0}, + {"Float64", Func, 0}, + {"Int", Func, 0}, + {"Int31", Func, 0}, + {"Int31n", Func, 0}, + {"Int63", Func, 0}, + {"Int63n", Func, 0}, + {"Intn", Func, 0}, + {"New", Func, 0}, + {"NewSource", Func, 0}, + {"NewZipf", Func, 0}, + {"NormFloat64", Func, 0}, + {"Perm", Func, 0}, + {"Rand", Type, 0}, + {"Read", Func, 6}, + {"Seed", Func, 0}, + {"Shuffle", Func, 10}, + {"Source", Type, 0}, + {"Source64", Type, 8}, + {"Uint32", Func, 0}, + {"Uint64", Func, 8}, + {"Zipf", Type, 0}, + }, + "math/rand/v2": { + {"(*ChaCha8).MarshalBinary", Method, 22}, + {"(*ChaCha8).Seed", Method, 22}, + {"(*ChaCha8).Uint64", Method, 22}, + {"(*ChaCha8).UnmarshalBinary", Method, 22}, + {"(*PCG).MarshalBinary", Method, 22}, + {"(*PCG).Seed", Method, 22}, + {"(*PCG).Uint64", Method, 22}, + {"(*PCG).UnmarshalBinary", Method, 22}, + {"(*Rand).ExpFloat64", Method, 22}, + {"(*Rand).Float32", Method, 22}, + {"(*Rand).Float64", Method, 22}, + {"(*Rand).Int", Method, 22}, + {"(*Rand).Int32", Method, 22}, + {"(*Rand).Int32N", Method, 22}, + {"(*Rand).Int64", Method, 22}, + {"(*Rand).Int64N", Method, 22}, + {"(*Rand).IntN", Method, 22}, + {"(*Rand).NormFloat64", Method, 22}, + {"(*Rand).Perm", Method, 22}, + {"(*Rand).Shuffle", Method, 22}, + {"(*Rand).Uint32", Method, 22}, + {"(*Rand).Uint32N", Method, 22}, + {"(*Rand).Uint64", Method, 22}, + {"(*Rand).Uint64N", Method, 22}, + {"(*Rand).UintN", Method, 22}, + {"(*Zipf).Uint64", Method, 22}, + {"ChaCha8", Type, 22}, + {"ExpFloat64", Func, 22}, + {"Float32", Func, 22}, + {"Float64", Func, 22}, + {"Int", Func, 22}, + {"Int32", Func, 22}, + {"Int32N", Func, 22}, + {"Int64", Func, 22}, + {"Int64N", Func, 22}, + {"IntN", Func, 22}, + {"N", Func, 22}, + {"New", Func, 22}, + {"NewChaCha8", Func, 22}, + {"NewPCG", Func, 22}, + {"NewZipf", Func, 22}, + {"NormFloat64", Func, 22}, + {"PCG", Type, 22}, + {"Perm", Func, 22}, + {"Rand", Type, 22}, + {"Shuffle", Func, 22}, + {"Source", Type, 22}, + {"Uint32", Func, 22}, + {"Uint32N", Func, 22}, + {"Uint64", Func, 22}, + {"Uint64N", Func, 22}, + {"UintN", Func, 22}, + {"Zipf", Type, 22}, + }, + "mime": { + {"(*WordDecoder).Decode", Method, 5}, + {"(*WordDecoder).DecodeHeader", Method, 5}, + {"(WordEncoder).Encode", Method, 5}, + {"AddExtensionType", Func, 0}, + {"BEncoding", Const, 5}, + {"ErrInvalidMediaParameter", Var, 9}, + {"ExtensionsByType", Func, 5}, + {"FormatMediaType", Func, 0}, + {"ParseMediaType", Func, 0}, + {"QEncoding", Const, 5}, + {"TypeByExtension", Func, 0}, + {"WordDecoder", Type, 5}, + {"WordDecoder.CharsetReader", Field, 5}, + {"WordEncoder", Type, 5}, + }, + "mime/multipart": { + {"(*FileHeader).Open", Method, 0}, + {"(*Form).RemoveAll", Method, 0}, + {"(*Part).Close", Method, 0}, + {"(*Part).FileName", Method, 0}, + {"(*Part).FormName", Method, 0}, + {"(*Part).Read", Method, 0}, + {"(*Reader).NextPart", Method, 0}, + {"(*Reader).NextRawPart", Method, 14}, + {"(*Reader).ReadForm", Method, 0}, + {"(*Writer).Boundary", Method, 0}, + {"(*Writer).Close", Method, 0}, + {"(*Writer).CreateFormField", Method, 0}, + {"(*Writer).CreateFormFile", Method, 0}, + {"(*Writer).CreatePart", Method, 0}, + {"(*Writer).FormDataContentType", Method, 0}, + {"(*Writer).SetBoundary", Method, 1}, + {"(*Writer).WriteField", Method, 0}, + {"ErrMessageTooLarge", Var, 9}, + {"File", Type, 0}, + {"FileHeader", Type, 0}, + {"FileHeader.Filename", Field, 0}, + {"FileHeader.Header", Field, 0}, + {"FileHeader.Size", Field, 9}, + {"Form", Type, 0}, + {"Form.File", Field, 0}, + {"Form.Value", Field, 0}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"Part", Type, 0}, + {"Part.Header", Field, 0}, + {"Reader", Type, 0}, + {"Writer", Type, 0}, + }, + "mime/quotedprintable": { + {"(*Reader).Read", Method, 5}, + {"(*Writer).Close", Method, 5}, + {"(*Writer).Write", Method, 5}, + {"NewReader", Func, 5}, + {"NewWriter", Func, 5}, + {"Reader", Type, 5}, + {"Writer", Type, 5}, + {"Writer.Binary", Field, 5}, + }, + "net": { + {"(*AddrError).Error", Method, 0}, + {"(*AddrError).Temporary", Method, 0}, + {"(*AddrError).Timeout", Method, 0}, + {"(*Buffers).Read", Method, 8}, + {"(*Buffers).WriteTo", Method, 8}, + {"(*DNSConfigError).Error", Method, 0}, + {"(*DNSConfigError).Temporary", Method, 0}, + {"(*DNSConfigError).Timeout", Method, 0}, + {"(*DNSConfigError).Unwrap", Method, 13}, + {"(*DNSError).Error", Method, 0}, + {"(*DNSError).Temporary", Method, 0}, + {"(*DNSError).Timeout", Method, 0}, + {"(*Dialer).Dial", Method, 1}, + {"(*Dialer).DialContext", Method, 7}, + {"(*Dialer).MultipathTCP", Method, 21}, + {"(*Dialer).SetMultipathTCP", Method, 21}, + {"(*IP).UnmarshalText", Method, 2}, + {"(*IPAddr).Network", Method, 0}, + {"(*IPAddr).String", Method, 0}, + {"(*IPConn).Close", Method, 0}, + {"(*IPConn).File", Method, 0}, + {"(*IPConn).LocalAddr", Method, 0}, + {"(*IPConn).Read", Method, 0}, + {"(*IPConn).ReadFrom", Method, 0}, + {"(*IPConn).ReadFromIP", Method, 0}, + {"(*IPConn).ReadMsgIP", Method, 1}, + {"(*IPConn).RemoteAddr", Method, 0}, + {"(*IPConn).SetDeadline", Method, 0}, + {"(*IPConn).SetReadBuffer", Method, 0}, + {"(*IPConn).SetReadDeadline", Method, 0}, + {"(*IPConn).SetWriteBuffer", Method, 0}, + {"(*IPConn).SetWriteDeadline", Method, 0}, + {"(*IPConn).SyscallConn", Method, 9}, + {"(*IPConn).Write", Method, 0}, + {"(*IPConn).WriteMsgIP", Method, 1}, + {"(*IPConn).WriteTo", Method, 0}, + {"(*IPConn).WriteToIP", Method, 0}, + {"(*IPNet).Contains", Method, 0}, + {"(*IPNet).Network", Method, 0}, + {"(*IPNet).String", Method, 0}, + {"(*Interface).Addrs", Method, 0}, + {"(*Interface).MulticastAddrs", Method, 0}, + {"(*ListenConfig).Listen", Method, 11}, + {"(*ListenConfig).ListenPacket", Method, 11}, + {"(*ListenConfig).MultipathTCP", Method, 21}, + {"(*ListenConfig).SetMultipathTCP", Method, 21}, + {"(*OpError).Error", Method, 0}, + {"(*OpError).Temporary", Method, 0}, + {"(*OpError).Timeout", Method, 0}, + {"(*OpError).Unwrap", Method, 13}, + {"(*ParseError).Error", Method, 0}, + {"(*ParseError).Temporary", Method, 17}, + {"(*ParseError).Timeout", Method, 17}, + {"(*Resolver).LookupAddr", Method, 8}, + {"(*Resolver).LookupCNAME", Method, 8}, + {"(*Resolver).LookupHost", Method, 8}, + {"(*Resolver).LookupIP", Method, 15}, + {"(*Resolver).LookupIPAddr", Method, 8}, + {"(*Resolver).LookupMX", Method, 8}, + {"(*Resolver).LookupNS", Method, 8}, + {"(*Resolver).LookupNetIP", Method, 18}, + {"(*Resolver).LookupPort", Method, 8}, + {"(*Resolver).LookupSRV", Method, 8}, + {"(*Resolver).LookupTXT", Method, 8}, + {"(*TCPAddr).AddrPort", Method, 18}, + {"(*TCPAddr).Network", Method, 0}, + {"(*TCPAddr).String", Method, 0}, + {"(*TCPConn).Close", Method, 0}, + {"(*TCPConn).CloseRead", Method, 0}, + {"(*TCPConn).CloseWrite", Method, 0}, + {"(*TCPConn).File", Method, 0}, + {"(*TCPConn).LocalAddr", Method, 0}, + {"(*TCPConn).MultipathTCP", Method, 21}, + {"(*TCPConn).Read", Method, 0}, + {"(*TCPConn).ReadFrom", Method, 0}, + {"(*TCPConn).RemoteAddr", Method, 0}, + {"(*TCPConn).SetDeadline", Method, 0}, + {"(*TCPConn).SetKeepAlive", Method, 0}, + {"(*TCPConn).SetKeepAlivePeriod", Method, 2}, + {"(*TCPConn).SetLinger", Method, 0}, + {"(*TCPConn).SetNoDelay", Method, 0}, + {"(*TCPConn).SetReadBuffer", Method, 0}, + {"(*TCPConn).SetReadDeadline", Method, 0}, + {"(*TCPConn).SetWriteBuffer", Method, 0}, + {"(*TCPConn).SetWriteDeadline", Method, 0}, + {"(*TCPConn).SyscallConn", Method, 9}, + {"(*TCPConn).Write", Method, 0}, + {"(*TCPConn).WriteTo", Method, 22}, + {"(*TCPListener).Accept", Method, 0}, + {"(*TCPListener).AcceptTCP", Method, 0}, + {"(*TCPListener).Addr", Method, 0}, + {"(*TCPListener).Close", Method, 0}, + {"(*TCPListener).File", Method, 0}, + {"(*TCPListener).SetDeadline", Method, 0}, + {"(*TCPListener).SyscallConn", Method, 10}, + {"(*UDPAddr).AddrPort", Method, 18}, + {"(*UDPAddr).Network", Method, 0}, + {"(*UDPAddr).String", Method, 0}, + {"(*UDPConn).Close", Method, 0}, + {"(*UDPConn).File", Method, 0}, + {"(*UDPConn).LocalAddr", Method, 0}, + {"(*UDPConn).Read", Method, 0}, + {"(*UDPConn).ReadFrom", Method, 0}, + {"(*UDPConn).ReadFromUDP", Method, 0}, + {"(*UDPConn).ReadFromUDPAddrPort", Method, 18}, + {"(*UDPConn).ReadMsgUDP", Method, 1}, + {"(*UDPConn).ReadMsgUDPAddrPort", Method, 18}, + {"(*UDPConn).RemoteAddr", Method, 0}, + {"(*UDPConn).SetDeadline", Method, 0}, + {"(*UDPConn).SetReadBuffer", Method, 0}, + {"(*UDPConn).SetReadDeadline", Method, 0}, + {"(*UDPConn).SetWriteBuffer", Method, 0}, + {"(*UDPConn).SetWriteDeadline", Method, 0}, + {"(*UDPConn).SyscallConn", Method, 9}, + {"(*UDPConn).Write", Method, 0}, + {"(*UDPConn).WriteMsgUDP", Method, 1}, + {"(*UDPConn).WriteMsgUDPAddrPort", Method, 18}, + {"(*UDPConn).WriteTo", Method, 0}, + {"(*UDPConn).WriteToUDP", Method, 0}, + {"(*UDPConn).WriteToUDPAddrPort", Method, 18}, + {"(*UnixAddr).Network", Method, 0}, + {"(*UnixAddr).String", Method, 0}, + {"(*UnixConn).Close", Method, 0}, + {"(*UnixConn).CloseRead", Method, 1}, + {"(*UnixConn).CloseWrite", Method, 1}, + {"(*UnixConn).File", Method, 0}, + {"(*UnixConn).LocalAddr", Method, 0}, + {"(*UnixConn).Read", Method, 0}, + {"(*UnixConn).ReadFrom", Method, 0}, + {"(*UnixConn).ReadFromUnix", Method, 0}, + {"(*UnixConn).ReadMsgUnix", Method, 0}, + {"(*UnixConn).RemoteAddr", Method, 0}, + {"(*UnixConn).SetDeadline", Method, 0}, + {"(*UnixConn).SetReadBuffer", Method, 0}, + {"(*UnixConn).SetReadDeadline", Method, 0}, + {"(*UnixConn).SetWriteBuffer", Method, 0}, + {"(*UnixConn).SetWriteDeadline", Method, 0}, + {"(*UnixConn).SyscallConn", Method, 9}, + {"(*UnixConn).Write", Method, 0}, + {"(*UnixConn).WriteMsgUnix", Method, 0}, + {"(*UnixConn).WriteTo", Method, 0}, + {"(*UnixConn).WriteToUnix", Method, 0}, + {"(*UnixListener).Accept", Method, 0}, + {"(*UnixListener).AcceptUnix", Method, 0}, + {"(*UnixListener).Addr", Method, 0}, + {"(*UnixListener).Close", Method, 0}, + {"(*UnixListener).File", Method, 0}, + {"(*UnixListener).SetDeadline", Method, 0}, + {"(*UnixListener).SetUnlinkOnClose", Method, 8}, + {"(*UnixListener).SyscallConn", Method, 10}, + {"(Flags).String", Method, 0}, + {"(HardwareAddr).String", Method, 0}, + {"(IP).DefaultMask", Method, 0}, + {"(IP).Equal", Method, 0}, + {"(IP).IsGlobalUnicast", Method, 0}, + {"(IP).IsInterfaceLocalMulticast", Method, 0}, + {"(IP).IsLinkLocalMulticast", Method, 0}, + {"(IP).IsLinkLocalUnicast", Method, 0}, + {"(IP).IsLoopback", Method, 0}, + {"(IP).IsMulticast", Method, 0}, + {"(IP).IsPrivate", Method, 17}, + {"(IP).IsUnspecified", Method, 0}, + {"(IP).MarshalText", Method, 2}, + {"(IP).Mask", Method, 0}, + {"(IP).String", Method, 0}, + {"(IP).To16", Method, 0}, + {"(IP).To4", Method, 0}, + {"(IPMask).Size", Method, 0}, + {"(IPMask).String", Method, 0}, + {"(InvalidAddrError).Error", Method, 0}, + {"(InvalidAddrError).Temporary", Method, 0}, + {"(InvalidAddrError).Timeout", Method, 0}, + {"(UnknownNetworkError).Error", Method, 0}, + {"(UnknownNetworkError).Temporary", Method, 0}, + {"(UnknownNetworkError).Timeout", Method, 0}, + {"Addr", Type, 0}, + {"AddrError", Type, 0}, + {"AddrError.Addr", Field, 0}, + {"AddrError.Err", Field, 0}, + {"Buffers", Type, 8}, + {"CIDRMask", Func, 0}, + {"Conn", Type, 0}, + {"DNSConfigError", Type, 0}, + {"DNSConfigError.Err", Field, 0}, + {"DNSError", Type, 0}, + {"DNSError.Err", Field, 0}, + {"DNSError.IsNotFound", Field, 13}, + {"DNSError.IsTemporary", Field, 6}, + {"DNSError.IsTimeout", Field, 0}, + {"DNSError.Name", Field, 0}, + {"DNSError.Server", Field, 0}, + {"DefaultResolver", Var, 8}, + {"Dial", Func, 0}, + {"DialIP", Func, 0}, + {"DialTCP", Func, 0}, + {"DialTimeout", Func, 0}, + {"DialUDP", Func, 0}, + {"DialUnix", Func, 0}, + {"Dialer", Type, 1}, + {"Dialer.Cancel", Field, 6}, + {"Dialer.Control", Field, 11}, + {"Dialer.ControlContext", Field, 20}, + {"Dialer.Deadline", Field, 1}, + {"Dialer.DualStack", Field, 2}, + {"Dialer.FallbackDelay", Field, 5}, + {"Dialer.KeepAlive", Field, 3}, + {"Dialer.LocalAddr", Field, 1}, + {"Dialer.Resolver", Field, 8}, + {"Dialer.Timeout", Field, 1}, + {"ErrClosed", Var, 16}, + {"ErrWriteToConnected", Var, 0}, + {"Error", Type, 0}, + {"FileConn", Func, 0}, + {"FileListener", Func, 0}, + {"FilePacketConn", Func, 0}, + {"FlagBroadcast", Const, 0}, + {"FlagLoopback", Const, 0}, + {"FlagMulticast", Const, 0}, + {"FlagPointToPoint", Const, 0}, + {"FlagRunning", Const, 20}, + {"FlagUp", Const, 0}, + {"Flags", Type, 0}, + {"HardwareAddr", Type, 0}, + {"IP", Type, 0}, + {"IPAddr", Type, 0}, + {"IPAddr.IP", Field, 0}, + {"IPAddr.Zone", Field, 1}, + {"IPConn", Type, 0}, + {"IPMask", Type, 0}, + {"IPNet", Type, 0}, + {"IPNet.IP", Field, 0}, + {"IPNet.Mask", Field, 0}, + {"IPv4", Func, 0}, + {"IPv4Mask", Func, 0}, + {"IPv4allrouter", Var, 0}, + {"IPv4allsys", Var, 0}, + {"IPv4bcast", Var, 0}, + {"IPv4len", Const, 0}, + {"IPv4zero", Var, 0}, + {"IPv6interfacelocalallnodes", Var, 0}, + {"IPv6len", Const, 0}, + {"IPv6linklocalallnodes", Var, 0}, + {"IPv6linklocalallrouters", Var, 0}, + {"IPv6loopback", Var, 0}, + {"IPv6unspecified", Var, 0}, + {"IPv6zero", Var, 0}, + {"Interface", Type, 0}, + {"Interface.Flags", Field, 0}, + {"Interface.HardwareAddr", Field, 0}, + {"Interface.Index", Field, 0}, + {"Interface.MTU", Field, 0}, + {"Interface.Name", Field, 0}, + {"InterfaceAddrs", Func, 0}, + {"InterfaceByIndex", Func, 0}, + {"InterfaceByName", Func, 0}, + {"Interfaces", Func, 0}, + {"InvalidAddrError", Type, 0}, + {"JoinHostPort", Func, 0}, + {"Listen", Func, 0}, + {"ListenConfig", Type, 11}, + {"ListenConfig.Control", Field, 11}, + {"ListenConfig.KeepAlive", Field, 13}, + {"ListenIP", Func, 0}, + {"ListenMulticastUDP", Func, 0}, + {"ListenPacket", Func, 0}, + {"ListenTCP", Func, 0}, + {"ListenUDP", Func, 0}, + {"ListenUnix", Func, 0}, + {"ListenUnixgram", Func, 0}, + {"Listener", Type, 0}, + {"LookupAddr", Func, 0}, + {"LookupCNAME", Func, 0}, + {"LookupHost", Func, 0}, + {"LookupIP", Func, 0}, + {"LookupMX", Func, 0}, + {"LookupNS", Func, 1}, + {"LookupPort", Func, 0}, + {"LookupSRV", Func, 0}, + {"LookupTXT", Func, 0}, + {"MX", Type, 0}, + {"MX.Host", Field, 0}, + {"MX.Pref", Field, 0}, + {"NS", Type, 1}, + {"NS.Host", Field, 1}, + {"OpError", Type, 0}, + {"OpError.Addr", Field, 0}, + {"OpError.Err", Field, 0}, + {"OpError.Net", Field, 0}, + {"OpError.Op", Field, 0}, + {"OpError.Source", Field, 5}, + {"PacketConn", Type, 0}, + {"ParseCIDR", Func, 0}, + {"ParseError", Type, 0}, + {"ParseError.Text", Field, 0}, + {"ParseError.Type", Field, 0}, + {"ParseIP", Func, 0}, + {"ParseMAC", Func, 0}, + {"Pipe", Func, 0}, + {"ResolveIPAddr", Func, 0}, + {"ResolveTCPAddr", Func, 0}, + {"ResolveUDPAddr", Func, 0}, + {"ResolveUnixAddr", Func, 0}, + {"Resolver", Type, 8}, + {"Resolver.Dial", Field, 9}, + {"Resolver.PreferGo", Field, 8}, + {"Resolver.StrictErrors", Field, 9}, + {"SRV", Type, 0}, + {"SRV.Port", Field, 0}, + {"SRV.Priority", Field, 0}, + {"SRV.Target", Field, 0}, + {"SRV.Weight", Field, 0}, + {"SplitHostPort", Func, 0}, + {"TCPAddr", Type, 0}, + {"TCPAddr.IP", Field, 0}, + {"TCPAddr.Port", Field, 0}, + {"TCPAddr.Zone", Field, 1}, + {"TCPAddrFromAddrPort", Func, 18}, + {"TCPConn", Type, 0}, + {"TCPListener", Type, 0}, + {"UDPAddr", Type, 0}, + {"UDPAddr.IP", Field, 0}, + {"UDPAddr.Port", Field, 0}, + {"UDPAddr.Zone", Field, 1}, + {"UDPAddrFromAddrPort", Func, 18}, + {"UDPConn", Type, 0}, + {"UnixAddr", Type, 0}, + {"UnixAddr.Name", Field, 0}, + {"UnixAddr.Net", Field, 0}, + {"UnixConn", Type, 0}, + {"UnixListener", Type, 0}, + {"UnknownNetworkError", Type, 0}, + }, + "net/http": { + {"(*Client).CloseIdleConnections", Method, 12}, + {"(*Client).Do", Method, 0}, + {"(*Client).Get", Method, 0}, + {"(*Client).Head", Method, 0}, + {"(*Client).Post", Method, 0}, + {"(*Client).PostForm", Method, 0}, + {"(*Cookie).String", Method, 0}, + {"(*Cookie).Valid", Method, 18}, + {"(*MaxBytesError).Error", Method, 19}, + {"(*ProtocolError).Error", Method, 0}, + {"(*ProtocolError).Is", Method, 21}, + {"(*Request).AddCookie", Method, 0}, + {"(*Request).BasicAuth", Method, 4}, + {"(*Request).Clone", Method, 13}, + {"(*Request).Context", Method, 7}, + {"(*Request).Cookie", Method, 0}, + {"(*Request).Cookies", Method, 0}, + {"(*Request).FormFile", Method, 0}, + {"(*Request).FormValue", Method, 0}, + {"(*Request).MultipartReader", Method, 0}, + {"(*Request).ParseForm", Method, 0}, + {"(*Request).ParseMultipartForm", Method, 0}, + {"(*Request).PathValue", Method, 22}, + {"(*Request).PostFormValue", Method, 1}, + {"(*Request).ProtoAtLeast", Method, 0}, + {"(*Request).Referer", Method, 0}, + {"(*Request).SetBasicAuth", Method, 0}, + {"(*Request).SetPathValue", Method, 22}, + {"(*Request).UserAgent", Method, 0}, + {"(*Request).WithContext", Method, 7}, + {"(*Request).Write", Method, 0}, + {"(*Request).WriteProxy", Method, 0}, + {"(*Response).Cookies", Method, 0}, + {"(*Response).Location", Method, 0}, + {"(*Response).ProtoAtLeast", Method, 0}, + {"(*Response).Write", Method, 0}, + {"(*ResponseController).EnableFullDuplex", Method, 21}, + {"(*ResponseController).Flush", Method, 20}, + {"(*ResponseController).Hijack", Method, 20}, + {"(*ResponseController).SetReadDeadline", Method, 20}, + {"(*ResponseController).SetWriteDeadline", Method, 20}, + {"(*ServeMux).Handle", Method, 0}, + {"(*ServeMux).HandleFunc", Method, 0}, + {"(*ServeMux).Handler", Method, 1}, + {"(*ServeMux).ServeHTTP", Method, 0}, + {"(*Server).Close", Method, 8}, + {"(*Server).ListenAndServe", Method, 0}, + {"(*Server).ListenAndServeTLS", Method, 0}, + {"(*Server).RegisterOnShutdown", Method, 9}, + {"(*Server).Serve", Method, 0}, + {"(*Server).ServeTLS", Method, 9}, + {"(*Server).SetKeepAlivesEnabled", Method, 3}, + {"(*Server).Shutdown", Method, 8}, + {"(*Transport).CancelRequest", Method, 1}, + {"(*Transport).Clone", Method, 13}, + {"(*Transport).CloseIdleConnections", Method, 0}, + {"(*Transport).RegisterProtocol", Method, 0}, + {"(*Transport).RoundTrip", Method, 0}, + {"(ConnState).String", Method, 3}, + {"(Dir).Open", Method, 0}, + {"(HandlerFunc).ServeHTTP", Method, 0}, + {"(Header).Add", Method, 0}, + {"(Header).Clone", Method, 13}, + {"(Header).Del", Method, 0}, + {"(Header).Get", Method, 0}, + {"(Header).Set", Method, 0}, + {"(Header).Values", Method, 14}, + {"(Header).Write", Method, 0}, + {"(Header).WriteSubset", Method, 0}, + {"AllowQuerySemicolons", Func, 17}, + {"CanonicalHeaderKey", Func, 0}, + {"Client", Type, 0}, + {"Client.CheckRedirect", Field, 0}, + {"Client.Jar", Field, 0}, + {"Client.Timeout", Field, 3}, + {"Client.Transport", Field, 0}, + {"CloseNotifier", Type, 1}, + {"ConnState", Type, 3}, + {"Cookie", Type, 0}, + {"Cookie.Domain", Field, 0}, + {"Cookie.Expires", Field, 0}, + {"Cookie.HttpOnly", Field, 0}, + {"Cookie.MaxAge", Field, 0}, + {"Cookie.Name", Field, 0}, + {"Cookie.Path", Field, 0}, + {"Cookie.Raw", Field, 0}, + {"Cookie.RawExpires", Field, 0}, + {"Cookie.SameSite", Field, 11}, + {"Cookie.Secure", Field, 0}, + {"Cookie.Unparsed", Field, 0}, + {"Cookie.Value", Field, 0}, + {"CookieJar", Type, 0}, + {"DefaultClient", Var, 0}, + {"DefaultMaxHeaderBytes", Const, 0}, + {"DefaultMaxIdleConnsPerHost", Const, 0}, + {"DefaultServeMux", Var, 0}, + {"DefaultTransport", Var, 0}, + {"DetectContentType", Func, 0}, + {"Dir", Type, 0}, + {"ErrAbortHandler", Var, 8}, + {"ErrBodyNotAllowed", Var, 0}, + {"ErrBodyReadAfterClose", Var, 0}, + {"ErrContentLength", Var, 0}, + {"ErrHandlerTimeout", Var, 0}, + {"ErrHeaderTooLong", Var, 0}, + {"ErrHijacked", Var, 0}, + {"ErrLineTooLong", Var, 0}, + {"ErrMissingBoundary", Var, 0}, + {"ErrMissingContentLength", Var, 0}, + {"ErrMissingFile", Var, 0}, + {"ErrNoCookie", Var, 0}, + {"ErrNoLocation", Var, 0}, + {"ErrNotMultipart", Var, 0}, + {"ErrNotSupported", Var, 0}, + {"ErrSchemeMismatch", Var, 21}, + {"ErrServerClosed", Var, 8}, + {"ErrShortBody", Var, 0}, + {"ErrSkipAltProtocol", Var, 6}, + {"ErrUnexpectedTrailer", Var, 0}, + {"ErrUseLastResponse", Var, 7}, + {"ErrWriteAfterFlush", Var, 0}, + {"Error", Func, 0}, + {"FS", Func, 16}, + {"File", Type, 0}, + {"FileServer", Func, 0}, + {"FileServerFS", Func, 22}, + {"FileSystem", Type, 0}, + {"Flusher", Type, 0}, + {"Get", Func, 0}, + {"Handle", Func, 0}, + {"HandleFunc", Func, 0}, + {"Handler", Type, 0}, + {"HandlerFunc", Type, 0}, + {"Head", Func, 0}, + {"Header", Type, 0}, + {"Hijacker", Type, 0}, + {"ListenAndServe", Func, 0}, + {"ListenAndServeTLS", Func, 0}, + {"LocalAddrContextKey", Var, 7}, + {"MaxBytesError", Type, 19}, + {"MaxBytesError.Limit", Field, 19}, + {"MaxBytesHandler", Func, 18}, + {"MaxBytesReader", Func, 0}, + {"MethodConnect", Const, 6}, + {"MethodDelete", Const, 6}, + {"MethodGet", Const, 6}, + {"MethodHead", Const, 6}, + {"MethodOptions", Const, 6}, + {"MethodPatch", Const, 6}, + {"MethodPost", Const, 6}, + {"MethodPut", Const, 6}, + {"MethodTrace", Const, 6}, + {"NewFileTransport", Func, 0}, + {"NewFileTransportFS", Func, 22}, + {"NewRequest", Func, 0}, + {"NewRequestWithContext", Func, 13}, + {"NewResponseController", Func, 20}, + {"NewServeMux", Func, 0}, + {"NoBody", Var, 8}, + {"NotFound", Func, 0}, + {"NotFoundHandler", Func, 0}, + {"ParseHTTPVersion", Func, 0}, + {"ParseTime", Func, 1}, + {"Post", Func, 0}, + {"PostForm", Func, 0}, + {"ProtocolError", Type, 0}, + {"ProtocolError.ErrorString", Field, 0}, + {"ProxyFromEnvironment", Func, 0}, + {"ProxyURL", Func, 0}, + {"PushOptions", Type, 8}, + {"PushOptions.Header", Field, 8}, + {"PushOptions.Method", Field, 8}, + {"Pusher", Type, 8}, + {"ReadRequest", Func, 0}, + {"ReadResponse", Func, 0}, + {"Redirect", Func, 0}, + {"RedirectHandler", Func, 0}, + {"Request", Type, 0}, + {"Request.Body", Field, 0}, + {"Request.Cancel", Field, 5}, + {"Request.Close", Field, 0}, + {"Request.ContentLength", Field, 0}, + {"Request.Form", Field, 0}, + {"Request.GetBody", Field, 8}, + {"Request.Header", Field, 0}, + {"Request.Host", Field, 0}, + {"Request.Method", Field, 0}, + {"Request.MultipartForm", Field, 0}, + {"Request.PostForm", Field, 1}, + {"Request.Proto", Field, 0}, + {"Request.ProtoMajor", Field, 0}, + {"Request.ProtoMinor", Field, 0}, + {"Request.RemoteAddr", Field, 0}, + {"Request.RequestURI", Field, 0}, + {"Request.Response", Field, 7}, + {"Request.TLS", Field, 0}, + {"Request.Trailer", Field, 0}, + {"Request.TransferEncoding", Field, 0}, + {"Request.URL", Field, 0}, + {"Response", Type, 0}, + {"Response.Body", Field, 0}, + {"Response.Close", Field, 0}, + {"Response.ContentLength", Field, 0}, + {"Response.Header", Field, 0}, + {"Response.Proto", Field, 0}, + {"Response.ProtoMajor", Field, 0}, + {"Response.ProtoMinor", Field, 0}, + {"Response.Request", Field, 0}, + {"Response.Status", Field, 0}, + {"Response.StatusCode", Field, 0}, + {"Response.TLS", Field, 3}, + {"Response.Trailer", Field, 0}, + {"Response.TransferEncoding", Field, 0}, + {"Response.Uncompressed", Field, 7}, + {"ResponseController", Type, 20}, + {"ResponseWriter", Type, 0}, + {"RoundTripper", Type, 0}, + {"SameSite", Type, 11}, + {"SameSiteDefaultMode", Const, 11}, + {"SameSiteLaxMode", Const, 11}, + {"SameSiteNoneMode", Const, 13}, + {"SameSiteStrictMode", Const, 11}, + {"Serve", Func, 0}, + {"ServeContent", Func, 0}, + {"ServeFile", Func, 0}, + {"ServeFileFS", Func, 22}, + {"ServeMux", Type, 0}, + {"ServeTLS", Func, 9}, + {"Server", Type, 0}, + {"Server.Addr", Field, 0}, + {"Server.BaseContext", Field, 13}, + {"Server.ConnContext", Field, 13}, + {"Server.ConnState", Field, 3}, + {"Server.DisableGeneralOptionsHandler", Field, 20}, + {"Server.ErrorLog", Field, 3}, + {"Server.Handler", Field, 0}, + {"Server.IdleTimeout", Field, 8}, + {"Server.MaxHeaderBytes", Field, 0}, + {"Server.ReadHeaderTimeout", Field, 8}, + {"Server.ReadTimeout", Field, 0}, + {"Server.TLSConfig", Field, 0}, + {"Server.TLSNextProto", Field, 1}, + {"Server.WriteTimeout", Field, 0}, + {"ServerContextKey", Var, 7}, + {"SetCookie", Func, 0}, + {"StateActive", Const, 3}, + {"StateClosed", Const, 3}, + {"StateHijacked", Const, 3}, + {"StateIdle", Const, 3}, + {"StateNew", Const, 3}, + {"StatusAccepted", Const, 0}, + {"StatusAlreadyReported", Const, 7}, + {"StatusBadGateway", Const, 0}, + {"StatusBadRequest", Const, 0}, + {"StatusConflict", Const, 0}, + {"StatusContinue", Const, 0}, + {"StatusCreated", Const, 0}, + {"StatusEarlyHints", Const, 13}, + {"StatusExpectationFailed", Const, 0}, + {"StatusFailedDependency", Const, 7}, + {"StatusForbidden", Const, 0}, + {"StatusFound", Const, 0}, + {"StatusGatewayTimeout", Const, 0}, + {"StatusGone", Const, 0}, + {"StatusHTTPVersionNotSupported", Const, 0}, + {"StatusIMUsed", Const, 7}, + {"StatusInsufficientStorage", Const, 7}, + {"StatusInternalServerError", Const, 0}, + {"StatusLengthRequired", Const, 0}, + {"StatusLocked", Const, 7}, + {"StatusLoopDetected", Const, 7}, + {"StatusMethodNotAllowed", Const, 0}, + {"StatusMisdirectedRequest", Const, 11}, + {"StatusMovedPermanently", Const, 0}, + {"StatusMultiStatus", Const, 7}, + {"StatusMultipleChoices", Const, 0}, + {"StatusNetworkAuthenticationRequired", Const, 6}, + {"StatusNoContent", Const, 0}, + {"StatusNonAuthoritativeInfo", Const, 0}, + {"StatusNotAcceptable", Const, 0}, + {"StatusNotExtended", Const, 7}, + {"StatusNotFound", Const, 0}, + {"StatusNotImplemented", Const, 0}, + {"StatusNotModified", Const, 0}, + {"StatusOK", Const, 0}, + {"StatusPartialContent", Const, 0}, + {"StatusPaymentRequired", Const, 0}, + {"StatusPermanentRedirect", Const, 7}, + {"StatusPreconditionFailed", Const, 0}, + {"StatusPreconditionRequired", Const, 6}, + {"StatusProcessing", Const, 7}, + {"StatusProxyAuthRequired", Const, 0}, + {"StatusRequestEntityTooLarge", Const, 0}, + {"StatusRequestHeaderFieldsTooLarge", Const, 6}, + {"StatusRequestTimeout", Const, 0}, + {"StatusRequestURITooLong", Const, 0}, + {"StatusRequestedRangeNotSatisfiable", Const, 0}, + {"StatusResetContent", Const, 0}, + {"StatusSeeOther", Const, 0}, + {"StatusServiceUnavailable", Const, 0}, + {"StatusSwitchingProtocols", Const, 0}, + {"StatusTeapot", Const, 0}, + {"StatusTemporaryRedirect", Const, 0}, + {"StatusText", Func, 0}, + {"StatusTooEarly", Const, 12}, + {"StatusTooManyRequests", Const, 6}, + {"StatusUnauthorized", Const, 0}, + {"StatusUnavailableForLegalReasons", Const, 6}, + {"StatusUnprocessableEntity", Const, 7}, + {"StatusUnsupportedMediaType", Const, 0}, + {"StatusUpgradeRequired", Const, 7}, + {"StatusUseProxy", Const, 0}, + {"StatusVariantAlsoNegotiates", Const, 7}, + {"StripPrefix", Func, 0}, + {"TimeFormat", Const, 0}, + {"TimeoutHandler", Func, 0}, + {"TrailerPrefix", Const, 8}, + {"Transport", Type, 0}, + {"Transport.Dial", Field, 0}, + {"Transport.DialContext", Field, 7}, + {"Transport.DialTLS", Field, 4}, + {"Transport.DialTLSContext", Field, 14}, + {"Transport.DisableCompression", Field, 0}, + {"Transport.DisableKeepAlives", Field, 0}, + {"Transport.ExpectContinueTimeout", Field, 6}, + {"Transport.ForceAttemptHTTP2", Field, 13}, + {"Transport.GetProxyConnectHeader", Field, 16}, + {"Transport.IdleConnTimeout", Field, 7}, + {"Transport.MaxConnsPerHost", Field, 11}, + {"Transport.MaxIdleConns", Field, 7}, + {"Transport.MaxIdleConnsPerHost", Field, 0}, + {"Transport.MaxResponseHeaderBytes", Field, 7}, + {"Transport.OnProxyConnectResponse", Field, 20}, + {"Transport.Proxy", Field, 0}, + {"Transport.ProxyConnectHeader", Field, 8}, + {"Transport.ReadBufferSize", Field, 13}, + {"Transport.ResponseHeaderTimeout", Field, 1}, + {"Transport.TLSClientConfig", Field, 0}, + {"Transport.TLSHandshakeTimeout", Field, 3}, + {"Transport.TLSNextProto", Field, 6}, + {"Transport.WriteBufferSize", Field, 13}, + }, + "net/http/cgi": { + {"(*Handler).ServeHTTP", Method, 0}, + {"Handler", Type, 0}, + {"Handler.Args", Field, 0}, + {"Handler.Dir", Field, 0}, + {"Handler.Env", Field, 0}, + {"Handler.InheritEnv", Field, 0}, + {"Handler.Logger", Field, 0}, + {"Handler.Path", Field, 0}, + {"Handler.PathLocationHandler", Field, 0}, + {"Handler.Root", Field, 0}, + {"Handler.Stderr", Field, 7}, + {"Request", Func, 0}, + {"RequestFromMap", Func, 0}, + {"Serve", Func, 0}, + }, + "net/http/cookiejar": { + {"(*Jar).Cookies", Method, 1}, + {"(*Jar).SetCookies", Method, 1}, + {"Jar", Type, 1}, + {"New", Func, 1}, + {"Options", Type, 1}, + {"Options.PublicSuffixList", Field, 1}, + {"PublicSuffixList", Type, 1}, + }, + "net/http/fcgi": { + {"ErrConnClosed", Var, 5}, + {"ErrRequestAborted", Var, 5}, + {"ProcessEnv", Func, 9}, + {"Serve", Func, 0}, + }, + "net/http/httptest": { + {"(*ResponseRecorder).Flush", Method, 0}, + {"(*ResponseRecorder).Header", Method, 0}, + {"(*ResponseRecorder).Result", Method, 7}, + {"(*ResponseRecorder).Write", Method, 0}, + {"(*ResponseRecorder).WriteHeader", Method, 0}, + {"(*ResponseRecorder).WriteString", Method, 6}, + {"(*Server).Certificate", Method, 9}, + {"(*Server).Client", Method, 9}, + {"(*Server).Close", Method, 0}, + {"(*Server).CloseClientConnections", Method, 0}, + {"(*Server).Start", Method, 0}, + {"(*Server).StartTLS", Method, 0}, + {"DefaultRemoteAddr", Const, 0}, + {"NewRecorder", Func, 0}, + {"NewRequest", Func, 7}, + {"NewServer", Func, 0}, + {"NewTLSServer", Func, 0}, + {"NewUnstartedServer", Func, 0}, + {"ResponseRecorder", Type, 0}, + {"ResponseRecorder.Body", Field, 0}, + {"ResponseRecorder.Code", Field, 0}, + {"ResponseRecorder.Flushed", Field, 0}, + {"ResponseRecorder.HeaderMap", Field, 0}, + {"Server", Type, 0}, + {"Server.Config", Field, 0}, + {"Server.EnableHTTP2", Field, 14}, + {"Server.Listener", Field, 0}, + {"Server.TLS", Field, 0}, + {"Server.URL", Field, 0}, + }, + "net/http/httptrace": { + {"ClientTrace", Type, 7}, + {"ClientTrace.ConnectDone", Field, 7}, + {"ClientTrace.ConnectStart", Field, 7}, + {"ClientTrace.DNSDone", Field, 7}, + {"ClientTrace.DNSStart", Field, 7}, + {"ClientTrace.GetConn", Field, 7}, + {"ClientTrace.Got100Continue", Field, 7}, + {"ClientTrace.Got1xxResponse", Field, 11}, + {"ClientTrace.GotConn", Field, 7}, + {"ClientTrace.GotFirstResponseByte", Field, 7}, + {"ClientTrace.PutIdleConn", Field, 7}, + {"ClientTrace.TLSHandshakeDone", Field, 8}, + {"ClientTrace.TLSHandshakeStart", Field, 8}, + {"ClientTrace.Wait100Continue", Field, 7}, + {"ClientTrace.WroteHeaderField", Field, 11}, + {"ClientTrace.WroteHeaders", Field, 7}, + {"ClientTrace.WroteRequest", Field, 7}, + {"ContextClientTrace", Func, 7}, + {"DNSDoneInfo", Type, 7}, + {"DNSDoneInfo.Addrs", Field, 7}, + {"DNSDoneInfo.Coalesced", Field, 7}, + {"DNSDoneInfo.Err", Field, 7}, + {"DNSStartInfo", Type, 7}, + {"DNSStartInfo.Host", Field, 7}, + {"GotConnInfo", Type, 7}, + {"GotConnInfo.Conn", Field, 7}, + {"GotConnInfo.IdleTime", Field, 7}, + {"GotConnInfo.Reused", Field, 7}, + {"GotConnInfo.WasIdle", Field, 7}, + {"WithClientTrace", Func, 7}, + {"WroteRequestInfo", Type, 7}, + {"WroteRequestInfo.Err", Field, 7}, + }, + "net/http/httputil": { + {"(*ClientConn).Close", Method, 0}, + {"(*ClientConn).Do", Method, 0}, + {"(*ClientConn).Hijack", Method, 0}, + {"(*ClientConn).Pending", Method, 0}, + {"(*ClientConn).Read", Method, 0}, + {"(*ClientConn).Write", Method, 0}, + {"(*ProxyRequest).SetURL", Method, 20}, + {"(*ProxyRequest).SetXForwarded", Method, 20}, + {"(*ReverseProxy).ServeHTTP", Method, 0}, + {"(*ServerConn).Close", Method, 0}, + {"(*ServerConn).Hijack", Method, 0}, + {"(*ServerConn).Pending", Method, 0}, + {"(*ServerConn).Read", Method, 0}, + {"(*ServerConn).Write", Method, 0}, + {"BufferPool", Type, 6}, + {"ClientConn", Type, 0}, + {"DumpRequest", Func, 0}, + {"DumpRequestOut", Func, 0}, + {"DumpResponse", Func, 0}, + {"ErrClosed", Var, 0}, + {"ErrLineTooLong", Var, 0}, + {"ErrPersistEOF", Var, 0}, + {"ErrPipeline", Var, 0}, + {"NewChunkedReader", Func, 0}, + {"NewChunkedWriter", Func, 0}, + {"NewClientConn", Func, 0}, + {"NewProxyClientConn", Func, 0}, + {"NewServerConn", Func, 0}, + {"NewSingleHostReverseProxy", Func, 0}, + {"ProxyRequest", Type, 20}, + {"ProxyRequest.In", Field, 20}, + {"ProxyRequest.Out", Field, 20}, + {"ReverseProxy", Type, 0}, + {"ReverseProxy.BufferPool", Field, 6}, + {"ReverseProxy.Director", Field, 0}, + {"ReverseProxy.ErrorHandler", Field, 11}, + {"ReverseProxy.ErrorLog", Field, 4}, + {"ReverseProxy.FlushInterval", Field, 0}, + {"ReverseProxy.ModifyResponse", Field, 8}, + {"ReverseProxy.Rewrite", Field, 20}, + {"ReverseProxy.Transport", Field, 0}, + {"ServerConn", Type, 0}, + }, + "net/http/pprof": { + {"Cmdline", Func, 0}, + {"Handler", Func, 0}, + {"Index", Func, 0}, + {"Profile", Func, 0}, + {"Symbol", Func, 0}, + {"Trace", Func, 5}, + }, + "net/mail": { + {"(*Address).String", Method, 0}, + {"(*AddressParser).Parse", Method, 5}, + {"(*AddressParser).ParseList", Method, 5}, + {"(Header).AddressList", Method, 0}, + {"(Header).Date", Method, 0}, + {"(Header).Get", Method, 0}, + {"Address", Type, 0}, + {"Address.Address", Field, 0}, + {"Address.Name", Field, 0}, + {"AddressParser", Type, 5}, + {"AddressParser.WordDecoder", Field, 5}, + {"ErrHeaderNotPresent", Var, 0}, + {"Header", Type, 0}, + {"Message", Type, 0}, + {"Message.Body", Field, 0}, + {"Message.Header", Field, 0}, + {"ParseAddress", Func, 1}, + {"ParseAddressList", Func, 1}, + {"ParseDate", Func, 8}, + {"ReadMessage", Func, 0}, + }, + "net/netip": { + {"(*Addr).UnmarshalBinary", Method, 18}, + {"(*Addr).UnmarshalText", Method, 18}, + {"(*AddrPort).UnmarshalBinary", Method, 18}, + {"(*AddrPort).UnmarshalText", Method, 18}, + {"(*Prefix).UnmarshalBinary", Method, 18}, + {"(*Prefix).UnmarshalText", Method, 18}, + {"(Addr).AppendTo", Method, 18}, + {"(Addr).As16", Method, 18}, + {"(Addr).As4", Method, 18}, + {"(Addr).AsSlice", Method, 18}, + {"(Addr).BitLen", Method, 18}, + {"(Addr).Compare", Method, 18}, + {"(Addr).Is4", Method, 18}, + {"(Addr).Is4In6", Method, 18}, + {"(Addr).Is6", Method, 18}, + {"(Addr).IsGlobalUnicast", Method, 18}, + {"(Addr).IsInterfaceLocalMulticast", Method, 18}, + {"(Addr).IsLinkLocalMulticast", Method, 18}, + {"(Addr).IsLinkLocalUnicast", Method, 18}, + {"(Addr).IsLoopback", Method, 18}, + {"(Addr).IsMulticast", Method, 18}, + {"(Addr).IsPrivate", Method, 18}, + {"(Addr).IsUnspecified", Method, 18}, + {"(Addr).IsValid", Method, 18}, + {"(Addr).Less", Method, 18}, + {"(Addr).MarshalBinary", Method, 18}, + {"(Addr).MarshalText", Method, 18}, + {"(Addr).Next", Method, 18}, + {"(Addr).Prefix", Method, 18}, + {"(Addr).Prev", Method, 18}, + {"(Addr).String", Method, 18}, + {"(Addr).StringExpanded", Method, 18}, + {"(Addr).Unmap", Method, 18}, + {"(Addr).WithZone", Method, 18}, + {"(Addr).Zone", Method, 18}, + {"(AddrPort).Addr", Method, 18}, + {"(AddrPort).AppendTo", Method, 18}, + {"(AddrPort).Compare", Method, 22}, + {"(AddrPort).IsValid", Method, 18}, + {"(AddrPort).MarshalBinary", Method, 18}, + {"(AddrPort).MarshalText", Method, 18}, + {"(AddrPort).Port", Method, 18}, + {"(AddrPort).String", Method, 18}, + {"(Prefix).Addr", Method, 18}, + {"(Prefix).AppendTo", Method, 18}, + {"(Prefix).Bits", Method, 18}, + {"(Prefix).Contains", Method, 18}, + {"(Prefix).IsSingleIP", Method, 18}, + {"(Prefix).IsValid", Method, 18}, + {"(Prefix).MarshalBinary", Method, 18}, + {"(Prefix).MarshalText", Method, 18}, + {"(Prefix).Masked", Method, 18}, + {"(Prefix).Overlaps", Method, 18}, + {"(Prefix).String", Method, 18}, + {"Addr", Type, 18}, + {"AddrFrom16", Func, 18}, + {"AddrFrom4", Func, 18}, + {"AddrFromSlice", Func, 18}, + {"AddrPort", Type, 18}, + {"AddrPortFrom", Func, 18}, + {"IPv4Unspecified", Func, 18}, + {"IPv6LinkLocalAllNodes", Func, 18}, + {"IPv6LinkLocalAllRouters", Func, 20}, + {"IPv6Loopback", Func, 20}, + {"IPv6Unspecified", Func, 18}, + {"MustParseAddr", Func, 18}, + {"MustParseAddrPort", Func, 18}, + {"MustParsePrefix", Func, 18}, + {"ParseAddr", Func, 18}, + {"ParseAddrPort", Func, 18}, + {"ParsePrefix", Func, 18}, + {"Prefix", Type, 18}, + {"PrefixFrom", Func, 18}, + }, + "net/rpc": { + {"(*Client).Call", Method, 0}, + {"(*Client).Close", Method, 0}, + {"(*Client).Go", Method, 0}, + {"(*Server).Accept", Method, 0}, + {"(*Server).HandleHTTP", Method, 0}, + {"(*Server).Register", Method, 0}, + {"(*Server).RegisterName", Method, 0}, + {"(*Server).ServeCodec", Method, 0}, + {"(*Server).ServeConn", Method, 0}, + {"(*Server).ServeHTTP", Method, 0}, + {"(*Server).ServeRequest", Method, 0}, + {"(ServerError).Error", Method, 0}, + {"Accept", Func, 0}, + {"Call", Type, 0}, + {"Call.Args", Field, 0}, + {"Call.Done", Field, 0}, + {"Call.Error", Field, 0}, + {"Call.Reply", Field, 0}, + {"Call.ServiceMethod", Field, 0}, + {"Client", Type, 0}, + {"ClientCodec", Type, 0}, + {"DefaultDebugPath", Const, 0}, + {"DefaultRPCPath", Const, 0}, + {"DefaultServer", Var, 0}, + {"Dial", Func, 0}, + {"DialHTTP", Func, 0}, + {"DialHTTPPath", Func, 0}, + {"ErrShutdown", Var, 0}, + {"HandleHTTP", Func, 0}, + {"NewClient", Func, 0}, + {"NewClientWithCodec", Func, 0}, + {"NewServer", Func, 0}, + {"Register", Func, 0}, + {"RegisterName", Func, 0}, + {"Request", Type, 0}, + {"Request.Seq", Field, 0}, + {"Request.ServiceMethod", Field, 0}, + {"Response", Type, 0}, + {"Response.Error", Field, 0}, + {"Response.Seq", Field, 0}, + {"Response.ServiceMethod", Field, 0}, + {"ServeCodec", Func, 0}, + {"ServeConn", Func, 0}, + {"ServeRequest", Func, 0}, + {"Server", Type, 0}, + {"ServerCodec", Type, 0}, + {"ServerError", Type, 0}, + }, + "net/rpc/jsonrpc": { + {"Dial", Func, 0}, + {"NewClient", Func, 0}, + {"NewClientCodec", Func, 0}, + {"NewServerCodec", Func, 0}, + {"ServeConn", Func, 0}, + }, + "net/smtp": { + {"(*Client).Auth", Method, 0}, + {"(*Client).Close", Method, 2}, + {"(*Client).Data", Method, 0}, + {"(*Client).Extension", Method, 0}, + {"(*Client).Hello", Method, 1}, + {"(*Client).Mail", Method, 0}, + {"(*Client).Noop", Method, 10}, + {"(*Client).Quit", Method, 0}, + {"(*Client).Rcpt", Method, 0}, + {"(*Client).Reset", Method, 0}, + {"(*Client).StartTLS", Method, 0}, + {"(*Client).TLSConnectionState", Method, 5}, + {"(*Client).Verify", Method, 0}, + {"Auth", Type, 0}, + {"CRAMMD5Auth", Func, 0}, + {"Client", Type, 0}, + {"Client.Text", Field, 0}, + {"Dial", Func, 0}, + {"NewClient", Func, 0}, + {"PlainAuth", Func, 0}, + {"SendMail", Func, 0}, + {"ServerInfo", Type, 0}, + {"ServerInfo.Auth", Field, 0}, + {"ServerInfo.Name", Field, 0}, + {"ServerInfo.TLS", Field, 0}, + }, + "net/textproto": { + {"(*Conn).Close", Method, 0}, + {"(*Conn).Cmd", Method, 0}, + {"(*Conn).DotReader", Method, 0}, + {"(*Conn).DotWriter", Method, 0}, + {"(*Conn).EndRequest", Method, 0}, + {"(*Conn).EndResponse", Method, 0}, + {"(*Conn).Next", Method, 0}, + {"(*Conn).PrintfLine", Method, 0}, + {"(*Conn).ReadCodeLine", Method, 0}, + {"(*Conn).ReadContinuedLine", Method, 0}, + {"(*Conn).ReadContinuedLineBytes", Method, 0}, + {"(*Conn).ReadDotBytes", Method, 0}, + {"(*Conn).ReadDotLines", Method, 0}, + {"(*Conn).ReadLine", Method, 0}, + {"(*Conn).ReadLineBytes", Method, 0}, + {"(*Conn).ReadMIMEHeader", Method, 0}, + {"(*Conn).ReadResponse", Method, 0}, + {"(*Conn).StartRequest", Method, 0}, + {"(*Conn).StartResponse", Method, 0}, + {"(*Error).Error", Method, 0}, + {"(*Pipeline).EndRequest", Method, 0}, + {"(*Pipeline).EndResponse", Method, 0}, + {"(*Pipeline).Next", Method, 0}, + {"(*Pipeline).StartRequest", Method, 0}, + {"(*Pipeline).StartResponse", Method, 0}, + {"(*Reader).DotReader", Method, 0}, + {"(*Reader).ReadCodeLine", Method, 0}, + {"(*Reader).ReadContinuedLine", Method, 0}, + {"(*Reader).ReadContinuedLineBytes", Method, 0}, + {"(*Reader).ReadDotBytes", Method, 0}, + {"(*Reader).ReadDotLines", Method, 0}, + {"(*Reader).ReadLine", Method, 0}, + {"(*Reader).ReadLineBytes", Method, 0}, + {"(*Reader).ReadMIMEHeader", Method, 0}, + {"(*Reader).ReadResponse", Method, 0}, + {"(*Writer).DotWriter", Method, 0}, + {"(*Writer).PrintfLine", Method, 0}, + {"(MIMEHeader).Add", Method, 0}, + {"(MIMEHeader).Del", Method, 0}, + {"(MIMEHeader).Get", Method, 0}, + {"(MIMEHeader).Set", Method, 0}, + {"(MIMEHeader).Values", Method, 14}, + {"(ProtocolError).Error", Method, 0}, + {"CanonicalMIMEHeaderKey", Func, 0}, + {"Conn", Type, 0}, + {"Conn.Pipeline", Field, 0}, + {"Conn.Reader", Field, 0}, + {"Conn.Writer", Field, 0}, + {"Dial", Func, 0}, + {"Error", Type, 0}, + {"Error.Code", Field, 0}, + {"Error.Msg", Field, 0}, + {"MIMEHeader", Type, 0}, + {"NewConn", Func, 0}, + {"NewReader", Func, 0}, + {"NewWriter", Func, 0}, + {"Pipeline", Type, 0}, + {"ProtocolError", Type, 0}, + {"Reader", Type, 0}, + {"Reader.R", Field, 0}, + {"TrimBytes", Func, 1}, + {"TrimString", Func, 1}, + {"Writer", Type, 0}, + {"Writer.W", Field, 0}, + }, + "net/url": { + {"(*Error).Error", Method, 0}, + {"(*Error).Temporary", Method, 6}, + {"(*Error).Timeout", Method, 6}, + {"(*Error).Unwrap", Method, 13}, + {"(*URL).EscapedFragment", Method, 15}, + {"(*URL).EscapedPath", Method, 5}, + {"(*URL).Hostname", Method, 8}, + {"(*URL).IsAbs", Method, 0}, + {"(*URL).JoinPath", Method, 19}, + {"(*URL).MarshalBinary", Method, 8}, + {"(*URL).Parse", Method, 0}, + {"(*URL).Port", Method, 8}, + {"(*URL).Query", Method, 0}, + {"(*URL).Redacted", Method, 15}, + {"(*URL).RequestURI", Method, 0}, + {"(*URL).ResolveReference", Method, 0}, + {"(*URL).String", Method, 0}, + {"(*URL).UnmarshalBinary", Method, 8}, + {"(*Userinfo).Password", Method, 0}, + {"(*Userinfo).String", Method, 0}, + {"(*Userinfo).Username", Method, 0}, + {"(EscapeError).Error", Method, 0}, + {"(InvalidHostError).Error", Method, 6}, + {"(Values).Add", Method, 0}, + {"(Values).Del", Method, 0}, + {"(Values).Encode", Method, 0}, + {"(Values).Get", Method, 0}, + {"(Values).Has", Method, 17}, + {"(Values).Set", Method, 0}, + {"Error", Type, 0}, + {"Error.Err", Field, 0}, + {"Error.Op", Field, 0}, + {"Error.URL", Field, 0}, + {"EscapeError", Type, 0}, + {"InvalidHostError", Type, 6}, + {"JoinPath", Func, 19}, + {"Parse", Func, 0}, + {"ParseQuery", Func, 0}, + {"ParseRequestURI", Func, 0}, + {"PathEscape", Func, 8}, + {"PathUnescape", Func, 8}, + {"QueryEscape", Func, 0}, + {"QueryUnescape", Func, 0}, + {"URL", Type, 0}, + {"URL.ForceQuery", Field, 7}, + {"URL.Fragment", Field, 0}, + {"URL.Host", Field, 0}, + {"URL.OmitHost", Field, 19}, + {"URL.Opaque", Field, 0}, + {"URL.Path", Field, 0}, + {"URL.RawFragment", Field, 15}, + {"URL.RawPath", Field, 5}, + {"URL.RawQuery", Field, 0}, + {"URL.Scheme", Field, 0}, + {"URL.User", Field, 0}, + {"User", Func, 0}, + {"UserPassword", Func, 0}, + {"Userinfo", Type, 0}, + {"Values", Type, 0}, + }, + "os": { + {"(*File).Chdir", Method, 0}, + {"(*File).Chmod", Method, 0}, + {"(*File).Chown", Method, 0}, + {"(*File).Close", Method, 0}, + {"(*File).Fd", Method, 0}, + {"(*File).Name", Method, 0}, + {"(*File).Read", Method, 0}, + {"(*File).ReadAt", Method, 0}, + {"(*File).ReadDir", Method, 16}, + {"(*File).ReadFrom", Method, 15}, + {"(*File).Readdir", Method, 0}, + {"(*File).Readdirnames", Method, 0}, + {"(*File).Seek", Method, 0}, + {"(*File).SetDeadline", Method, 10}, + {"(*File).SetReadDeadline", Method, 10}, + {"(*File).SetWriteDeadline", Method, 10}, + {"(*File).Stat", Method, 0}, + {"(*File).Sync", Method, 0}, + {"(*File).SyscallConn", Method, 12}, + {"(*File).Truncate", Method, 0}, + {"(*File).Write", Method, 0}, + {"(*File).WriteAt", Method, 0}, + {"(*File).WriteString", Method, 0}, + {"(*File).WriteTo", Method, 22}, + {"(*LinkError).Error", Method, 0}, + {"(*LinkError).Unwrap", Method, 13}, + {"(*PathError).Error", Method, 0}, + {"(*PathError).Timeout", Method, 10}, + {"(*PathError).Unwrap", Method, 13}, + {"(*Process).Kill", Method, 0}, + {"(*Process).Release", Method, 0}, + {"(*Process).Signal", Method, 0}, + {"(*Process).Wait", Method, 0}, + {"(*ProcessState).ExitCode", Method, 12}, + {"(*ProcessState).Exited", Method, 0}, + {"(*ProcessState).Pid", Method, 0}, + {"(*ProcessState).String", Method, 0}, + {"(*ProcessState).Success", Method, 0}, + {"(*ProcessState).Sys", Method, 0}, + {"(*ProcessState).SysUsage", Method, 0}, + {"(*ProcessState).SystemTime", Method, 0}, + {"(*ProcessState).UserTime", Method, 0}, + {"(*SyscallError).Error", Method, 0}, + {"(*SyscallError).Timeout", Method, 10}, + {"(*SyscallError).Unwrap", Method, 13}, + {"(FileMode).IsDir", Method, 0}, + {"(FileMode).IsRegular", Method, 1}, + {"(FileMode).Perm", Method, 0}, + {"(FileMode).String", Method, 0}, + {"Args", Var, 0}, + {"Chdir", Func, 0}, + {"Chmod", Func, 0}, + {"Chown", Func, 0}, + {"Chtimes", Func, 0}, + {"Clearenv", Func, 0}, + {"Create", Func, 0}, + {"CreateTemp", Func, 16}, + {"DevNull", Const, 0}, + {"DirEntry", Type, 16}, + {"DirFS", Func, 16}, + {"Environ", Func, 0}, + {"ErrClosed", Var, 8}, + {"ErrDeadlineExceeded", Var, 15}, + {"ErrExist", Var, 0}, + {"ErrInvalid", Var, 0}, + {"ErrNoDeadline", Var, 10}, + {"ErrNotExist", Var, 0}, + {"ErrPermission", Var, 0}, + {"ErrProcessDone", Var, 16}, + {"Executable", Func, 8}, + {"Exit", Func, 0}, + {"Expand", Func, 0}, + {"ExpandEnv", Func, 0}, + {"File", Type, 0}, + {"FileInfo", Type, 0}, + {"FileMode", Type, 0}, + {"FindProcess", Func, 0}, + {"Getegid", Func, 0}, + {"Getenv", Func, 0}, + {"Geteuid", Func, 0}, + {"Getgid", Func, 0}, + {"Getgroups", Func, 0}, + {"Getpagesize", Func, 0}, + {"Getpid", Func, 0}, + {"Getppid", Func, 0}, + {"Getuid", Func, 0}, + {"Getwd", Func, 0}, + {"Hostname", Func, 0}, + {"Interrupt", Var, 0}, + {"IsExist", Func, 0}, + {"IsNotExist", Func, 0}, + {"IsPathSeparator", Func, 0}, + {"IsPermission", Func, 0}, + {"IsTimeout", Func, 10}, + {"Kill", Var, 0}, + {"Lchown", Func, 0}, + {"Link", Func, 0}, + {"LinkError", Type, 0}, + {"LinkError.Err", Field, 0}, + {"LinkError.New", Field, 0}, + {"LinkError.Old", Field, 0}, + {"LinkError.Op", Field, 0}, + {"LookupEnv", Func, 5}, + {"Lstat", Func, 0}, + {"Mkdir", Func, 0}, + {"MkdirAll", Func, 0}, + {"MkdirTemp", Func, 16}, + {"ModeAppend", Const, 0}, + {"ModeCharDevice", Const, 0}, + {"ModeDevice", Const, 0}, + {"ModeDir", Const, 0}, + {"ModeExclusive", Const, 0}, + {"ModeIrregular", Const, 11}, + {"ModeNamedPipe", Const, 0}, + {"ModePerm", Const, 0}, + {"ModeSetgid", Const, 0}, + {"ModeSetuid", Const, 0}, + {"ModeSocket", Const, 0}, + {"ModeSticky", Const, 0}, + {"ModeSymlink", Const, 0}, + {"ModeTemporary", Const, 0}, + {"ModeType", Const, 0}, + {"NewFile", Func, 0}, + {"NewSyscallError", Func, 0}, + {"O_APPEND", Const, 0}, + {"O_CREATE", Const, 0}, + {"O_EXCL", Const, 0}, + {"O_RDONLY", Const, 0}, + {"O_RDWR", Const, 0}, + {"O_SYNC", Const, 0}, + {"O_TRUNC", Const, 0}, + {"O_WRONLY", Const, 0}, + {"Open", Func, 0}, + {"OpenFile", Func, 0}, + {"PathError", Type, 0}, + {"PathError.Err", Field, 0}, + {"PathError.Op", Field, 0}, + {"PathError.Path", Field, 0}, + {"PathListSeparator", Const, 0}, + {"PathSeparator", Const, 0}, + {"Pipe", Func, 0}, + {"ProcAttr", Type, 0}, + {"ProcAttr.Dir", Field, 0}, + {"ProcAttr.Env", Field, 0}, + {"ProcAttr.Files", Field, 0}, + {"ProcAttr.Sys", Field, 0}, + {"Process", Type, 0}, + {"Process.Pid", Field, 0}, + {"ProcessState", Type, 0}, + {"ReadDir", Func, 16}, + {"ReadFile", Func, 16}, + {"Readlink", Func, 0}, + {"Remove", Func, 0}, + {"RemoveAll", Func, 0}, + {"Rename", Func, 0}, + {"SEEK_CUR", Const, 0}, + {"SEEK_END", Const, 0}, + {"SEEK_SET", Const, 0}, + {"SameFile", Func, 0}, + {"Setenv", Func, 0}, + {"Signal", Type, 0}, + {"StartProcess", Func, 0}, + {"Stat", Func, 0}, + {"Stderr", Var, 0}, + {"Stdin", Var, 0}, + {"Stdout", Var, 0}, + {"Symlink", Func, 0}, + {"SyscallError", Type, 0}, + {"SyscallError.Err", Field, 0}, + {"SyscallError.Syscall", Field, 0}, + {"TempDir", Func, 0}, + {"Truncate", Func, 0}, + {"Unsetenv", Func, 4}, + {"UserCacheDir", Func, 11}, + {"UserConfigDir", Func, 13}, + {"UserHomeDir", Func, 12}, + {"WriteFile", Func, 16}, + }, + "os/exec": { + {"(*Cmd).CombinedOutput", Method, 0}, + {"(*Cmd).Environ", Method, 19}, + {"(*Cmd).Output", Method, 0}, + {"(*Cmd).Run", Method, 0}, + {"(*Cmd).Start", Method, 0}, + {"(*Cmd).StderrPipe", Method, 0}, + {"(*Cmd).StdinPipe", Method, 0}, + {"(*Cmd).StdoutPipe", Method, 0}, + {"(*Cmd).String", Method, 13}, + {"(*Cmd).Wait", Method, 0}, + {"(*Error).Error", Method, 0}, + {"(*Error).Unwrap", Method, 13}, + {"(*ExitError).Error", Method, 0}, + {"(ExitError).ExitCode", Method, 12}, + {"(ExitError).Exited", Method, 0}, + {"(ExitError).Pid", Method, 0}, + {"(ExitError).String", Method, 0}, + {"(ExitError).Success", Method, 0}, + {"(ExitError).Sys", Method, 0}, + {"(ExitError).SysUsage", Method, 0}, + {"(ExitError).SystemTime", Method, 0}, + {"(ExitError).UserTime", Method, 0}, + {"Cmd", Type, 0}, + {"Cmd.Args", Field, 0}, + {"Cmd.Cancel", Field, 20}, + {"Cmd.Dir", Field, 0}, + {"Cmd.Env", Field, 0}, + {"Cmd.Err", Field, 19}, + {"Cmd.ExtraFiles", Field, 0}, + {"Cmd.Path", Field, 0}, + {"Cmd.Process", Field, 0}, + {"Cmd.ProcessState", Field, 0}, + {"Cmd.Stderr", Field, 0}, + {"Cmd.Stdin", Field, 0}, + {"Cmd.Stdout", Field, 0}, + {"Cmd.SysProcAttr", Field, 0}, + {"Cmd.WaitDelay", Field, 20}, + {"Command", Func, 0}, + {"CommandContext", Func, 7}, + {"ErrDot", Var, 19}, + {"ErrNotFound", Var, 0}, + {"ErrWaitDelay", Var, 20}, + {"Error", Type, 0}, + {"Error.Err", Field, 0}, + {"Error.Name", Field, 0}, + {"ExitError", Type, 0}, + {"ExitError.ProcessState", Field, 0}, + {"ExitError.Stderr", Field, 6}, + {"LookPath", Func, 0}, + }, + "os/signal": { + {"Ignore", Func, 5}, + {"Ignored", Func, 11}, + {"Notify", Func, 0}, + {"NotifyContext", Func, 16}, + {"Reset", Func, 5}, + {"Stop", Func, 1}, + }, + "os/user": { + {"(*User).GroupIds", Method, 7}, + {"(UnknownGroupError).Error", Method, 7}, + {"(UnknownGroupIdError).Error", Method, 7}, + {"(UnknownUserError).Error", Method, 0}, + {"(UnknownUserIdError).Error", Method, 0}, + {"Current", Func, 0}, + {"Group", Type, 7}, + {"Group.Gid", Field, 7}, + {"Group.Name", Field, 7}, + {"Lookup", Func, 0}, + {"LookupGroup", Func, 7}, + {"LookupGroupId", Func, 7}, + {"LookupId", Func, 0}, + {"UnknownGroupError", Type, 7}, + {"UnknownGroupIdError", Type, 7}, + {"UnknownUserError", Type, 0}, + {"UnknownUserIdError", Type, 0}, + {"User", Type, 0}, + {"User.Gid", Field, 0}, + {"User.HomeDir", Field, 0}, + {"User.Name", Field, 0}, + {"User.Uid", Field, 0}, + {"User.Username", Field, 0}, + }, + "path": { + {"Base", Func, 0}, + {"Clean", Func, 0}, + {"Dir", Func, 0}, + {"ErrBadPattern", Var, 0}, + {"Ext", Func, 0}, + {"IsAbs", Func, 0}, + {"Join", Func, 0}, + {"Match", Func, 0}, + {"Split", Func, 0}, + }, + "path/filepath": { + {"Abs", Func, 0}, + {"Base", Func, 0}, + {"Clean", Func, 0}, + {"Dir", Func, 0}, + {"ErrBadPattern", Var, 0}, + {"EvalSymlinks", Func, 0}, + {"Ext", Func, 0}, + {"FromSlash", Func, 0}, + {"Glob", Func, 0}, + {"HasPrefix", Func, 0}, + {"IsAbs", Func, 0}, + {"IsLocal", Func, 20}, + {"Join", Func, 0}, + {"ListSeparator", Const, 0}, + {"Match", Func, 0}, + {"Rel", Func, 0}, + {"Separator", Const, 0}, + {"SkipAll", Var, 20}, + {"SkipDir", Var, 0}, + {"Split", Func, 0}, + {"SplitList", Func, 0}, + {"ToSlash", Func, 0}, + {"VolumeName", Func, 0}, + {"Walk", Func, 0}, + {"WalkDir", Func, 16}, + {"WalkFunc", Type, 0}, + }, + "plugin": { + {"(*Plugin).Lookup", Method, 8}, + {"Open", Func, 8}, + {"Plugin", Type, 8}, + {"Symbol", Type, 8}, + }, + "reflect": { + {"(*MapIter).Key", Method, 12}, + {"(*MapIter).Next", Method, 12}, + {"(*MapIter).Reset", Method, 18}, + {"(*MapIter).Value", Method, 12}, + {"(*ValueError).Error", Method, 0}, + {"(ChanDir).String", Method, 0}, + {"(Kind).String", Method, 0}, + {"(Method).IsExported", Method, 17}, + {"(StructField).IsExported", Method, 17}, + {"(StructTag).Get", Method, 0}, + {"(StructTag).Lookup", Method, 7}, + {"(Value).Addr", Method, 0}, + {"(Value).Bool", Method, 0}, + {"(Value).Bytes", Method, 0}, + {"(Value).Call", Method, 0}, + {"(Value).CallSlice", Method, 0}, + {"(Value).CanAddr", Method, 0}, + {"(Value).CanComplex", Method, 18}, + {"(Value).CanConvert", Method, 17}, + {"(Value).CanFloat", Method, 18}, + {"(Value).CanInt", Method, 18}, + {"(Value).CanInterface", Method, 0}, + {"(Value).CanSet", Method, 0}, + {"(Value).CanUint", Method, 18}, + {"(Value).Cap", Method, 0}, + {"(Value).Clear", Method, 21}, + {"(Value).Close", Method, 0}, + {"(Value).Comparable", Method, 20}, + {"(Value).Complex", Method, 0}, + {"(Value).Convert", Method, 1}, + {"(Value).Elem", Method, 0}, + {"(Value).Equal", Method, 20}, + {"(Value).Field", Method, 0}, + {"(Value).FieldByIndex", Method, 0}, + {"(Value).FieldByIndexErr", Method, 18}, + {"(Value).FieldByName", Method, 0}, + {"(Value).FieldByNameFunc", Method, 0}, + {"(Value).Float", Method, 0}, + {"(Value).Grow", Method, 20}, + {"(Value).Index", Method, 0}, + {"(Value).Int", Method, 0}, + {"(Value).Interface", Method, 0}, + {"(Value).InterfaceData", Method, 0}, + {"(Value).IsNil", Method, 0}, + {"(Value).IsValid", Method, 0}, + {"(Value).IsZero", Method, 13}, + {"(Value).Kind", Method, 0}, + {"(Value).Len", Method, 0}, + {"(Value).MapIndex", Method, 0}, + {"(Value).MapKeys", Method, 0}, + {"(Value).MapRange", Method, 12}, + {"(Value).Method", Method, 0}, + {"(Value).MethodByName", Method, 0}, + {"(Value).NumField", Method, 0}, + {"(Value).NumMethod", Method, 0}, + {"(Value).OverflowComplex", Method, 0}, + {"(Value).OverflowFloat", Method, 0}, + {"(Value).OverflowInt", Method, 0}, + {"(Value).OverflowUint", Method, 0}, + {"(Value).Pointer", Method, 0}, + {"(Value).Recv", Method, 0}, + {"(Value).Send", Method, 0}, + {"(Value).Set", Method, 0}, + {"(Value).SetBool", Method, 0}, + {"(Value).SetBytes", Method, 0}, + {"(Value).SetCap", Method, 2}, + {"(Value).SetComplex", Method, 0}, + {"(Value).SetFloat", Method, 0}, + {"(Value).SetInt", Method, 0}, + {"(Value).SetIterKey", Method, 18}, + {"(Value).SetIterValue", Method, 18}, + {"(Value).SetLen", Method, 0}, + {"(Value).SetMapIndex", Method, 0}, + {"(Value).SetPointer", Method, 0}, + {"(Value).SetString", Method, 0}, + {"(Value).SetUint", Method, 0}, + {"(Value).SetZero", Method, 20}, + {"(Value).Slice", Method, 0}, + {"(Value).Slice3", Method, 2}, + {"(Value).String", Method, 0}, + {"(Value).TryRecv", Method, 0}, + {"(Value).TrySend", Method, 0}, + {"(Value).Type", Method, 0}, + {"(Value).Uint", Method, 0}, + {"(Value).UnsafeAddr", Method, 0}, + {"(Value).UnsafePointer", Method, 18}, + {"Append", Func, 0}, + {"AppendSlice", Func, 0}, + {"Array", Const, 0}, + {"ArrayOf", Func, 5}, + {"Bool", Const, 0}, + {"BothDir", Const, 0}, + {"Chan", Const, 0}, + {"ChanDir", Type, 0}, + {"ChanOf", Func, 1}, + {"Complex128", Const, 0}, + {"Complex64", Const, 0}, + {"Copy", Func, 0}, + {"DeepEqual", Func, 0}, + {"Float32", Const, 0}, + {"Float64", Const, 0}, + {"Func", Const, 0}, + {"FuncOf", Func, 5}, + {"Indirect", Func, 0}, + {"Int", Const, 0}, + {"Int16", Const, 0}, + {"Int32", Const, 0}, + {"Int64", Const, 0}, + {"Int8", Const, 0}, + {"Interface", Const, 0}, + {"Invalid", Const, 0}, + {"Kind", Type, 0}, + {"MakeChan", Func, 0}, + {"MakeFunc", Func, 1}, + {"MakeMap", Func, 0}, + {"MakeMapWithSize", Func, 9}, + {"MakeSlice", Func, 0}, + {"Map", Const, 0}, + {"MapIter", Type, 12}, + {"MapOf", Func, 1}, + {"Method", Type, 0}, + {"Method.Func", Field, 0}, + {"Method.Index", Field, 0}, + {"Method.Name", Field, 0}, + {"Method.PkgPath", Field, 0}, + {"Method.Type", Field, 0}, + {"New", Func, 0}, + {"NewAt", Func, 0}, + {"Pointer", Const, 18}, + {"PointerTo", Func, 18}, + {"Ptr", Const, 0}, + {"PtrTo", Func, 0}, + {"RecvDir", Const, 0}, + {"Select", Func, 1}, + {"SelectCase", Type, 1}, + {"SelectCase.Chan", Field, 1}, + {"SelectCase.Dir", Field, 1}, + {"SelectCase.Send", Field, 1}, + {"SelectDefault", Const, 1}, + {"SelectDir", Type, 1}, + {"SelectRecv", Const, 1}, + {"SelectSend", Const, 1}, + {"SendDir", Const, 0}, + {"Slice", Const, 0}, + {"SliceHeader", Type, 0}, + {"SliceHeader.Cap", Field, 0}, + {"SliceHeader.Data", Field, 0}, + {"SliceHeader.Len", Field, 0}, + {"SliceOf", Func, 1}, + {"String", Const, 0}, + {"StringHeader", Type, 0}, + {"StringHeader.Data", Field, 0}, + {"StringHeader.Len", Field, 0}, + {"Struct", Const, 0}, + {"StructField", Type, 0}, + {"StructField.Anonymous", Field, 0}, + {"StructField.Index", Field, 0}, + {"StructField.Name", Field, 0}, + {"StructField.Offset", Field, 0}, + {"StructField.PkgPath", Field, 0}, + {"StructField.Tag", Field, 0}, + {"StructField.Type", Field, 0}, + {"StructOf", Func, 7}, + {"StructTag", Type, 0}, + {"Swapper", Func, 8}, + {"Type", Type, 0}, + {"TypeFor", Func, 22}, + {"TypeOf", Func, 0}, + {"Uint", Const, 0}, + {"Uint16", Const, 0}, + {"Uint32", Const, 0}, + {"Uint64", Const, 0}, + {"Uint8", Const, 0}, + {"Uintptr", Const, 0}, + {"UnsafePointer", Const, 0}, + {"Value", Type, 0}, + {"ValueError", Type, 0}, + {"ValueError.Kind", Field, 0}, + {"ValueError.Method", Field, 0}, + {"ValueOf", Func, 0}, + {"VisibleFields", Func, 17}, + {"Zero", Func, 0}, + }, + "regexp": { + {"(*Regexp).Copy", Method, 6}, + {"(*Regexp).Expand", Method, 0}, + {"(*Regexp).ExpandString", Method, 0}, + {"(*Regexp).Find", Method, 0}, + {"(*Regexp).FindAll", Method, 0}, + {"(*Regexp).FindAllIndex", Method, 0}, + {"(*Regexp).FindAllString", Method, 0}, + {"(*Regexp).FindAllStringIndex", Method, 0}, + {"(*Regexp).FindAllStringSubmatch", Method, 0}, + {"(*Regexp).FindAllStringSubmatchIndex", Method, 0}, + {"(*Regexp).FindAllSubmatch", Method, 0}, + {"(*Regexp).FindAllSubmatchIndex", Method, 0}, + {"(*Regexp).FindIndex", Method, 0}, + {"(*Regexp).FindReaderIndex", Method, 0}, + {"(*Regexp).FindReaderSubmatchIndex", Method, 0}, + {"(*Regexp).FindString", Method, 0}, + {"(*Regexp).FindStringIndex", Method, 0}, + {"(*Regexp).FindStringSubmatch", Method, 0}, + {"(*Regexp).FindStringSubmatchIndex", Method, 0}, + {"(*Regexp).FindSubmatch", Method, 0}, + {"(*Regexp).FindSubmatchIndex", Method, 0}, + {"(*Regexp).LiteralPrefix", Method, 0}, + {"(*Regexp).Longest", Method, 1}, + {"(*Regexp).MarshalText", Method, 21}, + {"(*Regexp).Match", Method, 0}, + {"(*Regexp).MatchReader", Method, 0}, + {"(*Regexp).MatchString", Method, 0}, + {"(*Regexp).NumSubexp", Method, 0}, + {"(*Regexp).ReplaceAll", Method, 0}, + {"(*Regexp).ReplaceAllFunc", Method, 0}, + {"(*Regexp).ReplaceAllLiteral", Method, 0}, + {"(*Regexp).ReplaceAllLiteralString", Method, 0}, + {"(*Regexp).ReplaceAllString", Method, 0}, + {"(*Regexp).ReplaceAllStringFunc", Method, 0}, + {"(*Regexp).Split", Method, 1}, + {"(*Regexp).String", Method, 0}, + {"(*Regexp).SubexpIndex", Method, 15}, + {"(*Regexp).SubexpNames", Method, 0}, + {"(*Regexp).UnmarshalText", Method, 21}, + {"Compile", Func, 0}, + {"CompilePOSIX", Func, 0}, + {"Match", Func, 0}, + {"MatchReader", Func, 0}, + {"MatchString", Func, 0}, + {"MustCompile", Func, 0}, + {"MustCompilePOSIX", Func, 0}, + {"QuoteMeta", Func, 0}, + {"Regexp", Type, 0}, + }, + "regexp/syntax": { + {"(*Error).Error", Method, 0}, + {"(*Inst).MatchEmptyWidth", Method, 0}, + {"(*Inst).MatchRune", Method, 0}, + {"(*Inst).MatchRunePos", Method, 3}, + {"(*Inst).String", Method, 0}, + {"(*Prog).Prefix", Method, 0}, + {"(*Prog).StartCond", Method, 0}, + {"(*Prog).String", Method, 0}, + {"(*Regexp).CapNames", Method, 0}, + {"(*Regexp).Equal", Method, 0}, + {"(*Regexp).MaxCap", Method, 0}, + {"(*Regexp).Simplify", Method, 0}, + {"(*Regexp).String", Method, 0}, + {"(ErrorCode).String", Method, 0}, + {"(InstOp).String", Method, 3}, + {"(Op).String", Method, 11}, + {"ClassNL", Const, 0}, + {"Compile", Func, 0}, + {"DotNL", Const, 0}, + {"EmptyBeginLine", Const, 0}, + {"EmptyBeginText", Const, 0}, + {"EmptyEndLine", Const, 0}, + {"EmptyEndText", Const, 0}, + {"EmptyNoWordBoundary", Const, 0}, + {"EmptyOp", Type, 0}, + {"EmptyOpContext", Func, 0}, + {"EmptyWordBoundary", Const, 0}, + {"ErrInternalError", Const, 0}, + {"ErrInvalidCharClass", Const, 0}, + {"ErrInvalidCharRange", Const, 0}, + {"ErrInvalidEscape", Const, 0}, + {"ErrInvalidNamedCapture", Const, 0}, + {"ErrInvalidPerlOp", Const, 0}, + {"ErrInvalidRepeatOp", Const, 0}, + {"ErrInvalidRepeatSize", Const, 0}, + {"ErrInvalidUTF8", Const, 0}, + {"ErrLarge", Const, 20}, + {"ErrMissingBracket", Const, 0}, + {"ErrMissingParen", Const, 0}, + {"ErrMissingRepeatArgument", Const, 0}, + {"ErrNestingDepth", Const, 19}, + {"ErrTrailingBackslash", Const, 0}, + {"ErrUnexpectedParen", Const, 1}, + {"Error", Type, 0}, + {"Error.Code", Field, 0}, + {"Error.Expr", Field, 0}, + {"ErrorCode", Type, 0}, + {"Flags", Type, 0}, + {"FoldCase", Const, 0}, + {"Inst", Type, 0}, + {"Inst.Arg", Field, 0}, + {"Inst.Op", Field, 0}, + {"Inst.Out", Field, 0}, + {"Inst.Rune", Field, 0}, + {"InstAlt", Const, 0}, + {"InstAltMatch", Const, 0}, + {"InstCapture", Const, 0}, + {"InstEmptyWidth", Const, 0}, + {"InstFail", Const, 0}, + {"InstMatch", Const, 0}, + {"InstNop", Const, 0}, + {"InstOp", Type, 0}, + {"InstRune", Const, 0}, + {"InstRune1", Const, 0}, + {"InstRuneAny", Const, 0}, + {"InstRuneAnyNotNL", Const, 0}, + {"IsWordChar", Func, 0}, + {"Literal", Const, 0}, + {"MatchNL", Const, 0}, + {"NonGreedy", Const, 0}, + {"OneLine", Const, 0}, + {"Op", Type, 0}, + {"OpAlternate", Const, 0}, + {"OpAnyChar", Const, 0}, + {"OpAnyCharNotNL", Const, 0}, + {"OpBeginLine", Const, 0}, + {"OpBeginText", Const, 0}, + {"OpCapture", Const, 0}, + {"OpCharClass", Const, 0}, + {"OpConcat", Const, 0}, + {"OpEmptyMatch", Const, 0}, + {"OpEndLine", Const, 0}, + {"OpEndText", Const, 0}, + {"OpLiteral", Const, 0}, + {"OpNoMatch", Const, 0}, + {"OpNoWordBoundary", Const, 0}, + {"OpPlus", Const, 0}, + {"OpQuest", Const, 0}, + {"OpRepeat", Const, 0}, + {"OpStar", Const, 0}, + {"OpWordBoundary", Const, 0}, + {"POSIX", Const, 0}, + {"Parse", Func, 0}, + {"Perl", Const, 0}, + {"PerlX", Const, 0}, + {"Prog", Type, 0}, + {"Prog.Inst", Field, 0}, + {"Prog.NumCap", Field, 0}, + {"Prog.Start", Field, 0}, + {"Regexp", Type, 0}, + {"Regexp.Cap", Field, 0}, + {"Regexp.Flags", Field, 0}, + {"Regexp.Max", Field, 0}, + {"Regexp.Min", Field, 0}, + {"Regexp.Name", Field, 0}, + {"Regexp.Op", Field, 0}, + {"Regexp.Rune", Field, 0}, + {"Regexp.Rune0", Field, 0}, + {"Regexp.Sub", Field, 0}, + {"Regexp.Sub0", Field, 0}, + {"Simple", Const, 0}, + {"UnicodeGroups", Const, 0}, + {"WasDollar", Const, 0}, + }, + "runtime": { + {"(*BlockProfileRecord).Stack", Method, 1}, + {"(*Frames).Next", Method, 7}, + {"(*Func).Entry", Method, 0}, + {"(*Func).FileLine", Method, 0}, + {"(*Func).Name", Method, 0}, + {"(*MemProfileRecord).InUseBytes", Method, 0}, + {"(*MemProfileRecord).InUseObjects", Method, 0}, + {"(*MemProfileRecord).Stack", Method, 0}, + {"(*PanicNilError).Error", Method, 21}, + {"(*PanicNilError).RuntimeError", Method, 21}, + {"(*Pinner).Pin", Method, 21}, + {"(*Pinner).Unpin", Method, 21}, + {"(*StackRecord).Stack", Method, 0}, + {"(*TypeAssertionError).Error", Method, 0}, + {"(*TypeAssertionError).RuntimeError", Method, 0}, + {"BlockProfile", Func, 1}, + {"BlockProfileRecord", Type, 1}, + {"BlockProfileRecord.Count", Field, 1}, + {"BlockProfileRecord.Cycles", Field, 1}, + {"BlockProfileRecord.StackRecord", Field, 1}, + {"Breakpoint", Func, 0}, + {"CPUProfile", Func, 0}, + {"Caller", Func, 0}, + {"Callers", Func, 0}, + {"CallersFrames", Func, 7}, + {"Compiler", Const, 0}, + {"Error", Type, 0}, + {"Frame", Type, 7}, + {"Frame.Entry", Field, 7}, + {"Frame.File", Field, 7}, + {"Frame.Func", Field, 7}, + {"Frame.Function", Field, 7}, + {"Frame.Line", Field, 7}, + {"Frame.PC", Field, 7}, + {"Frames", Type, 7}, + {"Func", Type, 0}, + {"FuncForPC", Func, 0}, + {"GC", Func, 0}, + {"GOARCH", Const, 0}, + {"GOMAXPROCS", Func, 0}, + {"GOOS", Const, 0}, + {"GOROOT", Func, 0}, + {"Goexit", Func, 0}, + {"GoroutineProfile", Func, 0}, + {"Gosched", Func, 0}, + {"KeepAlive", Func, 7}, + {"LockOSThread", Func, 0}, + {"MemProfile", Func, 0}, + {"MemProfileRate", Var, 0}, + {"MemProfileRecord", Type, 0}, + {"MemProfileRecord.AllocBytes", Field, 0}, + {"MemProfileRecord.AllocObjects", Field, 0}, + {"MemProfileRecord.FreeBytes", Field, 0}, + {"MemProfileRecord.FreeObjects", Field, 0}, + {"MemProfileRecord.Stack0", Field, 0}, + {"MemStats", Type, 0}, + {"MemStats.Alloc", Field, 0}, + {"MemStats.BuckHashSys", Field, 0}, + {"MemStats.BySize", Field, 0}, + {"MemStats.DebugGC", Field, 0}, + {"MemStats.EnableGC", Field, 0}, + {"MemStats.Frees", Field, 0}, + {"MemStats.GCCPUFraction", Field, 5}, + {"MemStats.GCSys", Field, 2}, + {"MemStats.HeapAlloc", Field, 0}, + {"MemStats.HeapIdle", Field, 0}, + {"MemStats.HeapInuse", Field, 0}, + {"MemStats.HeapObjects", Field, 0}, + {"MemStats.HeapReleased", Field, 0}, + {"MemStats.HeapSys", Field, 0}, + {"MemStats.LastGC", Field, 0}, + {"MemStats.Lookups", Field, 0}, + {"MemStats.MCacheInuse", Field, 0}, + {"MemStats.MCacheSys", Field, 0}, + {"MemStats.MSpanInuse", Field, 0}, + {"MemStats.MSpanSys", Field, 0}, + {"MemStats.Mallocs", Field, 0}, + {"MemStats.NextGC", Field, 0}, + {"MemStats.NumForcedGC", Field, 8}, + {"MemStats.NumGC", Field, 0}, + {"MemStats.OtherSys", Field, 2}, + {"MemStats.PauseEnd", Field, 4}, + {"MemStats.PauseNs", Field, 0}, + {"MemStats.PauseTotalNs", Field, 0}, + {"MemStats.StackInuse", Field, 0}, + {"MemStats.StackSys", Field, 0}, + {"MemStats.Sys", Field, 0}, + {"MemStats.TotalAlloc", Field, 0}, + {"MutexProfile", Func, 8}, + {"NumCPU", Func, 0}, + {"NumCgoCall", Func, 0}, + {"NumGoroutine", Func, 0}, + {"PanicNilError", Type, 21}, + {"Pinner", Type, 21}, + {"ReadMemStats", Func, 0}, + {"ReadTrace", Func, 5}, + {"SetBlockProfileRate", Func, 1}, + {"SetCPUProfileRate", Func, 0}, + {"SetCgoTraceback", Func, 7}, + {"SetFinalizer", Func, 0}, + {"SetMutexProfileFraction", Func, 8}, + {"Stack", Func, 0}, + {"StackRecord", Type, 0}, + {"StackRecord.Stack0", Field, 0}, + {"StartTrace", Func, 5}, + {"StopTrace", Func, 5}, + {"ThreadCreateProfile", Func, 0}, + {"TypeAssertionError", Type, 0}, + {"UnlockOSThread", Func, 0}, + {"Version", Func, 0}, + }, + "runtime/cgo": { + {"(Handle).Delete", Method, 17}, + {"(Handle).Value", Method, 17}, + {"Handle", Type, 17}, + {"Incomplete", Type, 20}, + {"NewHandle", Func, 17}, + }, + "runtime/coverage": { + {"ClearCounters", Func, 20}, + {"WriteCounters", Func, 20}, + {"WriteCountersDir", Func, 20}, + {"WriteMeta", Func, 20}, + {"WriteMetaDir", Func, 20}, + }, + "runtime/debug": { + {"(*BuildInfo).String", Method, 18}, + {"BuildInfo", Type, 12}, + {"BuildInfo.Deps", Field, 12}, + {"BuildInfo.GoVersion", Field, 18}, + {"BuildInfo.Main", Field, 12}, + {"BuildInfo.Path", Field, 12}, + {"BuildInfo.Settings", Field, 18}, + {"BuildSetting", Type, 18}, + {"BuildSetting.Key", Field, 18}, + {"BuildSetting.Value", Field, 18}, + {"FreeOSMemory", Func, 1}, + {"GCStats", Type, 1}, + {"GCStats.LastGC", Field, 1}, + {"GCStats.NumGC", Field, 1}, + {"GCStats.Pause", Field, 1}, + {"GCStats.PauseEnd", Field, 4}, + {"GCStats.PauseQuantiles", Field, 1}, + {"GCStats.PauseTotal", Field, 1}, + {"Module", Type, 12}, + {"Module.Path", Field, 12}, + {"Module.Replace", Field, 12}, + {"Module.Sum", Field, 12}, + {"Module.Version", Field, 12}, + {"ParseBuildInfo", Func, 18}, + {"PrintStack", Func, 0}, + {"ReadBuildInfo", Func, 12}, + {"ReadGCStats", Func, 1}, + {"SetGCPercent", Func, 1}, + {"SetMaxStack", Func, 2}, + {"SetMaxThreads", Func, 2}, + {"SetMemoryLimit", Func, 19}, + {"SetPanicOnFault", Func, 3}, + {"SetTraceback", Func, 6}, + {"Stack", Func, 0}, + {"WriteHeapDump", Func, 3}, + }, + "runtime/metrics": { + {"(Value).Float64", Method, 16}, + {"(Value).Float64Histogram", Method, 16}, + {"(Value).Kind", Method, 16}, + {"(Value).Uint64", Method, 16}, + {"All", Func, 16}, + {"Description", Type, 16}, + {"Description.Cumulative", Field, 16}, + {"Description.Description", Field, 16}, + {"Description.Kind", Field, 16}, + {"Description.Name", Field, 16}, + {"Float64Histogram", Type, 16}, + {"Float64Histogram.Buckets", Field, 16}, + {"Float64Histogram.Counts", Field, 16}, + {"KindBad", Const, 16}, + {"KindFloat64", Const, 16}, + {"KindFloat64Histogram", Const, 16}, + {"KindUint64", Const, 16}, + {"Read", Func, 16}, + {"Sample", Type, 16}, + {"Sample.Name", Field, 16}, + {"Sample.Value", Field, 16}, + {"Value", Type, 16}, + {"ValueKind", Type, 16}, + }, + "runtime/pprof": { + {"(*Profile).Add", Method, 0}, + {"(*Profile).Count", Method, 0}, + {"(*Profile).Name", Method, 0}, + {"(*Profile).Remove", Method, 0}, + {"(*Profile).WriteTo", Method, 0}, + {"Do", Func, 9}, + {"ForLabels", Func, 9}, + {"Label", Func, 9}, + {"LabelSet", Type, 9}, + {"Labels", Func, 9}, + {"Lookup", Func, 0}, + {"NewProfile", Func, 0}, + {"Profile", Type, 0}, + {"Profiles", Func, 0}, + {"SetGoroutineLabels", Func, 9}, + {"StartCPUProfile", Func, 0}, + {"StopCPUProfile", Func, 0}, + {"WithLabels", Func, 9}, + {"WriteHeapProfile", Func, 0}, + }, + "runtime/trace": { + {"(*Region).End", Method, 11}, + {"(*Task).End", Method, 11}, + {"IsEnabled", Func, 11}, + {"Log", Func, 11}, + {"Logf", Func, 11}, + {"NewTask", Func, 11}, + {"Region", Type, 11}, + {"Start", Func, 5}, + {"StartRegion", Func, 11}, + {"Stop", Func, 5}, + {"Task", Type, 11}, + {"WithRegion", Func, 11}, + }, + "slices": { + {"BinarySearch", Func, 21}, + {"BinarySearchFunc", Func, 21}, + {"Clip", Func, 21}, + {"Clone", Func, 21}, + {"Compact", Func, 21}, + {"CompactFunc", Func, 21}, + {"Compare", Func, 21}, + {"CompareFunc", Func, 21}, + {"Concat", Func, 22}, + {"Contains", Func, 21}, + {"ContainsFunc", Func, 21}, + {"Delete", Func, 21}, + {"DeleteFunc", Func, 21}, + {"Equal", Func, 21}, + {"EqualFunc", Func, 21}, + {"Grow", Func, 21}, + {"Index", Func, 21}, + {"IndexFunc", Func, 21}, + {"Insert", Func, 21}, + {"IsSorted", Func, 21}, + {"IsSortedFunc", Func, 21}, + {"Max", Func, 21}, + {"MaxFunc", Func, 21}, + {"Min", Func, 21}, + {"MinFunc", Func, 21}, + {"Replace", Func, 21}, + {"Reverse", Func, 21}, + {"Sort", Func, 21}, + {"SortFunc", Func, 21}, + {"SortStableFunc", Func, 21}, + }, + "sort": { + {"(Float64Slice).Len", Method, 0}, + {"(Float64Slice).Less", Method, 0}, + {"(Float64Slice).Search", Method, 0}, + {"(Float64Slice).Sort", Method, 0}, + {"(Float64Slice).Swap", Method, 0}, + {"(IntSlice).Len", Method, 0}, + {"(IntSlice).Less", Method, 0}, + {"(IntSlice).Search", Method, 0}, + {"(IntSlice).Sort", Method, 0}, + {"(IntSlice).Swap", Method, 0}, + {"(StringSlice).Len", Method, 0}, + {"(StringSlice).Less", Method, 0}, + {"(StringSlice).Search", Method, 0}, + {"(StringSlice).Sort", Method, 0}, + {"(StringSlice).Swap", Method, 0}, + {"Find", Func, 19}, + {"Float64Slice", Type, 0}, + {"Float64s", Func, 0}, + {"Float64sAreSorted", Func, 0}, + {"IntSlice", Type, 0}, + {"Interface", Type, 0}, + {"Ints", Func, 0}, + {"IntsAreSorted", Func, 0}, + {"IsSorted", Func, 0}, + {"Reverse", Func, 1}, + {"Search", Func, 0}, + {"SearchFloat64s", Func, 0}, + {"SearchInts", Func, 0}, + {"SearchStrings", Func, 0}, + {"Slice", Func, 8}, + {"SliceIsSorted", Func, 8}, + {"SliceStable", Func, 8}, + {"Sort", Func, 0}, + {"Stable", Func, 2}, + {"StringSlice", Type, 0}, + {"Strings", Func, 0}, + {"StringsAreSorted", Func, 0}, + }, + "strconv": { + {"(*NumError).Error", Method, 0}, + {"(*NumError).Unwrap", Method, 14}, + {"AppendBool", Func, 0}, + {"AppendFloat", Func, 0}, + {"AppendInt", Func, 0}, + {"AppendQuote", Func, 0}, + {"AppendQuoteRune", Func, 0}, + {"AppendQuoteRuneToASCII", Func, 0}, + {"AppendQuoteRuneToGraphic", Func, 6}, + {"AppendQuoteToASCII", Func, 0}, + {"AppendQuoteToGraphic", Func, 6}, + {"AppendUint", Func, 0}, + {"Atoi", Func, 0}, + {"CanBackquote", Func, 0}, + {"ErrRange", Var, 0}, + {"ErrSyntax", Var, 0}, + {"FormatBool", Func, 0}, + {"FormatComplex", Func, 15}, + {"FormatFloat", Func, 0}, + {"FormatInt", Func, 0}, + {"FormatUint", Func, 0}, + {"IntSize", Const, 0}, + {"IsGraphic", Func, 6}, + {"IsPrint", Func, 0}, + {"Itoa", Func, 0}, + {"NumError", Type, 0}, + {"NumError.Err", Field, 0}, + {"NumError.Func", Field, 0}, + {"NumError.Num", Field, 0}, + {"ParseBool", Func, 0}, + {"ParseComplex", Func, 15}, + {"ParseFloat", Func, 0}, + {"ParseInt", Func, 0}, + {"ParseUint", Func, 0}, + {"Quote", Func, 0}, + {"QuoteRune", Func, 0}, + {"QuoteRuneToASCII", Func, 0}, + {"QuoteRuneToGraphic", Func, 6}, + {"QuoteToASCII", Func, 0}, + {"QuoteToGraphic", Func, 6}, + {"QuotedPrefix", Func, 17}, + {"Unquote", Func, 0}, + {"UnquoteChar", Func, 0}, + }, + "strings": { + {"(*Builder).Cap", Method, 12}, + {"(*Builder).Grow", Method, 10}, + {"(*Builder).Len", Method, 10}, + {"(*Builder).Reset", Method, 10}, + {"(*Builder).String", Method, 10}, + {"(*Builder).Write", Method, 10}, + {"(*Builder).WriteByte", Method, 10}, + {"(*Builder).WriteRune", Method, 10}, + {"(*Builder).WriteString", Method, 10}, + {"(*Reader).Len", Method, 0}, + {"(*Reader).Read", Method, 0}, + {"(*Reader).ReadAt", Method, 0}, + {"(*Reader).ReadByte", Method, 0}, + {"(*Reader).ReadRune", Method, 0}, + {"(*Reader).Reset", Method, 7}, + {"(*Reader).Seek", Method, 0}, + {"(*Reader).Size", Method, 5}, + {"(*Reader).UnreadByte", Method, 0}, + {"(*Reader).UnreadRune", Method, 0}, + {"(*Reader).WriteTo", Method, 1}, + {"(*Replacer).Replace", Method, 0}, + {"(*Replacer).WriteString", Method, 0}, + {"Builder", Type, 10}, + {"Clone", Func, 18}, + {"Compare", Func, 5}, + {"Contains", Func, 0}, + {"ContainsAny", Func, 0}, + {"ContainsFunc", Func, 21}, + {"ContainsRune", Func, 0}, + {"Count", Func, 0}, + {"Cut", Func, 18}, + {"CutPrefix", Func, 20}, + {"CutSuffix", Func, 20}, + {"EqualFold", Func, 0}, + {"Fields", Func, 0}, + {"FieldsFunc", Func, 0}, + {"HasPrefix", Func, 0}, + {"HasSuffix", Func, 0}, + {"Index", Func, 0}, + {"IndexAny", Func, 0}, + {"IndexByte", Func, 2}, + {"IndexFunc", Func, 0}, + {"IndexRune", Func, 0}, + {"Join", Func, 0}, + {"LastIndex", Func, 0}, + {"LastIndexAny", Func, 0}, + {"LastIndexByte", Func, 5}, + {"LastIndexFunc", Func, 0}, + {"Map", Func, 0}, + {"NewReader", Func, 0}, + {"NewReplacer", Func, 0}, + {"Reader", Type, 0}, + {"Repeat", Func, 0}, + {"Replace", Func, 0}, + {"ReplaceAll", Func, 12}, + {"Replacer", Type, 0}, + {"Split", Func, 0}, + {"SplitAfter", Func, 0}, + {"SplitAfterN", Func, 0}, + {"SplitN", Func, 0}, + {"Title", Func, 0}, + {"ToLower", Func, 0}, + {"ToLowerSpecial", Func, 0}, + {"ToTitle", Func, 0}, + {"ToTitleSpecial", Func, 0}, + {"ToUpper", Func, 0}, + {"ToUpperSpecial", Func, 0}, + {"ToValidUTF8", Func, 13}, + {"Trim", Func, 0}, + {"TrimFunc", Func, 0}, + {"TrimLeft", Func, 0}, + {"TrimLeftFunc", Func, 0}, + {"TrimPrefix", Func, 1}, + {"TrimRight", Func, 0}, + {"TrimRightFunc", Func, 0}, + {"TrimSpace", Func, 0}, + {"TrimSuffix", Func, 1}, + }, + "sync": { + {"(*Cond).Broadcast", Method, 0}, + {"(*Cond).Signal", Method, 0}, + {"(*Cond).Wait", Method, 0}, + {"(*Map).CompareAndDelete", Method, 20}, + {"(*Map).CompareAndSwap", Method, 20}, + {"(*Map).Delete", Method, 9}, + {"(*Map).Load", Method, 9}, + {"(*Map).LoadAndDelete", Method, 15}, + {"(*Map).LoadOrStore", Method, 9}, + {"(*Map).Range", Method, 9}, + {"(*Map).Store", Method, 9}, + {"(*Map).Swap", Method, 20}, + {"(*Mutex).Lock", Method, 0}, + {"(*Mutex).TryLock", Method, 18}, + {"(*Mutex).Unlock", Method, 0}, + {"(*Once).Do", Method, 0}, + {"(*Pool).Get", Method, 3}, + {"(*Pool).Put", Method, 3}, + {"(*RWMutex).Lock", Method, 0}, + {"(*RWMutex).RLock", Method, 0}, + {"(*RWMutex).RLocker", Method, 0}, + {"(*RWMutex).RUnlock", Method, 0}, + {"(*RWMutex).TryLock", Method, 18}, + {"(*RWMutex).TryRLock", Method, 18}, + {"(*RWMutex).Unlock", Method, 0}, + {"(*WaitGroup).Add", Method, 0}, + {"(*WaitGroup).Done", Method, 0}, + {"(*WaitGroup).Wait", Method, 0}, + {"Cond", Type, 0}, + {"Cond.L", Field, 0}, + {"Locker", Type, 0}, + {"Map", Type, 9}, + {"Mutex", Type, 0}, + {"NewCond", Func, 0}, + {"Once", Type, 0}, + {"OnceFunc", Func, 21}, + {"OnceValue", Func, 21}, + {"OnceValues", Func, 21}, + {"Pool", Type, 3}, + {"Pool.New", Field, 3}, + {"RWMutex", Type, 0}, + {"WaitGroup", Type, 0}, + }, + "sync/atomic": { + {"(*Bool).CompareAndSwap", Method, 19}, + {"(*Bool).Load", Method, 19}, + {"(*Bool).Store", Method, 19}, + {"(*Bool).Swap", Method, 19}, + {"(*Int32).Add", Method, 19}, + {"(*Int32).CompareAndSwap", Method, 19}, + {"(*Int32).Load", Method, 19}, + {"(*Int32).Store", Method, 19}, + {"(*Int32).Swap", Method, 19}, + {"(*Int64).Add", Method, 19}, + {"(*Int64).CompareAndSwap", Method, 19}, + {"(*Int64).Load", Method, 19}, + {"(*Int64).Store", Method, 19}, + {"(*Int64).Swap", Method, 19}, + {"(*Pointer).CompareAndSwap", Method, 19}, + {"(*Pointer).Load", Method, 19}, + {"(*Pointer).Store", Method, 19}, + {"(*Pointer).Swap", Method, 19}, + {"(*Uint32).Add", Method, 19}, + {"(*Uint32).CompareAndSwap", Method, 19}, + {"(*Uint32).Load", Method, 19}, + {"(*Uint32).Store", Method, 19}, + {"(*Uint32).Swap", Method, 19}, + {"(*Uint64).Add", Method, 19}, + {"(*Uint64).CompareAndSwap", Method, 19}, + {"(*Uint64).Load", Method, 19}, + {"(*Uint64).Store", Method, 19}, + {"(*Uint64).Swap", Method, 19}, + {"(*Uintptr).Add", Method, 19}, + {"(*Uintptr).CompareAndSwap", Method, 19}, + {"(*Uintptr).Load", Method, 19}, + {"(*Uintptr).Store", Method, 19}, + {"(*Uintptr).Swap", Method, 19}, + {"(*Value).CompareAndSwap", Method, 17}, + {"(*Value).Load", Method, 4}, + {"(*Value).Store", Method, 4}, + {"(*Value).Swap", Method, 17}, + {"AddInt32", Func, 0}, + {"AddInt64", Func, 0}, + {"AddUint32", Func, 0}, + {"AddUint64", Func, 0}, + {"AddUintptr", Func, 0}, + {"Bool", Type, 19}, + {"CompareAndSwapInt32", Func, 0}, + {"CompareAndSwapInt64", Func, 0}, + {"CompareAndSwapPointer", Func, 0}, + {"CompareAndSwapUint32", Func, 0}, + {"CompareAndSwapUint64", Func, 0}, + {"CompareAndSwapUintptr", Func, 0}, + {"Int32", Type, 19}, + {"Int64", Type, 19}, + {"LoadInt32", Func, 0}, + {"LoadInt64", Func, 0}, + {"LoadPointer", Func, 0}, + {"LoadUint32", Func, 0}, + {"LoadUint64", Func, 0}, + {"LoadUintptr", Func, 0}, + {"Pointer", Type, 19}, + {"StoreInt32", Func, 0}, + {"StoreInt64", Func, 0}, + {"StorePointer", Func, 0}, + {"StoreUint32", Func, 0}, + {"StoreUint64", Func, 0}, + {"StoreUintptr", Func, 0}, + {"SwapInt32", Func, 2}, + {"SwapInt64", Func, 2}, + {"SwapPointer", Func, 2}, + {"SwapUint32", Func, 2}, + {"SwapUint64", Func, 2}, + {"SwapUintptr", Func, 2}, + {"Uint32", Type, 19}, + {"Uint64", Type, 19}, + {"Uintptr", Type, 19}, + {"Value", Type, 4}, + }, + "syscall": { + {"(*Cmsghdr).SetLen", Method, 0}, + {"(*DLL).FindProc", Method, 0}, + {"(*DLL).MustFindProc", Method, 0}, + {"(*DLL).Release", Method, 0}, + {"(*DLLError).Error", Method, 0}, + {"(*DLLError).Unwrap", Method, 16}, + {"(*Filetime).Nanoseconds", Method, 0}, + {"(*Iovec).SetLen", Method, 0}, + {"(*LazyDLL).Handle", Method, 0}, + {"(*LazyDLL).Load", Method, 0}, + {"(*LazyDLL).NewProc", Method, 0}, + {"(*LazyProc).Addr", Method, 0}, + {"(*LazyProc).Call", Method, 0}, + {"(*LazyProc).Find", Method, 0}, + {"(*Msghdr).SetControllen", Method, 0}, + {"(*Proc).Addr", Method, 0}, + {"(*Proc).Call", Method, 0}, + {"(*PtraceRegs).PC", Method, 0}, + {"(*PtraceRegs).SetPC", Method, 0}, + {"(*RawSockaddrAny).Sockaddr", Method, 0}, + {"(*SID).Copy", Method, 0}, + {"(*SID).Len", Method, 0}, + {"(*SID).LookupAccount", Method, 0}, + {"(*SID).String", Method, 0}, + {"(*Timespec).Nano", Method, 0}, + {"(*Timespec).Unix", Method, 0}, + {"(*Timeval).Nano", Method, 0}, + {"(*Timeval).Nanoseconds", Method, 0}, + {"(*Timeval).Unix", Method, 0}, + {"(Errno).Error", Method, 0}, + {"(Errno).Is", Method, 13}, + {"(Errno).Temporary", Method, 0}, + {"(Errno).Timeout", Method, 0}, + {"(Signal).Signal", Method, 0}, + {"(Signal).String", Method, 0}, + {"(Token).Close", Method, 0}, + {"(Token).GetTokenPrimaryGroup", Method, 0}, + {"(Token).GetTokenUser", Method, 0}, + {"(Token).GetUserProfileDirectory", Method, 0}, + {"(WaitStatus).Continued", Method, 0}, + {"(WaitStatus).CoreDump", Method, 0}, + {"(WaitStatus).ExitStatus", Method, 0}, + {"(WaitStatus).Exited", Method, 0}, + {"(WaitStatus).Signal", Method, 0}, + {"(WaitStatus).Signaled", Method, 0}, + {"(WaitStatus).StopSignal", Method, 0}, + {"(WaitStatus).Stopped", Method, 0}, + {"(WaitStatus).TrapCause", Method, 0}, + {"AF_ALG", Const, 0}, + {"AF_APPLETALK", Const, 0}, + {"AF_ARP", Const, 0}, + {"AF_ASH", Const, 0}, + {"AF_ATM", Const, 0}, + {"AF_ATMPVC", Const, 0}, + {"AF_ATMSVC", Const, 0}, + {"AF_AX25", Const, 0}, + {"AF_BLUETOOTH", Const, 0}, + {"AF_BRIDGE", Const, 0}, + {"AF_CAIF", Const, 0}, + {"AF_CAN", Const, 0}, + {"AF_CCITT", Const, 0}, + {"AF_CHAOS", Const, 0}, + {"AF_CNT", Const, 0}, + {"AF_COIP", Const, 0}, + {"AF_DATAKIT", Const, 0}, + {"AF_DECnet", Const, 0}, + {"AF_DLI", Const, 0}, + {"AF_E164", Const, 0}, + {"AF_ECMA", Const, 0}, + {"AF_ECONET", Const, 0}, + {"AF_ENCAP", Const, 1}, + {"AF_FILE", Const, 0}, + {"AF_HYLINK", Const, 0}, + {"AF_IEEE80211", Const, 0}, + {"AF_IEEE802154", Const, 0}, + {"AF_IMPLINK", Const, 0}, + {"AF_INET", Const, 0}, + {"AF_INET6", Const, 0}, + {"AF_INET6_SDP", Const, 3}, + {"AF_INET_SDP", Const, 3}, + {"AF_IPX", Const, 0}, + {"AF_IRDA", Const, 0}, + {"AF_ISDN", Const, 0}, + {"AF_ISO", Const, 0}, + {"AF_IUCV", Const, 0}, + {"AF_KEY", Const, 0}, + {"AF_LAT", Const, 0}, + {"AF_LINK", Const, 0}, + {"AF_LLC", Const, 0}, + {"AF_LOCAL", Const, 0}, + {"AF_MAX", Const, 0}, + {"AF_MPLS", Const, 1}, + {"AF_NATM", Const, 0}, + {"AF_NDRV", Const, 0}, + {"AF_NETBEUI", Const, 0}, + {"AF_NETBIOS", Const, 0}, + {"AF_NETGRAPH", Const, 0}, + {"AF_NETLINK", Const, 0}, + {"AF_NETROM", Const, 0}, + {"AF_NS", Const, 0}, + {"AF_OROUTE", Const, 1}, + {"AF_OSI", Const, 0}, + {"AF_PACKET", Const, 0}, + {"AF_PHONET", Const, 0}, + {"AF_PPP", Const, 0}, + {"AF_PPPOX", Const, 0}, + {"AF_PUP", Const, 0}, + {"AF_RDS", Const, 0}, + {"AF_RESERVED_36", Const, 0}, + {"AF_ROSE", Const, 0}, + {"AF_ROUTE", Const, 0}, + {"AF_RXRPC", Const, 0}, + {"AF_SCLUSTER", Const, 0}, + {"AF_SECURITY", Const, 0}, + {"AF_SIP", Const, 0}, + {"AF_SLOW", Const, 0}, + {"AF_SNA", Const, 0}, + {"AF_SYSTEM", Const, 0}, + {"AF_TIPC", Const, 0}, + {"AF_UNIX", Const, 0}, + {"AF_UNSPEC", Const, 0}, + {"AF_UTUN", Const, 16}, + {"AF_VENDOR00", Const, 0}, + {"AF_VENDOR01", Const, 0}, + {"AF_VENDOR02", Const, 0}, + {"AF_VENDOR03", Const, 0}, + {"AF_VENDOR04", Const, 0}, + {"AF_VENDOR05", Const, 0}, + {"AF_VENDOR06", Const, 0}, + {"AF_VENDOR07", Const, 0}, + {"AF_VENDOR08", Const, 0}, + {"AF_VENDOR09", Const, 0}, + {"AF_VENDOR10", Const, 0}, + {"AF_VENDOR11", Const, 0}, + {"AF_VENDOR12", Const, 0}, + {"AF_VENDOR13", Const, 0}, + {"AF_VENDOR14", Const, 0}, + {"AF_VENDOR15", Const, 0}, + {"AF_VENDOR16", Const, 0}, + {"AF_VENDOR17", Const, 0}, + {"AF_VENDOR18", Const, 0}, + {"AF_VENDOR19", Const, 0}, + {"AF_VENDOR20", Const, 0}, + {"AF_VENDOR21", Const, 0}, + {"AF_VENDOR22", Const, 0}, + {"AF_VENDOR23", Const, 0}, + {"AF_VENDOR24", Const, 0}, + {"AF_VENDOR25", Const, 0}, + {"AF_VENDOR26", Const, 0}, + {"AF_VENDOR27", Const, 0}, + {"AF_VENDOR28", Const, 0}, + {"AF_VENDOR29", Const, 0}, + {"AF_VENDOR30", Const, 0}, + {"AF_VENDOR31", Const, 0}, + {"AF_VENDOR32", Const, 0}, + {"AF_VENDOR33", Const, 0}, + {"AF_VENDOR34", Const, 0}, + {"AF_VENDOR35", Const, 0}, + {"AF_VENDOR36", Const, 0}, + {"AF_VENDOR37", Const, 0}, + {"AF_VENDOR38", Const, 0}, + {"AF_VENDOR39", Const, 0}, + {"AF_VENDOR40", Const, 0}, + {"AF_VENDOR41", Const, 0}, + {"AF_VENDOR42", Const, 0}, + {"AF_VENDOR43", Const, 0}, + {"AF_VENDOR44", Const, 0}, + {"AF_VENDOR45", Const, 0}, + {"AF_VENDOR46", Const, 0}, + {"AF_VENDOR47", Const, 0}, + {"AF_WANPIPE", Const, 0}, + {"AF_X25", Const, 0}, + {"AI_CANONNAME", Const, 1}, + {"AI_NUMERICHOST", Const, 1}, + {"AI_PASSIVE", Const, 1}, + {"APPLICATION_ERROR", Const, 0}, + {"ARPHRD_ADAPT", Const, 0}, + {"ARPHRD_APPLETLK", Const, 0}, + {"ARPHRD_ARCNET", Const, 0}, + {"ARPHRD_ASH", Const, 0}, + {"ARPHRD_ATM", Const, 0}, + {"ARPHRD_AX25", Const, 0}, + {"ARPHRD_BIF", Const, 0}, + {"ARPHRD_CHAOS", Const, 0}, + {"ARPHRD_CISCO", Const, 0}, + {"ARPHRD_CSLIP", Const, 0}, + {"ARPHRD_CSLIP6", Const, 0}, + {"ARPHRD_DDCMP", Const, 0}, + {"ARPHRD_DLCI", Const, 0}, + {"ARPHRD_ECONET", Const, 0}, + {"ARPHRD_EETHER", Const, 0}, + {"ARPHRD_ETHER", Const, 0}, + {"ARPHRD_EUI64", Const, 0}, + {"ARPHRD_FCAL", Const, 0}, + {"ARPHRD_FCFABRIC", Const, 0}, + {"ARPHRD_FCPL", Const, 0}, + {"ARPHRD_FCPP", Const, 0}, + {"ARPHRD_FDDI", Const, 0}, + {"ARPHRD_FRAD", Const, 0}, + {"ARPHRD_FRELAY", Const, 1}, + {"ARPHRD_HDLC", Const, 0}, + {"ARPHRD_HIPPI", Const, 0}, + {"ARPHRD_HWX25", Const, 0}, + {"ARPHRD_IEEE1394", Const, 0}, + {"ARPHRD_IEEE802", Const, 0}, + {"ARPHRD_IEEE80211", Const, 0}, + {"ARPHRD_IEEE80211_PRISM", Const, 0}, + {"ARPHRD_IEEE80211_RADIOTAP", Const, 0}, + {"ARPHRD_IEEE802154", Const, 0}, + {"ARPHRD_IEEE802154_PHY", Const, 0}, + {"ARPHRD_IEEE802_TR", Const, 0}, + {"ARPHRD_INFINIBAND", Const, 0}, + {"ARPHRD_IPDDP", Const, 0}, + {"ARPHRD_IPGRE", Const, 0}, + {"ARPHRD_IRDA", Const, 0}, + {"ARPHRD_LAPB", Const, 0}, + {"ARPHRD_LOCALTLK", Const, 0}, + {"ARPHRD_LOOPBACK", Const, 0}, + {"ARPHRD_METRICOM", Const, 0}, + {"ARPHRD_NETROM", Const, 0}, + {"ARPHRD_NONE", Const, 0}, + {"ARPHRD_PIMREG", Const, 0}, + {"ARPHRD_PPP", Const, 0}, + {"ARPHRD_PRONET", Const, 0}, + {"ARPHRD_RAWHDLC", Const, 0}, + {"ARPHRD_ROSE", Const, 0}, + {"ARPHRD_RSRVD", Const, 0}, + {"ARPHRD_SIT", Const, 0}, + {"ARPHRD_SKIP", Const, 0}, + {"ARPHRD_SLIP", Const, 0}, + {"ARPHRD_SLIP6", Const, 0}, + {"ARPHRD_STRIP", Const, 1}, + {"ARPHRD_TUNNEL", Const, 0}, + {"ARPHRD_TUNNEL6", Const, 0}, + {"ARPHRD_VOID", Const, 0}, + {"ARPHRD_X25", Const, 0}, + {"AUTHTYPE_CLIENT", Const, 0}, + {"AUTHTYPE_SERVER", Const, 0}, + {"Accept", Func, 0}, + {"Accept4", Func, 1}, + {"AcceptEx", Func, 0}, + {"Access", Func, 0}, + {"Acct", Func, 0}, + {"AddrinfoW", Type, 1}, + {"AddrinfoW.Addr", Field, 1}, + {"AddrinfoW.Addrlen", Field, 1}, + {"AddrinfoW.Canonname", Field, 1}, + {"AddrinfoW.Family", Field, 1}, + {"AddrinfoW.Flags", Field, 1}, + {"AddrinfoW.Next", Field, 1}, + {"AddrinfoW.Protocol", Field, 1}, + {"AddrinfoW.Socktype", Field, 1}, + {"Adjtime", Func, 0}, + {"Adjtimex", Func, 0}, + {"AllThreadsSyscall", Func, 16}, + {"AllThreadsSyscall6", Func, 16}, + {"AttachLsf", Func, 0}, + {"B0", Const, 0}, + {"B1000000", Const, 0}, + {"B110", Const, 0}, + {"B115200", Const, 0}, + {"B1152000", Const, 0}, + {"B1200", Const, 0}, + {"B134", Const, 0}, + {"B14400", Const, 1}, + {"B150", Const, 0}, + {"B1500000", Const, 0}, + {"B1800", Const, 0}, + {"B19200", Const, 0}, + {"B200", Const, 0}, + {"B2000000", Const, 0}, + {"B230400", Const, 0}, + {"B2400", Const, 0}, + {"B2500000", Const, 0}, + {"B28800", Const, 1}, + {"B300", Const, 0}, + {"B3000000", Const, 0}, + {"B3500000", Const, 0}, + {"B38400", Const, 0}, + {"B4000000", Const, 0}, + {"B460800", Const, 0}, + {"B4800", Const, 0}, + {"B50", Const, 0}, + {"B500000", Const, 0}, + {"B57600", Const, 0}, + {"B576000", Const, 0}, + {"B600", Const, 0}, + {"B7200", Const, 1}, + {"B75", Const, 0}, + {"B76800", Const, 1}, + {"B921600", Const, 0}, + {"B9600", Const, 0}, + {"BASE_PROTOCOL", Const, 2}, + {"BIOCFEEDBACK", Const, 0}, + {"BIOCFLUSH", Const, 0}, + {"BIOCGBLEN", Const, 0}, + {"BIOCGDIRECTION", Const, 0}, + {"BIOCGDIRFILT", Const, 1}, + {"BIOCGDLT", Const, 0}, + {"BIOCGDLTLIST", Const, 0}, + {"BIOCGETBUFMODE", Const, 0}, + {"BIOCGETIF", Const, 0}, + {"BIOCGETZMAX", Const, 0}, + {"BIOCGFEEDBACK", Const, 1}, + {"BIOCGFILDROP", Const, 1}, + {"BIOCGHDRCMPLT", Const, 0}, + {"BIOCGRSIG", Const, 0}, + {"BIOCGRTIMEOUT", Const, 0}, + {"BIOCGSEESENT", Const, 0}, + {"BIOCGSTATS", Const, 0}, + {"BIOCGSTATSOLD", Const, 1}, + {"BIOCGTSTAMP", Const, 1}, + {"BIOCIMMEDIATE", Const, 0}, + {"BIOCLOCK", Const, 0}, + {"BIOCPROMISC", Const, 0}, + {"BIOCROTZBUF", Const, 0}, + {"BIOCSBLEN", Const, 0}, + {"BIOCSDIRECTION", Const, 0}, + {"BIOCSDIRFILT", Const, 1}, + {"BIOCSDLT", Const, 0}, + {"BIOCSETBUFMODE", Const, 0}, + {"BIOCSETF", Const, 0}, + {"BIOCSETFNR", Const, 0}, + {"BIOCSETIF", Const, 0}, + {"BIOCSETWF", Const, 0}, + {"BIOCSETZBUF", Const, 0}, + {"BIOCSFEEDBACK", Const, 1}, + {"BIOCSFILDROP", Const, 1}, + {"BIOCSHDRCMPLT", Const, 0}, + {"BIOCSRSIG", Const, 0}, + {"BIOCSRTIMEOUT", Const, 0}, + {"BIOCSSEESENT", Const, 0}, + {"BIOCSTCPF", Const, 1}, + {"BIOCSTSTAMP", Const, 1}, + {"BIOCSUDPF", Const, 1}, + {"BIOCVERSION", Const, 0}, + {"BPF_A", Const, 0}, + {"BPF_ABS", Const, 0}, + {"BPF_ADD", Const, 0}, + {"BPF_ALIGNMENT", Const, 0}, + {"BPF_ALIGNMENT32", Const, 1}, + {"BPF_ALU", Const, 0}, + {"BPF_AND", Const, 0}, + {"BPF_B", Const, 0}, + {"BPF_BUFMODE_BUFFER", Const, 0}, + {"BPF_BUFMODE_ZBUF", Const, 0}, + {"BPF_DFLTBUFSIZE", Const, 1}, + {"BPF_DIRECTION_IN", Const, 1}, + {"BPF_DIRECTION_OUT", Const, 1}, + {"BPF_DIV", Const, 0}, + {"BPF_H", Const, 0}, + {"BPF_IMM", Const, 0}, + {"BPF_IND", Const, 0}, + {"BPF_JA", Const, 0}, + {"BPF_JEQ", Const, 0}, + {"BPF_JGE", Const, 0}, + {"BPF_JGT", Const, 0}, + {"BPF_JMP", Const, 0}, + {"BPF_JSET", Const, 0}, + {"BPF_K", Const, 0}, + {"BPF_LD", Const, 0}, + {"BPF_LDX", Const, 0}, + {"BPF_LEN", Const, 0}, + {"BPF_LSH", Const, 0}, + {"BPF_MAJOR_VERSION", Const, 0}, + {"BPF_MAXBUFSIZE", Const, 0}, + {"BPF_MAXINSNS", Const, 0}, + {"BPF_MEM", Const, 0}, + {"BPF_MEMWORDS", Const, 0}, + {"BPF_MINBUFSIZE", Const, 0}, + {"BPF_MINOR_VERSION", Const, 0}, + {"BPF_MISC", Const, 0}, + {"BPF_MSH", Const, 0}, + {"BPF_MUL", Const, 0}, + {"BPF_NEG", Const, 0}, + {"BPF_OR", Const, 0}, + {"BPF_RELEASE", Const, 0}, + {"BPF_RET", Const, 0}, + {"BPF_RSH", Const, 0}, + {"BPF_ST", Const, 0}, + {"BPF_STX", Const, 0}, + {"BPF_SUB", Const, 0}, + {"BPF_TAX", Const, 0}, + {"BPF_TXA", Const, 0}, + {"BPF_T_BINTIME", Const, 1}, + {"BPF_T_BINTIME_FAST", Const, 1}, + {"BPF_T_BINTIME_MONOTONIC", Const, 1}, + {"BPF_T_BINTIME_MONOTONIC_FAST", Const, 1}, + {"BPF_T_FAST", Const, 1}, + {"BPF_T_FLAG_MASK", Const, 1}, + {"BPF_T_FORMAT_MASK", Const, 1}, + {"BPF_T_MICROTIME", Const, 1}, + {"BPF_T_MICROTIME_FAST", Const, 1}, + {"BPF_T_MICROTIME_MONOTONIC", Const, 1}, + {"BPF_T_MICROTIME_MONOTONIC_FAST", Const, 1}, + {"BPF_T_MONOTONIC", Const, 1}, + {"BPF_T_MONOTONIC_FAST", Const, 1}, + {"BPF_T_NANOTIME", Const, 1}, + {"BPF_T_NANOTIME_FAST", Const, 1}, + {"BPF_T_NANOTIME_MONOTONIC", Const, 1}, + {"BPF_T_NANOTIME_MONOTONIC_FAST", Const, 1}, + {"BPF_T_NONE", Const, 1}, + {"BPF_T_NORMAL", Const, 1}, + {"BPF_W", Const, 0}, + {"BPF_X", Const, 0}, + {"BRKINT", Const, 0}, + {"Bind", Func, 0}, + {"BindToDevice", Func, 0}, + {"BpfBuflen", Func, 0}, + {"BpfDatalink", Func, 0}, + {"BpfHdr", Type, 0}, + {"BpfHdr.Caplen", Field, 0}, + {"BpfHdr.Datalen", Field, 0}, + {"BpfHdr.Hdrlen", Field, 0}, + {"BpfHdr.Pad_cgo_0", Field, 0}, + {"BpfHdr.Tstamp", Field, 0}, + {"BpfHeadercmpl", Func, 0}, + {"BpfInsn", Type, 0}, + {"BpfInsn.Code", Field, 0}, + {"BpfInsn.Jf", Field, 0}, + {"BpfInsn.Jt", Field, 0}, + {"BpfInsn.K", Field, 0}, + {"BpfInterface", Func, 0}, + {"BpfJump", Func, 0}, + {"BpfProgram", Type, 0}, + {"BpfProgram.Insns", Field, 0}, + {"BpfProgram.Len", Field, 0}, + {"BpfProgram.Pad_cgo_0", Field, 0}, + {"BpfStat", Type, 0}, + {"BpfStat.Capt", Field, 2}, + {"BpfStat.Drop", Field, 0}, + {"BpfStat.Padding", Field, 2}, + {"BpfStat.Recv", Field, 0}, + {"BpfStats", Func, 0}, + {"BpfStmt", Func, 0}, + {"BpfTimeout", Func, 0}, + {"BpfTimeval", Type, 2}, + {"BpfTimeval.Sec", Field, 2}, + {"BpfTimeval.Usec", Field, 2}, + {"BpfVersion", Type, 0}, + {"BpfVersion.Major", Field, 0}, + {"BpfVersion.Minor", Field, 0}, + {"BpfZbuf", Type, 0}, + {"BpfZbuf.Bufa", Field, 0}, + {"BpfZbuf.Bufb", Field, 0}, + {"BpfZbuf.Buflen", Field, 0}, + {"BpfZbufHeader", Type, 0}, + {"BpfZbufHeader.Kernel_gen", Field, 0}, + {"BpfZbufHeader.Kernel_len", Field, 0}, + {"BpfZbufHeader.User_gen", Field, 0}, + {"BpfZbufHeader.X_bzh_pad", Field, 0}, + {"ByHandleFileInformation", Type, 0}, + {"ByHandleFileInformation.CreationTime", Field, 0}, + {"ByHandleFileInformation.FileAttributes", Field, 0}, + {"ByHandleFileInformation.FileIndexHigh", Field, 0}, + {"ByHandleFileInformation.FileIndexLow", Field, 0}, + {"ByHandleFileInformation.FileSizeHigh", Field, 0}, + {"ByHandleFileInformation.FileSizeLow", Field, 0}, + {"ByHandleFileInformation.LastAccessTime", Field, 0}, + {"ByHandleFileInformation.LastWriteTime", Field, 0}, + {"ByHandleFileInformation.NumberOfLinks", Field, 0}, + {"ByHandleFileInformation.VolumeSerialNumber", Field, 0}, + {"BytePtrFromString", Func, 1}, + {"ByteSliceFromString", Func, 1}, + {"CCR0_FLUSH", Const, 1}, + {"CERT_CHAIN_POLICY_AUTHENTICODE", Const, 0}, + {"CERT_CHAIN_POLICY_AUTHENTICODE_TS", Const, 0}, + {"CERT_CHAIN_POLICY_BASE", Const, 0}, + {"CERT_CHAIN_POLICY_BASIC_CONSTRAINTS", Const, 0}, + {"CERT_CHAIN_POLICY_EV", Const, 0}, + {"CERT_CHAIN_POLICY_MICROSOFT_ROOT", Const, 0}, + {"CERT_CHAIN_POLICY_NT_AUTH", Const, 0}, + {"CERT_CHAIN_POLICY_SSL", Const, 0}, + {"CERT_E_CN_NO_MATCH", Const, 0}, + {"CERT_E_EXPIRED", Const, 0}, + {"CERT_E_PURPOSE", Const, 0}, + {"CERT_E_ROLE", Const, 0}, + {"CERT_E_UNTRUSTEDROOT", Const, 0}, + {"CERT_STORE_ADD_ALWAYS", Const, 0}, + {"CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG", Const, 0}, + {"CERT_STORE_PROV_MEMORY", Const, 0}, + {"CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT", Const, 0}, + {"CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT", Const, 0}, + {"CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT", Const, 0}, + {"CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT", Const, 0}, + {"CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT", Const, 0}, + {"CERT_TRUST_INVALID_BASIC_CONSTRAINTS", Const, 0}, + {"CERT_TRUST_INVALID_EXTENSION", Const, 0}, + {"CERT_TRUST_INVALID_NAME_CONSTRAINTS", Const, 0}, + {"CERT_TRUST_INVALID_POLICY_CONSTRAINTS", Const, 0}, + {"CERT_TRUST_IS_CYCLIC", Const, 0}, + {"CERT_TRUST_IS_EXPLICIT_DISTRUST", Const, 0}, + {"CERT_TRUST_IS_NOT_SIGNATURE_VALID", Const, 0}, + {"CERT_TRUST_IS_NOT_TIME_VALID", Const, 0}, + {"CERT_TRUST_IS_NOT_VALID_FOR_USAGE", Const, 0}, + {"CERT_TRUST_IS_OFFLINE_REVOCATION", Const, 0}, + {"CERT_TRUST_IS_REVOKED", Const, 0}, + {"CERT_TRUST_IS_UNTRUSTED_ROOT", Const, 0}, + {"CERT_TRUST_NO_ERROR", Const, 0}, + {"CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY", Const, 0}, + {"CERT_TRUST_REVOCATION_STATUS_UNKNOWN", Const, 0}, + {"CFLUSH", Const, 1}, + {"CLOCAL", Const, 0}, + {"CLONE_CHILD_CLEARTID", Const, 2}, + {"CLONE_CHILD_SETTID", Const, 2}, + {"CLONE_CLEAR_SIGHAND", Const, 20}, + {"CLONE_CSIGNAL", Const, 3}, + {"CLONE_DETACHED", Const, 2}, + {"CLONE_FILES", Const, 2}, + {"CLONE_FS", Const, 2}, + {"CLONE_INTO_CGROUP", Const, 20}, + {"CLONE_IO", Const, 2}, + {"CLONE_NEWCGROUP", Const, 20}, + {"CLONE_NEWIPC", Const, 2}, + {"CLONE_NEWNET", Const, 2}, + {"CLONE_NEWNS", Const, 2}, + {"CLONE_NEWPID", Const, 2}, + {"CLONE_NEWTIME", Const, 20}, + {"CLONE_NEWUSER", Const, 2}, + {"CLONE_NEWUTS", Const, 2}, + {"CLONE_PARENT", Const, 2}, + {"CLONE_PARENT_SETTID", Const, 2}, + {"CLONE_PID", Const, 3}, + {"CLONE_PIDFD", Const, 20}, + {"CLONE_PTRACE", Const, 2}, + {"CLONE_SETTLS", Const, 2}, + {"CLONE_SIGHAND", Const, 2}, + {"CLONE_SYSVSEM", Const, 2}, + {"CLONE_THREAD", Const, 2}, + {"CLONE_UNTRACED", Const, 2}, + {"CLONE_VFORK", Const, 2}, + {"CLONE_VM", Const, 2}, + {"CPUID_CFLUSH", Const, 1}, + {"CREAD", Const, 0}, + {"CREATE_ALWAYS", Const, 0}, + {"CREATE_NEW", Const, 0}, + {"CREATE_NEW_PROCESS_GROUP", Const, 1}, + {"CREATE_UNICODE_ENVIRONMENT", Const, 0}, + {"CRYPT_DEFAULT_CONTAINER_OPTIONAL", Const, 0}, + {"CRYPT_DELETEKEYSET", Const, 0}, + {"CRYPT_MACHINE_KEYSET", Const, 0}, + {"CRYPT_NEWKEYSET", Const, 0}, + {"CRYPT_SILENT", Const, 0}, + {"CRYPT_VERIFYCONTEXT", Const, 0}, + {"CS5", Const, 0}, + {"CS6", Const, 0}, + {"CS7", Const, 0}, + {"CS8", Const, 0}, + {"CSIZE", Const, 0}, + {"CSTART", Const, 1}, + {"CSTATUS", Const, 1}, + {"CSTOP", Const, 1}, + {"CSTOPB", Const, 0}, + {"CSUSP", Const, 1}, + {"CTL_MAXNAME", Const, 0}, + {"CTL_NET", Const, 0}, + {"CTL_QUERY", Const, 1}, + {"CTRL_BREAK_EVENT", Const, 1}, + {"CTRL_CLOSE_EVENT", Const, 14}, + {"CTRL_C_EVENT", Const, 1}, + {"CTRL_LOGOFF_EVENT", Const, 14}, + {"CTRL_SHUTDOWN_EVENT", Const, 14}, + {"CancelIo", Func, 0}, + {"CancelIoEx", Func, 1}, + {"CertAddCertificateContextToStore", Func, 0}, + {"CertChainContext", Type, 0}, + {"CertChainContext.ChainCount", Field, 0}, + {"CertChainContext.Chains", Field, 0}, + {"CertChainContext.HasRevocationFreshnessTime", Field, 0}, + {"CertChainContext.LowerQualityChainCount", Field, 0}, + {"CertChainContext.LowerQualityChains", Field, 0}, + {"CertChainContext.RevocationFreshnessTime", Field, 0}, + {"CertChainContext.Size", Field, 0}, + {"CertChainContext.TrustStatus", Field, 0}, + {"CertChainElement", Type, 0}, + {"CertChainElement.ApplicationUsage", Field, 0}, + {"CertChainElement.CertContext", Field, 0}, + {"CertChainElement.ExtendedErrorInfo", Field, 0}, + {"CertChainElement.IssuanceUsage", Field, 0}, + {"CertChainElement.RevocationInfo", Field, 0}, + {"CertChainElement.Size", Field, 0}, + {"CertChainElement.TrustStatus", Field, 0}, + {"CertChainPara", Type, 0}, + {"CertChainPara.CacheResync", Field, 0}, + {"CertChainPara.CheckRevocationFreshnessTime", Field, 0}, + {"CertChainPara.RequestedUsage", Field, 0}, + {"CertChainPara.RequstedIssuancePolicy", Field, 0}, + {"CertChainPara.RevocationFreshnessTime", Field, 0}, + {"CertChainPara.Size", Field, 0}, + {"CertChainPara.URLRetrievalTimeout", Field, 0}, + {"CertChainPolicyPara", Type, 0}, + {"CertChainPolicyPara.ExtraPolicyPara", Field, 0}, + {"CertChainPolicyPara.Flags", Field, 0}, + {"CertChainPolicyPara.Size", Field, 0}, + {"CertChainPolicyStatus", Type, 0}, + {"CertChainPolicyStatus.ChainIndex", Field, 0}, + {"CertChainPolicyStatus.ElementIndex", Field, 0}, + {"CertChainPolicyStatus.Error", Field, 0}, + {"CertChainPolicyStatus.ExtraPolicyStatus", Field, 0}, + {"CertChainPolicyStatus.Size", Field, 0}, + {"CertCloseStore", Func, 0}, + {"CertContext", Type, 0}, + {"CertContext.CertInfo", Field, 0}, + {"CertContext.EncodedCert", Field, 0}, + {"CertContext.EncodingType", Field, 0}, + {"CertContext.Length", Field, 0}, + {"CertContext.Store", Field, 0}, + {"CertCreateCertificateContext", Func, 0}, + {"CertEnhKeyUsage", Type, 0}, + {"CertEnhKeyUsage.Length", Field, 0}, + {"CertEnhKeyUsage.UsageIdentifiers", Field, 0}, + {"CertEnumCertificatesInStore", Func, 0}, + {"CertFreeCertificateChain", Func, 0}, + {"CertFreeCertificateContext", Func, 0}, + {"CertGetCertificateChain", Func, 0}, + {"CertInfo", Type, 11}, + {"CertOpenStore", Func, 0}, + {"CertOpenSystemStore", Func, 0}, + {"CertRevocationCrlInfo", Type, 11}, + {"CertRevocationInfo", Type, 0}, + {"CertRevocationInfo.CrlInfo", Field, 0}, + {"CertRevocationInfo.FreshnessTime", Field, 0}, + {"CertRevocationInfo.HasFreshnessTime", Field, 0}, + {"CertRevocationInfo.OidSpecificInfo", Field, 0}, + {"CertRevocationInfo.RevocationOid", Field, 0}, + {"CertRevocationInfo.RevocationResult", Field, 0}, + {"CertRevocationInfo.Size", Field, 0}, + {"CertSimpleChain", Type, 0}, + {"CertSimpleChain.Elements", Field, 0}, + {"CertSimpleChain.HasRevocationFreshnessTime", Field, 0}, + {"CertSimpleChain.NumElements", Field, 0}, + {"CertSimpleChain.RevocationFreshnessTime", Field, 0}, + {"CertSimpleChain.Size", Field, 0}, + {"CertSimpleChain.TrustListInfo", Field, 0}, + {"CertSimpleChain.TrustStatus", Field, 0}, + {"CertTrustListInfo", Type, 11}, + {"CertTrustStatus", Type, 0}, + {"CertTrustStatus.ErrorStatus", Field, 0}, + {"CertTrustStatus.InfoStatus", Field, 0}, + {"CertUsageMatch", Type, 0}, + {"CertUsageMatch.Type", Field, 0}, + {"CertUsageMatch.Usage", Field, 0}, + {"CertVerifyCertificateChainPolicy", Func, 0}, + {"Chdir", Func, 0}, + {"CheckBpfVersion", Func, 0}, + {"Chflags", Func, 0}, + {"Chmod", Func, 0}, + {"Chown", Func, 0}, + {"Chroot", Func, 0}, + {"Clearenv", Func, 0}, + {"Close", Func, 0}, + {"CloseHandle", Func, 0}, + {"CloseOnExec", Func, 0}, + {"Closesocket", Func, 0}, + {"CmsgLen", Func, 0}, + {"CmsgSpace", Func, 0}, + {"Cmsghdr", Type, 0}, + {"Cmsghdr.Len", Field, 0}, + {"Cmsghdr.Level", Field, 0}, + {"Cmsghdr.Type", Field, 0}, + {"Cmsghdr.X__cmsg_data", Field, 0}, + {"CommandLineToArgv", Func, 0}, + {"ComputerName", Func, 0}, + {"Conn", Type, 9}, + {"Connect", Func, 0}, + {"ConnectEx", Func, 1}, + {"ConvertSidToStringSid", Func, 0}, + {"ConvertStringSidToSid", Func, 0}, + {"CopySid", Func, 0}, + {"Creat", Func, 0}, + {"CreateDirectory", Func, 0}, + {"CreateFile", Func, 0}, + {"CreateFileMapping", Func, 0}, + {"CreateHardLink", Func, 4}, + {"CreateIoCompletionPort", Func, 0}, + {"CreatePipe", Func, 0}, + {"CreateProcess", Func, 0}, + {"CreateProcessAsUser", Func, 10}, + {"CreateSymbolicLink", Func, 4}, + {"CreateToolhelp32Snapshot", Func, 4}, + {"Credential", Type, 0}, + {"Credential.Gid", Field, 0}, + {"Credential.Groups", Field, 0}, + {"Credential.NoSetGroups", Field, 9}, + {"Credential.Uid", Field, 0}, + {"CryptAcquireContext", Func, 0}, + {"CryptGenRandom", Func, 0}, + {"CryptReleaseContext", Func, 0}, + {"DIOCBSFLUSH", Const, 1}, + {"DIOCOSFPFLUSH", Const, 1}, + {"DLL", Type, 0}, + {"DLL.Handle", Field, 0}, + {"DLL.Name", Field, 0}, + {"DLLError", Type, 0}, + {"DLLError.Err", Field, 0}, + {"DLLError.Msg", Field, 0}, + {"DLLError.ObjName", Field, 0}, + {"DLT_A429", Const, 0}, + {"DLT_A653_ICM", Const, 0}, + {"DLT_AIRONET_HEADER", Const, 0}, + {"DLT_AOS", Const, 1}, + {"DLT_APPLE_IP_OVER_IEEE1394", Const, 0}, + {"DLT_ARCNET", Const, 0}, + {"DLT_ARCNET_LINUX", Const, 0}, + {"DLT_ATM_CLIP", Const, 0}, + {"DLT_ATM_RFC1483", Const, 0}, + {"DLT_AURORA", Const, 0}, + {"DLT_AX25", Const, 0}, + {"DLT_AX25_KISS", Const, 0}, + {"DLT_BACNET_MS_TP", Const, 0}, + {"DLT_BLUETOOTH_HCI_H4", Const, 0}, + {"DLT_BLUETOOTH_HCI_H4_WITH_PHDR", Const, 0}, + {"DLT_CAN20B", Const, 0}, + {"DLT_CAN_SOCKETCAN", Const, 1}, + {"DLT_CHAOS", Const, 0}, + {"DLT_CHDLC", Const, 0}, + {"DLT_CISCO_IOS", Const, 0}, + {"DLT_C_HDLC", Const, 0}, + {"DLT_C_HDLC_WITH_DIR", Const, 0}, + {"DLT_DBUS", Const, 1}, + {"DLT_DECT", Const, 1}, + {"DLT_DOCSIS", Const, 0}, + {"DLT_DVB_CI", Const, 1}, + {"DLT_ECONET", Const, 0}, + {"DLT_EN10MB", Const, 0}, + {"DLT_EN3MB", Const, 0}, + {"DLT_ENC", Const, 0}, + {"DLT_ERF", Const, 0}, + {"DLT_ERF_ETH", Const, 0}, + {"DLT_ERF_POS", Const, 0}, + {"DLT_FC_2", Const, 1}, + {"DLT_FC_2_WITH_FRAME_DELIMS", Const, 1}, + {"DLT_FDDI", Const, 0}, + {"DLT_FLEXRAY", Const, 0}, + {"DLT_FRELAY", Const, 0}, + {"DLT_FRELAY_WITH_DIR", Const, 0}, + {"DLT_GCOM_SERIAL", Const, 0}, + {"DLT_GCOM_T1E1", Const, 0}, + {"DLT_GPF_F", Const, 0}, + {"DLT_GPF_T", Const, 0}, + {"DLT_GPRS_LLC", Const, 0}, + {"DLT_GSMTAP_ABIS", Const, 1}, + {"DLT_GSMTAP_UM", Const, 1}, + {"DLT_HDLC", Const, 1}, + {"DLT_HHDLC", Const, 0}, + {"DLT_HIPPI", Const, 1}, + {"DLT_IBM_SN", Const, 0}, + {"DLT_IBM_SP", Const, 0}, + {"DLT_IEEE802", Const, 0}, + {"DLT_IEEE802_11", Const, 0}, + {"DLT_IEEE802_11_RADIO", Const, 0}, + {"DLT_IEEE802_11_RADIO_AVS", Const, 0}, + {"DLT_IEEE802_15_4", Const, 0}, + {"DLT_IEEE802_15_4_LINUX", Const, 0}, + {"DLT_IEEE802_15_4_NOFCS", Const, 1}, + {"DLT_IEEE802_15_4_NONASK_PHY", Const, 0}, + {"DLT_IEEE802_16_MAC_CPS", Const, 0}, + {"DLT_IEEE802_16_MAC_CPS_RADIO", Const, 0}, + {"DLT_IPFILTER", Const, 0}, + {"DLT_IPMB", Const, 0}, + {"DLT_IPMB_LINUX", Const, 0}, + {"DLT_IPNET", Const, 1}, + {"DLT_IPOIB", Const, 1}, + {"DLT_IPV4", Const, 1}, + {"DLT_IPV6", Const, 1}, + {"DLT_IP_OVER_FC", Const, 0}, + {"DLT_JUNIPER_ATM1", Const, 0}, + {"DLT_JUNIPER_ATM2", Const, 0}, + {"DLT_JUNIPER_ATM_CEMIC", Const, 1}, + {"DLT_JUNIPER_CHDLC", Const, 0}, + {"DLT_JUNIPER_ES", Const, 0}, + {"DLT_JUNIPER_ETHER", Const, 0}, + {"DLT_JUNIPER_FIBRECHANNEL", Const, 1}, + {"DLT_JUNIPER_FRELAY", Const, 0}, + {"DLT_JUNIPER_GGSN", Const, 0}, + {"DLT_JUNIPER_ISM", Const, 0}, + {"DLT_JUNIPER_MFR", Const, 0}, + {"DLT_JUNIPER_MLFR", Const, 0}, + {"DLT_JUNIPER_MLPPP", Const, 0}, + {"DLT_JUNIPER_MONITOR", Const, 0}, + {"DLT_JUNIPER_PIC_PEER", Const, 0}, + {"DLT_JUNIPER_PPP", Const, 0}, + {"DLT_JUNIPER_PPPOE", Const, 0}, + {"DLT_JUNIPER_PPPOE_ATM", Const, 0}, + {"DLT_JUNIPER_SERVICES", Const, 0}, + {"DLT_JUNIPER_SRX_E2E", Const, 1}, + {"DLT_JUNIPER_ST", Const, 0}, + {"DLT_JUNIPER_VP", Const, 0}, + {"DLT_JUNIPER_VS", Const, 1}, + {"DLT_LAPB_WITH_DIR", Const, 0}, + {"DLT_LAPD", Const, 0}, + {"DLT_LIN", Const, 0}, + {"DLT_LINUX_EVDEV", Const, 1}, + {"DLT_LINUX_IRDA", Const, 0}, + {"DLT_LINUX_LAPD", Const, 0}, + {"DLT_LINUX_PPP_WITHDIRECTION", Const, 0}, + {"DLT_LINUX_SLL", Const, 0}, + {"DLT_LOOP", Const, 0}, + {"DLT_LTALK", Const, 0}, + {"DLT_MATCHING_MAX", Const, 1}, + {"DLT_MATCHING_MIN", Const, 1}, + {"DLT_MFR", Const, 0}, + {"DLT_MOST", Const, 0}, + {"DLT_MPEG_2_TS", Const, 1}, + {"DLT_MPLS", Const, 1}, + {"DLT_MTP2", Const, 0}, + {"DLT_MTP2_WITH_PHDR", Const, 0}, + {"DLT_MTP3", Const, 0}, + {"DLT_MUX27010", Const, 1}, + {"DLT_NETANALYZER", Const, 1}, + {"DLT_NETANALYZER_TRANSPARENT", Const, 1}, + {"DLT_NFC_LLCP", Const, 1}, + {"DLT_NFLOG", Const, 1}, + {"DLT_NG40", Const, 1}, + {"DLT_NULL", Const, 0}, + {"DLT_PCI_EXP", Const, 0}, + {"DLT_PFLOG", Const, 0}, + {"DLT_PFSYNC", Const, 0}, + {"DLT_PPI", Const, 0}, + {"DLT_PPP", Const, 0}, + {"DLT_PPP_BSDOS", Const, 0}, + {"DLT_PPP_ETHER", Const, 0}, + {"DLT_PPP_PPPD", Const, 0}, + {"DLT_PPP_SERIAL", Const, 0}, + {"DLT_PPP_WITH_DIR", Const, 0}, + {"DLT_PPP_WITH_DIRECTION", Const, 0}, + {"DLT_PRISM_HEADER", Const, 0}, + {"DLT_PRONET", Const, 0}, + {"DLT_RAIF1", Const, 0}, + {"DLT_RAW", Const, 0}, + {"DLT_RAWAF_MASK", Const, 1}, + {"DLT_RIO", Const, 0}, + {"DLT_SCCP", Const, 0}, + {"DLT_SITA", Const, 0}, + {"DLT_SLIP", Const, 0}, + {"DLT_SLIP_BSDOS", Const, 0}, + {"DLT_STANAG_5066_D_PDU", Const, 1}, + {"DLT_SUNATM", Const, 0}, + {"DLT_SYMANTEC_FIREWALL", Const, 0}, + {"DLT_TZSP", Const, 0}, + {"DLT_USB", Const, 0}, + {"DLT_USB_LINUX", Const, 0}, + {"DLT_USB_LINUX_MMAPPED", Const, 1}, + {"DLT_USER0", Const, 0}, + {"DLT_USER1", Const, 0}, + {"DLT_USER10", Const, 0}, + {"DLT_USER11", Const, 0}, + {"DLT_USER12", Const, 0}, + {"DLT_USER13", Const, 0}, + {"DLT_USER14", Const, 0}, + {"DLT_USER15", Const, 0}, + {"DLT_USER2", Const, 0}, + {"DLT_USER3", Const, 0}, + {"DLT_USER4", Const, 0}, + {"DLT_USER5", Const, 0}, + {"DLT_USER6", Const, 0}, + {"DLT_USER7", Const, 0}, + {"DLT_USER8", Const, 0}, + {"DLT_USER9", Const, 0}, + {"DLT_WIHART", Const, 1}, + {"DLT_X2E_SERIAL", Const, 0}, + {"DLT_X2E_XORAYA", Const, 0}, + {"DNSMXData", Type, 0}, + {"DNSMXData.NameExchange", Field, 0}, + {"DNSMXData.Pad", Field, 0}, + {"DNSMXData.Preference", Field, 0}, + {"DNSPTRData", Type, 0}, + {"DNSPTRData.Host", Field, 0}, + {"DNSRecord", Type, 0}, + {"DNSRecord.Data", Field, 0}, + {"DNSRecord.Dw", Field, 0}, + {"DNSRecord.Length", Field, 0}, + {"DNSRecord.Name", Field, 0}, + {"DNSRecord.Next", Field, 0}, + {"DNSRecord.Reserved", Field, 0}, + {"DNSRecord.Ttl", Field, 0}, + {"DNSRecord.Type", Field, 0}, + {"DNSSRVData", Type, 0}, + {"DNSSRVData.Pad", Field, 0}, + {"DNSSRVData.Port", Field, 0}, + {"DNSSRVData.Priority", Field, 0}, + {"DNSSRVData.Target", Field, 0}, + {"DNSSRVData.Weight", Field, 0}, + {"DNSTXTData", Type, 0}, + {"DNSTXTData.StringArray", Field, 0}, + {"DNSTXTData.StringCount", Field, 0}, + {"DNS_INFO_NO_RECORDS", Const, 4}, + {"DNS_TYPE_A", Const, 0}, + {"DNS_TYPE_A6", Const, 0}, + {"DNS_TYPE_AAAA", Const, 0}, + {"DNS_TYPE_ADDRS", Const, 0}, + {"DNS_TYPE_AFSDB", Const, 0}, + {"DNS_TYPE_ALL", Const, 0}, + {"DNS_TYPE_ANY", Const, 0}, + {"DNS_TYPE_ATMA", Const, 0}, + {"DNS_TYPE_AXFR", Const, 0}, + {"DNS_TYPE_CERT", Const, 0}, + {"DNS_TYPE_CNAME", Const, 0}, + {"DNS_TYPE_DHCID", Const, 0}, + {"DNS_TYPE_DNAME", Const, 0}, + {"DNS_TYPE_DNSKEY", Const, 0}, + {"DNS_TYPE_DS", Const, 0}, + {"DNS_TYPE_EID", Const, 0}, + {"DNS_TYPE_GID", Const, 0}, + {"DNS_TYPE_GPOS", Const, 0}, + {"DNS_TYPE_HINFO", Const, 0}, + {"DNS_TYPE_ISDN", Const, 0}, + {"DNS_TYPE_IXFR", Const, 0}, + {"DNS_TYPE_KEY", Const, 0}, + {"DNS_TYPE_KX", Const, 0}, + {"DNS_TYPE_LOC", Const, 0}, + {"DNS_TYPE_MAILA", Const, 0}, + {"DNS_TYPE_MAILB", Const, 0}, + {"DNS_TYPE_MB", Const, 0}, + {"DNS_TYPE_MD", Const, 0}, + {"DNS_TYPE_MF", Const, 0}, + {"DNS_TYPE_MG", Const, 0}, + {"DNS_TYPE_MINFO", Const, 0}, + {"DNS_TYPE_MR", Const, 0}, + {"DNS_TYPE_MX", Const, 0}, + {"DNS_TYPE_NAPTR", Const, 0}, + {"DNS_TYPE_NBSTAT", Const, 0}, + {"DNS_TYPE_NIMLOC", Const, 0}, + {"DNS_TYPE_NS", Const, 0}, + {"DNS_TYPE_NSAP", Const, 0}, + {"DNS_TYPE_NSAPPTR", Const, 0}, + {"DNS_TYPE_NSEC", Const, 0}, + {"DNS_TYPE_NULL", Const, 0}, + {"DNS_TYPE_NXT", Const, 0}, + {"DNS_TYPE_OPT", Const, 0}, + {"DNS_TYPE_PTR", Const, 0}, + {"DNS_TYPE_PX", Const, 0}, + {"DNS_TYPE_RP", Const, 0}, + {"DNS_TYPE_RRSIG", Const, 0}, + {"DNS_TYPE_RT", Const, 0}, + {"DNS_TYPE_SIG", Const, 0}, + {"DNS_TYPE_SINK", Const, 0}, + {"DNS_TYPE_SOA", Const, 0}, + {"DNS_TYPE_SRV", Const, 0}, + {"DNS_TYPE_TEXT", Const, 0}, + {"DNS_TYPE_TKEY", Const, 0}, + {"DNS_TYPE_TSIG", Const, 0}, + {"DNS_TYPE_UID", Const, 0}, + {"DNS_TYPE_UINFO", Const, 0}, + {"DNS_TYPE_UNSPEC", Const, 0}, + {"DNS_TYPE_WINS", Const, 0}, + {"DNS_TYPE_WINSR", Const, 0}, + {"DNS_TYPE_WKS", Const, 0}, + {"DNS_TYPE_X25", Const, 0}, + {"DT_BLK", Const, 0}, + {"DT_CHR", Const, 0}, + {"DT_DIR", Const, 0}, + {"DT_FIFO", Const, 0}, + {"DT_LNK", Const, 0}, + {"DT_REG", Const, 0}, + {"DT_SOCK", Const, 0}, + {"DT_UNKNOWN", Const, 0}, + {"DT_WHT", Const, 0}, + {"DUPLICATE_CLOSE_SOURCE", Const, 0}, + {"DUPLICATE_SAME_ACCESS", Const, 0}, + {"DeleteFile", Func, 0}, + {"DetachLsf", Func, 0}, + {"DeviceIoControl", Func, 4}, + {"Dirent", Type, 0}, + {"Dirent.Fileno", Field, 0}, + {"Dirent.Ino", Field, 0}, + {"Dirent.Name", Field, 0}, + {"Dirent.Namlen", Field, 0}, + {"Dirent.Off", Field, 0}, + {"Dirent.Pad0", Field, 12}, + {"Dirent.Pad1", Field, 12}, + {"Dirent.Pad_cgo_0", Field, 0}, + {"Dirent.Reclen", Field, 0}, + {"Dirent.Seekoff", Field, 0}, + {"Dirent.Type", Field, 0}, + {"Dirent.X__d_padding", Field, 3}, + {"DnsNameCompare", Func, 4}, + {"DnsQuery", Func, 0}, + {"DnsRecordListFree", Func, 0}, + {"DnsSectionAdditional", Const, 4}, + {"DnsSectionAnswer", Const, 4}, + {"DnsSectionAuthority", Const, 4}, + {"DnsSectionQuestion", Const, 4}, + {"Dup", Func, 0}, + {"Dup2", Func, 0}, + {"Dup3", Func, 2}, + {"DuplicateHandle", Func, 0}, + {"E2BIG", Const, 0}, + {"EACCES", Const, 0}, + {"EADDRINUSE", Const, 0}, + {"EADDRNOTAVAIL", Const, 0}, + {"EADV", Const, 0}, + {"EAFNOSUPPORT", Const, 0}, + {"EAGAIN", Const, 0}, + {"EALREADY", Const, 0}, + {"EAUTH", Const, 0}, + {"EBADARCH", Const, 0}, + {"EBADE", Const, 0}, + {"EBADEXEC", Const, 0}, + {"EBADF", Const, 0}, + {"EBADFD", Const, 0}, + {"EBADMACHO", Const, 0}, + {"EBADMSG", Const, 0}, + {"EBADR", Const, 0}, + {"EBADRPC", Const, 0}, + {"EBADRQC", Const, 0}, + {"EBADSLT", Const, 0}, + {"EBFONT", Const, 0}, + {"EBUSY", Const, 0}, + {"ECANCELED", Const, 0}, + {"ECAPMODE", Const, 1}, + {"ECHILD", Const, 0}, + {"ECHO", Const, 0}, + {"ECHOCTL", Const, 0}, + {"ECHOE", Const, 0}, + {"ECHOK", Const, 0}, + {"ECHOKE", Const, 0}, + {"ECHONL", Const, 0}, + {"ECHOPRT", Const, 0}, + {"ECHRNG", Const, 0}, + {"ECOMM", Const, 0}, + {"ECONNABORTED", Const, 0}, + {"ECONNREFUSED", Const, 0}, + {"ECONNRESET", Const, 0}, + {"EDEADLK", Const, 0}, + {"EDEADLOCK", Const, 0}, + {"EDESTADDRREQ", Const, 0}, + {"EDEVERR", Const, 0}, + {"EDOM", Const, 0}, + {"EDOOFUS", Const, 0}, + {"EDOTDOT", Const, 0}, + {"EDQUOT", Const, 0}, + {"EEXIST", Const, 0}, + {"EFAULT", Const, 0}, + {"EFBIG", Const, 0}, + {"EFER_LMA", Const, 1}, + {"EFER_LME", Const, 1}, + {"EFER_NXE", Const, 1}, + {"EFER_SCE", Const, 1}, + {"EFTYPE", Const, 0}, + {"EHOSTDOWN", Const, 0}, + {"EHOSTUNREACH", Const, 0}, + {"EHWPOISON", Const, 0}, + {"EIDRM", Const, 0}, + {"EILSEQ", Const, 0}, + {"EINPROGRESS", Const, 0}, + {"EINTR", Const, 0}, + {"EINVAL", Const, 0}, + {"EIO", Const, 0}, + {"EIPSEC", Const, 1}, + {"EISCONN", Const, 0}, + {"EISDIR", Const, 0}, + {"EISNAM", Const, 0}, + {"EKEYEXPIRED", Const, 0}, + {"EKEYREJECTED", Const, 0}, + {"EKEYREVOKED", Const, 0}, + {"EL2HLT", Const, 0}, + {"EL2NSYNC", Const, 0}, + {"EL3HLT", Const, 0}, + {"EL3RST", Const, 0}, + {"ELAST", Const, 0}, + {"ELF_NGREG", Const, 0}, + {"ELF_PRARGSZ", Const, 0}, + {"ELIBACC", Const, 0}, + {"ELIBBAD", Const, 0}, + {"ELIBEXEC", Const, 0}, + {"ELIBMAX", Const, 0}, + {"ELIBSCN", Const, 0}, + {"ELNRNG", Const, 0}, + {"ELOOP", Const, 0}, + {"EMEDIUMTYPE", Const, 0}, + {"EMFILE", Const, 0}, + {"EMLINK", Const, 0}, + {"EMSGSIZE", Const, 0}, + {"EMT_TAGOVF", Const, 1}, + {"EMULTIHOP", Const, 0}, + {"EMUL_ENABLED", Const, 1}, + {"EMUL_LINUX", Const, 1}, + {"EMUL_LINUX32", Const, 1}, + {"EMUL_MAXID", Const, 1}, + {"EMUL_NATIVE", Const, 1}, + {"ENAMETOOLONG", Const, 0}, + {"ENAVAIL", Const, 0}, + {"ENDRUNDISC", Const, 1}, + {"ENEEDAUTH", Const, 0}, + {"ENETDOWN", Const, 0}, + {"ENETRESET", Const, 0}, + {"ENETUNREACH", Const, 0}, + {"ENFILE", Const, 0}, + {"ENOANO", Const, 0}, + {"ENOATTR", Const, 0}, + {"ENOBUFS", Const, 0}, + {"ENOCSI", Const, 0}, + {"ENODATA", Const, 0}, + {"ENODEV", Const, 0}, + {"ENOENT", Const, 0}, + {"ENOEXEC", Const, 0}, + {"ENOKEY", Const, 0}, + {"ENOLCK", Const, 0}, + {"ENOLINK", Const, 0}, + {"ENOMEDIUM", Const, 0}, + {"ENOMEM", Const, 0}, + {"ENOMSG", Const, 0}, + {"ENONET", Const, 0}, + {"ENOPKG", Const, 0}, + {"ENOPOLICY", Const, 0}, + {"ENOPROTOOPT", Const, 0}, + {"ENOSPC", Const, 0}, + {"ENOSR", Const, 0}, + {"ENOSTR", Const, 0}, + {"ENOSYS", Const, 0}, + {"ENOTBLK", Const, 0}, + {"ENOTCAPABLE", Const, 0}, + {"ENOTCONN", Const, 0}, + {"ENOTDIR", Const, 0}, + {"ENOTEMPTY", Const, 0}, + {"ENOTNAM", Const, 0}, + {"ENOTRECOVERABLE", Const, 0}, + {"ENOTSOCK", Const, 0}, + {"ENOTSUP", Const, 0}, + {"ENOTTY", Const, 0}, + {"ENOTUNIQ", Const, 0}, + {"ENXIO", Const, 0}, + {"EN_SW_CTL_INF", Const, 1}, + {"EN_SW_CTL_PREC", Const, 1}, + {"EN_SW_CTL_ROUND", Const, 1}, + {"EN_SW_DATACHAIN", Const, 1}, + {"EN_SW_DENORM", Const, 1}, + {"EN_SW_INVOP", Const, 1}, + {"EN_SW_OVERFLOW", Const, 1}, + {"EN_SW_PRECLOSS", Const, 1}, + {"EN_SW_UNDERFLOW", Const, 1}, + {"EN_SW_ZERODIV", Const, 1}, + {"EOPNOTSUPP", Const, 0}, + {"EOVERFLOW", Const, 0}, + {"EOWNERDEAD", Const, 0}, + {"EPERM", Const, 0}, + {"EPFNOSUPPORT", Const, 0}, + {"EPIPE", Const, 0}, + {"EPOLLERR", Const, 0}, + {"EPOLLET", Const, 0}, + {"EPOLLHUP", Const, 0}, + {"EPOLLIN", Const, 0}, + {"EPOLLMSG", Const, 0}, + {"EPOLLONESHOT", Const, 0}, + {"EPOLLOUT", Const, 0}, + {"EPOLLPRI", Const, 0}, + {"EPOLLRDBAND", Const, 0}, + {"EPOLLRDHUP", Const, 0}, + {"EPOLLRDNORM", Const, 0}, + {"EPOLLWRBAND", Const, 0}, + {"EPOLLWRNORM", Const, 0}, + {"EPOLL_CLOEXEC", Const, 0}, + {"EPOLL_CTL_ADD", Const, 0}, + {"EPOLL_CTL_DEL", Const, 0}, + {"EPOLL_CTL_MOD", Const, 0}, + {"EPOLL_NONBLOCK", Const, 0}, + {"EPROCLIM", Const, 0}, + {"EPROCUNAVAIL", Const, 0}, + {"EPROGMISMATCH", Const, 0}, + {"EPROGUNAVAIL", Const, 0}, + {"EPROTO", Const, 0}, + {"EPROTONOSUPPORT", Const, 0}, + {"EPROTOTYPE", Const, 0}, + {"EPWROFF", Const, 0}, + {"EQFULL", Const, 16}, + {"ERANGE", Const, 0}, + {"EREMCHG", Const, 0}, + {"EREMOTE", Const, 0}, + {"EREMOTEIO", Const, 0}, + {"ERESTART", Const, 0}, + {"ERFKILL", Const, 0}, + {"EROFS", Const, 0}, + {"ERPCMISMATCH", Const, 0}, + {"ERROR_ACCESS_DENIED", Const, 0}, + {"ERROR_ALREADY_EXISTS", Const, 0}, + {"ERROR_BROKEN_PIPE", Const, 0}, + {"ERROR_BUFFER_OVERFLOW", Const, 0}, + {"ERROR_DIR_NOT_EMPTY", Const, 8}, + {"ERROR_ENVVAR_NOT_FOUND", Const, 0}, + {"ERROR_FILE_EXISTS", Const, 0}, + {"ERROR_FILE_NOT_FOUND", Const, 0}, + {"ERROR_HANDLE_EOF", Const, 2}, + {"ERROR_INSUFFICIENT_BUFFER", Const, 0}, + {"ERROR_IO_PENDING", Const, 0}, + {"ERROR_MOD_NOT_FOUND", Const, 0}, + {"ERROR_MORE_DATA", Const, 3}, + {"ERROR_NETNAME_DELETED", Const, 3}, + {"ERROR_NOT_FOUND", Const, 1}, + {"ERROR_NO_MORE_FILES", Const, 0}, + {"ERROR_OPERATION_ABORTED", Const, 0}, + {"ERROR_PATH_NOT_FOUND", Const, 0}, + {"ERROR_PRIVILEGE_NOT_HELD", Const, 4}, + {"ERROR_PROC_NOT_FOUND", Const, 0}, + {"ESHLIBVERS", Const, 0}, + {"ESHUTDOWN", Const, 0}, + {"ESOCKTNOSUPPORT", Const, 0}, + {"ESPIPE", Const, 0}, + {"ESRCH", Const, 0}, + {"ESRMNT", Const, 0}, + {"ESTALE", Const, 0}, + {"ESTRPIPE", Const, 0}, + {"ETHERCAP_JUMBO_MTU", Const, 1}, + {"ETHERCAP_VLAN_HWTAGGING", Const, 1}, + {"ETHERCAP_VLAN_MTU", Const, 1}, + {"ETHERMIN", Const, 1}, + {"ETHERMTU", Const, 1}, + {"ETHERMTU_JUMBO", Const, 1}, + {"ETHERTYPE_8023", Const, 1}, + {"ETHERTYPE_AARP", Const, 1}, + {"ETHERTYPE_ACCTON", Const, 1}, + {"ETHERTYPE_AEONIC", Const, 1}, + {"ETHERTYPE_ALPHA", Const, 1}, + {"ETHERTYPE_AMBER", Const, 1}, + {"ETHERTYPE_AMOEBA", Const, 1}, + {"ETHERTYPE_AOE", Const, 1}, + {"ETHERTYPE_APOLLO", Const, 1}, + {"ETHERTYPE_APOLLODOMAIN", Const, 1}, + {"ETHERTYPE_APPLETALK", Const, 1}, + {"ETHERTYPE_APPLITEK", Const, 1}, + {"ETHERTYPE_ARGONAUT", Const, 1}, + {"ETHERTYPE_ARP", Const, 1}, + {"ETHERTYPE_AT", Const, 1}, + {"ETHERTYPE_ATALK", Const, 1}, + {"ETHERTYPE_ATOMIC", Const, 1}, + {"ETHERTYPE_ATT", Const, 1}, + {"ETHERTYPE_ATTSTANFORD", Const, 1}, + {"ETHERTYPE_AUTOPHON", Const, 1}, + {"ETHERTYPE_AXIS", Const, 1}, + {"ETHERTYPE_BCLOOP", Const, 1}, + {"ETHERTYPE_BOFL", Const, 1}, + {"ETHERTYPE_CABLETRON", Const, 1}, + {"ETHERTYPE_CHAOS", Const, 1}, + {"ETHERTYPE_COMDESIGN", Const, 1}, + {"ETHERTYPE_COMPUGRAPHIC", Const, 1}, + {"ETHERTYPE_COUNTERPOINT", Const, 1}, + {"ETHERTYPE_CRONUS", Const, 1}, + {"ETHERTYPE_CRONUSVLN", Const, 1}, + {"ETHERTYPE_DCA", Const, 1}, + {"ETHERTYPE_DDE", Const, 1}, + {"ETHERTYPE_DEBNI", Const, 1}, + {"ETHERTYPE_DECAM", Const, 1}, + {"ETHERTYPE_DECCUST", Const, 1}, + {"ETHERTYPE_DECDIAG", Const, 1}, + {"ETHERTYPE_DECDNS", Const, 1}, + {"ETHERTYPE_DECDTS", Const, 1}, + {"ETHERTYPE_DECEXPER", Const, 1}, + {"ETHERTYPE_DECLAST", Const, 1}, + {"ETHERTYPE_DECLTM", Const, 1}, + {"ETHERTYPE_DECMUMPS", Const, 1}, + {"ETHERTYPE_DECNETBIOS", Const, 1}, + {"ETHERTYPE_DELTACON", Const, 1}, + {"ETHERTYPE_DIDDLE", Const, 1}, + {"ETHERTYPE_DLOG1", Const, 1}, + {"ETHERTYPE_DLOG2", Const, 1}, + {"ETHERTYPE_DN", Const, 1}, + {"ETHERTYPE_DOGFIGHT", Const, 1}, + {"ETHERTYPE_DSMD", Const, 1}, + {"ETHERTYPE_ECMA", Const, 1}, + {"ETHERTYPE_ENCRYPT", Const, 1}, + {"ETHERTYPE_ES", Const, 1}, + {"ETHERTYPE_EXCELAN", Const, 1}, + {"ETHERTYPE_EXPERDATA", Const, 1}, + {"ETHERTYPE_FLIP", Const, 1}, + {"ETHERTYPE_FLOWCONTROL", Const, 1}, + {"ETHERTYPE_FRARP", Const, 1}, + {"ETHERTYPE_GENDYN", Const, 1}, + {"ETHERTYPE_HAYES", Const, 1}, + {"ETHERTYPE_HIPPI_FP", Const, 1}, + {"ETHERTYPE_HITACHI", Const, 1}, + {"ETHERTYPE_HP", Const, 1}, + {"ETHERTYPE_IEEEPUP", Const, 1}, + {"ETHERTYPE_IEEEPUPAT", Const, 1}, + {"ETHERTYPE_IMLBL", Const, 1}, + {"ETHERTYPE_IMLBLDIAG", Const, 1}, + {"ETHERTYPE_IP", Const, 1}, + {"ETHERTYPE_IPAS", Const, 1}, + {"ETHERTYPE_IPV6", Const, 1}, + {"ETHERTYPE_IPX", Const, 1}, + {"ETHERTYPE_IPXNEW", Const, 1}, + {"ETHERTYPE_KALPANA", Const, 1}, + {"ETHERTYPE_LANBRIDGE", Const, 1}, + {"ETHERTYPE_LANPROBE", Const, 1}, + {"ETHERTYPE_LAT", Const, 1}, + {"ETHERTYPE_LBACK", Const, 1}, + {"ETHERTYPE_LITTLE", Const, 1}, + {"ETHERTYPE_LLDP", Const, 1}, + {"ETHERTYPE_LOGICRAFT", Const, 1}, + {"ETHERTYPE_LOOPBACK", Const, 1}, + {"ETHERTYPE_MATRA", Const, 1}, + {"ETHERTYPE_MAX", Const, 1}, + {"ETHERTYPE_MERIT", Const, 1}, + {"ETHERTYPE_MICP", Const, 1}, + {"ETHERTYPE_MOPDL", Const, 1}, + {"ETHERTYPE_MOPRC", Const, 1}, + {"ETHERTYPE_MOTOROLA", Const, 1}, + {"ETHERTYPE_MPLS", Const, 1}, + {"ETHERTYPE_MPLS_MCAST", Const, 1}, + {"ETHERTYPE_MUMPS", Const, 1}, + {"ETHERTYPE_NBPCC", Const, 1}, + {"ETHERTYPE_NBPCLAIM", Const, 1}, + {"ETHERTYPE_NBPCLREQ", Const, 1}, + {"ETHERTYPE_NBPCLRSP", Const, 1}, + {"ETHERTYPE_NBPCREQ", Const, 1}, + {"ETHERTYPE_NBPCRSP", Const, 1}, + {"ETHERTYPE_NBPDG", Const, 1}, + {"ETHERTYPE_NBPDGB", Const, 1}, + {"ETHERTYPE_NBPDLTE", Const, 1}, + {"ETHERTYPE_NBPRAR", Const, 1}, + {"ETHERTYPE_NBPRAS", Const, 1}, + {"ETHERTYPE_NBPRST", Const, 1}, + {"ETHERTYPE_NBPSCD", Const, 1}, + {"ETHERTYPE_NBPVCD", Const, 1}, + {"ETHERTYPE_NBS", Const, 1}, + {"ETHERTYPE_NCD", Const, 1}, + {"ETHERTYPE_NESTAR", Const, 1}, + {"ETHERTYPE_NETBEUI", Const, 1}, + {"ETHERTYPE_NOVELL", Const, 1}, + {"ETHERTYPE_NS", Const, 1}, + {"ETHERTYPE_NSAT", Const, 1}, + {"ETHERTYPE_NSCOMPAT", Const, 1}, + {"ETHERTYPE_NTRAILER", Const, 1}, + {"ETHERTYPE_OS9", Const, 1}, + {"ETHERTYPE_OS9NET", Const, 1}, + {"ETHERTYPE_PACER", Const, 1}, + {"ETHERTYPE_PAE", Const, 1}, + {"ETHERTYPE_PCS", Const, 1}, + {"ETHERTYPE_PLANNING", Const, 1}, + {"ETHERTYPE_PPP", Const, 1}, + {"ETHERTYPE_PPPOE", Const, 1}, + {"ETHERTYPE_PPPOEDISC", Const, 1}, + {"ETHERTYPE_PRIMENTS", Const, 1}, + {"ETHERTYPE_PUP", Const, 1}, + {"ETHERTYPE_PUPAT", Const, 1}, + {"ETHERTYPE_QINQ", Const, 1}, + {"ETHERTYPE_RACAL", Const, 1}, + {"ETHERTYPE_RATIONAL", Const, 1}, + {"ETHERTYPE_RAWFR", Const, 1}, + {"ETHERTYPE_RCL", Const, 1}, + {"ETHERTYPE_RDP", Const, 1}, + {"ETHERTYPE_RETIX", Const, 1}, + {"ETHERTYPE_REVARP", Const, 1}, + {"ETHERTYPE_SCA", Const, 1}, + {"ETHERTYPE_SECTRA", Const, 1}, + {"ETHERTYPE_SECUREDATA", Const, 1}, + {"ETHERTYPE_SGITW", Const, 1}, + {"ETHERTYPE_SG_BOUNCE", Const, 1}, + {"ETHERTYPE_SG_DIAG", Const, 1}, + {"ETHERTYPE_SG_NETGAMES", Const, 1}, + {"ETHERTYPE_SG_RESV", Const, 1}, + {"ETHERTYPE_SIMNET", Const, 1}, + {"ETHERTYPE_SLOW", Const, 1}, + {"ETHERTYPE_SLOWPROTOCOLS", Const, 1}, + {"ETHERTYPE_SNA", Const, 1}, + {"ETHERTYPE_SNMP", Const, 1}, + {"ETHERTYPE_SONIX", Const, 1}, + {"ETHERTYPE_SPIDER", Const, 1}, + {"ETHERTYPE_SPRITE", Const, 1}, + {"ETHERTYPE_STP", Const, 1}, + {"ETHERTYPE_TALARIS", Const, 1}, + {"ETHERTYPE_TALARISMC", Const, 1}, + {"ETHERTYPE_TCPCOMP", Const, 1}, + {"ETHERTYPE_TCPSM", Const, 1}, + {"ETHERTYPE_TEC", Const, 1}, + {"ETHERTYPE_TIGAN", Const, 1}, + {"ETHERTYPE_TRAIL", Const, 1}, + {"ETHERTYPE_TRANSETHER", Const, 1}, + {"ETHERTYPE_TYMSHARE", Const, 1}, + {"ETHERTYPE_UBBST", Const, 1}, + {"ETHERTYPE_UBDEBUG", Const, 1}, + {"ETHERTYPE_UBDIAGLOOP", Const, 1}, + {"ETHERTYPE_UBDL", Const, 1}, + {"ETHERTYPE_UBNIU", Const, 1}, + {"ETHERTYPE_UBNMC", Const, 1}, + {"ETHERTYPE_VALID", Const, 1}, + {"ETHERTYPE_VARIAN", Const, 1}, + {"ETHERTYPE_VAXELN", Const, 1}, + {"ETHERTYPE_VEECO", Const, 1}, + {"ETHERTYPE_VEXP", Const, 1}, + {"ETHERTYPE_VGLAB", Const, 1}, + {"ETHERTYPE_VINES", Const, 1}, + {"ETHERTYPE_VINESECHO", Const, 1}, + {"ETHERTYPE_VINESLOOP", Const, 1}, + {"ETHERTYPE_VITAL", Const, 1}, + {"ETHERTYPE_VLAN", Const, 1}, + {"ETHERTYPE_VLTLMAN", Const, 1}, + {"ETHERTYPE_VPROD", Const, 1}, + {"ETHERTYPE_VURESERVED", Const, 1}, + {"ETHERTYPE_WATERLOO", Const, 1}, + {"ETHERTYPE_WELLFLEET", Const, 1}, + {"ETHERTYPE_X25", Const, 1}, + {"ETHERTYPE_X75", Const, 1}, + {"ETHERTYPE_XNSSM", Const, 1}, + {"ETHERTYPE_XTP", Const, 1}, + {"ETHER_ADDR_LEN", Const, 1}, + {"ETHER_ALIGN", Const, 1}, + {"ETHER_CRC_LEN", Const, 1}, + {"ETHER_CRC_POLY_BE", Const, 1}, + {"ETHER_CRC_POLY_LE", Const, 1}, + {"ETHER_HDR_LEN", Const, 1}, + {"ETHER_MAX_DIX_LEN", Const, 1}, + {"ETHER_MAX_LEN", Const, 1}, + {"ETHER_MAX_LEN_JUMBO", Const, 1}, + {"ETHER_MIN_LEN", Const, 1}, + {"ETHER_PPPOE_ENCAP_LEN", Const, 1}, + {"ETHER_TYPE_LEN", Const, 1}, + {"ETHER_VLAN_ENCAP_LEN", Const, 1}, + {"ETH_P_1588", Const, 0}, + {"ETH_P_8021Q", Const, 0}, + {"ETH_P_802_2", Const, 0}, + {"ETH_P_802_3", Const, 0}, + {"ETH_P_AARP", Const, 0}, + {"ETH_P_ALL", Const, 0}, + {"ETH_P_AOE", Const, 0}, + {"ETH_P_ARCNET", Const, 0}, + {"ETH_P_ARP", Const, 0}, + {"ETH_P_ATALK", Const, 0}, + {"ETH_P_ATMFATE", Const, 0}, + {"ETH_P_ATMMPOA", Const, 0}, + {"ETH_P_AX25", Const, 0}, + {"ETH_P_BPQ", Const, 0}, + {"ETH_P_CAIF", Const, 0}, + {"ETH_P_CAN", Const, 0}, + {"ETH_P_CONTROL", Const, 0}, + {"ETH_P_CUST", Const, 0}, + {"ETH_P_DDCMP", Const, 0}, + {"ETH_P_DEC", Const, 0}, + {"ETH_P_DIAG", Const, 0}, + {"ETH_P_DNA_DL", Const, 0}, + {"ETH_P_DNA_RC", Const, 0}, + {"ETH_P_DNA_RT", Const, 0}, + {"ETH_P_DSA", Const, 0}, + {"ETH_P_ECONET", Const, 0}, + {"ETH_P_EDSA", Const, 0}, + {"ETH_P_FCOE", Const, 0}, + {"ETH_P_FIP", Const, 0}, + {"ETH_P_HDLC", Const, 0}, + {"ETH_P_IEEE802154", Const, 0}, + {"ETH_P_IEEEPUP", Const, 0}, + {"ETH_P_IEEEPUPAT", Const, 0}, + {"ETH_P_IP", Const, 0}, + {"ETH_P_IPV6", Const, 0}, + {"ETH_P_IPX", Const, 0}, + {"ETH_P_IRDA", Const, 0}, + {"ETH_P_LAT", Const, 0}, + {"ETH_P_LINK_CTL", Const, 0}, + {"ETH_P_LOCALTALK", Const, 0}, + {"ETH_P_LOOP", Const, 0}, + {"ETH_P_MOBITEX", Const, 0}, + {"ETH_P_MPLS_MC", Const, 0}, + {"ETH_P_MPLS_UC", Const, 0}, + {"ETH_P_PAE", Const, 0}, + {"ETH_P_PAUSE", Const, 0}, + {"ETH_P_PHONET", Const, 0}, + {"ETH_P_PPPTALK", Const, 0}, + {"ETH_P_PPP_DISC", Const, 0}, + {"ETH_P_PPP_MP", Const, 0}, + {"ETH_P_PPP_SES", Const, 0}, + {"ETH_P_PUP", Const, 0}, + {"ETH_P_PUPAT", Const, 0}, + {"ETH_P_RARP", Const, 0}, + {"ETH_P_SCA", Const, 0}, + {"ETH_P_SLOW", Const, 0}, + {"ETH_P_SNAP", Const, 0}, + {"ETH_P_TEB", Const, 0}, + {"ETH_P_TIPC", Const, 0}, + {"ETH_P_TRAILER", Const, 0}, + {"ETH_P_TR_802_2", Const, 0}, + {"ETH_P_WAN_PPP", Const, 0}, + {"ETH_P_WCCP", Const, 0}, + {"ETH_P_X25", Const, 0}, + {"ETIME", Const, 0}, + {"ETIMEDOUT", Const, 0}, + {"ETOOMANYREFS", Const, 0}, + {"ETXTBSY", Const, 0}, + {"EUCLEAN", Const, 0}, + {"EUNATCH", Const, 0}, + {"EUSERS", Const, 0}, + {"EVFILT_AIO", Const, 0}, + {"EVFILT_FS", Const, 0}, + {"EVFILT_LIO", Const, 0}, + {"EVFILT_MACHPORT", Const, 0}, + {"EVFILT_PROC", Const, 0}, + {"EVFILT_READ", Const, 0}, + {"EVFILT_SIGNAL", Const, 0}, + {"EVFILT_SYSCOUNT", Const, 0}, + {"EVFILT_THREADMARKER", Const, 0}, + {"EVFILT_TIMER", Const, 0}, + {"EVFILT_USER", Const, 0}, + {"EVFILT_VM", Const, 0}, + {"EVFILT_VNODE", Const, 0}, + {"EVFILT_WRITE", Const, 0}, + {"EV_ADD", Const, 0}, + {"EV_CLEAR", Const, 0}, + {"EV_DELETE", Const, 0}, + {"EV_DISABLE", Const, 0}, + {"EV_DISPATCH", Const, 0}, + {"EV_DROP", Const, 3}, + {"EV_ENABLE", Const, 0}, + {"EV_EOF", Const, 0}, + {"EV_ERROR", Const, 0}, + {"EV_FLAG0", Const, 0}, + {"EV_FLAG1", Const, 0}, + {"EV_ONESHOT", Const, 0}, + {"EV_OOBAND", Const, 0}, + {"EV_POLL", Const, 0}, + {"EV_RECEIPT", Const, 0}, + {"EV_SYSFLAGS", Const, 0}, + {"EWINDOWS", Const, 0}, + {"EWOULDBLOCK", Const, 0}, + {"EXDEV", Const, 0}, + {"EXFULL", Const, 0}, + {"EXTA", Const, 0}, + {"EXTB", Const, 0}, + {"EXTPROC", Const, 0}, + {"Environ", Func, 0}, + {"EpollCreate", Func, 0}, + {"EpollCreate1", Func, 0}, + {"EpollCtl", Func, 0}, + {"EpollEvent", Type, 0}, + {"EpollEvent.Events", Field, 0}, + {"EpollEvent.Fd", Field, 0}, + {"EpollEvent.Pad", Field, 0}, + {"EpollEvent.PadFd", Field, 0}, + {"EpollWait", Func, 0}, + {"Errno", Type, 0}, + {"EscapeArg", Func, 0}, + {"Exchangedata", Func, 0}, + {"Exec", Func, 0}, + {"Exit", Func, 0}, + {"ExitProcess", Func, 0}, + {"FD_CLOEXEC", Const, 0}, + {"FD_SETSIZE", Const, 0}, + {"FILE_ACTION_ADDED", Const, 0}, + {"FILE_ACTION_MODIFIED", Const, 0}, + {"FILE_ACTION_REMOVED", Const, 0}, + {"FILE_ACTION_RENAMED_NEW_NAME", Const, 0}, + {"FILE_ACTION_RENAMED_OLD_NAME", Const, 0}, + {"FILE_APPEND_DATA", Const, 0}, + {"FILE_ATTRIBUTE_ARCHIVE", Const, 0}, + {"FILE_ATTRIBUTE_DIRECTORY", Const, 0}, + {"FILE_ATTRIBUTE_HIDDEN", Const, 0}, + {"FILE_ATTRIBUTE_NORMAL", Const, 0}, + {"FILE_ATTRIBUTE_READONLY", Const, 0}, + {"FILE_ATTRIBUTE_REPARSE_POINT", Const, 4}, + {"FILE_ATTRIBUTE_SYSTEM", Const, 0}, + {"FILE_BEGIN", Const, 0}, + {"FILE_CURRENT", Const, 0}, + {"FILE_END", Const, 0}, + {"FILE_FLAG_BACKUP_SEMANTICS", Const, 0}, + {"FILE_FLAG_OPEN_REPARSE_POINT", Const, 4}, + {"FILE_FLAG_OVERLAPPED", Const, 0}, + {"FILE_LIST_DIRECTORY", Const, 0}, + {"FILE_MAP_COPY", Const, 0}, + {"FILE_MAP_EXECUTE", Const, 0}, + {"FILE_MAP_READ", Const, 0}, + {"FILE_MAP_WRITE", Const, 0}, + {"FILE_NOTIFY_CHANGE_ATTRIBUTES", Const, 0}, + {"FILE_NOTIFY_CHANGE_CREATION", Const, 0}, + {"FILE_NOTIFY_CHANGE_DIR_NAME", Const, 0}, + {"FILE_NOTIFY_CHANGE_FILE_NAME", Const, 0}, + {"FILE_NOTIFY_CHANGE_LAST_ACCESS", Const, 0}, + {"FILE_NOTIFY_CHANGE_LAST_WRITE", Const, 0}, + {"FILE_NOTIFY_CHANGE_SIZE", Const, 0}, + {"FILE_SHARE_DELETE", Const, 0}, + {"FILE_SHARE_READ", Const, 0}, + {"FILE_SHARE_WRITE", Const, 0}, + {"FILE_SKIP_COMPLETION_PORT_ON_SUCCESS", Const, 2}, + {"FILE_SKIP_SET_EVENT_ON_HANDLE", Const, 2}, + {"FILE_TYPE_CHAR", Const, 0}, + {"FILE_TYPE_DISK", Const, 0}, + {"FILE_TYPE_PIPE", Const, 0}, + {"FILE_TYPE_REMOTE", Const, 0}, + {"FILE_TYPE_UNKNOWN", Const, 0}, + {"FILE_WRITE_ATTRIBUTES", Const, 0}, + {"FLUSHO", Const, 0}, + {"FORMAT_MESSAGE_ALLOCATE_BUFFER", Const, 0}, + {"FORMAT_MESSAGE_ARGUMENT_ARRAY", Const, 0}, + {"FORMAT_MESSAGE_FROM_HMODULE", Const, 0}, + {"FORMAT_MESSAGE_FROM_STRING", Const, 0}, + {"FORMAT_MESSAGE_FROM_SYSTEM", Const, 0}, + {"FORMAT_MESSAGE_IGNORE_INSERTS", Const, 0}, + {"FORMAT_MESSAGE_MAX_WIDTH_MASK", Const, 0}, + {"FSCTL_GET_REPARSE_POINT", Const, 4}, + {"F_ADDFILESIGS", Const, 0}, + {"F_ADDSIGS", Const, 0}, + {"F_ALLOCATEALL", Const, 0}, + {"F_ALLOCATECONTIG", Const, 0}, + {"F_CANCEL", Const, 0}, + {"F_CHKCLEAN", Const, 0}, + {"F_CLOSEM", Const, 1}, + {"F_DUP2FD", Const, 0}, + {"F_DUP2FD_CLOEXEC", Const, 1}, + {"F_DUPFD", Const, 0}, + {"F_DUPFD_CLOEXEC", Const, 0}, + {"F_EXLCK", Const, 0}, + {"F_FINDSIGS", Const, 16}, + {"F_FLUSH_DATA", Const, 0}, + {"F_FREEZE_FS", Const, 0}, + {"F_FSCTL", Const, 1}, + {"F_FSDIRMASK", Const, 1}, + {"F_FSIN", Const, 1}, + {"F_FSINOUT", Const, 1}, + {"F_FSOUT", Const, 1}, + {"F_FSPRIV", Const, 1}, + {"F_FSVOID", Const, 1}, + {"F_FULLFSYNC", Const, 0}, + {"F_GETCODEDIR", Const, 16}, + {"F_GETFD", Const, 0}, + {"F_GETFL", Const, 0}, + {"F_GETLEASE", Const, 0}, + {"F_GETLK", Const, 0}, + {"F_GETLK64", Const, 0}, + {"F_GETLKPID", Const, 0}, + {"F_GETNOSIGPIPE", Const, 0}, + {"F_GETOWN", Const, 0}, + {"F_GETOWN_EX", Const, 0}, + {"F_GETPATH", Const, 0}, + {"F_GETPATH_MTMINFO", Const, 0}, + {"F_GETPIPE_SZ", Const, 0}, + {"F_GETPROTECTIONCLASS", Const, 0}, + {"F_GETPROTECTIONLEVEL", Const, 16}, + {"F_GETSIG", Const, 0}, + {"F_GLOBAL_NOCACHE", Const, 0}, + {"F_LOCK", Const, 0}, + {"F_LOG2PHYS", Const, 0}, + {"F_LOG2PHYS_EXT", Const, 0}, + {"F_MARKDEPENDENCY", Const, 0}, + {"F_MAXFD", Const, 1}, + {"F_NOCACHE", Const, 0}, + {"F_NODIRECT", Const, 0}, + {"F_NOTIFY", Const, 0}, + {"F_OGETLK", Const, 0}, + {"F_OK", Const, 0}, + {"F_OSETLK", Const, 0}, + {"F_OSETLKW", Const, 0}, + {"F_PARAM_MASK", Const, 1}, + {"F_PARAM_MAX", Const, 1}, + {"F_PATHPKG_CHECK", Const, 0}, + {"F_PEOFPOSMODE", Const, 0}, + {"F_PREALLOCATE", Const, 0}, + {"F_RDADVISE", Const, 0}, + {"F_RDAHEAD", Const, 0}, + {"F_RDLCK", Const, 0}, + {"F_READAHEAD", Const, 0}, + {"F_READBOOTSTRAP", Const, 0}, + {"F_SETBACKINGSTORE", Const, 0}, + {"F_SETFD", Const, 0}, + {"F_SETFL", Const, 0}, + {"F_SETLEASE", Const, 0}, + {"F_SETLK", Const, 0}, + {"F_SETLK64", Const, 0}, + {"F_SETLKW", Const, 0}, + {"F_SETLKW64", Const, 0}, + {"F_SETLKWTIMEOUT", Const, 16}, + {"F_SETLK_REMOTE", Const, 0}, + {"F_SETNOSIGPIPE", Const, 0}, + {"F_SETOWN", Const, 0}, + {"F_SETOWN_EX", Const, 0}, + {"F_SETPIPE_SZ", Const, 0}, + {"F_SETPROTECTIONCLASS", Const, 0}, + {"F_SETSIG", Const, 0}, + {"F_SETSIZE", Const, 0}, + {"F_SHLCK", Const, 0}, + {"F_SINGLE_WRITER", Const, 16}, + {"F_TEST", Const, 0}, + {"F_THAW_FS", Const, 0}, + {"F_TLOCK", Const, 0}, + {"F_TRANSCODEKEY", Const, 16}, + {"F_ULOCK", Const, 0}, + {"F_UNLCK", Const, 0}, + {"F_UNLCKSYS", Const, 0}, + {"F_VOLPOSMODE", Const, 0}, + {"F_WRITEBOOTSTRAP", Const, 0}, + {"F_WRLCK", Const, 0}, + {"Faccessat", Func, 0}, + {"Fallocate", Func, 0}, + {"Fbootstraptransfer_t", Type, 0}, + {"Fbootstraptransfer_t.Buffer", Field, 0}, + {"Fbootstraptransfer_t.Length", Field, 0}, + {"Fbootstraptransfer_t.Offset", Field, 0}, + {"Fchdir", Func, 0}, + {"Fchflags", Func, 0}, + {"Fchmod", Func, 0}, + {"Fchmodat", Func, 0}, + {"Fchown", Func, 0}, + {"Fchownat", Func, 0}, + {"FcntlFlock", Func, 3}, + {"FdSet", Type, 0}, + {"FdSet.Bits", Field, 0}, + {"FdSet.X__fds_bits", Field, 0}, + {"Fdatasync", Func, 0}, + {"FileNotifyInformation", Type, 0}, + {"FileNotifyInformation.Action", Field, 0}, + {"FileNotifyInformation.FileName", Field, 0}, + {"FileNotifyInformation.FileNameLength", Field, 0}, + {"FileNotifyInformation.NextEntryOffset", Field, 0}, + {"Filetime", Type, 0}, + {"Filetime.HighDateTime", Field, 0}, + {"Filetime.LowDateTime", Field, 0}, + {"FindClose", Func, 0}, + {"FindFirstFile", Func, 0}, + {"FindNextFile", Func, 0}, + {"Flock", Func, 0}, + {"Flock_t", Type, 0}, + {"Flock_t.Len", Field, 0}, + {"Flock_t.Pad_cgo_0", Field, 0}, + {"Flock_t.Pad_cgo_1", Field, 3}, + {"Flock_t.Pid", Field, 0}, + {"Flock_t.Start", Field, 0}, + {"Flock_t.Sysid", Field, 0}, + {"Flock_t.Type", Field, 0}, + {"Flock_t.Whence", Field, 0}, + {"FlushBpf", Func, 0}, + {"FlushFileBuffers", Func, 0}, + {"FlushViewOfFile", Func, 0}, + {"ForkExec", Func, 0}, + {"ForkLock", Var, 0}, + {"FormatMessage", Func, 0}, + {"Fpathconf", Func, 0}, + {"FreeAddrInfoW", Func, 1}, + {"FreeEnvironmentStrings", Func, 0}, + {"FreeLibrary", Func, 0}, + {"Fsid", Type, 0}, + {"Fsid.Val", Field, 0}, + {"Fsid.X__fsid_val", Field, 2}, + {"Fsid.X__val", Field, 0}, + {"Fstat", Func, 0}, + {"Fstatat", Func, 12}, + {"Fstatfs", Func, 0}, + {"Fstore_t", Type, 0}, + {"Fstore_t.Bytesalloc", Field, 0}, + {"Fstore_t.Flags", Field, 0}, + {"Fstore_t.Length", Field, 0}, + {"Fstore_t.Offset", Field, 0}, + {"Fstore_t.Posmode", Field, 0}, + {"Fsync", Func, 0}, + {"Ftruncate", Func, 0}, + {"FullPath", Func, 4}, + {"Futimes", Func, 0}, + {"Futimesat", Func, 0}, + {"GENERIC_ALL", Const, 0}, + {"GENERIC_EXECUTE", Const, 0}, + {"GENERIC_READ", Const, 0}, + {"GENERIC_WRITE", Const, 0}, + {"GUID", Type, 1}, + {"GUID.Data1", Field, 1}, + {"GUID.Data2", Field, 1}, + {"GUID.Data3", Field, 1}, + {"GUID.Data4", Field, 1}, + {"GetAcceptExSockaddrs", Func, 0}, + {"GetAdaptersInfo", Func, 0}, + {"GetAddrInfoW", Func, 1}, + {"GetCommandLine", Func, 0}, + {"GetComputerName", Func, 0}, + {"GetConsoleMode", Func, 1}, + {"GetCurrentDirectory", Func, 0}, + {"GetCurrentProcess", Func, 0}, + {"GetEnvironmentStrings", Func, 0}, + {"GetEnvironmentVariable", Func, 0}, + {"GetExitCodeProcess", Func, 0}, + {"GetFileAttributes", Func, 0}, + {"GetFileAttributesEx", Func, 0}, + {"GetFileExInfoStandard", Const, 0}, + {"GetFileExMaxInfoLevel", Const, 0}, + {"GetFileInformationByHandle", Func, 0}, + {"GetFileType", Func, 0}, + {"GetFullPathName", Func, 0}, + {"GetHostByName", Func, 0}, + {"GetIfEntry", Func, 0}, + {"GetLastError", Func, 0}, + {"GetLengthSid", Func, 0}, + {"GetLongPathName", Func, 0}, + {"GetProcAddress", Func, 0}, + {"GetProcessTimes", Func, 0}, + {"GetProtoByName", Func, 0}, + {"GetQueuedCompletionStatus", Func, 0}, + {"GetServByName", Func, 0}, + {"GetShortPathName", Func, 0}, + {"GetStartupInfo", Func, 0}, + {"GetStdHandle", Func, 0}, + {"GetSystemTimeAsFileTime", Func, 0}, + {"GetTempPath", Func, 0}, + {"GetTimeZoneInformation", Func, 0}, + {"GetTokenInformation", Func, 0}, + {"GetUserNameEx", Func, 0}, + {"GetUserProfileDirectory", Func, 0}, + {"GetVersion", Func, 0}, + {"Getcwd", Func, 0}, + {"Getdents", Func, 0}, + {"Getdirentries", Func, 0}, + {"Getdtablesize", Func, 0}, + {"Getegid", Func, 0}, + {"Getenv", Func, 0}, + {"Geteuid", Func, 0}, + {"Getfsstat", Func, 0}, + {"Getgid", Func, 0}, + {"Getgroups", Func, 0}, + {"Getpagesize", Func, 0}, + {"Getpeername", Func, 0}, + {"Getpgid", Func, 0}, + {"Getpgrp", Func, 0}, + {"Getpid", Func, 0}, + {"Getppid", Func, 0}, + {"Getpriority", Func, 0}, + {"Getrlimit", Func, 0}, + {"Getrusage", Func, 0}, + {"Getsid", Func, 0}, + {"Getsockname", Func, 0}, + {"Getsockopt", Func, 1}, + {"GetsockoptByte", Func, 0}, + {"GetsockoptICMPv6Filter", Func, 2}, + {"GetsockoptIPMreq", Func, 0}, + {"GetsockoptIPMreqn", Func, 0}, + {"GetsockoptIPv6MTUInfo", Func, 2}, + {"GetsockoptIPv6Mreq", Func, 0}, + {"GetsockoptInet4Addr", Func, 0}, + {"GetsockoptInt", Func, 0}, + {"GetsockoptUcred", Func, 1}, + {"Gettid", Func, 0}, + {"Gettimeofday", Func, 0}, + {"Getuid", Func, 0}, + {"Getwd", Func, 0}, + {"Getxattr", Func, 1}, + {"HANDLE_FLAG_INHERIT", Const, 0}, + {"HKEY_CLASSES_ROOT", Const, 0}, + {"HKEY_CURRENT_CONFIG", Const, 0}, + {"HKEY_CURRENT_USER", Const, 0}, + {"HKEY_DYN_DATA", Const, 0}, + {"HKEY_LOCAL_MACHINE", Const, 0}, + {"HKEY_PERFORMANCE_DATA", Const, 0}, + {"HKEY_USERS", Const, 0}, + {"HUPCL", Const, 0}, + {"Handle", Type, 0}, + {"Hostent", Type, 0}, + {"Hostent.AddrList", Field, 0}, + {"Hostent.AddrType", Field, 0}, + {"Hostent.Aliases", Field, 0}, + {"Hostent.Length", Field, 0}, + {"Hostent.Name", Field, 0}, + {"ICANON", Const, 0}, + {"ICMP6_FILTER", Const, 2}, + {"ICMPV6_FILTER", Const, 2}, + {"ICMPv6Filter", Type, 2}, + {"ICMPv6Filter.Data", Field, 2}, + {"ICMPv6Filter.Filt", Field, 2}, + {"ICRNL", Const, 0}, + {"IEXTEN", Const, 0}, + {"IFAN_ARRIVAL", Const, 1}, + {"IFAN_DEPARTURE", Const, 1}, + {"IFA_ADDRESS", Const, 0}, + {"IFA_ANYCAST", Const, 0}, + {"IFA_BROADCAST", Const, 0}, + {"IFA_CACHEINFO", Const, 0}, + {"IFA_F_DADFAILED", Const, 0}, + {"IFA_F_DEPRECATED", Const, 0}, + {"IFA_F_HOMEADDRESS", Const, 0}, + {"IFA_F_NODAD", Const, 0}, + {"IFA_F_OPTIMISTIC", Const, 0}, + {"IFA_F_PERMANENT", Const, 0}, + {"IFA_F_SECONDARY", Const, 0}, + {"IFA_F_TEMPORARY", Const, 0}, + {"IFA_F_TENTATIVE", Const, 0}, + {"IFA_LABEL", Const, 0}, + {"IFA_LOCAL", Const, 0}, + {"IFA_MAX", Const, 0}, + {"IFA_MULTICAST", Const, 0}, + {"IFA_ROUTE", Const, 1}, + {"IFA_UNSPEC", Const, 0}, + {"IFF_ALLMULTI", Const, 0}, + {"IFF_ALTPHYS", Const, 0}, + {"IFF_AUTOMEDIA", Const, 0}, + {"IFF_BROADCAST", Const, 0}, + {"IFF_CANTCHANGE", Const, 0}, + {"IFF_CANTCONFIG", Const, 1}, + {"IFF_DEBUG", Const, 0}, + {"IFF_DRV_OACTIVE", Const, 0}, + {"IFF_DRV_RUNNING", Const, 0}, + {"IFF_DYING", Const, 0}, + {"IFF_DYNAMIC", Const, 0}, + {"IFF_LINK0", Const, 0}, + {"IFF_LINK1", Const, 0}, + {"IFF_LINK2", Const, 0}, + {"IFF_LOOPBACK", Const, 0}, + {"IFF_MASTER", Const, 0}, + {"IFF_MONITOR", Const, 0}, + {"IFF_MULTICAST", Const, 0}, + {"IFF_NOARP", Const, 0}, + {"IFF_NOTRAILERS", Const, 0}, + {"IFF_NO_PI", Const, 0}, + {"IFF_OACTIVE", Const, 0}, + {"IFF_ONE_QUEUE", Const, 0}, + {"IFF_POINTOPOINT", Const, 0}, + {"IFF_POINTTOPOINT", Const, 0}, + {"IFF_PORTSEL", Const, 0}, + {"IFF_PPROMISC", Const, 0}, + {"IFF_PROMISC", Const, 0}, + {"IFF_RENAMING", Const, 0}, + {"IFF_RUNNING", Const, 0}, + {"IFF_SIMPLEX", Const, 0}, + {"IFF_SLAVE", Const, 0}, + {"IFF_SMART", Const, 0}, + {"IFF_STATICARP", Const, 0}, + {"IFF_TAP", Const, 0}, + {"IFF_TUN", Const, 0}, + {"IFF_TUN_EXCL", Const, 0}, + {"IFF_UP", Const, 0}, + {"IFF_VNET_HDR", Const, 0}, + {"IFLA_ADDRESS", Const, 0}, + {"IFLA_BROADCAST", Const, 0}, + {"IFLA_COST", Const, 0}, + {"IFLA_IFALIAS", Const, 0}, + {"IFLA_IFNAME", Const, 0}, + {"IFLA_LINK", Const, 0}, + {"IFLA_LINKINFO", Const, 0}, + {"IFLA_LINKMODE", Const, 0}, + {"IFLA_MAP", Const, 0}, + {"IFLA_MASTER", Const, 0}, + {"IFLA_MAX", Const, 0}, + {"IFLA_MTU", Const, 0}, + {"IFLA_NET_NS_PID", Const, 0}, + {"IFLA_OPERSTATE", Const, 0}, + {"IFLA_PRIORITY", Const, 0}, + {"IFLA_PROTINFO", Const, 0}, + {"IFLA_QDISC", Const, 0}, + {"IFLA_STATS", Const, 0}, + {"IFLA_TXQLEN", Const, 0}, + {"IFLA_UNSPEC", Const, 0}, + {"IFLA_WEIGHT", Const, 0}, + {"IFLA_WIRELESS", Const, 0}, + {"IFNAMSIZ", Const, 0}, + {"IFT_1822", Const, 0}, + {"IFT_A12MPPSWITCH", Const, 0}, + {"IFT_AAL2", Const, 0}, + {"IFT_AAL5", Const, 0}, + {"IFT_ADSL", Const, 0}, + {"IFT_AFLANE8023", Const, 0}, + {"IFT_AFLANE8025", Const, 0}, + {"IFT_ARAP", Const, 0}, + {"IFT_ARCNET", Const, 0}, + {"IFT_ARCNETPLUS", Const, 0}, + {"IFT_ASYNC", Const, 0}, + {"IFT_ATM", Const, 0}, + {"IFT_ATMDXI", Const, 0}, + {"IFT_ATMFUNI", Const, 0}, + {"IFT_ATMIMA", Const, 0}, + {"IFT_ATMLOGICAL", Const, 0}, + {"IFT_ATMRADIO", Const, 0}, + {"IFT_ATMSUBINTERFACE", Const, 0}, + {"IFT_ATMVCIENDPT", Const, 0}, + {"IFT_ATMVIRTUAL", Const, 0}, + {"IFT_BGPPOLICYACCOUNTING", Const, 0}, + {"IFT_BLUETOOTH", Const, 1}, + {"IFT_BRIDGE", Const, 0}, + {"IFT_BSC", Const, 0}, + {"IFT_CARP", Const, 0}, + {"IFT_CCTEMUL", Const, 0}, + {"IFT_CELLULAR", Const, 0}, + {"IFT_CEPT", Const, 0}, + {"IFT_CES", Const, 0}, + {"IFT_CHANNEL", Const, 0}, + {"IFT_CNR", Const, 0}, + {"IFT_COFFEE", Const, 0}, + {"IFT_COMPOSITELINK", Const, 0}, + {"IFT_DCN", Const, 0}, + {"IFT_DIGITALPOWERLINE", Const, 0}, + {"IFT_DIGITALWRAPPEROVERHEADCHANNEL", Const, 0}, + {"IFT_DLSW", Const, 0}, + {"IFT_DOCSCABLEDOWNSTREAM", Const, 0}, + {"IFT_DOCSCABLEMACLAYER", Const, 0}, + {"IFT_DOCSCABLEUPSTREAM", Const, 0}, + {"IFT_DOCSCABLEUPSTREAMCHANNEL", Const, 1}, + {"IFT_DS0", Const, 0}, + {"IFT_DS0BUNDLE", Const, 0}, + {"IFT_DS1FDL", Const, 0}, + {"IFT_DS3", Const, 0}, + {"IFT_DTM", Const, 0}, + {"IFT_DUMMY", Const, 1}, + {"IFT_DVBASILN", Const, 0}, + {"IFT_DVBASIOUT", Const, 0}, + {"IFT_DVBRCCDOWNSTREAM", Const, 0}, + {"IFT_DVBRCCMACLAYER", Const, 0}, + {"IFT_DVBRCCUPSTREAM", Const, 0}, + {"IFT_ECONET", Const, 1}, + {"IFT_ENC", Const, 0}, + {"IFT_EON", Const, 0}, + {"IFT_EPLRS", Const, 0}, + {"IFT_ESCON", Const, 0}, + {"IFT_ETHER", Const, 0}, + {"IFT_FAITH", Const, 0}, + {"IFT_FAST", Const, 0}, + {"IFT_FASTETHER", Const, 0}, + {"IFT_FASTETHERFX", Const, 0}, + {"IFT_FDDI", Const, 0}, + {"IFT_FIBRECHANNEL", Const, 0}, + {"IFT_FRAMERELAYINTERCONNECT", Const, 0}, + {"IFT_FRAMERELAYMPI", Const, 0}, + {"IFT_FRDLCIENDPT", Const, 0}, + {"IFT_FRELAY", Const, 0}, + {"IFT_FRELAYDCE", Const, 0}, + {"IFT_FRF16MFRBUNDLE", Const, 0}, + {"IFT_FRFORWARD", Const, 0}, + {"IFT_G703AT2MB", Const, 0}, + {"IFT_G703AT64K", Const, 0}, + {"IFT_GIF", Const, 0}, + {"IFT_GIGABITETHERNET", Const, 0}, + {"IFT_GR303IDT", Const, 0}, + {"IFT_GR303RDT", Const, 0}, + {"IFT_H323GATEKEEPER", Const, 0}, + {"IFT_H323PROXY", Const, 0}, + {"IFT_HDH1822", Const, 0}, + {"IFT_HDLC", Const, 0}, + {"IFT_HDSL2", Const, 0}, + {"IFT_HIPERLAN2", Const, 0}, + {"IFT_HIPPI", Const, 0}, + {"IFT_HIPPIINTERFACE", Const, 0}, + {"IFT_HOSTPAD", Const, 0}, + {"IFT_HSSI", Const, 0}, + {"IFT_HY", Const, 0}, + {"IFT_IBM370PARCHAN", Const, 0}, + {"IFT_IDSL", Const, 0}, + {"IFT_IEEE1394", Const, 0}, + {"IFT_IEEE80211", Const, 0}, + {"IFT_IEEE80212", Const, 0}, + {"IFT_IEEE8023ADLAG", Const, 0}, + {"IFT_IFGSN", Const, 0}, + {"IFT_IMT", Const, 0}, + {"IFT_INFINIBAND", Const, 1}, + {"IFT_INTERLEAVE", Const, 0}, + {"IFT_IP", Const, 0}, + {"IFT_IPFORWARD", Const, 0}, + {"IFT_IPOVERATM", Const, 0}, + {"IFT_IPOVERCDLC", Const, 0}, + {"IFT_IPOVERCLAW", Const, 0}, + {"IFT_IPSWITCH", Const, 0}, + {"IFT_IPXIP", Const, 0}, + {"IFT_ISDN", Const, 0}, + {"IFT_ISDNBASIC", Const, 0}, + {"IFT_ISDNPRIMARY", Const, 0}, + {"IFT_ISDNS", Const, 0}, + {"IFT_ISDNU", Const, 0}, + {"IFT_ISO88022LLC", Const, 0}, + {"IFT_ISO88023", Const, 0}, + {"IFT_ISO88024", Const, 0}, + {"IFT_ISO88025", Const, 0}, + {"IFT_ISO88025CRFPINT", Const, 0}, + {"IFT_ISO88025DTR", Const, 0}, + {"IFT_ISO88025FIBER", Const, 0}, + {"IFT_ISO88026", Const, 0}, + {"IFT_ISUP", Const, 0}, + {"IFT_L2VLAN", Const, 0}, + {"IFT_L3IPVLAN", Const, 0}, + {"IFT_L3IPXVLAN", Const, 0}, + {"IFT_LAPB", Const, 0}, + {"IFT_LAPD", Const, 0}, + {"IFT_LAPF", Const, 0}, + {"IFT_LINEGROUP", Const, 1}, + {"IFT_LOCALTALK", Const, 0}, + {"IFT_LOOP", Const, 0}, + {"IFT_MEDIAMAILOVERIP", Const, 0}, + {"IFT_MFSIGLINK", Const, 0}, + {"IFT_MIOX25", Const, 0}, + {"IFT_MODEM", Const, 0}, + {"IFT_MPC", Const, 0}, + {"IFT_MPLS", Const, 0}, + {"IFT_MPLSTUNNEL", Const, 0}, + {"IFT_MSDSL", Const, 0}, + {"IFT_MVL", Const, 0}, + {"IFT_MYRINET", Const, 0}, + {"IFT_NFAS", Const, 0}, + {"IFT_NSIP", Const, 0}, + {"IFT_OPTICALCHANNEL", Const, 0}, + {"IFT_OPTICALTRANSPORT", Const, 0}, + {"IFT_OTHER", Const, 0}, + {"IFT_P10", Const, 0}, + {"IFT_P80", Const, 0}, + {"IFT_PARA", Const, 0}, + {"IFT_PDP", Const, 0}, + {"IFT_PFLOG", Const, 0}, + {"IFT_PFLOW", Const, 1}, + {"IFT_PFSYNC", Const, 0}, + {"IFT_PLC", Const, 0}, + {"IFT_PON155", Const, 1}, + {"IFT_PON622", Const, 1}, + {"IFT_POS", Const, 0}, + {"IFT_PPP", Const, 0}, + {"IFT_PPPMULTILINKBUNDLE", Const, 0}, + {"IFT_PROPATM", Const, 1}, + {"IFT_PROPBWAP2MP", Const, 0}, + {"IFT_PROPCNLS", Const, 0}, + {"IFT_PROPDOCSWIRELESSDOWNSTREAM", Const, 0}, + {"IFT_PROPDOCSWIRELESSMACLAYER", Const, 0}, + {"IFT_PROPDOCSWIRELESSUPSTREAM", Const, 0}, + {"IFT_PROPMUX", Const, 0}, + {"IFT_PROPVIRTUAL", Const, 0}, + {"IFT_PROPWIRELESSP2P", Const, 0}, + {"IFT_PTPSERIAL", Const, 0}, + {"IFT_PVC", Const, 0}, + {"IFT_Q2931", Const, 1}, + {"IFT_QLLC", Const, 0}, + {"IFT_RADIOMAC", Const, 0}, + {"IFT_RADSL", Const, 0}, + {"IFT_REACHDSL", Const, 0}, + {"IFT_RFC1483", Const, 0}, + {"IFT_RS232", Const, 0}, + {"IFT_RSRB", Const, 0}, + {"IFT_SDLC", Const, 0}, + {"IFT_SDSL", Const, 0}, + {"IFT_SHDSL", Const, 0}, + {"IFT_SIP", Const, 0}, + {"IFT_SIPSIG", Const, 1}, + {"IFT_SIPTG", Const, 1}, + {"IFT_SLIP", Const, 0}, + {"IFT_SMDSDXI", Const, 0}, + {"IFT_SMDSICIP", Const, 0}, + {"IFT_SONET", Const, 0}, + {"IFT_SONETOVERHEADCHANNEL", Const, 0}, + {"IFT_SONETPATH", Const, 0}, + {"IFT_SONETVT", Const, 0}, + {"IFT_SRP", Const, 0}, + {"IFT_SS7SIGLINK", Const, 0}, + {"IFT_STACKTOSTACK", Const, 0}, + {"IFT_STARLAN", Const, 0}, + {"IFT_STF", Const, 0}, + {"IFT_T1", Const, 0}, + {"IFT_TDLC", Const, 0}, + {"IFT_TELINK", Const, 1}, + {"IFT_TERMPAD", Const, 0}, + {"IFT_TR008", Const, 0}, + {"IFT_TRANSPHDLC", Const, 0}, + {"IFT_TUNNEL", Const, 0}, + {"IFT_ULTRA", Const, 0}, + {"IFT_USB", Const, 0}, + {"IFT_V11", Const, 0}, + {"IFT_V35", Const, 0}, + {"IFT_V36", Const, 0}, + {"IFT_V37", Const, 0}, + {"IFT_VDSL", Const, 0}, + {"IFT_VIRTUALIPADDRESS", Const, 0}, + {"IFT_VIRTUALTG", Const, 1}, + {"IFT_VOICEDID", Const, 1}, + {"IFT_VOICEEM", Const, 0}, + {"IFT_VOICEEMFGD", Const, 1}, + {"IFT_VOICEENCAP", Const, 0}, + {"IFT_VOICEFGDEANA", Const, 1}, + {"IFT_VOICEFXO", Const, 0}, + {"IFT_VOICEFXS", Const, 0}, + {"IFT_VOICEOVERATM", Const, 0}, + {"IFT_VOICEOVERCABLE", Const, 1}, + {"IFT_VOICEOVERFRAMERELAY", Const, 0}, + {"IFT_VOICEOVERIP", Const, 0}, + {"IFT_X213", Const, 0}, + {"IFT_X25", Const, 0}, + {"IFT_X25DDN", Const, 0}, + {"IFT_X25HUNTGROUP", Const, 0}, + {"IFT_X25MLP", Const, 0}, + {"IFT_X25PLE", Const, 0}, + {"IFT_XETHER", Const, 0}, + {"IGNBRK", Const, 0}, + {"IGNCR", Const, 0}, + {"IGNORE", Const, 0}, + {"IGNPAR", Const, 0}, + {"IMAXBEL", Const, 0}, + {"INFINITE", Const, 0}, + {"INLCR", Const, 0}, + {"INPCK", Const, 0}, + {"INVALID_FILE_ATTRIBUTES", Const, 0}, + {"IN_ACCESS", Const, 0}, + {"IN_ALL_EVENTS", Const, 0}, + {"IN_ATTRIB", Const, 0}, + {"IN_CLASSA_HOST", Const, 0}, + {"IN_CLASSA_MAX", Const, 0}, + {"IN_CLASSA_NET", Const, 0}, + {"IN_CLASSA_NSHIFT", Const, 0}, + {"IN_CLASSB_HOST", Const, 0}, + {"IN_CLASSB_MAX", Const, 0}, + {"IN_CLASSB_NET", Const, 0}, + {"IN_CLASSB_NSHIFT", Const, 0}, + {"IN_CLASSC_HOST", Const, 0}, + {"IN_CLASSC_NET", Const, 0}, + {"IN_CLASSC_NSHIFT", Const, 0}, + {"IN_CLASSD_HOST", Const, 0}, + {"IN_CLASSD_NET", Const, 0}, + {"IN_CLASSD_NSHIFT", Const, 0}, + {"IN_CLOEXEC", Const, 0}, + {"IN_CLOSE", Const, 0}, + {"IN_CLOSE_NOWRITE", Const, 0}, + {"IN_CLOSE_WRITE", Const, 0}, + {"IN_CREATE", Const, 0}, + {"IN_DELETE", Const, 0}, + {"IN_DELETE_SELF", Const, 0}, + {"IN_DONT_FOLLOW", Const, 0}, + {"IN_EXCL_UNLINK", Const, 0}, + {"IN_IGNORED", Const, 0}, + {"IN_ISDIR", Const, 0}, + {"IN_LINKLOCALNETNUM", Const, 0}, + {"IN_LOOPBACKNET", Const, 0}, + {"IN_MASK_ADD", Const, 0}, + {"IN_MODIFY", Const, 0}, + {"IN_MOVE", Const, 0}, + {"IN_MOVED_FROM", Const, 0}, + {"IN_MOVED_TO", Const, 0}, + {"IN_MOVE_SELF", Const, 0}, + {"IN_NONBLOCK", Const, 0}, + {"IN_ONESHOT", Const, 0}, + {"IN_ONLYDIR", Const, 0}, + {"IN_OPEN", Const, 0}, + {"IN_Q_OVERFLOW", Const, 0}, + {"IN_RFC3021_HOST", Const, 1}, + {"IN_RFC3021_MASK", Const, 1}, + {"IN_RFC3021_NET", Const, 1}, + {"IN_RFC3021_NSHIFT", Const, 1}, + {"IN_UNMOUNT", Const, 0}, + {"IOC_IN", Const, 1}, + {"IOC_INOUT", Const, 1}, + {"IOC_OUT", Const, 1}, + {"IOC_VENDOR", Const, 3}, + {"IOC_WS2", Const, 1}, + {"IO_REPARSE_TAG_SYMLINK", Const, 4}, + {"IPMreq", Type, 0}, + {"IPMreq.Interface", Field, 0}, + {"IPMreq.Multiaddr", Field, 0}, + {"IPMreqn", Type, 0}, + {"IPMreqn.Address", Field, 0}, + {"IPMreqn.Ifindex", Field, 0}, + {"IPMreqn.Multiaddr", Field, 0}, + {"IPPROTO_3PC", Const, 0}, + {"IPPROTO_ADFS", Const, 0}, + {"IPPROTO_AH", Const, 0}, + {"IPPROTO_AHIP", Const, 0}, + {"IPPROTO_APES", Const, 0}, + {"IPPROTO_ARGUS", Const, 0}, + {"IPPROTO_AX25", Const, 0}, + {"IPPROTO_BHA", Const, 0}, + {"IPPROTO_BLT", Const, 0}, + {"IPPROTO_BRSATMON", Const, 0}, + {"IPPROTO_CARP", Const, 0}, + {"IPPROTO_CFTP", Const, 0}, + {"IPPROTO_CHAOS", Const, 0}, + {"IPPROTO_CMTP", Const, 0}, + {"IPPROTO_COMP", Const, 0}, + {"IPPROTO_CPHB", Const, 0}, + {"IPPROTO_CPNX", Const, 0}, + {"IPPROTO_DCCP", Const, 0}, + {"IPPROTO_DDP", Const, 0}, + {"IPPROTO_DGP", Const, 0}, + {"IPPROTO_DIVERT", Const, 0}, + {"IPPROTO_DIVERT_INIT", Const, 3}, + {"IPPROTO_DIVERT_RESP", Const, 3}, + {"IPPROTO_DONE", Const, 0}, + {"IPPROTO_DSTOPTS", Const, 0}, + {"IPPROTO_EGP", Const, 0}, + {"IPPROTO_EMCON", Const, 0}, + {"IPPROTO_ENCAP", Const, 0}, + {"IPPROTO_EON", Const, 0}, + {"IPPROTO_ESP", Const, 0}, + {"IPPROTO_ETHERIP", Const, 0}, + {"IPPROTO_FRAGMENT", Const, 0}, + {"IPPROTO_GGP", Const, 0}, + {"IPPROTO_GMTP", Const, 0}, + {"IPPROTO_GRE", Const, 0}, + {"IPPROTO_HELLO", Const, 0}, + {"IPPROTO_HMP", Const, 0}, + {"IPPROTO_HOPOPTS", Const, 0}, + {"IPPROTO_ICMP", Const, 0}, + {"IPPROTO_ICMPV6", Const, 0}, + {"IPPROTO_IDP", Const, 0}, + {"IPPROTO_IDPR", Const, 0}, + {"IPPROTO_IDRP", Const, 0}, + {"IPPROTO_IGMP", Const, 0}, + {"IPPROTO_IGP", Const, 0}, + {"IPPROTO_IGRP", Const, 0}, + {"IPPROTO_IL", Const, 0}, + {"IPPROTO_INLSP", Const, 0}, + {"IPPROTO_INP", Const, 0}, + {"IPPROTO_IP", Const, 0}, + {"IPPROTO_IPCOMP", Const, 0}, + {"IPPROTO_IPCV", Const, 0}, + {"IPPROTO_IPEIP", Const, 0}, + {"IPPROTO_IPIP", Const, 0}, + {"IPPROTO_IPPC", Const, 0}, + {"IPPROTO_IPV4", Const, 0}, + {"IPPROTO_IPV6", Const, 0}, + {"IPPROTO_IPV6_ICMP", Const, 1}, + {"IPPROTO_IRTP", Const, 0}, + {"IPPROTO_KRYPTOLAN", Const, 0}, + {"IPPROTO_LARP", Const, 0}, + {"IPPROTO_LEAF1", Const, 0}, + {"IPPROTO_LEAF2", Const, 0}, + {"IPPROTO_MAX", Const, 0}, + {"IPPROTO_MAXID", Const, 0}, + {"IPPROTO_MEAS", Const, 0}, + {"IPPROTO_MH", Const, 1}, + {"IPPROTO_MHRP", Const, 0}, + {"IPPROTO_MICP", Const, 0}, + {"IPPROTO_MOBILE", Const, 0}, + {"IPPROTO_MPLS", Const, 1}, + {"IPPROTO_MTP", Const, 0}, + {"IPPROTO_MUX", Const, 0}, + {"IPPROTO_ND", Const, 0}, + {"IPPROTO_NHRP", Const, 0}, + {"IPPROTO_NONE", Const, 0}, + {"IPPROTO_NSP", Const, 0}, + {"IPPROTO_NVPII", Const, 0}, + {"IPPROTO_OLD_DIVERT", Const, 0}, + {"IPPROTO_OSPFIGP", Const, 0}, + {"IPPROTO_PFSYNC", Const, 0}, + {"IPPROTO_PGM", Const, 0}, + {"IPPROTO_PIGP", Const, 0}, + {"IPPROTO_PIM", Const, 0}, + {"IPPROTO_PRM", Const, 0}, + {"IPPROTO_PUP", Const, 0}, + {"IPPROTO_PVP", Const, 0}, + {"IPPROTO_RAW", Const, 0}, + {"IPPROTO_RCCMON", Const, 0}, + {"IPPROTO_RDP", Const, 0}, + {"IPPROTO_ROUTING", Const, 0}, + {"IPPROTO_RSVP", Const, 0}, + {"IPPROTO_RVD", Const, 0}, + {"IPPROTO_SATEXPAK", Const, 0}, + {"IPPROTO_SATMON", Const, 0}, + {"IPPROTO_SCCSP", Const, 0}, + {"IPPROTO_SCTP", Const, 0}, + {"IPPROTO_SDRP", Const, 0}, + {"IPPROTO_SEND", Const, 1}, + {"IPPROTO_SEP", Const, 0}, + {"IPPROTO_SKIP", Const, 0}, + {"IPPROTO_SPACER", Const, 0}, + {"IPPROTO_SRPC", Const, 0}, + {"IPPROTO_ST", Const, 0}, + {"IPPROTO_SVMTP", Const, 0}, + {"IPPROTO_SWIPE", Const, 0}, + {"IPPROTO_TCF", Const, 0}, + {"IPPROTO_TCP", Const, 0}, + {"IPPROTO_TLSP", Const, 0}, + {"IPPROTO_TP", Const, 0}, + {"IPPROTO_TPXX", Const, 0}, + {"IPPROTO_TRUNK1", Const, 0}, + {"IPPROTO_TRUNK2", Const, 0}, + {"IPPROTO_TTP", Const, 0}, + {"IPPROTO_UDP", Const, 0}, + {"IPPROTO_UDPLITE", Const, 0}, + {"IPPROTO_VINES", Const, 0}, + {"IPPROTO_VISA", Const, 0}, + {"IPPROTO_VMTP", Const, 0}, + {"IPPROTO_VRRP", Const, 1}, + {"IPPROTO_WBEXPAK", Const, 0}, + {"IPPROTO_WBMON", Const, 0}, + {"IPPROTO_WSN", Const, 0}, + {"IPPROTO_XNET", Const, 0}, + {"IPPROTO_XTP", Const, 0}, + {"IPV6_2292DSTOPTS", Const, 0}, + {"IPV6_2292HOPLIMIT", Const, 0}, + {"IPV6_2292HOPOPTS", Const, 0}, + {"IPV6_2292NEXTHOP", Const, 0}, + {"IPV6_2292PKTINFO", Const, 0}, + {"IPV6_2292PKTOPTIONS", Const, 0}, + {"IPV6_2292RTHDR", Const, 0}, + {"IPV6_ADDRFORM", Const, 0}, + {"IPV6_ADD_MEMBERSHIP", Const, 0}, + {"IPV6_AUTHHDR", Const, 0}, + {"IPV6_AUTH_LEVEL", Const, 1}, + {"IPV6_AUTOFLOWLABEL", Const, 0}, + {"IPV6_BINDANY", Const, 0}, + {"IPV6_BINDV6ONLY", Const, 0}, + {"IPV6_BOUND_IF", Const, 0}, + {"IPV6_CHECKSUM", Const, 0}, + {"IPV6_DEFAULT_MULTICAST_HOPS", Const, 0}, + {"IPV6_DEFAULT_MULTICAST_LOOP", Const, 0}, + {"IPV6_DEFHLIM", Const, 0}, + {"IPV6_DONTFRAG", Const, 0}, + {"IPV6_DROP_MEMBERSHIP", Const, 0}, + {"IPV6_DSTOPTS", Const, 0}, + {"IPV6_ESP_NETWORK_LEVEL", Const, 1}, + {"IPV6_ESP_TRANS_LEVEL", Const, 1}, + {"IPV6_FAITH", Const, 0}, + {"IPV6_FLOWINFO_MASK", Const, 0}, + {"IPV6_FLOWLABEL_MASK", Const, 0}, + {"IPV6_FRAGTTL", Const, 0}, + {"IPV6_FW_ADD", Const, 0}, + {"IPV6_FW_DEL", Const, 0}, + {"IPV6_FW_FLUSH", Const, 0}, + {"IPV6_FW_GET", Const, 0}, + {"IPV6_FW_ZERO", Const, 0}, + {"IPV6_HLIMDEC", Const, 0}, + {"IPV6_HOPLIMIT", Const, 0}, + {"IPV6_HOPOPTS", Const, 0}, + {"IPV6_IPCOMP_LEVEL", Const, 1}, + {"IPV6_IPSEC_POLICY", Const, 0}, + {"IPV6_JOIN_ANYCAST", Const, 0}, + {"IPV6_JOIN_GROUP", Const, 0}, + {"IPV6_LEAVE_ANYCAST", Const, 0}, + {"IPV6_LEAVE_GROUP", Const, 0}, + {"IPV6_MAXHLIM", Const, 0}, + {"IPV6_MAXOPTHDR", Const, 0}, + {"IPV6_MAXPACKET", Const, 0}, + {"IPV6_MAX_GROUP_SRC_FILTER", Const, 0}, + {"IPV6_MAX_MEMBERSHIPS", Const, 0}, + {"IPV6_MAX_SOCK_SRC_FILTER", Const, 0}, + {"IPV6_MIN_MEMBERSHIPS", Const, 0}, + {"IPV6_MMTU", Const, 0}, + {"IPV6_MSFILTER", Const, 0}, + {"IPV6_MTU", Const, 0}, + {"IPV6_MTU_DISCOVER", Const, 0}, + {"IPV6_MULTICAST_HOPS", Const, 0}, + {"IPV6_MULTICAST_IF", Const, 0}, + {"IPV6_MULTICAST_LOOP", Const, 0}, + {"IPV6_NEXTHOP", Const, 0}, + {"IPV6_OPTIONS", Const, 1}, + {"IPV6_PATHMTU", Const, 0}, + {"IPV6_PIPEX", Const, 1}, + {"IPV6_PKTINFO", Const, 0}, + {"IPV6_PMTUDISC_DO", Const, 0}, + {"IPV6_PMTUDISC_DONT", Const, 0}, + {"IPV6_PMTUDISC_PROBE", Const, 0}, + {"IPV6_PMTUDISC_WANT", Const, 0}, + {"IPV6_PORTRANGE", Const, 0}, + {"IPV6_PORTRANGE_DEFAULT", Const, 0}, + {"IPV6_PORTRANGE_HIGH", Const, 0}, + {"IPV6_PORTRANGE_LOW", Const, 0}, + {"IPV6_PREFER_TEMPADDR", Const, 0}, + {"IPV6_RECVDSTOPTS", Const, 0}, + {"IPV6_RECVDSTPORT", Const, 3}, + {"IPV6_RECVERR", Const, 0}, + {"IPV6_RECVHOPLIMIT", Const, 0}, + {"IPV6_RECVHOPOPTS", Const, 0}, + {"IPV6_RECVPATHMTU", Const, 0}, + {"IPV6_RECVPKTINFO", Const, 0}, + {"IPV6_RECVRTHDR", Const, 0}, + {"IPV6_RECVTCLASS", Const, 0}, + {"IPV6_ROUTER_ALERT", Const, 0}, + {"IPV6_RTABLE", Const, 1}, + {"IPV6_RTHDR", Const, 0}, + {"IPV6_RTHDRDSTOPTS", Const, 0}, + {"IPV6_RTHDR_LOOSE", Const, 0}, + {"IPV6_RTHDR_STRICT", Const, 0}, + {"IPV6_RTHDR_TYPE_0", Const, 0}, + {"IPV6_RXDSTOPTS", Const, 0}, + {"IPV6_RXHOPOPTS", Const, 0}, + {"IPV6_SOCKOPT_RESERVED1", Const, 0}, + {"IPV6_TCLASS", Const, 0}, + {"IPV6_UNICAST_HOPS", Const, 0}, + {"IPV6_USE_MIN_MTU", Const, 0}, + {"IPV6_V6ONLY", Const, 0}, + {"IPV6_VERSION", Const, 0}, + {"IPV6_VERSION_MASK", Const, 0}, + {"IPV6_XFRM_POLICY", Const, 0}, + {"IP_ADD_MEMBERSHIP", Const, 0}, + {"IP_ADD_SOURCE_MEMBERSHIP", Const, 0}, + {"IP_AUTH_LEVEL", Const, 1}, + {"IP_BINDANY", Const, 0}, + {"IP_BLOCK_SOURCE", Const, 0}, + {"IP_BOUND_IF", Const, 0}, + {"IP_DEFAULT_MULTICAST_LOOP", Const, 0}, + {"IP_DEFAULT_MULTICAST_TTL", Const, 0}, + {"IP_DF", Const, 0}, + {"IP_DIVERTFL", Const, 3}, + {"IP_DONTFRAG", Const, 0}, + {"IP_DROP_MEMBERSHIP", Const, 0}, + {"IP_DROP_SOURCE_MEMBERSHIP", Const, 0}, + {"IP_DUMMYNET3", Const, 0}, + {"IP_DUMMYNET_CONFIGURE", Const, 0}, + {"IP_DUMMYNET_DEL", Const, 0}, + {"IP_DUMMYNET_FLUSH", Const, 0}, + {"IP_DUMMYNET_GET", Const, 0}, + {"IP_EF", Const, 1}, + {"IP_ERRORMTU", Const, 1}, + {"IP_ESP_NETWORK_LEVEL", Const, 1}, + {"IP_ESP_TRANS_LEVEL", Const, 1}, + {"IP_FAITH", Const, 0}, + {"IP_FREEBIND", Const, 0}, + {"IP_FW3", Const, 0}, + {"IP_FW_ADD", Const, 0}, + {"IP_FW_DEL", Const, 0}, + {"IP_FW_FLUSH", Const, 0}, + {"IP_FW_GET", Const, 0}, + {"IP_FW_NAT_CFG", Const, 0}, + {"IP_FW_NAT_DEL", Const, 0}, + {"IP_FW_NAT_GET_CONFIG", Const, 0}, + {"IP_FW_NAT_GET_LOG", Const, 0}, + {"IP_FW_RESETLOG", Const, 0}, + {"IP_FW_TABLE_ADD", Const, 0}, + {"IP_FW_TABLE_DEL", Const, 0}, + {"IP_FW_TABLE_FLUSH", Const, 0}, + {"IP_FW_TABLE_GETSIZE", Const, 0}, + {"IP_FW_TABLE_LIST", Const, 0}, + {"IP_FW_ZERO", Const, 0}, + {"IP_HDRINCL", Const, 0}, + {"IP_IPCOMP_LEVEL", Const, 1}, + {"IP_IPSECFLOWINFO", Const, 1}, + {"IP_IPSEC_LOCAL_AUTH", Const, 1}, + {"IP_IPSEC_LOCAL_CRED", Const, 1}, + {"IP_IPSEC_LOCAL_ID", Const, 1}, + {"IP_IPSEC_POLICY", Const, 0}, + {"IP_IPSEC_REMOTE_AUTH", Const, 1}, + {"IP_IPSEC_REMOTE_CRED", Const, 1}, + {"IP_IPSEC_REMOTE_ID", Const, 1}, + {"IP_MAXPACKET", Const, 0}, + {"IP_MAX_GROUP_SRC_FILTER", Const, 0}, + {"IP_MAX_MEMBERSHIPS", Const, 0}, + {"IP_MAX_SOCK_MUTE_FILTER", Const, 0}, + {"IP_MAX_SOCK_SRC_FILTER", Const, 0}, + {"IP_MAX_SOURCE_FILTER", Const, 0}, + {"IP_MF", Const, 0}, + {"IP_MINFRAGSIZE", Const, 1}, + {"IP_MINTTL", Const, 0}, + {"IP_MIN_MEMBERSHIPS", Const, 0}, + {"IP_MSFILTER", Const, 0}, + {"IP_MSS", Const, 0}, + {"IP_MTU", Const, 0}, + {"IP_MTU_DISCOVER", Const, 0}, + {"IP_MULTICAST_IF", Const, 0}, + {"IP_MULTICAST_IFINDEX", Const, 0}, + {"IP_MULTICAST_LOOP", Const, 0}, + {"IP_MULTICAST_TTL", Const, 0}, + {"IP_MULTICAST_VIF", Const, 0}, + {"IP_NAT__XXX", Const, 0}, + {"IP_OFFMASK", Const, 0}, + {"IP_OLD_FW_ADD", Const, 0}, + {"IP_OLD_FW_DEL", Const, 0}, + {"IP_OLD_FW_FLUSH", Const, 0}, + {"IP_OLD_FW_GET", Const, 0}, + {"IP_OLD_FW_RESETLOG", Const, 0}, + {"IP_OLD_FW_ZERO", Const, 0}, + {"IP_ONESBCAST", Const, 0}, + {"IP_OPTIONS", Const, 0}, + {"IP_ORIGDSTADDR", Const, 0}, + {"IP_PASSSEC", Const, 0}, + {"IP_PIPEX", Const, 1}, + {"IP_PKTINFO", Const, 0}, + {"IP_PKTOPTIONS", Const, 0}, + {"IP_PMTUDISC", Const, 0}, + {"IP_PMTUDISC_DO", Const, 0}, + {"IP_PMTUDISC_DONT", Const, 0}, + {"IP_PMTUDISC_PROBE", Const, 0}, + {"IP_PMTUDISC_WANT", Const, 0}, + {"IP_PORTRANGE", Const, 0}, + {"IP_PORTRANGE_DEFAULT", Const, 0}, + {"IP_PORTRANGE_HIGH", Const, 0}, + {"IP_PORTRANGE_LOW", Const, 0}, + {"IP_RECVDSTADDR", Const, 0}, + {"IP_RECVDSTPORT", Const, 1}, + {"IP_RECVERR", Const, 0}, + {"IP_RECVIF", Const, 0}, + {"IP_RECVOPTS", Const, 0}, + {"IP_RECVORIGDSTADDR", Const, 0}, + {"IP_RECVPKTINFO", Const, 0}, + {"IP_RECVRETOPTS", Const, 0}, + {"IP_RECVRTABLE", Const, 1}, + {"IP_RECVTOS", Const, 0}, + {"IP_RECVTTL", Const, 0}, + {"IP_RETOPTS", Const, 0}, + {"IP_RF", Const, 0}, + {"IP_ROUTER_ALERT", Const, 0}, + {"IP_RSVP_OFF", Const, 0}, + {"IP_RSVP_ON", Const, 0}, + {"IP_RSVP_VIF_OFF", Const, 0}, + {"IP_RSVP_VIF_ON", Const, 0}, + {"IP_RTABLE", Const, 1}, + {"IP_SENDSRCADDR", Const, 0}, + {"IP_STRIPHDR", Const, 0}, + {"IP_TOS", Const, 0}, + {"IP_TRAFFIC_MGT_BACKGROUND", Const, 0}, + {"IP_TRANSPARENT", Const, 0}, + {"IP_TTL", Const, 0}, + {"IP_UNBLOCK_SOURCE", Const, 0}, + {"IP_XFRM_POLICY", Const, 0}, + {"IPv6MTUInfo", Type, 2}, + {"IPv6MTUInfo.Addr", Field, 2}, + {"IPv6MTUInfo.Mtu", Field, 2}, + {"IPv6Mreq", Type, 0}, + {"IPv6Mreq.Interface", Field, 0}, + {"IPv6Mreq.Multiaddr", Field, 0}, + {"ISIG", Const, 0}, + {"ISTRIP", Const, 0}, + {"IUCLC", Const, 0}, + {"IUTF8", Const, 0}, + {"IXANY", Const, 0}, + {"IXOFF", Const, 0}, + {"IXON", Const, 0}, + {"IfAddrmsg", Type, 0}, + {"IfAddrmsg.Family", Field, 0}, + {"IfAddrmsg.Flags", Field, 0}, + {"IfAddrmsg.Index", Field, 0}, + {"IfAddrmsg.Prefixlen", Field, 0}, + {"IfAddrmsg.Scope", Field, 0}, + {"IfAnnounceMsghdr", Type, 1}, + {"IfAnnounceMsghdr.Hdrlen", Field, 2}, + {"IfAnnounceMsghdr.Index", Field, 1}, + {"IfAnnounceMsghdr.Msglen", Field, 1}, + {"IfAnnounceMsghdr.Name", Field, 1}, + {"IfAnnounceMsghdr.Type", Field, 1}, + {"IfAnnounceMsghdr.Version", Field, 1}, + {"IfAnnounceMsghdr.What", Field, 1}, + {"IfData", Type, 0}, + {"IfData.Addrlen", Field, 0}, + {"IfData.Baudrate", Field, 0}, + {"IfData.Capabilities", Field, 2}, + {"IfData.Collisions", Field, 0}, + {"IfData.Datalen", Field, 0}, + {"IfData.Epoch", Field, 0}, + {"IfData.Hdrlen", Field, 0}, + {"IfData.Hwassist", Field, 0}, + {"IfData.Ibytes", Field, 0}, + {"IfData.Ierrors", Field, 0}, + {"IfData.Imcasts", Field, 0}, + {"IfData.Ipackets", Field, 0}, + {"IfData.Iqdrops", Field, 0}, + {"IfData.Lastchange", Field, 0}, + {"IfData.Link_state", Field, 0}, + {"IfData.Mclpool", Field, 2}, + {"IfData.Metric", Field, 0}, + {"IfData.Mtu", Field, 0}, + {"IfData.Noproto", Field, 0}, + {"IfData.Obytes", Field, 0}, + {"IfData.Oerrors", Field, 0}, + {"IfData.Omcasts", Field, 0}, + {"IfData.Opackets", Field, 0}, + {"IfData.Pad", Field, 2}, + {"IfData.Pad_cgo_0", Field, 2}, + {"IfData.Pad_cgo_1", Field, 2}, + {"IfData.Physical", Field, 0}, + {"IfData.Recvquota", Field, 0}, + {"IfData.Recvtiming", Field, 0}, + {"IfData.Reserved1", Field, 0}, + {"IfData.Reserved2", Field, 0}, + {"IfData.Spare_char1", Field, 0}, + {"IfData.Spare_char2", Field, 0}, + {"IfData.Type", Field, 0}, + {"IfData.Typelen", Field, 0}, + {"IfData.Unused1", Field, 0}, + {"IfData.Unused2", Field, 0}, + {"IfData.Xmitquota", Field, 0}, + {"IfData.Xmittiming", Field, 0}, + {"IfInfomsg", Type, 0}, + {"IfInfomsg.Change", Field, 0}, + {"IfInfomsg.Family", Field, 0}, + {"IfInfomsg.Flags", Field, 0}, + {"IfInfomsg.Index", Field, 0}, + {"IfInfomsg.Type", Field, 0}, + {"IfInfomsg.X__ifi_pad", Field, 0}, + {"IfMsghdr", Type, 0}, + {"IfMsghdr.Addrs", Field, 0}, + {"IfMsghdr.Data", Field, 0}, + {"IfMsghdr.Flags", Field, 0}, + {"IfMsghdr.Hdrlen", Field, 2}, + {"IfMsghdr.Index", Field, 0}, + {"IfMsghdr.Msglen", Field, 0}, + {"IfMsghdr.Pad1", Field, 2}, + {"IfMsghdr.Pad2", Field, 2}, + {"IfMsghdr.Pad_cgo_0", Field, 0}, + {"IfMsghdr.Pad_cgo_1", Field, 2}, + {"IfMsghdr.Tableid", Field, 2}, + {"IfMsghdr.Type", Field, 0}, + {"IfMsghdr.Version", Field, 0}, + {"IfMsghdr.Xflags", Field, 2}, + {"IfaMsghdr", Type, 0}, + {"IfaMsghdr.Addrs", Field, 0}, + {"IfaMsghdr.Flags", Field, 0}, + {"IfaMsghdr.Hdrlen", Field, 2}, + {"IfaMsghdr.Index", Field, 0}, + {"IfaMsghdr.Metric", Field, 0}, + {"IfaMsghdr.Msglen", Field, 0}, + {"IfaMsghdr.Pad1", Field, 2}, + {"IfaMsghdr.Pad2", Field, 2}, + {"IfaMsghdr.Pad_cgo_0", Field, 0}, + {"IfaMsghdr.Tableid", Field, 2}, + {"IfaMsghdr.Type", Field, 0}, + {"IfaMsghdr.Version", Field, 0}, + {"IfmaMsghdr", Type, 0}, + {"IfmaMsghdr.Addrs", Field, 0}, + {"IfmaMsghdr.Flags", Field, 0}, + {"IfmaMsghdr.Index", Field, 0}, + {"IfmaMsghdr.Msglen", Field, 0}, + {"IfmaMsghdr.Pad_cgo_0", Field, 0}, + {"IfmaMsghdr.Type", Field, 0}, + {"IfmaMsghdr.Version", Field, 0}, + {"IfmaMsghdr2", Type, 0}, + {"IfmaMsghdr2.Addrs", Field, 0}, + {"IfmaMsghdr2.Flags", Field, 0}, + {"IfmaMsghdr2.Index", Field, 0}, + {"IfmaMsghdr2.Msglen", Field, 0}, + {"IfmaMsghdr2.Pad_cgo_0", Field, 0}, + {"IfmaMsghdr2.Refcount", Field, 0}, + {"IfmaMsghdr2.Type", Field, 0}, + {"IfmaMsghdr2.Version", Field, 0}, + {"ImplementsGetwd", Const, 0}, + {"Inet4Pktinfo", Type, 0}, + {"Inet4Pktinfo.Addr", Field, 0}, + {"Inet4Pktinfo.Ifindex", Field, 0}, + {"Inet4Pktinfo.Spec_dst", Field, 0}, + {"Inet6Pktinfo", Type, 0}, + {"Inet6Pktinfo.Addr", Field, 0}, + {"Inet6Pktinfo.Ifindex", Field, 0}, + {"InotifyAddWatch", Func, 0}, + {"InotifyEvent", Type, 0}, + {"InotifyEvent.Cookie", Field, 0}, + {"InotifyEvent.Len", Field, 0}, + {"InotifyEvent.Mask", Field, 0}, + {"InotifyEvent.Name", Field, 0}, + {"InotifyEvent.Wd", Field, 0}, + {"InotifyInit", Func, 0}, + {"InotifyInit1", Func, 0}, + {"InotifyRmWatch", Func, 0}, + {"InterfaceAddrMessage", Type, 0}, + {"InterfaceAddrMessage.Data", Field, 0}, + {"InterfaceAddrMessage.Header", Field, 0}, + {"InterfaceAnnounceMessage", Type, 1}, + {"InterfaceAnnounceMessage.Header", Field, 1}, + {"InterfaceInfo", Type, 0}, + {"InterfaceInfo.Address", Field, 0}, + {"InterfaceInfo.BroadcastAddress", Field, 0}, + {"InterfaceInfo.Flags", Field, 0}, + {"InterfaceInfo.Netmask", Field, 0}, + {"InterfaceMessage", Type, 0}, + {"InterfaceMessage.Data", Field, 0}, + {"InterfaceMessage.Header", Field, 0}, + {"InterfaceMulticastAddrMessage", Type, 0}, + {"InterfaceMulticastAddrMessage.Data", Field, 0}, + {"InterfaceMulticastAddrMessage.Header", Field, 0}, + {"InvalidHandle", Const, 0}, + {"Ioperm", Func, 0}, + {"Iopl", Func, 0}, + {"Iovec", Type, 0}, + {"Iovec.Base", Field, 0}, + {"Iovec.Len", Field, 0}, + {"IpAdapterInfo", Type, 0}, + {"IpAdapterInfo.AdapterName", Field, 0}, + {"IpAdapterInfo.Address", Field, 0}, + {"IpAdapterInfo.AddressLength", Field, 0}, + {"IpAdapterInfo.ComboIndex", Field, 0}, + {"IpAdapterInfo.CurrentIpAddress", Field, 0}, + {"IpAdapterInfo.Description", Field, 0}, + {"IpAdapterInfo.DhcpEnabled", Field, 0}, + {"IpAdapterInfo.DhcpServer", Field, 0}, + {"IpAdapterInfo.GatewayList", Field, 0}, + {"IpAdapterInfo.HaveWins", Field, 0}, + {"IpAdapterInfo.Index", Field, 0}, + {"IpAdapterInfo.IpAddressList", Field, 0}, + {"IpAdapterInfo.LeaseExpires", Field, 0}, + {"IpAdapterInfo.LeaseObtained", Field, 0}, + {"IpAdapterInfo.Next", Field, 0}, + {"IpAdapterInfo.PrimaryWinsServer", Field, 0}, + {"IpAdapterInfo.SecondaryWinsServer", Field, 0}, + {"IpAdapterInfo.Type", Field, 0}, + {"IpAddrString", Type, 0}, + {"IpAddrString.Context", Field, 0}, + {"IpAddrString.IpAddress", Field, 0}, + {"IpAddrString.IpMask", Field, 0}, + {"IpAddrString.Next", Field, 0}, + {"IpAddressString", Type, 0}, + {"IpAddressString.String", Field, 0}, + {"IpMaskString", Type, 0}, + {"IpMaskString.String", Field, 2}, + {"Issetugid", Func, 0}, + {"KEY_ALL_ACCESS", Const, 0}, + {"KEY_CREATE_LINK", Const, 0}, + {"KEY_CREATE_SUB_KEY", Const, 0}, + {"KEY_ENUMERATE_SUB_KEYS", Const, 0}, + {"KEY_EXECUTE", Const, 0}, + {"KEY_NOTIFY", Const, 0}, + {"KEY_QUERY_VALUE", Const, 0}, + {"KEY_READ", Const, 0}, + {"KEY_SET_VALUE", Const, 0}, + {"KEY_WOW64_32KEY", Const, 0}, + {"KEY_WOW64_64KEY", Const, 0}, + {"KEY_WRITE", Const, 0}, + {"Kevent", Func, 0}, + {"Kevent_t", Type, 0}, + {"Kevent_t.Data", Field, 0}, + {"Kevent_t.Fflags", Field, 0}, + {"Kevent_t.Filter", Field, 0}, + {"Kevent_t.Flags", Field, 0}, + {"Kevent_t.Ident", Field, 0}, + {"Kevent_t.Pad_cgo_0", Field, 2}, + {"Kevent_t.Udata", Field, 0}, + {"Kill", Func, 0}, + {"Klogctl", Func, 0}, + {"Kqueue", Func, 0}, + {"LANG_ENGLISH", Const, 0}, + {"LAYERED_PROTOCOL", Const, 2}, + {"LCNT_OVERLOAD_FLUSH", Const, 1}, + {"LINUX_REBOOT_CMD_CAD_OFF", Const, 0}, + {"LINUX_REBOOT_CMD_CAD_ON", Const, 0}, + {"LINUX_REBOOT_CMD_HALT", Const, 0}, + {"LINUX_REBOOT_CMD_KEXEC", Const, 0}, + {"LINUX_REBOOT_CMD_POWER_OFF", Const, 0}, + {"LINUX_REBOOT_CMD_RESTART", Const, 0}, + {"LINUX_REBOOT_CMD_RESTART2", Const, 0}, + {"LINUX_REBOOT_CMD_SW_SUSPEND", Const, 0}, + {"LINUX_REBOOT_MAGIC1", Const, 0}, + {"LINUX_REBOOT_MAGIC2", Const, 0}, + {"LOCK_EX", Const, 0}, + {"LOCK_NB", Const, 0}, + {"LOCK_SH", Const, 0}, + {"LOCK_UN", Const, 0}, + {"LazyDLL", Type, 0}, + {"LazyDLL.Name", Field, 0}, + {"LazyProc", Type, 0}, + {"LazyProc.Name", Field, 0}, + {"Lchown", Func, 0}, + {"Linger", Type, 0}, + {"Linger.Linger", Field, 0}, + {"Linger.Onoff", Field, 0}, + {"Link", Func, 0}, + {"Listen", Func, 0}, + {"Listxattr", Func, 1}, + {"LoadCancelIoEx", Func, 1}, + {"LoadConnectEx", Func, 1}, + {"LoadCreateSymbolicLink", Func, 4}, + {"LoadDLL", Func, 0}, + {"LoadGetAddrInfo", Func, 1}, + {"LoadLibrary", Func, 0}, + {"LoadSetFileCompletionNotificationModes", Func, 2}, + {"LocalFree", Func, 0}, + {"Log2phys_t", Type, 0}, + {"Log2phys_t.Contigbytes", Field, 0}, + {"Log2phys_t.Devoffset", Field, 0}, + {"Log2phys_t.Flags", Field, 0}, + {"LookupAccountName", Func, 0}, + {"LookupAccountSid", Func, 0}, + {"LookupSID", Func, 0}, + {"LsfJump", Func, 0}, + {"LsfSocket", Func, 0}, + {"LsfStmt", Func, 0}, + {"Lstat", Func, 0}, + {"MADV_AUTOSYNC", Const, 1}, + {"MADV_CAN_REUSE", Const, 0}, + {"MADV_CORE", Const, 1}, + {"MADV_DOFORK", Const, 0}, + {"MADV_DONTFORK", Const, 0}, + {"MADV_DONTNEED", Const, 0}, + {"MADV_FREE", Const, 0}, + {"MADV_FREE_REUSABLE", Const, 0}, + {"MADV_FREE_REUSE", Const, 0}, + {"MADV_HUGEPAGE", Const, 0}, + {"MADV_HWPOISON", Const, 0}, + {"MADV_MERGEABLE", Const, 0}, + {"MADV_NOCORE", Const, 1}, + {"MADV_NOHUGEPAGE", Const, 0}, + {"MADV_NORMAL", Const, 0}, + {"MADV_NOSYNC", Const, 1}, + {"MADV_PROTECT", Const, 1}, + {"MADV_RANDOM", Const, 0}, + {"MADV_REMOVE", Const, 0}, + {"MADV_SEQUENTIAL", Const, 0}, + {"MADV_SPACEAVAIL", Const, 3}, + {"MADV_UNMERGEABLE", Const, 0}, + {"MADV_WILLNEED", Const, 0}, + {"MADV_ZERO_WIRED_PAGES", Const, 0}, + {"MAP_32BIT", Const, 0}, + {"MAP_ALIGNED_SUPER", Const, 3}, + {"MAP_ALIGNMENT_16MB", Const, 3}, + {"MAP_ALIGNMENT_1TB", Const, 3}, + {"MAP_ALIGNMENT_256TB", Const, 3}, + {"MAP_ALIGNMENT_4GB", Const, 3}, + {"MAP_ALIGNMENT_64KB", Const, 3}, + {"MAP_ALIGNMENT_64PB", Const, 3}, + {"MAP_ALIGNMENT_MASK", Const, 3}, + {"MAP_ALIGNMENT_SHIFT", Const, 3}, + {"MAP_ANON", Const, 0}, + {"MAP_ANONYMOUS", Const, 0}, + {"MAP_COPY", Const, 0}, + {"MAP_DENYWRITE", Const, 0}, + {"MAP_EXECUTABLE", Const, 0}, + {"MAP_FILE", Const, 0}, + {"MAP_FIXED", Const, 0}, + {"MAP_FLAGMASK", Const, 3}, + {"MAP_GROWSDOWN", Const, 0}, + {"MAP_HASSEMAPHORE", Const, 0}, + {"MAP_HUGETLB", Const, 0}, + {"MAP_INHERIT", Const, 3}, + {"MAP_INHERIT_COPY", Const, 3}, + {"MAP_INHERIT_DEFAULT", Const, 3}, + {"MAP_INHERIT_DONATE_COPY", Const, 3}, + {"MAP_INHERIT_NONE", Const, 3}, + {"MAP_INHERIT_SHARE", Const, 3}, + {"MAP_JIT", Const, 0}, + {"MAP_LOCKED", Const, 0}, + {"MAP_NOCACHE", Const, 0}, + {"MAP_NOCORE", Const, 1}, + {"MAP_NOEXTEND", Const, 0}, + {"MAP_NONBLOCK", Const, 0}, + {"MAP_NORESERVE", Const, 0}, + {"MAP_NOSYNC", Const, 1}, + {"MAP_POPULATE", Const, 0}, + {"MAP_PREFAULT_READ", Const, 1}, + {"MAP_PRIVATE", Const, 0}, + {"MAP_RENAME", Const, 0}, + {"MAP_RESERVED0080", Const, 0}, + {"MAP_RESERVED0100", Const, 1}, + {"MAP_SHARED", Const, 0}, + {"MAP_STACK", Const, 0}, + {"MAP_TRYFIXED", Const, 3}, + {"MAP_TYPE", Const, 0}, + {"MAP_WIRED", Const, 3}, + {"MAXIMUM_REPARSE_DATA_BUFFER_SIZE", Const, 4}, + {"MAXLEN_IFDESCR", Const, 0}, + {"MAXLEN_PHYSADDR", Const, 0}, + {"MAX_ADAPTER_ADDRESS_LENGTH", Const, 0}, + {"MAX_ADAPTER_DESCRIPTION_LENGTH", Const, 0}, + {"MAX_ADAPTER_NAME_LENGTH", Const, 0}, + {"MAX_COMPUTERNAME_LENGTH", Const, 0}, + {"MAX_INTERFACE_NAME_LEN", Const, 0}, + {"MAX_LONG_PATH", Const, 0}, + {"MAX_PATH", Const, 0}, + {"MAX_PROTOCOL_CHAIN", Const, 2}, + {"MCL_CURRENT", Const, 0}, + {"MCL_FUTURE", Const, 0}, + {"MNT_DETACH", Const, 0}, + {"MNT_EXPIRE", Const, 0}, + {"MNT_FORCE", Const, 0}, + {"MSG_BCAST", Const, 1}, + {"MSG_CMSG_CLOEXEC", Const, 0}, + {"MSG_COMPAT", Const, 0}, + {"MSG_CONFIRM", Const, 0}, + {"MSG_CONTROLMBUF", Const, 1}, + {"MSG_CTRUNC", Const, 0}, + {"MSG_DONTROUTE", Const, 0}, + {"MSG_DONTWAIT", Const, 0}, + {"MSG_EOF", Const, 0}, + {"MSG_EOR", Const, 0}, + {"MSG_ERRQUEUE", Const, 0}, + {"MSG_FASTOPEN", Const, 1}, + {"MSG_FIN", Const, 0}, + {"MSG_FLUSH", Const, 0}, + {"MSG_HAVEMORE", Const, 0}, + {"MSG_HOLD", Const, 0}, + {"MSG_IOVUSRSPACE", Const, 1}, + {"MSG_LENUSRSPACE", Const, 1}, + {"MSG_MCAST", Const, 1}, + {"MSG_MORE", Const, 0}, + {"MSG_NAMEMBUF", Const, 1}, + {"MSG_NBIO", Const, 0}, + {"MSG_NEEDSA", Const, 0}, + {"MSG_NOSIGNAL", Const, 0}, + {"MSG_NOTIFICATION", Const, 0}, + {"MSG_OOB", Const, 0}, + {"MSG_PEEK", Const, 0}, + {"MSG_PROXY", Const, 0}, + {"MSG_RCVMORE", Const, 0}, + {"MSG_RST", Const, 0}, + {"MSG_SEND", Const, 0}, + {"MSG_SYN", Const, 0}, + {"MSG_TRUNC", Const, 0}, + {"MSG_TRYHARD", Const, 0}, + {"MSG_USERFLAGS", Const, 1}, + {"MSG_WAITALL", Const, 0}, + {"MSG_WAITFORONE", Const, 0}, + {"MSG_WAITSTREAM", Const, 0}, + {"MS_ACTIVE", Const, 0}, + {"MS_ASYNC", Const, 0}, + {"MS_BIND", Const, 0}, + {"MS_DEACTIVATE", Const, 0}, + {"MS_DIRSYNC", Const, 0}, + {"MS_INVALIDATE", Const, 0}, + {"MS_I_VERSION", Const, 0}, + {"MS_KERNMOUNT", Const, 0}, + {"MS_KILLPAGES", Const, 0}, + {"MS_MANDLOCK", Const, 0}, + {"MS_MGC_MSK", Const, 0}, + {"MS_MGC_VAL", Const, 0}, + {"MS_MOVE", Const, 0}, + {"MS_NOATIME", Const, 0}, + {"MS_NODEV", Const, 0}, + {"MS_NODIRATIME", Const, 0}, + {"MS_NOEXEC", Const, 0}, + {"MS_NOSUID", Const, 0}, + {"MS_NOUSER", Const, 0}, + {"MS_POSIXACL", Const, 0}, + {"MS_PRIVATE", Const, 0}, + {"MS_RDONLY", Const, 0}, + {"MS_REC", Const, 0}, + {"MS_RELATIME", Const, 0}, + {"MS_REMOUNT", Const, 0}, + {"MS_RMT_MASK", Const, 0}, + {"MS_SHARED", Const, 0}, + {"MS_SILENT", Const, 0}, + {"MS_SLAVE", Const, 0}, + {"MS_STRICTATIME", Const, 0}, + {"MS_SYNC", Const, 0}, + {"MS_SYNCHRONOUS", Const, 0}, + {"MS_UNBINDABLE", Const, 0}, + {"Madvise", Func, 0}, + {"MapViewOfFile", Func, 0}, + {"MaxTokenInfoClass", Const, 0}, + {"Mclpool", Type, 2}, + {"Mclpool.Alive", Field, 2}, + {"Mclpool.Cwm", Field, 2}, + {"Mclpool.Grown", Field, 2}, + {"Mclpool.Hwm", Field, 2}, + {"Mclpool.Lwm", Field, 2}, + {"MibIfRow", Type, 0}, + {"MibIfRow.AdminStatus", Field, 0}, + {"MibIfRow.Descr", Field, 0}, + {"MibIfRow.DescrLen", Field, 0}, + {"MibIfRow.InDiscards", Field, 0}, + {"MibIfRow.InErrors", Field, 0}, + {"MibIfRow.InNUcastPkts", Field, 0}, + {"MibIfRow.InOctets", Field, 0}, + {"MibIfRow.InUcastPkts", Field, 0}, + {"MibIfRow.InUnknownProtos", Field, 0}, + {"MibIfRow.Index", Field, 0}, + {"MibIfRow.LastChange", Field, 0}, + {"MibIfRow.Mtu", Field, 0}, + {"MibIfRow.Name", Field, 0}, + {"MibIfRow.OperStatus", Field, 0}, + {"MibIfRow.OutDiscards", Field, 0}, + {"MibIfRow.OutErrors", Field, 0}, + {"MibIfRow.OutNUcastPkts", Field, 0}, + {"MibIfRow.OutOctets", Field, 0}, + {"MibIfRow.OutQLen", Field, 0}, + {"MibIfRow.OutUcastPkts", Field, 0}, + {"MibIfRow.PhysAddr", Field, 0}, + {"MibIfRow.PhysAddrLen", Field, 0}, + {"MibIfRow.Speed", Field, 0}, + {"MibIfRow.Type", Field, 0}, + {"Mkdir", Func, 0}, + {"Mkdirat", Func, 0}, + {"Mkfifo", Func, 0}, + {"Mknod", Func, 0}, + {"Mknodat", Func, 0}, + {"Mlock", Func, 0}, + {"Mlockall", Func, 0}, + {"Mmap", Func, 0}, + {"Mount", Func, 0}, + {"MoveFile", Func, 0}, + {"Mprotect", Func, 0}, + {"Msghdr", Type, 0}, + {"Msghdr.Control", Field, 0}, + {"Msghdr.Controllen", Field, 0}, + {"Msghdr.Flags", Field, 0}, + {"Msghdr.Iov", Field, 0}, + {"Msghdr.Iovlen", Field, 0}, + {"Msghdr.Name", Field, 0}, + {"Msghdr.Namelen", Field, 0}, + {"Msghdr.Pad_cgo_0", Field, 0}, + {"Msghdr.Pad_cgo_1", Field, 0}, + {"Munlock", Func, 0}, + {"Munlockall", Func, 0}, + {"Munmap", Func, 0}, + {"MustLoadDLL", Func, 0}, + {"NAME_MAX", Const, 0}, + {"NETLINK_ADD_MEMBERSHIP", Const, 0}, + {"NETLINK_AUDIT", Const, 0}, + {"NETLINK_BROADCAST_ERROR", Const, 0}, + {"NETLINK_CONNECTOR", Const, 0}, + {"NETLINK_DNRTMSG", Const, 0}, + {"NETLINK_DROP_MEMBERSHIP", Const, 0}, + {"NETLINK_ECRYPTFS", Const, 0}, + {"NETLINK_FIB_LOOKUP", Const, 0}, + {"NETLINK_FIREWALL", Const, 0}, + {"NETLINK_GENERIC", Const, 0}, + {"NETLINK_INET_DIAG", Const, 0}, + {"NETLINK_IP6_FW", Const, 0}, + {"NETLINK_ISCSI", Const, 0}, + {"NETLINK_KOBJECT_UEVENT", Const, 0}, + {"NETLINK_NETFILTER", Const, 0}, + {"NETLINK_NFLOG", Const, 0}, + {"NETLINK_NO_ENOBUFS", Const, 0}, + {"NETLINK_PKTINFO", Const, 0}, + {"NETLINK_RDMA", Const, 0}, + {"NETLINK_ROUTE", Const, 0}, + {"NETLINK_SCSITRANSPORT", Const, 0}, + {"NETLINK_SELINUX", Const, 0}, + {"NETLINK_UNUSED", Const, 0}, + {"NETLINK_USERSOCK", Const, 0}, + {"NETLINK_XFRM", Const, 0}, + {"NET_RT_DUMP", Const, 0}, + {"NET_RT_DUMP2", Const, 0}, + {"NET_RT_FLAGS", Const, 0}, + {"NET_RT_IFLIST", Const, 0}, + {"NET_RT_IFLIST2", Const, 0}, + {"NET_RT_IFLISTL", Const, 1}, + {"NET_RT_IFMALIST", Const, 0}, + {"NET_RT_MAXID", Const, 0}, + {"NET_RT_OIFLIST", Const, 1}, + {"NET_RT_OOIFLIST", Const, 1}, + {"NET_RT_STAT", Const, 0}, + {"NET_RT_STATS", Const, 1}, + {"NET_RT_TABLE", Const, 1}, + {"NET_RT_TRASH", Const, 0}, + {"NLA_ALIGNTO", Const, 0}, + {"NLA_F_NESTED", Const, 0}, + {"NLA_F_NET_BYTEORDER", Const, 0}, + {"NLA_HDRLEN", Const, 0}, + {"NLMSG_ALIGNTO", Const, 0}, + {"NLMSG_DONE", Const, 0}, + {"NLMSG_ERROR", Const, 0}, + {"NLMSG_HDRLEN", Const, 0}, + {"NLMSG_MIN_TYPE", Const, 0}, + {"NLMSG_NOOP", Const, 0}, + {"NLMSG_OVERRUN", Const, 0}, + {"NLM_F_ACK", Const, 0}, + {"NLM_F_APPEND", Const, 0}, + {"NLM_F_ATOMIC", Const, 0}, + {"NLM_F_CREATE", Const, 0}, + {"NLM_F_DUMP", Const, 0}, + {"NLM_F_ECHO", Const, 0}, + {"NLM_F_EXCL", Const, 0}, + {"NLM_F_MATCH", Const, 0}, + {"NLM_F_MULTI", Const, 0}, + {"NLM_F_REPLACE", Const, 0}, + {"NLM_F_REQUEST", Const, 0}, + {"NLM_F_ROOT", Const, 0}, + {"NOFLSH", Const, 0}, + {"NOTE_ABSOLUTE", Const, 0}, + {"NOTE_ATTRIB", Const, 0}, + {"NOTE_BACKGROUND", Const, 16}, + {"NOTE_CHILD", Const, 0}, + {"NOTE_CRITICAL", Const, 16}, + {"NOTE_DELETE", Const, 0}, + {"NOTE_EOF", Const, 1}, + {"NOTE_EXEC", Const, 0}, + {"NOTE_EXIT", Const, 0}, + {"NOTE_EXITSTATUS", Const, 0}, + {"NOTE_EXIT_CSERROR", Const, 16}, + {"NOTE_EXIT_DECRYPTFAIL", Const, 16}, + {"NOTE_EXIT_DETAIL", Const, 16}, + {"NOTE_EXIT_DETAIL_MASK", Const, 16}, + {"NOTE_EXIT_MEMORY", Const, 16}, + {"NOTE_EXIT_REPARENTED", Const, 16}, + {"NOTE_EXTEND", Const, 0}, + {"NOTE_FFAND", Const, 0}, + {"NOTE_FFCOPY", Const, 0}, + {"NOTE_FFCTRLMASK", Const, 0}, + {"NOTE_FFLAGSMASK", Const, 0}, + {"NOTE_FFNOP", Const, 0}, + {"NOTE_FFOR", Const, 0}, + {"NOTE_FORK", Const, 0}, + {"NOTE_LEEWAY", Const, 16}, + {"NOTE_LINK", Const, 0}, + {"NOTE_LOWAT", Const, 0}, + {"NOTE_NONE", Const, 0}, + {"NOTE_NSECONDS", Const, 0}, + {"NOTE_PCTRLMASK", Const, 0}, + {"NOTE_PDATAMASK", Const, 0}, + {"NOTE_REAP", Const, 0}, + {"NOTE_RENAME", Const, 0}, + {"NOTE_RESOURCEEND", Const, 0}, + {"NOTE_REVOKE", Const, 0}, + {"NOTE_SECONDS", Const, 0}, + {"NOTE_SIGNAL", Const, 0}, + {"NOTE_TRACK", Const, 0}, + {"NOTE_TRACKERR", Const, 0}, + {"NOTE_TRIGGER", Const, 0}, + {"NOTE_TRUNCATE", Const, 1}, + {"NOTE_USECONDS", Const, 0}, + {"NOTE_VM_ERROR", Const, 0}, + {"NOTE_VM_PRESSURE", Const, 0}, + {"NOTE_VM_PRESSURE_SUDDEN_TERMINATE", Const, 0}, + {"NOTE_VM_PRESSURE_TERMINATE", Const, 0}, + {"NOTE_WRITE", Const, 0}, + {"NameCanonical", Const, 0}, + {"NameCanonicalEx", Const, 0}, + {"NameDisplay", Const, 0}, + {"NameDnsDomain", Const, 0}, + {"NameFullyQualifiedDN", Const, 0}, + {"NameSamCompatible", Const, 0}, + {"NameServicePrincipal", Const, 0}, + {"NameUniqueId", Const, 0}, + {"NameUnknown", Const, 0}, + {"NameUserPrincipal", Const, 0}, + {"Nanosleep", Func, 0}, + {"NetApiBufferFree", Func, 0}, + {"NetGetJoinInformation", Func, 2}, + {"NetSetupDomainName", Const, 2}, + {"NetSetupUnjoined", Const, 2}, + {"NetSetupUnknownStatus", Const, 2}, + {"NetSetupWorkgroupName", Const, 2}, + {"NetUserGetInfo", Func, 0}, + {"NetlinkMessage", Type, 0}, + {"NetlinkMessage.Data", Field, 0}, + {"NetlinkMessage.Header", Field, 0}, + {"NetlinkRIB", Func, 0}, + {"NetlinkRouteAttr", Type, 0}, + {"NetlinkRouteAttr.Attr", Field, 0}, + {"NetlinkRouteAttr.Value", Field, 0}, + {"NetlinkRouteRequest", Type, 0}, + {"NetlinkRouteRequest.Data", Field, 0}, + {"NetlinkRouteRequest.Header", Field, 0}, + {"NewCallback", Func, 0}, + {"NewCallbackCDecl", Func, 3}, + {"NewLazyDLL", Func, 0}, + {"NlAttr", Type, 0}, + {"NlAttr.Len", Field, 0}, + {"NlAttr.Type", Field, 0}, + {"NlMsgerr", Type, 0}, + {"NlMsgerr.Error", Field, 0}, + {"NlMsgerr.Msg", Field, 0}, + {"NlMsghdr", Type, 0}, + {"NlMsghdr.Flags", Field, 0}, + {"NlMsghdr.Len", Field, 0}, + {"NlMsghdr.Pid", Field, 0}, + {"NlMsghdr.Seq", Field, 0}, + {"NlMsghdr.Type", Field, 0}, + {"NsecToFiletime", Func, 0}, + {"NsecToTimespec", Func, 0}, + {"NsecToTimeval", Func, 0}, + {"Ntohs", Func, 0}, + {"OCRNL", Const, 0}, + {"OFDEL", Const, 0}, + {"OFILL", Const, 0}, + {"OFIOGETBMAP", Const, 1}, + {"OID_PKIX_KP_SERVER_AUTH", Var, 0}, + {"OID_SERVER_GATED_CRYPTO", Var, 0}, + {"OID_SGC_NETSCAPE", Var, 0}, + {"OLCUC", Const, 0}, + {"ONLCR", Const, 0}, + {"ONLRET", Const, 0}, + {"ONOCR", Const, 0}, + {"ONOEOT", Const, 1}, + {"OPEN_ALWAYS", Const, 0}, + {"OPEN_EXISTING", Const, 0}, + {"OPOST", Const, 0}, + {"O_ACCMODE", Const, 0}, + {"O_ALERT", Const, 0}, + {"O_ALT_IO", Const, 1}, + {"O_APPEND", Const, 0}, + {"O_ASYNC", Const, 0}, + {"O_CLOEXEC", Const, 0}, + {"O_CREAT", Const, 0}, + {"O_DIRECT", Const, 0}, + {"O_DIRECTORY", Const, 0}, + {"O_DP_GETRAWENCRYPTED", Const, 16}, + {"O_DSYNC", Const, 0}, + {"O_EVTONLY", Const, 0}, + {"O_EXCL", Const, 0}, + {"O_EXEC", Const, 0}, + {"O_EXLOCK", Const, 0}, + {"O_FSYNC", Const, 0}, + {"O_LARGEFILE", Const, 0}, + {"O_NDELAY", Const, 0}, + {"O_NOATIME", Const, 0}, + {"O_NOCTTY", Const, 0}, + {"O_NOFOLLOW", Const, 0}, + {"O_NONBLOCK", Const, 0}, + {"O_NOSIGPIPE", Const, 1}, + {"O_POPUP", Const, 0}, + {"O_RDONLY", Const, 0}, + {"O_RDWR", Const, 0}, + {"O_RSYNC", Const, 0}, + {"O_SHLOCK", Const, 0}, + {"O_SYMLINK", Const, 0}, + {"O_SYNC", Const, 0}, + {"O_TRUNC", Const, 0}, + {"O_TTY_INIT", Const, 0}, + {"O_WRONLY", Const, 0}, + {"Open", Func, 0}, + {"OpenCurrentProcessToken", Func, 0}, + {"OpenProcess", Func, 0}, + {"OpenProcessToken", Func, 0}, + {"Openat", Func, 0}, + {"Overlapped", Type, 0}, + {"Overlapped.HEvent", Field, 0}, + {"Overlapped.Internal", Field, 0}, + {"Overlapped.InternalHigh", Field, 0}, + {"Overlapped.Offset", Field, 0}, + {"Overlapped.OffsetHigh", Field, 0}, + {"PACKET_ADD_MEMBERSHIP", Const, 0}, + {"PACKET_BROADCAST", Const, 0}, + {"PACKET_DROP_MEMBERSHIP", Const, 0}, + {"PACKET_FASTROUTE", Const, 0}, + {"PACKET_HOST", Const, 0}, + {"PACKET_LOOPBACK", Const, 0}, + {"PACKET_MR_ALLMULTI", Const, 0}, + {"PACKET_MR_MULTICAST", Const, 0}, + {"PACKET_MR_PROMISC", Const, 0}, + {"PACKET_MULTICAST", Const, 0}, + {"PACKET_OTHERHOST", Const, 0}, + {"PACKET_OUTGOING", Const, 0}, + {"PACKET_RECV_OUTPUT", Const, 0}, + {"PACKET_RX_RING", Const, 0}, + {"PACKET_STATISTICS", Const, 0}, + {"PAGE_EXECUTE_READ", Const, 0}, + {"PAGE_EXECUTE_READWRITE", Const, 0}, + {"PAGE_EXECUTE_WRITECOPY", Const, 0}, + {"PAGE_READONLY", Const, 0}, + {"PAGE_READWRITE", Const, 0}, + {"PAGE_WRITECOPY", Const, 0}, + {"PARENB", Const, 0}, + {"PARMRK", Const, 0}, + {"PARODD", Const, 0}, + {"PENDIN", Const, 0}, + {"PFL_HIDDEN", Const, 2}, + {"PFL_MATCHES_PROTOCOL_ZERO", Const, 2}, + {"PFL_MULTIPLE_PROTO_ENTRIES", Const, 2}, + {"PFL_NETWORKDIRECT_PROVIDER", Const, 2}, + {"PFL_RECOMMENDED_PROTO_ENTRY", Const, 2}, + {"PF_FLUSH", Const, 1}, + {"PKCS_7_ASN_ENCODING", Const, 0}, + {"PMC5_PIPELINE_FLUSH", Const, 1}, + {"PRIO_PGRP", Const, 2}, + {"PRIO_PROCESS", Const, 2}, + {"PRIO_USER", Const, 2}, + {"PRI_IOFLUSH", Const, 1}, + {"PROCESS_QUERY_INFORMATION", Const, 0}, + {"PROCESS_TERMINATE", Const, 2}, + {"PROT_EXEC", Const, 0}, + {"PROT_GROWSDOWN", Const, 0}, + {"PROT_GROWSUP", Const, 0}, + {"PROT_NONE", Const, 0}, + {"PROT_READ", Const, 0}, + {"PROT_WRITE", Const, 0}, + {"PROV_DH_SCHANNEL", Const, 0}, + {"PROV_DSS", Const, 0}, + {"PROV_DSS_DH", Const, 0}, + {"PROV_EC_ECDSA_FULL", Const, 0}, + {"PROV_EC_ECDSA_SIG", Const, 0}, + {"PROV_EC_ECNRA_FULL", Const, 0}, + {"PROV_EC_ECNRA_SIG", Const, 0}, + {"PROV_FORTEZZA", Const, 0}, + {"PROV_INTEL_SEC", Const, 0}, + {"PROV_MS_EXCHANGE", Const, 0}, + {"PROV_REPLACE_OWF", Const, 0}, + {"PROV_RNG", Const, 0}, + {"PROV_RSA_AES", Const, 0}, + {"PROV_RSA_FULL", Const, 0}, + {"PROV_RSA_SCHANNEL", Const, 0}, + {"PROV_RSA_SIG", Const, 0}, + {"PROV_SPYRUS_LYNKS", Const, 0}, + {"PROV_SSL", Const, 0}, + {"PR_CAPBSET_DROP", Const, 0}, + {"PR_CAPBSET_READ", Const, 0}, + {"PR_CLEAR_SECCOMP_FILTER", Const, 0}, + {"PR_ENDIAN_BIG", Const, 0}, + {"PR_ENDIAN_LITTLE", Const, 0}, + {"PR_ENDIAN_PPC_LITTLE", Const, 0}, + {"PR_FPEMU_NOPRINT", Const, 0}, + {"PR_FPEMU_SIGFPE", Const, 0}, + {"PR_FP_EXC_ASYNC", Const, 0}, + {"PR_FP_EXC_DISABLED", Const, 0}, + {"PR_FP_EXC_DIV", Const, 0}, + {"PR_FP_EXC_INV", Const, 0}, + {"PR_FP_EXC_NONRECOV", Const, 0}, + {"PR_FP_EXC_OVF", Const, 0}, + {"PR_FP_EXC_PRECISE", Const, 0}, + {"PR_FP_EXC_RES", Const, 0}, + {"PR_FP_EXC_SW_ENABLE", Const, 0}, + {"PR_FP_EXC_UND", Const, 0}, + {"PR_GET_DUMPABLE", Const, 0}, + {"PR_GET_ENDIAN", Const, 0}, + {"PR_GET_FPEMU", Const, 0}, + {"PR_GET_FPEXC", Const, 0}, + {"PR_GET_KEEPCAPS", Const, 0}, + {"PR_GET_NAME", Const, 0}, + {"PR_GET_PDEATHSIG", Const, 0}, + {"PR_GET_SECCOMP", Const, 0}, + {"PR_GET_SECCOMP_FILTER", Const, 0}, + {"PR_GET_SECUREBITS", Const, 0}, + {"PR_GET_TIMERSLACK", Const, 0}, + {"PR_GET_TIMING", Const, 0}, + {"PR_GET_TSC", Const, 0}, + {"PR_GET_UNALIGN", Const, 0}, + {"PR_MCE_KILL", Const, 0}, + {"PR_MCE_KILL_CLEAR", Const, 0}, + {"PR_MCE_KILL_DEFAULT", Const, 0}, + {"PR_MCE_KILL_EARLY", Const, 0}, + {"PR_MCE_KILL_GET", Const, 0}, + {"PR_MCE_KILL_LATE", Const, 0}, + {"PR_MCE_KILL_SET", Const, 0}, + {"PR_SECCOMP_FILTER_EVENT", Const, 0}, + {"PR_SECCOMP_FILTER_SYSCALL", Const, 0}, + {"PR_SET_DUMPABLE", Const, 0}, + {"PR_SET_ENDIAN", Const, 0}, + {"PR_SET_FPEMU", Const, 0}, + {"PR_SET_FPEXC", Const, 0}, + {"PR_SET_KEEPCAPS", Const, 0}, + {"PR_SET_NAME", Const, 0}, + {"PR_SET_PDEATHSIG", Const, 0}, + {"PR_SET_PTRACER", Const, 0}, + {"PR_SET_SECCOMP", Const, 0}, + {"PR_SET_SECCOMP_FILTER", Const, 0}, + {"PR_SET_SECUREBITS", Const, 0}, + {"PR_SET_TIMERSLACK", Const, 0}, + {"PR_SET_TIMING", Const, 0}, + {"PR_SET_TSC", Const, 0}, + {"PR_SET_UNALIGN", Const, 0}, + {"PR_TASK_PERF_EVENTS_DISABLE", Const, 0}, + {"PR_TASK_PERF_EVENTS_ENABLE", Const, 0}, + {"PR_TIMING_STATISTICAL", Const, 0}, + {"PR_TIMING_TIMESTAMP", Const, 0}, + {"PR_TSC_ENABLE", Const, 0}, + {"PR_TSC_SIGSEGV", Const, 0}, + {"PR_UNALIGN_NOPRINT", Const, 0}, + {"PR_UNALIGN_SIGBUS", Const, 0}, + {"PTRACE_ARCH_PRCTL", Const, 0}, + {"PTRACE_ATTACH", Const, 0}, + {"PTRACE_CONT", Const, 0}, + {"PTRACE_DETACH", Const, 0}, + {"PTRACE_EVENT_CLONE", Const, 0}, + {"PTRACE_EVENT_EXEC", Const, 0}, + {"PTRACE_EVENT_EXIT", Const, 0}, + {"PTRACE_EVENT_FORK", Const, 0}, + {"PTRACE_EVENT_VFORK", Const, 0}, + {"PTRACE_EVENT_VFORK_DONE", Const, 0}, + {"PTRACE_GETCRUNCHREGS", Const, 0}, + {"PTRACE_GETEVENTMSG", Const, 0}, + {"PTRACE_GETFPREGS", Const, 0}, + {"PTRACE_GETFPXREGS", Const, 0}, + {"PTRACE_GETHBPREGS", Const, 0}, + {"PTRACE_GETREGS", Const, 0}, + {"PTRACE_GETREGSET", Const, 0}, + {"PTRACE_GETSIGINFO", Const, 0}, + {"PTRACE_GETVFPREGS", Const, 0}, + {"PTRACE_GETWMMXREGS", Const, 0}, + {"PTRACE_GET_THREAD_AREA", Const, 0}, + {"PTRACE_KILL", Const, 0}, + {"PTRACE_OLDSETOPTIONS", Const, 0}, + {"PTRACE_O_MASK", Const, 0}, + {"PTRACE_O_TRACECLONE", Const, 0}, + {"PTRACE_O_TRACEEXEC", Const, 0}, + {"PTRACE_O_TRACEEXIT", Const, 0}, + {"PTRACE_O_TRACEFORK", Const, 0}, + {"PTRACE_O_TRACESYSGOOD", Const, 0}, + {"PTRACE_O_TRACEVFORK", Const, 0}, + {"PTRACE_O_TRACEVFORKDONE", Const, 0}, + {"PTRACE_PEEKDATA", Const, 0}, + {"PTRACE_PEEKTEXT", Const, 0}, + {"PTRACE_PEEKUSR", Const, 0}, + {"PTRACE_POKEDATA", Const, 0}, + {"PTRACE_POKETEXT", Const, 0}, + {"PTRACE_POKEUSR", Const, 0}, + {"PTRACE_SETCRUNCHREGS", Const, 0}, + {"PTRACE_SETFPREGS", Const, 0}, + {"PTRACE_SETFPXREGS", Const, 0}, + {"PTRACE_SETHBPREGS", Const, 0}, + {"PTRACE_SETOPTIONS", Const, 0}, + {"PTRACE_SETREGS", Const, 0}, + {"PTRACE_SETREGSET", Const, 0}, + {"PTRACE_SETSIGINFO", Const, 0}, + {"PTRACE_SETVFPREGS", Const, 0}, + {"PTRACE_SETWMMXREGS", Const, 0}, + {"PTRACE_SET_SYSCALL", Const, 0}, + {"PTRACE_SET_THREAD_AREA", Const, 0}, + {"PTRACE_SINGLEBLOCK", Const, 0}, + {"PTRACE_SINGLESTEP", Const, 0}, + {"PTRACE_SYSCALL", Const, 0}, + {"PTRACE_SYSEMU", Const, 0}, + {"PTRACE_SYSEMU_SINGLESTEP", Const, 0}, + {"PTRACE_TRACEME", Const, 0}, + {"PT_ATTACH", Const, 0}, + {"PT_ATTACHEXC", Const, 0}, + {"PT_CONTINUE", Const, 0}, + {"PT_DATA_ADDR", Const, 0}, + {"PT_DENY_ATTACH", Const, 0}, + {"PT_DETACH", Const, 0}, + {"PT_FIRSTMACH", Const, 0}, + {"PT_FORCEQUOTA", Const, 0}, + {"PT_KILL", Const, 0}, + {"PT_MASK", Const, 1}, + {"PT_READ_D", Const, 0}, + {"PT_READ_I", Const, 0}, + {"PT_READ_U", Const, 0}, + {"PT_SIGEXC", Const, 0}, + {"PT_STEP", Const, 0}, + {"PT_TEXT_ADDR", Const, 0}, + {"PT_TEXT_END_ADDR", Const, 0}, + {"PT_THUPDATE", Const, 0}, + {"PT_TRACE_ME", Const, 0}, + {"PT_WRITE_D", Const, 0}, + {"PT_WRITE_I", Const, 0}, + {"PT_WRITE_U", Const, 0}, + {"ParseDirent", Func, 0}, + {"ParseNetlinkMessage", Func, 0}, + {"ParseNetlinkRouteAttr", Func, 0}, + {"ParseRoutingMessage", Func, 0}, + {"ParseRoutingSockaddr", Func, 0}, + {"ParseSocketControlMessage", Func, 0}, + {"ParseUnixCredentials", Func, 0}, + {"ParseUnixRights", Func, 0}, + {"PathMax", Const, 0}, + {"Pathconf", Func, 0}, + {"Pause", Func, 0}, + {"Pipe", Func, 0}, + {"Pipe2", Func, 1}, + {"PivotRoot", Func, 0}, + {"Pointer", Type, 11}, + {"PostQueuedCompletionStatus", Func, 0}, + {"Pread", Func, 0}, + {"Proc", Type, 0}, + {"Proc.Dll", Field, 0}, + {"Proc.Name", Field, 0}, + {"ProcAttr", Type, 0}, + {"ProcAttr.Dir", Field, 0}, + {"ProcAttr.Env", Field, 0}, + {"ProcAttr.Files", Field, 0}, + {"ProcAttr.Sys", Field, 0}, + {"Process32First", Func, 4}, + {"Process32Next", Func, 4}, + {"ProcessEntry32", Type, 4}, + {"ProcessEntry32.DefaultHeapID", Field, 4}, + {"ProcessEntry32.ExeFile", Field, 4}, + {"ProcessEntry32.Flags", Field, 4}, + {"ProcessEntry32.ModuleID", Field, 4}, + {"ProcessEntry32.ParentProcessID", Field, 4}, + {"ProcessEntry32.PriClassBase", Field, 4}, + {"ProcessEntry32.ProcessID", Field, 4}, + {"ProcessEntry32.Size", Field, 4}, + {"ProcessEntry32.Threads", Field, 4}, + {"ProcessEntry32.Usage", Field, 4}, + {"ProcessInformation", Type, 0}, + {"ProcessInformation.Process", Field, 0}, + {"ProcessInformation.ProcessId", Field, 0}, + {"ProcessInformation.Thread", Field, 0}, + {"ProcessInformation.ThreadId", Field, 0}, + {"Protoent", Type, 0}, + {"Protoent.Aliases", Field, 0}, + {"Protoent.Name", Field, 0}, + {"Protoent.Proto", Field, 0}, + {"PtraceAttach", Func, 0}, + {"PtraceCont", Func, 0}, + {"PtraceDetach", Func, 0}, + {"PtraceGetEventMsg", Func, 0}, + {"PtraceGetRegs", Func, 0}, + {"PtracePeekData", Func, 0}, + {"PtracePeekText", Func, 0}, + {"PtracePokeData", Func, 0}, + {"PtracePokeText", Func, 0}, + {"PtraceRegs", Type, 0}, + {"PtraceRegs.Cs", Field, 0}, + {"PtraceRegs.Ds", Field, 0}, + {"PtraceRegs.Eax", Field, 0}, + {"PtraceRegs.Ebp", Field, 0}, + {"PtraceRegs.Ebx", Field, 0}, + {"PtraceRegs.Ecx", Field, 0}, + {"PtraceRegs.Edi", Field, 0}, + {"PtraceRegs.Edx", Field, 0}, + {"PtraceRegs.Eflags", Field, 0}, + {"PtraceRegs.Eip", Field, 0}, + {"PtraceRegs.Es", Field, 0}, + {"PtraceRegs.Esi", Field, 0}, + {"PtraceRegs.Esp", Field, 0}, + {"PtraceRegs.Fs", Field, 0}, + {"PtraceRegs.Fs_base", Field, 0}, + {"PtraceRegs.Gs", Field, 0}, + {"PtraceRegs.Gs_base", Field, 0}, + {"PtraceRegs.Orig_eax", Field, 0}, + {"PtraceRegs.Orig_rax", Field, 0}, + {"PtraceRegs.R10", Field, 0}, + {"PtraceRegs.R11", Field, 0}, + {"PtraceRegs.R12", Field, 0}, + {"PtraceRegs.R13", Field, 0}, + {"PtraceRegs.R14", Field, 0}, + {"PtraceRegs.R15", Field, 0}, + {"PtraceRegs.R8", Field, 0}, + {"PtraceRegs.R9", Field, 0}, + {"PtraceRegs.Rax", Field, 0}, + {"PtraceRegs.Rbp", Field, 0}, + {"PtraceRegs.Rbx", Field, 0}, + {"PtraceRegs.Rcx", Field, 0}, + {"PtraceRegs.Rdi", Field, 0}, + {"PtraceRegs.Rdx", Field, 0}, + {"PtraceRegs.Rip", Field, 0}, + {"PtraceRegs.Rsi", Field, 0}, + {"PtraceRegs.Rsp", Field, 0}, + {"PtraceRegs.Ss", Field, 0}, + {"PtraceRegs.Uregs", Field, 0}, + {"PtraceRegs.Xcs", Field, 0}, + {"PtraceRegs.Xds", Field, 0}, + {"PtraceRegs.Xes", Field, 0}, + {"PtraceRegs.Xfs", Field, 0}, + {"PtraceRegs.Xgs", Field, 0}, + {"PtraceRegs.Xss", Field, 0}, + {"PtraceSetOptions", Func, 0}, + {"PtraceSetRegs", Func, 0}, + {"PtraceSingleStep", Func, 0}, + {"PtraceSyscall", Func, 1}, + {"Pwrite", Func, 0}, + {"REG_BINARY", Const, 0}, + {"REG_DWORD", Const, 0}, + {"REG_DWORD_BIG_ENDIAN", Const, 0}, + {"REG_DWORD_LITTLE_ENDIAN", Const, 0}, + {"REG_EXPAND_SZ", Const, 0}, + {"REG_FULL_RESOURCE_DESCRIPTOR", Const, 0}, + {"REG_LINK", Const, 0}, + {"REG_MULTI_SZ", Const, 0}, + {"REG_NONE", Const, 0}, + {"REG_QWORD", Const, 0}, + {"REG_QWORD_LITTLE_ENDIAN", Const, 0}, + {"REG_RESOURCE_LIST", Const, 0}, + {"REG_RESOURCE_REQUIREMENTS_LIST", Const, 0}, + {"REG_SZ", Const, 0}, + {"RLIMIT_AS", Const, 0}, + {"RLIMIT_CORE", Const, 0}, + {"RLIMIT_CPU", Const, 0}, + {"RLIMIT_CPU_USAGE_MONITOR", Const, 16}, + {"RLIMIT_DATA", Const, 0}, + {"RLIMIT_FSIZE", Const, 0}, + {"RLIMIT_NOFILE", Const, 0}, + {"RLIMIT_STACK", Const, 0}, + {"RLIM_INFINITY", Const, 0}, + {"RTAX_ADVMSS", Const, 0}, + {"RTAX_AUTHOR", Const, 0}, + {"RTAX_BRD", Const, 0}, + {"RTAX_CWND", Const, 0}, + {"RTAX_DST", Const, 0}, + {"RTAX_FEATURES", Const, 0}, + {"RTAX_FEATURE_ALLFRAG", Const, 0}, + {"RTAX_FEATURE_ECN", Const, 0}, + {"RTAX_FEATURE_SACK", Const, 0}, + {"RTAX_FEATURE_TIMESTAMP", Const, 0}, + {"RTAX_GATEWAY", Const, 0}, + {"RTAX_GENMASK", Const, 0}, + {"RTAX_HOPLIMIT", Const, 0}, + {"RTAX_IFA", Const, 0}, + {"RTAX_IFP", Const, 0}, + {"RTAX_INITCWND", Const, 0}, + {"RTAX_INITRWND", Const, 0}, + {"RTAX_LABEL", Const, 1}, + {"RTAX_LOCK", Const, 0}, + {"RTAX_MAX", Const, 0}, + {"RTAX_MTU", Const, 0}, + {"RTAX_NETMASK", Const, 0}, + {"RTAX_REORDERING", Const, 0}, + {"RTAX_RTO_MIN", Const, 0}, + {"RTAX_RTT", Const, 0}, + {"RTAX_RTTVAR", Const, 0}, + {"RTAX_SRC", Const, 1}, + {"RTAX_SRCMASK", Const, 1}, + {"RTAX_SSTHRESH", Const, 0}, + {"RTAX_TAG", Const, 1}, + {"RTAX_UNSPEC", Const, 0}, + {"RTAX_WINDOW", Const, 0}, + {"RTA_ALIGNTO", Const, 0}, + {"RTA_AUTHOR", Const, 0}, + {"RTA_BRD", Const, 0}, + {"RTA_CACHEINFO", Const, 0}, + {"RTA_DST", Const, 0}, + {"RTA_FLOW", Const, 0}, + {"RTA_GATEWAY", Const, 0}, + {"RTA_GENMASK", Const, 0}, + {"RTA_IFA", Const, 0}, + {"RTA_IFP", Const, 0}, + {"RTA_IIF", Const, 0}, + {"RTA_LABEL", Const, 1}, + {"RTA_MAX", Const, 0}, + {"RTA_METRICS", Const, 0}, + {"RTA_MULTIPATH", Const, 0}, + {"RTA_NETMASK", Const, 0}, + {"RTA_OIF", Const, 0}, + {"RTA_PREFSRC", Const, 0}, + {"RTA_PRIORITY", Const, 0}, + {"RTA_SRC", Const, 0}, + {"RTA_SRCMASK", Const, 1}, + {"RTA_TABLE", Const, 0}, + {"RTA_TAG", Const, 1}, + {"RTA_UNSPEC", Const, 0}, + {"RTCF_DIRECTSRC", Const, 0}, + {"RTCF_DOREDIRECT", Const, 0}, + {"RTCF_LOG", Const, 0}, + {"RTCF_MASQ", Const, 0}, + {"RTCF_NAT", Const, 0}, + {"RTCF_VALVE", Const, 0}, + {"RTF_ADDRCLASSMASK", Const, 0}, + {"RTF_ADDRCONF", Const, 0}, + {"RTF_ALLONLINK", Const, 0}, + {"RTF_ANNOUNCE", Const, 1}, + {"RTF_BLACKHOLE", Const, 0}, + {"RTF_BROADCAST", Const, 0}, + {"RTF_CACHE", Const, 0}, + {"RTF_CLONED", Const, 1}, + {"RTF_CLONING", Const, 0}, + {"RTF_CONDEMNED", Const, 0}, + {"RTF_DEFAULT", Const, 0}, + {"RTF_DELCLONE", Const, 0}, + {"RTF_DONE", Const, 0}, + {"RTF_DYNAMIC", Const, 0}, + {"RTF_FLOW", Const, 0}, + {"RTF_FMASK", Const, 0}, + {"RTF_GATEWAY", Const, 0}, + {"RTF_GWFLAG_COMPAT", Const, 3}, + {"RTF_HOST", Const, 0}, + {"RTF_IFREF", Const, 0}, + {"RTF_IFSCOPE", Const, 0}, + {"RTF_INTERFACE", Const, 0}, + {"RTF_IRTT", Const, 0}, + {"RTF_LINKRT", Const, 0}, + {"RTF_LLDATA", Const, 0}, + {"RTF_LLINFO", Const, 0}, + {"RTF_LOCAL", Const, 0}, + {"RTF_MASK", Const, 1}, + {"RTF_MODIFIED", Const, 0}, + {"RTF_MPATH", Const, 1}, + {"RTF_MPLS", Const, 1}, + {"RTF_MSS", Const, 0}, + {"RTF_MTU", Const, 0}, + {"RTF_MULTICAST", Const, 0}, + {"RTF_NAT", Const, 0}, + {"RTF_NOFORWARD", Const, 0}, + {"RTF_NONEXTHOP", Const, 0}, + {"RTF_NOPMTUDISC", Const, 0}, + {"RTF_PERMANENT_ARP", Const, 1}, + {"RTF_PINNED", Const, 0}, + {"RTF_POLICY", Const, 0}, + {"RTF_PRCLONING", Const, 0}, + {"RTF_PROTO1", Const, 0}, + {"RTF_PROTO2", Const, 0}, + {"RTF_PROTO3", Const, 0}, + {"RTF_PROXY", Const, 16}, + {"RTF_REINSTATE", Const, 0}, + {"RTF_REJECT", Const, 0}, + {"RTF_RNH_LOCKED", Const, 0}, + {"RTF_ROUTER", Const, 16}, + {"RTF_SOURCE", Const, 1}, + {"RTF_SRC", Const, 1}, + {"RTF_STATIC", Const, 0}, + {"RTF_STICKY", Const, 0}, + {"RTF_THROW", Const, 0}, + {"RTF_TUNNEL", Const, 1}, + {"RTF_UP", Const, 0}, + {"RTF_USETRAILERS", Const, 1}, + {"RTF_WASCLONED", Const, 0}, + {"RTF_WINDOW", Const, 0}, + {"RTF_XRESOLVE", Const, 0}, + {"RTM_ADD", Const, 0}, + {"RTM_BASE", Const, 0}, + {"RTM_CHANGE", Const, 0}, + {"RTM_CHGADDR", Const, 1}, + {"RTM_DELACTION", Const, 0}, + {"RTM_DELADDR", Const, 0}, + {"RTM_DELADDRLABEL", Const, 0}, + {"RTM_DELETE", Const, 0}, + {"RTM_DELLINK", Const, 0}, + {"RTM_DELMADDR", Const, 0}, + {"RTM_DELNEIGH", Const, 0}, + {"RTM_DELQDISC", Const, 0}, + {"RTM_DELROUTE", Const, 0}, + {"RTM_DELRULE", Const, 0}, + {"RTM_DELTCLASS", Const, 0}, + {"RTM_DELTFILTER", Const, 0}, + {"RTM_DESYNC", Const, 1}, + {"RTM_F_CLONED", Const, 0}, + {"RTM_F_EQUALIZE", Const, 0}, + {"RTM_F_NOTIFY", Const, 0}, + {"RTM_F_PREFIX", Const, 0}, + {"RTM_GET", Const, 0}, + {"RTM_GET2", Const, 0}, + {"RTM_GETACTION", Const, 0}, + {"RTM_GETADDR", Const, 0}, + {"RTM_GETADDRLABEL", Const, 0}, + {"RTM_GETANYCAST", Const, 0}, + {"RTM_GETDCB", Const, 0}, + {"RTM_GETLINK", Const, 0}, + {"RTM_GETMULTICAST", Const, 0}, + {"RTM_GETNEIGH", Const, 0}, + {"RTM_GETNEIGHTBL", Const, 0}, + {"RTM_GETQDISC", Const, 0}, + {"RTM_GETROUTE", Const, 0}, + {"RTM_GETRULE", Const, 0}, + {"RTM_GETTCLASS", Const, 0}, + {"RTM_GETTFILTER", Const, 0}, + {"RTM_IEEE80211", Const, 0}, + {"RTM_IFANNOUNCE", Const, 0}, + {"RTM_IFINFO", Const, 0}, + {"RTM_IFINFO2", Const, 0}, + {"RTM_LLINFO_UPD", Const, 1}, + {"RTM_LOCK", Const, 0}, + {"RTM_LOSING", Const, 0}, + {"RTM_MAX", Const, 0}, + {"RTM_MAXSIZE", Const, 1}, + {"RTM_MISS", Const, 0}, + {"RTM_NEWACTION", Const, 0}, + {"RTM_NEWADDR", Const, 0}, + {"RTM_NEWADDRLABEL", Const, 0}, + {"RTM_NEWLINK", Const, 0}, + {"RTM_NEWMADDR", Const, 0}, + {"RTM_NEWMADDR2", Const, 0}, + {"RTM_NEWNDUSEROPT", Const, 0}, + {"RTM_NEWNEIGH", Const, 0}, + {"RTM_NEWNEIGHTBL", Const, 0}, + {"RTM_NEWPREFIX", Const, 0}, + {"RTM_NEWQDISC", Const, 0}, + {"RTM_NEWROUTE", Const, 0}, + {"RTM_NEWRULE", Const, 0}, + {"RTM_NEWTCLASS", Const, 0}, + {"RTM_NEWTFILTER", Const, 0}, + {"RTM_NR_FAMILIES", Const, 0}, + {"RTM_NR_MSGTYPES", Const, 0}, + {"RTM_OIFINFO", Const, 1}, + {"RTM_OLDADD", Const, 0}, + {"RTM_OLDDEL", Const, 0}, + {"RTM_OOIFINFO", Const, 1}, + {"RTM_REDIRECT", Const, 0}, + {"RTM_RESOLVE", Const, 0}, + {"RTM_RTTUNIT", Const, 0}, + {"RTM_SETDCB", Const, 0}, + {"RTM_SETGATE", Const, 1}, + {"RTM_SETLINK", Const, 0}, + {"RTM_SETNEIGHTBL", Const, 0}, + {"RTM_VERSION", Const, 0}, + {"RTNH_ALIGNTO", Const, 0}, + {"RTNH_F_DEAD", Const, 0}, + {"RTNH_F_ONLINK", Const, 0}, + {"RTNH_F_PERVASIVE", Const, 0}, + {"RTNLGRP_IPV4_IFADDR", Const, 1}, + {"RTNLGRP_IPV4_MROUTE", Const, 1}, + {"RTNLGRP_IPV4_ROUTE", Const, 1}, + {"RTNLGRP_IPV4_RULE", Const, 1}, + {"RTNLGRP_IPV6_IFADDR", Const, 1}, + {"RTNLGRP_IPV6_IFINFO", Const, 1}, + {"RTNLGRP_IPV6_MROUTE", Const, 1}, + {"RTNLGRP_IPV6_PREFIX", Const, 1}, + {"RTNLGRP_IPV6_ROUTE", Const, 1}, + {"RTNLGRP_IPV6_RULE", Const, 1}, + {"RTNLGRP_LINK", Const, 1}, + {"RTNLGRP_ND_USEROPT", Const, 1}, + {"RTNLGRP_NEIGH", Const, 1}, + {"RTNLGRP_NONE", Const, 1}, + {"RTNLGRP_NOTIFY", Const, 1}, + {"RTNLGRP_TC", Const, 1}, + {"RTN_ANYCAST", Const, 0}, + {"RTN_BLACKHOLE", Const, 0}, + {"RTN_BROADCAST", Const, 0}, + {"RTN_LOCAL", Const, 0}, + {"RTN_MAX", Const, 0}, + {"RTN_MULTICAST", Const, 0}, + {"RTN_NAT", Const, 0}, + {"RTN_PROHIBIT", Const, 0}, + {"RTN_THROW", Const, 0}, + {"RTN_UNICAST", Const, 0}, + {"RTN_UNREACHABLE", Const, 0}, + {"RTN_UNSPEC", Const, 0}, + {"RTN_XRESOLVE", Const, 0}, + {"RTPROT_BIRD", Const, 0}, + {"RTPROT_BOOT", Const, 0}, + {"RTPROT_DHCP", Const, 0}, + {"RTPROT_DNROUTED", Const, 0}, + {"RTPROT_GATED", Const, 0}, + {"RTPROT_KERNEL", Const, 0}, + {"RTPROT_MRT", Const, 0}, + {"RTPROT_NTK", Const, 0}, + {"RTPROT_RA", Const, 0}, + {"RTPROT_REDIRECT", Const, 0}, + {"RTPROT_STATIC", Const, 0}, + {"RTPROT_UNSPEC", Const, 0}, + {"RTPROT_XORP", Const, 0}, + {"RTPROT_ZEBRA", Const, 0}, + {"RTV_EXPIRE", Const, 0}, + {"RTV_HOPCOUNT", Const, 0}, + {"RTV_MTU", Const, 0}, + {"RTV_RPIPE", Const, 0}, + {"RTV_RTT", Const, 0}, + {"RTV_RTTVAR", Const, 0}, + {"RTV_SPIPE", Const, 0}, + {"RTV_SSTHRESH", Const, 0}, + {"RTV_WEIGHT", Const, 0}, + {"RT_CACHING_CONTEXT", Const, 1}, + {"RT_CLASS_DEFAULT", Const, 0}, + {"RT_CLASS_LOCAL", Const, 0}, + {"RT_CLASS_MAIN", Const, 0}, + {"RT_CLASS_MAX", Const, 0}, + {"RT_CLASS_UNSPEC", Const, 0}, + {"RT_DEFAULT_FIB", Const, 1}, + {"RT_NORTREF", Const, 1}, + {"RT_SCOPE_HOST", Const, 0}, + {"RT_SCOPE_LINK", Const, 0}, + {"RT_SCOPE_NOWHERE", Const, 0}, + {"RT_SCOPE_SITE", Const, 0}, + {"RT_SCOPE_UNIVERSE", Const, 0}, + {"RT_TABLEID_MAX", Const, 1}, + {"RT_TABLE_COMPAT", Const, 0}, + {"RT_TABLE_DEFAULT", Const, 0}, + {"RT_TABLE_LOCAL", Const, 0}, + {"RT_TABLE_MAIN", Const, 0}, + {"RT_TABLE_MAX", Const, 0}, + {"RT_TABLE_UNSPEC", Const, 0}, + {"RUSAGE_CHILDREN", Const, 0}, + {"RUSAGE_SELF", Const, 0}, + {"RUSAGE_THREAD", Const, 0}, + {"Radvisory_t", Type, 0}, + {"Radvisory_t.Count", Field, 0}, + {"Radvisory_t.Offset", Field, 0}, + {"Radvisory_t.Pad_cgo_0", Field, 0}, + {"RawConn", Type, 9}, + {"RawSockaddr", Type, 0}, + {"RawSockaddr.Data", Field, 0}, + {"RawSockaddr.Family", Field, 0}, + {"RawSockaddr.Len", Field, 0}, + {"RawSockaddrAny", Type, 0}, + {"RawSockaddrAny.Addr", Field, 0}, + {"RawSockaddrAny.Pad", Field, 0}, + {"RawSockaddrDatalink", Type, 0}, + {"RawSockaddrDatalink.Alen", Field, 0}, + {"RawSockaddrDatalink.Data", Field, 0}, + {"RawSockaddrDatalink.Family", Field, 0}, + {"RawSockaddrDatalink.Index", Field, 0}, + {"RawSockaddrDatalink.Len", Field, 0}, + {"RawSockaddrDatalink.Nlen", Field, 0}, + {"RawSockaddrDatalink.Pad_cgo_0", Field, 2}, + {"RawSockaddrDatalink.Slen", Field, 0}, + {"RawSockaddrDatalink.Type", Field, 0}, + {"RawSockaddrInet4", Type, 0}, + {"RawSockaddrInet4.Addr", Field, 0}, + {"RawSockaddrInet4.Family", Field, 0}, + {"RawSockaddrInet4.Len", Field, 0}, + {"RawSockaddrInet4.Port", Field, 0}, + {"RawSockaddrInet4.Zero", Field, 0}, + {"RawSockaddrInet6", Type, 0}, + {"RawSockaddrInet6.Addr", Field, 0}, + {"RawSockaddrInet6.Family", Field, 0}, + {"RawSockaddrInet6.Flowinfo", Field, 0}, + {"RawSockaddrInet6.Len", Field, 0}, + {"RawSockaddrInet6.Port", Field, 0}, + {"RawSockaddrInet6.Scope_id", Field, 0}, + {"RawSockaddrLinklayer", Type, 0}, + {"RawSockaddrLinklayer.Addr", Field, 0}, + {"RawSockaddrLinklayer.Family", Field, 0}, + {"RawSockaddrLinklayer.Halen", Field, 0}, + {"RawSockaddrLinklayer.Hatype", Field, 0}, + {"RawSockaddrLinklayer.Ifindex", Field, 0}, + {"RawSockaddrLinklayer.Pkttype", Field, 0}, + {"RawSockaddrLinklayer.Protocol", Field, 0}, + {"RawSockaddrNetlink", Type, 0}, + {"RawSockaddrNetlink.Family", Field, 0}, + {"RawSockaddrNetlink.Groups", Field, 0}, + {"RawSockaddrNetlink.Pad", Field, 0}, + {"RawSockaddrNetlink.Pid", Field, 0}, + {"RawSockaddrUnix", Type, 0}, + {"RawSockaddrUnix.Family", Field, 0}, + {"RawSockaddrUnix.Len", Field, 0}, + {"RawSockaddrUnix.Pad_cgo_0", Field, 2}, + {"RawSockaddrUnix.Path", Field, 0}, + {"RawSyscall", Func, 0}, + {"RawSyscall6", Func, 0}, + {"Read", Func, 0}, + {"ReadConsole", Func, 1}, + {"ReadDirectoryChanges", Func, 0}, + {"ReadDirent", Func, 0}, + {"ReadFile", Func, 0}, + {"Readlink", Func, 0}, + {"Reboot", Func, 0}, + {"Recvfrom", Func, 0}, + {"Recvmsg", Func, 0}, + {"RegCloseKey", Func, 0}, + {"RegEnumKeyEx", Func, 0}, + {"RegOpenKeyEx", Func, 0}, + {"RegQueryInfoKey", Func, 0}, + {"RegQueryValueEx", Func, 0}, + {"RemoveDirectory", Func, 0}, + {"Removexattr", Func, 1}, + {"Rename", Func, 0}, + {"Renameat", Func, 0}, + {"Revoke", Func, 0}, + {"Rlimit", Type, 0}, + {"Rlimit.Cur", Field, 0}, + {"Rlimit.Max", Field, 0}, + {"Rmdir", Func, 0}, + {"RouteMessage", Type, 0}, + {"RouteMessage.Data", Field, 0}, + {"RouteMessage.Header", Field, 0}, + {"RouteRIB", Func, 0}, + {"RoutingMessage", Type, 0}, + {"RtAttr", Type, 0}, + {"RtAttr.Len", Field, 0}, + {"RtAttr.Type", Field, 0}, + {"RtGenmsg", Type, 0}, + {"RtGenmsg.Family", Field, 0}, + {"RtMetrics", Type, 0}, + {"RtMetrics.Expire", Field, 0}, + {"RtMetrics.Filler", Field, 0}, + {"RtMetrics.Hopcount", Field, 0}, + {"RtMetrics.Locks", Field, 0}, + {"RtMetrics.Mtu", Field, 0}, + {"RtMetrics.Pad", Field, 3}, + {"RtMetrics.Pksent", Field, 0}, + {"RtMetrics.Recvpipe", Field, 0}, + {"RtMetrics.Refcnt", Field, 2}, + {"RtMetrics.Rtt", Field, 0}, + {"RtMetrics.Rttvar", Field, 0}, + {"RtMetrics.Sendpipe", Field, 0}, + {"RtMetrics.Ssthresh", Field, 0}, + {"RtMetrics.Weight", Field, 0}, + {"RtMsg", Type, 0}, + {"RtMsg.Dst_len", Field, 0}, + {"RtMsg.Family", Field, 0}, + {"RtMsg.Flags", Field, 0}, + {"RtMsg.Protocol", Field, 0}, + {"RtMsg.Scope", Field, 0}, + {"RtMsg.Src_len", Field, 0}, + {"RtMsg.Table", Field, 0}, + {"RtMsg.Tos", Field, 0}, + {"RtMsg.Type", Field, 0}, + {"RtMsghdr", Type, 0}, + {"RtMsghdr.Addrs", Field, 0}, + {"RtMsghdr.Errno", Field, 0}, + {"RtMsghdr.Flags", Field, 0}, + {"RtMsghdr.Fmask", Field, 0}, + {"RtMsghdr.Hdrlen", Field, 2}, + {"RtMsghdr.Index", Field, 0}, + {"RtMsghdr.Inits", Field, 0}, + {"RtMsghdr.Mpls", Field, 2}, + {"RtMsghdr.Msglen", Field, 0}, + {"RtMsghdr.Pad_cgo_0", Field, 0}, + {"RtMsghdr.Pad_cgo_1", Field, 2}, + {"RtMsghdr.Pid", Field, 0}, + {"RtMsghdr.Priority", Field, 2}, + {"RtMsghdr.Rmx", Field, 0}, + {"RtMsghdr.Seq", Field, 0}, + {"RtMsghdr.Tableid", Field, 2}, + {"RtMsghdr.Type", Field, 0}, + {"RtMsghdr.Use", Field, 0}, + {"RtMsghdr.Version", Field, 0}, + {"RtNexthop", Type, 0}, + {"RtNexthop.Flags", Field, 0}, + {"RtNexthop.Hops", Field, 0}, + {"RtNexthop.Ifindex", Field, 0}, + {"RtNexthop.Len", Field, 0}, + {"Rusage", Type, 0}, + {"Rusage.CreationTime", Field, 0}, + {"Rusage.ExitTime", Field, 0}, + {"Rusage.Idrss", Field, 0}, + {"Rusage.Inblock", Field, 0}, + {"Rusage.Isrss", Field, 0}, + {"Rusage.Ixrss", Field, 0}, + {"Rusage.KernelTime", Field, 0}, + {"Rusage.Majflt", Field, 0}, + {"Rusage.Maxrss", Field, 0}, + {"Rusage.Minflt", Field, 0}, + {"Rusage.Msgrcv", Field, 0}, + {"Rusage.Msgsnd", Field, 0}, + {"Rusage.Nivcsw", Field, 0}, + {"Rusage.Nsignals", Field, 0}, + {"Rusage.Nswap", Field, 0}, + {"Rusage.Nvcsw", Field, 0}, + {"Rusage.Oublock", Field, 0}, + {"Rusage.Stime", Field, 0}, + {"Rusage.UserTime", Field, 0}, + {"Rusage.Utime", Field, 0}, + {"SCM_BINTIME", Const, 0}, + {"SCM_CREDENTIALS", Const, 0}, + {"SCM_CREDS", Const, 0}, + {"SCM_RIGHTS", Const, 0}, + {"SCM_TIMESTAMP", Const, 0}, + {"SCM_TIMESTAMPING", Const, 0}, + {"SCM_TIMESTAMPNS", Const, 0}, + {"SCM_TIMESTAMP_MONOTONIC", Const, 0}, + {"SHUT_RD", Const, 0}, + {"SHUT_RDWR", Const, 0}, + {"SHUT_WR", Const, 0}, + {"SID", Type, 0}, + {"SIDAndAttributes", Type, 0}, + {"SIDAndAttributes.Attributes", Field, 0}, + {"SIDAndAttributes.Sid", Field, 0}, + {"SIGABRT", Const, 0}, + {"SIGALRM", Const, 0}, + {"SIGBUS", Const, 0}, + {"SIGCHLD", Const, 0}, + {"SIGCLD", Const, 0}, + {"SIGCONT", Const, 0}, + {"SIGEMT", Const, 0}, + {"SIGFPE", Const, 0}, + {"SIGHUP", Const, 0}, + {"SIGILL", Const, 0}, + {"SIGINFO", Const, 0}, + {"SIGINT", Const, 0}, + {"SIGIO", Const, 0}, + {"SIGIOT", Const, 0}, + {"SIGKILL", Const, 0}, + {"SIGLIBRT", Const, 1}, + {"SIGLWP", Const, 0}, + {"SIGPIPE", Const, 0}, + {"SIGPOLL", Const, 0}, + {"SIGPROF", Const, 0}, + {"SIGPWR", Const, 0}, + {"SIGQUIT", Const, 0}, + {"SIGSEGV", Const, 0}, + {"SIGSTKFLT", Const, 0}, + {"SIGSTOP", Const, 0}, + {"SIGSYS", Const, 0}, + {"SIGTERM", Const, 0}, + {"SIGTHR", Const, 0}, + {"SIGTRAP", Const, 0}, + {"SIGTSTP", Const, 0}, + {"SIGTTIN", Const, 0}, + {"SIGTTOU", Const, 0}, + {"SIGUNUSED", Const, 0}, + {"SIGURG", Const, 0}, + {"SIGUSR1", Const, 0}, + {"SIGUSR2", Const, 0}, + {"SIGVTALRM", Const, 0}, + {"SIGWINCH", Const, 0}, + {"SIGXCPU", Const, 0}, + {"SIGXFSZ", Const, 0}, + {"SIOCADDDLCI", Const, 0}, + {"SIOCADDMULTI", Const, 0}, + {"SIOCADDRT", Const, 0}, + {"SIOCAIFADDR", Const, 0}, + {"SIOCAIFGROUP", Const, 0}, + {"SIOCALIFADDR", Const, 0}, + {"SIOCARPIPLL", Const, 0}, + {"SIOCATMARK", Const, 0}, + {"SIOCAUTOADDR", Const, 0}, + {"SIOCAUTONETMASK", Const, 0}, + {"SIOCBRDGADD", Const, 1}, + {"SIOCBRDGADDS", Const, 1}, + {"SIOCBRDGARL", Const, 1}, + {"SIOCBRDGDADDR", Const, 1}, + {"SIOCBRDGDEL", Const, 1}, + {"SIOCBRDGDELS", Const, 1}, + {"SIOCBRDGFLUSH", Const, 1}, + {"SIOCBRDGFRL", Const, 1}, + {"SIOCBRDGGCACHE", Const, 1}, + {"SIOCBRDGGFD", Const, 1}, + {"SIOCBRDGGHT", Const, 1}, + {"SIOCBRDGGIFFLGS", Const, 1}, + {"SIOCBRDGGMA", Const, 1}, + {"SIOCBRDGGPARAM", Const, 1}, + {"SIOCBRDGGPRI", Const, 1}, + {"SIOCBRDGGRL", Const, 1}, + {"SIOCBRDGGSIFS", Const, 1}, + {"SIOCBRDGGTO", Const, 1}, + {"SIOCBRDGIFS", Const, 1}, + {"SIOCBRDGRTS", Const, 1}, + {"SIOCBRDGSADDR", Const, 1}, + {"SIOCBRDGSCACHE", Const, 1}, + {"SIOCBRDGSFD", Const, 1}, + {"SIOCBRDGSHT", Const, 1}, + {"SIOCBRDGSIFCOST", Const, 1}, + {"SIOCBRDGSIFFLGS", Const, 1}, + {"SIOCBRDGSIFPRIO", Const, 1}, + {"SIOCBRDGSMA", Const, 1}, + {"SIOCBRDGSPRI", Const, 1}, + {"SIOCBRDGSPROTO", Const, 1}, + {"SIOCBRDGSTO", Const, 1}, + {"SIOCBRDGSTXHC", Const, 1}, + {"SIOCDARP", Const, 0}, + {"SIOCDELDLCI", Const, 0}, + {"SIOCDELMULTI", Const, 0}, + {"SIOCDELRT", Const, 0}, + {"SIOCDEVPRIVATE", Const, 0}, + {"SIOCDIFADDR", Const, 0}, + {"SIOCDIFGROUP", Const, 0}, + {"SIOCDIFPHYADDR", Const, 0}, + {"SIOCDLIFADDR", Const, 0}, + {"SIOCDRARP", Const, 0}, + {"SIOCGARP", Const, 0}, + {"SIOCGDRVSPEC", Const, 0}, + {"SIOCGETKALIVE", Const, 1}, + {"SIOCGETLABEL", Const, 1}, + {"SIOCGETPFLOW", Const, 1}, + {"SIOCGETPFSYNC", Const, 1}, + {"SIOCGETSGCNT", Const, 0}, + {"SIOCGETVIFCNT", Const, 0}, + {"SIOCGETVLAN", Const, 0}, + {"SIOCGHIWAT", Const, 0}, + {"SIOCGIFADDR", Const, 0}, + {"SIOCGIFADDRPREF", Const, 1}, + {"SIOCGIFALIAS", Const, 1}, + {"SIOCGIFALTMTU", Const, 0}, + {"SIOCGIFASYNCMAP", Const, 0}, + {"SIOCGIFBOND", Const, 0}, + {"SIOCGIFBR", Const, 0}, + {"SIOCGIFBRDADDR", Const, 0}, + {"SIOCGIFCAP", Const, 0}, + {"SIOCGIFCONF", Const, 0}, + {"SIOCGIFCOUNT", Const, 0}, + {"SIOCGIFDATA", Const, 1}, + {"SIOCGIFDESCR", Const, 0}, + {"SIOCGIFDEVMTU", Const, 0}, + {"SIOCGIFDLT", Const, 1}, + {"SIOCGIFDSTADDR", Const, 0}, + {"SIOCGIFENCAP", Const, 0}, + {"SIOCGIFFIB", Const, 1}, + {"SIOCGIFFLAGS", Const, 0}, + {"SIOCGIFGATTR", Const, 1}, + {"SIOCGIFGENERIC", Const, 0}, + {"SIOCGIFGMEMB", Const, 0}, + {"SIOCGIFGROUP", Const, 0}, + {"SIOCGIFHARDMTU", Const, 3}, + {"SIOCGIFHWADDR", Const, 0}, + {"SIOCGIFINDEX", Const, 0}, + {"SIOCGIFKPI", Const, 0}, + {"SIOCGIFMAC", Const, 0}, + {"SIOCGIFMAP", Const, 0}, + {"SIOCGIFMEDIA", Const, 0}, + {"SIOCGIFMEM", Const, 0}, + {"SIOCGIFMETRIC", Const, 0}, + {"SIOCGIFMTU", Const, 0}, + {"SIOCGIFNAME", Const, 0}, + {"SIOCGIFNETMASK", Const, 0}, + {"SIOCGIFPDSTADDR", Const, 0}, + {"SIOCGIFPFLAGS", Const, 0}, + {"SIOCGIFPHYS", Const, 0}, + {"SIOCGIFPRIORITY", Const, 1}, + {"SIOCGIFPSRCADDR", Const, 0}, + {"SIOCGIFRDOMAIN", Const, 1}, + {"SIOCGIFRTLABEL", Const, 1}, + {"SIOCGIFSLAVE", Const, 0}, + {"SIOCGIFSTATUS", Const, 0}, + {"SIOCGIFTIMESLOT", Const, 1}, + {"SIOCGIFTXQLEN", Const, 0}, + {"SIOCGIFVLAN", Const, 0}, + {"SIOCGIFWAKEFLAGS", Const, 0}, + {"SIOCGIFXFLAGS", Const, 1}, + {"SIOCGLIFADDR", Const, 0}, + {"SIOCGLIFPHYADDR", Const, 0}, + {"SIOCGLIFPHYRTABLE", Const, 1}, + {"SIOCGLIFPHYTTL", Const, 3}, + {"SIOCGLINKSTR", Const, 1}, + {"SIOCGLOWAT", Const, 0}, + {"SIOCGPGRP", Const, 0}, + {"SIOCGPRIVATE_0", Const, 0}, + {"SIOCGPRIVATE_1", Const, 0}, + {"SIOCGRARP", Const, 0}, + {"SIOCGSPPPPARAMS", Const, 3}, + {"SIOCGSTAMP", Const, 0}, + {"SIOCGSTAMPNS", Const, 0}, + {"SIOCGVH", Const, 1}, + {"SIOCGVNETID", Const, 3}, + {"SIOCIFCREATE", Const, 0}, + {"SIOCIFCREATE2", Const, 0}, + {"SIOCIFDESTROY", Const, 0}, + {"SIOCIFGCLONERS", Const, 0}, + {"SIOCINITIFADDR", Const, 1}, + {"SIOCPROTOPRIVATE", Const, 0}, + {"SIOCRSLVMULTI", Const, 0}, + {"SIOCRTMSG", Const, 0}, + {"SIOCSARP", Const, 0}, + {"SIOCSDRVSPEC", Const, 0}, + {"SIOCSETKALIVE", Const, 1}, + {"SIOCSETLABEL", Const, 1}, + {"SIOCSETPFLOW", Const, 1}, + {"SIOCSETPFSYNC", Const, 1}, + {"SIOCSETVLAN", Const, 0}, + {"SIOCSHIWAT", Const, 0}, + {"SIOCSIFADDR", Const, 0}, + {"SIOCSIFADDRPREF", Const, 1}, + {"SIOCSIFALTMTU", Const, 0}, + {"SIOCSIFASYNCMAP", Const, 0}, + {"SIOCSIFBOND", Const, 0}, + {"SIOCSIFBR", Const, 0}, + {"SIOCSIFBRDADDR", Const, 0}, + {"SIOCSIFCAP", Const, 0}, + {"SIOCSIFDESCR", Const, 0}, + {"SIOCSIFDSTADDR", Const, 0}, + {"SIOCSIFENCAP", Const, 0}, + {"SIOCSIFFIB", Const, 1}, + {"SIOCSIFFLAGS", Const, 0}, + {"SIOCSIFGATTR", Const, 1}, + {"SIOCSIFGENERIC", Const, 0}, + {"SIOCSIFHWADDR", Const, 0}, + {"SIOCSIFHWBROADCAST", Const, 0}, + {"SIOCSIFKPI", Const, 0}, + {"SIOCSIFLINK", Const, 0}, + {"SIOCSIFLLADDR", Const, 0}, + {"SIOCSIFMAC", Const, 0}, + {"SIOCSIFMAP", Const, 0}, + {"SIOCSIFMEDIA", Const, 0}, + {"SIOCSIFMEM", Const, 0}, + {"SIOCSIFMETRIC", Const, 0}, + {"SIOCSIFMTU", Const, 0}, + {"SIOCSIFNAME", Const, 0}, + {"SIOCSIFNETMASK", Const, 0}, + {"SIOCSIFPFLAGS", Const, 0}, + {"SIOCSIFPHYADDR", Const, 0}, + {"SIOCSIFPHYS", Const, 0}, + {"SIOCSIFPRIORITY", Const, 1}, + {"SIOCSIFRDOMAIN", Const, 1}, + {"SIOCSIFRTLABEL", Const, 1}, + {"SIOCSIFRVNET", Const, 0}, + {"SIOCSIFSLAVE", Const, 0}, + {"SIOCSIFTIMESLOT", Const, 1}, + {"SIOCSIFTXQLEN", Const, 0}, + {"SIOCSIFVLAN", Const, 0}, + {"SIOCSIFVNET", Const, 0}, + {"SIOCSIFXFLAGS", Const, 1}, + {"SIOCSLIFPHYADDR", Const, 0}, + {"SIOCSLIFPHYRTABLE", Const, 1}, + {"SIOCSLIFPHYTTL", Const, 3}, + {"SIOCSLINKSTR", Const, 1}, + {"SIOCSLOWAT", Const, 0}, + {"SIOCSPGRP", Const, 0}, + {"SIOCSRARP", Const, 0}, + {"SIOCSSPPPPARAMS", Const, 3}, + {"SIOCSVH", Const, 1}, + {"SIOCSVNETID", Const, 3}, + {"SIOCZIFDATA", Const, 1}, + {"SIO_GET_EXTENSION_FUNCTION_POINTER", Const, 1}, + {"SIO_GET_INTERFACE_LIST", Const, 0}, + {"SIO_KEEPALIVE_VALS", Const, 3}, + {"SIO_UDP_CONNRESET", Const, 4}, + {"SOCK_CLOEXEC", Const, 0}, + {"SOCK_DCCP", Const, 0}, + {"SOCK_DGRAM", Const, 0}, + {"SOCK_FLAGS_MASK", Const, 1}, + {"SOCK_MAXADDRLEN", Const, 0}, + {"SOCK_NONBLOCK", Const, 0}, + {"SOCK_NOSIGPIPE", Const, 1}, + {"SOCK_PACKET", Const, 0}, + {"SOCK_RAW", Const, 0}, + {"SOCK_RDM", Const, 0}, + {"SOCK_SEQPACKET", Const, 0}, + {"SOCK_STREAM", Const, 0}, + {"SOL_AAL", Const, 0}, + {"SOL_ATM", Const, 0}, + {"SOL_DECNET", Const, 0}, + {"SOL_ICMPV6", Const, 0}, + {"SOL_IP", Const, 0}, + {"SOL_IPV6", Const, 0}, + {"SOL_IRDA", Const, 0}, + {"SOL_PACKET", Const, 0}, + {"SOL_RAW", Const, 0}, + {"SOL_SOCKET", Const, 0}, + {"SOL_TCP", Const, 0}, + {"SOL_X25", Const, 0}, + {"SOMAXCONN", Const, 0}, + {"SO_ACCEPTCONN", Const, 0}, + {"SO_ACCEPTFILTER", Const, 0}, + {"SO_ATTACH_FILTER", Const, 0}, + {"SO_BINDANY", Const, 1}, + {"SO_BINDTODEVICE", Const, 0}, + {"SO_BINTIME", Const, 0}, + {"SO_BROADCAST", Const, 0}, + {"SO_BSDCOMPAT", Const, 0}, + {"SO_DEBUG", Const, 0}, + {"SO_DETACH_FILTER", Const, 0}, + {"SO_DOMAIN", Const, 0}, + {"SO_DONTROUTE", Const, 0}, + {"SO_DONTTRUNC", Const, 0}, + {"SO_ERROR", Const, 0}, + {"SO_KEEPALIVE", Const, 0}, + {"SO_LABEL", Const, 0}, + {"SO_LINGER", Const, 0}, + {"SO_LINGER_SEC", Const, 0}, + {"SO_LISTENINCQLEN", Const, 0}, + {"SO_LISTENQLEN", Const, 0}, + {"SO_LISTENQLIMIT", Const, 0}, + {"SO_MARK", Const, 0}, + {"SO_NETPROC", Const, 1}, + {"SO_NKE", Const, 0}, + {"SO_NOADDRERR", Const, 0}, + {"SO_NOHEADER", Const, 1}, + {"SO_NOSIGPIPE", Const, 0}, + {"SO_NOTIFYCONFLICT", Const, 0}, + {"SO_NO_CHECK", Const, 0}, + {"SO_NO_DDP", Const, 0}, + {"SO_NO_OFFLOAD", Const, 0}, + {"SO_NP_EXTENSIONS", Const, 0}, + {"SO_NREAD", Const, 0}, + {"SO_NUMRCVPKT", Const, 16}, + {"SO_NWRITE", Const, 0}, + {"SO_OOBINLINE", Const, 0}, + {"SO_OVERFLOWED", Const, 1}, + {"SO_PASSCRED", Const, 0}, + {"SO_PASSSEC", Const, 0}, + {"SO_PEERCRED", Const, 0}, + {"SO_PEERLABEL", Const, 0}, + {"SO_PEERNAME", Const, 0}, + {"SO_PEERSEC", Const, 0}, + {"SO_PRIORITY", Const, 0}, + {"SO_PROTOCOL", Const, 0}, + {"SO_PROTOTYPE", Const, 1}, + {"SO_RANDOMPORT", Const, 0}, + {"SO_RCVBUF", Const, 0}, + {"SO_RCVBUFFORCE", Const, 0}, + {"SO_RCVLOWAT", Const, 0}, + {"SO_RCVTIMEO", Const, 0}, + {"SO_RESTRICTIONS", Const, 0}, + {"SO_RESTRICT_DENYIN", Const, 0}, + {"SO_RESTRICT_DENYOUT", Const, 0}, + {"SO_RESTRICT_DENYSET", Const, 0}, + {"SO_REUSEADDR", Const, 0}, + {"SO_REUSEPORT", Const, 0}, + {"SO_REUSESHAREUID", Const, 0}, + {"SO_RTABLE", Const, 1}, + {"SO_RXQ_OVFL", Const, 0}, + {"SO_SECURITY_AUTHENTICATION", Const, 0}, + {"SO_SECURITY_ENCRYPTION_NETWORK", Const, 0}, + {"SO_SECURITY_ENCRYPTION_TRANSPORT", Const, 0}, + {"SO_SETFIB", Const, 0}, + {"SO_SNDBUF", Const, 0}, + {"SO_SNDBUFFORCE", Const, 0}, + {"SO_SNDLOWAT", Const, 0}, + {"SO_SNDTIMEO", Const, 0}, + {"SO_SPLICE", Const, 1}, + {"SO_TIMESTAMP", Const, 0}, + {"SO_TIMESTAMPING", Const, 0}, + {"SO_TIMESTAMPNS", Const, 0}, + {"SO_TIMESTAMP_MONOTONIC", Const, 0}, + {"SO_TYPE", Const, 0}, + {"SO_UPCALLCLOSEWAIT", Const, 0}, + {"SO_UPDATE_ACCEPT_CONTEXT", Const, 0}, + {"SO_UPDATE_CONNECT_CONTEXT", Const, 1}, + {"SO_USELOOPBACK", Const, 0}, + {"SO_USER_COOKIE", Const, 1}, + {"SO_VENDOR", Const, 3}, + {"SO_WANTMORE", Const, 0}, + {"SO_WANTOOBFLAG", Const, 0}, + {"SSLExtraCertChainPolicyPara", Type, 0}, + {"SSLExtraCertChainPolicyPara.AuthType", Field, 0}, + {"SSLExtraCertChainPolicyPara.Checks", Field, 0}, + {"SSLExtraCertChainPolicyPara.ServerName", Field, 0}, + {"SSLExtraCertChainPolicyPara.Size", Field, 0}, + {"STANDARD_RIGHTS_ALL", Const, 0}, + {"STANDARD_RIGHTS_EXECUTE", Const, 0}, + {"STANDARD_RIGHTS_READ", Const, 0}, + {"STANDARD_RIGHTS_REQUIRED", Const, 0}, + {"STANDARD_RIGHTS_WRITE", Const, 0}, + {"STARTF_USESHOWWINDOW", Const, 0}, + {"STARTF_USESTDHANDLES", Const, 0}, + {"STD_ERROR_HANDLE", Const, 0}, + {"STD_INPUT_HANDLE", Const, 0}, + {"STD_OUTPUT_HANDLE", Const, 0}, + {"SUBLANG_ENGLISH_US", Const, 0}, + {"SW_FORCEMINIMIZE", Const, 0}, + {"SW_HIDE", Const, 0}, + {"SW_MAXIMIZE", Const, 0}, + {"SW_MINIMIZE", Const, 0}, + {"SW_NORMAL", Const, 0}, + {"SW_RESTORE", Const, 0}, + {"SW_SHOW", Const, 0}, + {"SW_SHOWDEFAULT", Const, 0}, + {"SW_SHOWMAXIMIZED", Const, 0}, + {"SW_SHOWMINIMIZED", Const, 0}, + {"SW_SHOWMINNOACTIVE", Const, 0}, + {"SW_SHOWNA", Const, 0}, + {"SW_SHOWNOACTIVATE", Const, 0}, + {"SW_SHOWNORMAL", Const, 0}, + {"SYMBOLIC_LINK_FLAG_DIRECTORY", Const, 4}, + {"SYNCHRONIZE", Const, 0}, + {"SYSCTL_VERSION", Const, 1}, + {"SYSCTL_VERS_0", Const, 1}, + {"SYSCTL_VERS_1", Const, 1}, + {"SYSCTL_VERS_MASK", Const, 1}, + {"SYS_ABORT2", Const, 0}, + {"SYS_ACCEPT", Const, 0}, + {"SYS_ACCEPT4", Const, 0}, + {"SYS_ACCEPT_NOCANCEL", Const, 0}, + {"SYS_ACCESS", Const, 0}, + {"SYS_ACCESS_EXTENDED", Const, 0}, + {"SYS_ACCT", Const, 0}, + {"SYS_ADD_KEY", Const, 0}, + {"SYS_ADD_PROFIL", Const, 0}, + {"SYS_ADJFREQ", Const, 1}, + {"SYS_ADJTIME", Const, 0}, + {"SYS_ADJTIMEX", Const, 0}, + {"SYS_AFS_SYSCALL", Const, 0}, + {"SYS_AIO_CANCEL", Const, 0}, + {"SYS_AIO_ERROR", Const, 0}, + {"SYS_AIO_FSYNC", Const, 0}, + {"SYS_AIO_MLOCK", Const, 14}, + {"SYS_AIO_READ", Const, 0}, + {"SYS_AIO_RETURN", Const, 0}, + {"SYS_AIO_SUSPEND", Const, 0}, + {"SYS_AIO_SUSPEND_NOCANCEL", Const, 0}, + {"SYS_AIO_WAITCOMPLETE", Const, 14}, + {"SYS_AIO_WRITE", Const, 0}, + {"SYS_ALARM", Const, 0}, + {"SYS_ARCH_PRCTL", Const, 0}, + {"SYS_ARM_FADVISE64_64", Const, 0}, + {"SYS_ARM_SYNC_FILE_RANGE", Const, 0}, + {"SYS_ATGETMSG", Const, 0}, + {"SYS_ATPGETREQ", Const, 0}, + {"SYS_ATPGETRSP", Const, 0}, + {"SYS_ATPSNDREQ", Const, 0}, + {"SYS_ATPSNDRSP", Const, 0}, + {"SYS_ATPUTMSG", Const, 0}, + {"SYS_ATSOCKET", Const, 0}, + {"SYS_AUDIT", Const, 0}, + {"SYS_AUDITCTL", Const, 0}, + {"SYS_AUDITON", Const, 0}, + {"SYS_AUDIT_SESSION_JOIN", Const, 0}, + {"SYS_AUDIT_SESSION_PORT", Const, 0}, + {"SYS_AUDIT_SESSION_SELF", Const, 0}, + {"SYS_BDFLUSH", Const, 0}, + {"SYS_BIND", Const, 0}, + {"SYS_BINDAT", Const, 3}, + {"SYS_BREAK", Const, 0}, + {"SYS_BRK", Const, 0}, + {"SYS_BSDTHREAD_CREATE", Const, 0}, + {"SYS_BSDTHREAD_REGISTER", Const, 0}, + {"SYS_BSDTHREAD_TERMINATE", Const, 0}, + {"SYS_CAPGET", Const, 0}, + {"SYS_CAPSET", Const, 0}, + {"SYS_CAP_ENTER", Const, 0}, + {"SYS_CAP_FCNTLS_GET", Const, 1}, + {"SYS_CAP_FCNTLS_LIMIT", Const, 1}, + {"SYS_CAP_GETMODE", Const, 0}, + {"SYS_CAP_GETRIGHTS", Const, 0}, + {"SYS_CAP_IOCTLS_GET", Const, 1}, + {"SYS_CAP_IOCTLS_LIMIT", Const, 1}, + {"SYS_CAP_NEW", Const, 0}, + {"SYS_CAP_RIGHTS_GET", Const, 1}, + {"SYS_CAP_RIGHTS_LIMIT", Const, 1}, + {"SYS_CHDIR", Const, 0}, + {"SYS_CHFLAGS", Const, 0}, + {"SYS_CHFLAGSAT", Const, 3}, + {"SYS_CHMOD", Const, 0}, + {"SYS_CHMOD_EXTENDED", Const, 0}, + {"SYS_CHOWN", Const, 0}, + {"SYS_CHOWN32", Const, 0}, + {"SYS_CHROOT", Const, 0}, + {"SYS_CHUD", Const, 0}, + {"SYS_CLOCK_ADJTIME", Const, 0}, + {"SYS_CLOCK_GETCPUCLOCKID2", Const, 1}, + {"SYS_CLOCK_GETRES", Const, 0}, + {"SYS_CLOCK_GETTIME", Const, 0}, + {"SYS_CLOCK_NANOSLEEP", Const, 0}, + {"SYS_CLOCK_SETTIME", Const, 0}, + {"SYS_CLONE", Const, 0}, + {"SYS_CLOSE", Const, 0}, + {"SYS_CLOSEFROM", Const, 0}, + {"SYS_CLOSE_NOCANCEL", Const, 0}, + {"SYS_CONNECT", Const, 0}, + {"SYS_CONNECTAT", Const, 3}, + {"SYS_CONNECT_NOCANCEL", Const, 0}, + {"SYS_COPYFILE", Const, 0}, + {"SYS_CPUSET", Const, 0}, + {"SYS_CPUSET_GETAFFINITY", Const, 0}, + {"SYS_CPUSET_GETID", Const, 0}, + {"SYS_CPUSET_SETAFFINITY", Const, 0}, + {"SYS_CPUSET_SETID", Const, 0}, + {"SYS_CREAT", Const, 0}, + {"SYS_CREATE_MODULE", Const, 0}, + {"SYS_CSOPS", Const, 0}, + {"SYS_CSOPS_AUDITTOKEN", Const, 16}, + {"SYS_DELETE", Const, 0}, + {"SYS_DELETE_MODULE", Const, 0}, + {"SYS_DUP", Const, 0}, + {"SYS_DUP2", Const, 0}, + {"SYS_DUP3", Const, 0}, + {"SYS_EACCESS", Const, 0}, + {"SYS_EPOLL_CREATE", Const, 0}, + {"SYS_EPOLL_CREATE1", Const, 0}, + {"SYS_EPOLL_CTL", Const, 0}, + {"SYS_EPOLL_CTL_OLD", Const, 0}, + {"SYS_EPOLL_PWAIT", Const, 0}, + {"SYS_EPOLL_WAIT", Const, 0}, + {"SYS_EPOLL_WAIT_OLD", Const, 0}, + {"SYS_EVENTFD", Const, 0}, + {"SYS_EVENTFD2", Const, 0}, + {"SYS_EXCHANGEDATA", Const, 0}, + {"SYS_EXECVE", Const, 0}, + {"SYS_EXIT", Const, 0}, + {"SYS_EXIT_GROUP", Const, 0}, + {"SYS_EXTATTRCTL", Const, 0}, + {"SYS_EXTATTR_DELETE_FD", Const, 0}, + {"SYS_EXTATTR_DELETE_FILE", Const, 0}, + {"SYS_EXTATTR_DELETE_LINK", Const, 0}, + {"SYS_EXTATTR_GET_FD", Const, 0}, + {"SYS_EXTATTR_GET_FILE", Const, 0}, + {"SYS_EXTATTR_GET_LINK", Const, 0}, + {"SYS_EXTATTR_LIST_FD", Const, 0}, + {"SYS_EXTATTR_LIST_FILE", Const, 0}, + {"SYS_EXTATTR_LIST_LINK", Const, 0}, + {"SYS_EXTATTR_SET_FD", Const, 0}, + {"SYS_EXTATTR_SET_FILE", Const, 0}, + {"SYS_EXTATTR_SET_LINK", Const, 0}, + {"SYS_FACCESSAT", Const, 0}, + {"SYS_FADVISE64", Const, 0}, + {"SYS_FADVISE64_64", Const, 0}, + {"SYS_FALLOCATE", Const, 0}, + {"SYS_FANOTIFY_INIT", Const, 0}, + {"SYS_FANOTIFY_MARK", Const, 0}, + {"SYS_FCHDIR", Const, 0}, + {"SYS_FCHFLAGS", Const, 0}, + {"SYS_FCHMOD", Const, 0}, + {"SYS_FCHMODAT", Const, 0}, + {"SYS_FCHMOD_EXTENDED", Const, 0}, + {"SYS_FCHOWN", Const, 0}, + {"SYS_FCHOWN32", Const, 0}, + {"SYS_FCHOWNAT", Const, 0}, + {"SYS_FCHROOT", Const, 1}, + {"SYS_FCNTL", Const, 0}, + {"SYS_FCNTL64", Const, 0}, + {"SYS_FCNTL_NOCANCEL", Const, 0}, + {"SYS_FDATASYNC", Const, 0}, + {"SYS_FEXECVE", Const, 0}, + {"SYS_FFCLOCK_GETCOUNTER", Const, 0}, + {"SYS_FFCLOCK_GETESTIMATE", Const, 0}, + {"SYS_FFCLOCK_SETESTIMATE", Const, 0}, + {"SYS_FFSCTL", Const, 0}, + {"SYS_FGETATTRLIST", Const, 0}, + {"SYS_FGETXATTR", Const, 0}, + {"SYS_FHOPEN", Const, 0}, + {"SYS_FHSTAT", Const, 0}, + {"SYS_FHSTATFS", Const, 0}, + {"SYS_FILEPORT_MAKEFD", Const, 0}, + {"SYS_FILEPORT_MAKEPORT", Const, 0}, + {"SYS_FKTRACE", Const, 1}, + {"SYS_FLISTXATTR", Const, 0}, + {"SYS_FLOCK", Const, 0}, + {"SYS_FORK", Const, 0}, + {"SYS_FPATHCONF", Const, 0}, + {"SYS_FREEBSD6_FTRUNCATE", Const, 0}, + {"SYS_FREEBSD6_LSEEK", Const, 0}, + {"SYS_FREEBSD6_MMAP", Const, 0}, + {"SYS_FREEBSD6_PREAD", Const, 0}, + {"SYS_FREEBSD6_PWRITE", Const, 0}, + {"SYS_FREEBSD6_TRUNCATE", Const, 0}, + {"SYS_FREMOVEXATTR", Const, 0}, + {"SYS_FSCTL", Const, 0}, + {"SYS_FSETATTRLIST", Const, 0}, + {"SYS_FSETXATTR", Const, 0}, + {"SYS_FSGETPATH", Const, 0}, + {"SYS_FSTAT", Const, 0}, + {"SYS_FSTAT64", Const, 0}, + {"SYS_FSTAT64_EXTENDED", Const, 0}, + {"SYS_FSTATAT", Const, 0}, + {"SYS_FSTATAT64", Const, 0}, + {"SYS_FSTATFS", Const, 0}, + {"SYS_FSTATFS64", Const, 0}, + {"SYS_FSTATV", Const, 0}, + {"SYS_FSTATVFS1", Const, 1}, + {"SYS_FSTAT_EXTENDED", Const, 0}, + {"SYS_FSYNC", Const, 0}, + {"SYS_FSYNC_NOCANCEL", Const, 0}, + {"SYS_FSYNC_RANGE", Const, 1}, + {"SYS_FTIME", Const, 0}, + {"SYS_FTRUNCATE", Const, 0}, + {"SYS_FTRUNCATE64", Const, 0}, + {"SYS_FUTEX", Const, 0}, + {"SYS_FUTIMENS", Const, 1}, + {"SYS_FUTIMES", Const, 0}, + {"SYS_FUTIMESAT", Const, 0}, + {"SYS_GETATTRLIST", Const, 0}, + {"SYS_GETAUDIT", Const, 0}, + {"SYS_GETAUDIT_ADDR", Const, 0}, + {"SYS_GETAUID", Const, 0}, + {"SYS_GETCONTEXT", Const, 0}, + {"SYS_GETCPU", Const, 0}, + {"SYS_GETCWD", Const, 0}, + {"SYS_GETDENTS", Const, 0}, + {"SYS_GETDENTS64", Const, 0}, + {"SYS_GETDIRENTRIES", Const, 0}, + {"SYS_GETDIRENTRIES64", Const, 0}, + {"SYS_GETDIRENTRIESATTR", Const, 0}, + {"SYS_GETDTABLECOUNT", Const, 1}, + {"SYS_GETDTABLESIZE", Const, 0}, + {"SYS_GETEGID", Const, 0}, + {"SYS_GETEGID32", Const, 0}, + {"SYS_GETEUID", Const, 0}, + {"SYS_GETEUID32", Const, 0}, + {"SYS_GETFH", Const, 0}, + {"SYS_GETFSSTAT", Const, 0}, + {"SYS_GETFSSTAT64", Const, 0}, + {"SYS_GETGID", Const, 0}, + {"SYS_GETGID32", Const, 0}, + {"SYS_GETGROUPS", Const, 0}, + {"SYS_GETGROUPS32", Const, 0}, + {"SYS_GETHOSTUUID", Const, 0}, + {"SYS_GETITIMER", Const, 0}, + {"SYS_GETLCID", Const, 0}, + {"SYS_GETLOGIN", Const, 0}, + {"SYS_GETLOGINCLASS", Const, 0}, + {"SYS_GETPEERNAME", Const, 0}, + {"SYS_GETPGID", Const, 0}, + {"SYS_GETPGRP", Const, 0}, + {"SYS_GETPID", Const, 0}, + {"SYS_GETPMSG", Const, 0}, + {"SYS_GETPPID", Const, 0}, + {"SYS_GETPRIORITY", Const, 0}, + {"SYS_GETRESGID", Const, 0}, + {"SYS_GETRESGID32", Const, 0}, + {"SYS_GETRESUID", Const, 0}, + {"SYS_GETRESUID32", Const, 0}, + {"SYS_GETRLIMIT", Const, 0}, + {"SYS_GETRTABLE", Const, 1}, + {"SYS_GETRUSAGE", Const, 0}, + {"SYS_GETSGROUPS", Const, 0}, + {"SYS_GETSID", Const, 0}, + {"SYS_GETSOCKNAME", Const, 0}, + {"SYS_GETSOCKOPT", Const, 0}, + {"SYS_GETTHRID", Const, 1}, + {"SYS_GETTID", Const, 0}, + {"SYS_GETTIMEOFDAY", Const, 0}, + {"SYS_GETUID", Const, 0}, + {"SYS_GETUID32", Const, 0}, + {"SYS_GETVFSSTAT", Const, 1}, + {"SYS_GETWGROUPS", Const, 0}, + {"SYS_GETXATTR", Const, 0}, + {"SYS_GET_KERNEL_SYMS", Const, 0}, + {"SYS_GET_MEMPOLICY", Const, 0}, + {"SYS_GET_ROBUST_LIST", Const, 0}, + {"SYS_GET_THREAD_AREA", Const, 0}, + {"SYS_GSSD_SYSCALL", Const, 14}, + {"SYS_GTTY", Const, 0}, + {"SYS_IDENTITYSVC", Const, 0}, + {"SYS_IDLE", Const, 0}, + {"SYS_INITGROUPS", Const, 0}, + {"SYS_INIT_MODULE", Const, 0}, + {"SYS_INOTIFY_ADD_WATCH", Const, 0}, + {"SYS_INOTIFY_INIT", Const, 0}, + {"SYS_INOTIFY_INIT1", Const, 0}, + {"SYS_INOTIFY_RM_WATCH", Const, 0}, + {"SYS_IOCTL", Const, 0}, + {"SYS_IOPERM", Const, 0}, + {"SYS_IOPL", Const, 0}, + {"SYS_IOPOLICYSYS", Const, 0}, + {"SYS_IOPRIO_GET", Const, 0}, + {"SYS_IOPRIO_SET", Const, 0}, + {"SYS_IO_CANCEL", Const, 0}, + {"SYS_IO_DESTROY", Const, 0}, + {"SYS_IO_GETEVENTS", Const, 0}, + {"SYS_IO_SETUP", Const, 0}, + {"SYS_IO_SUBMIT", Const, 0}, + {"SYS_IPC", Const, 0}, + {"SYS_ISSETUGID", Const, 0}, + {"SYS_JAIL", Const, 0}, + {"SYS_JAIL_ATTACH", Const, 0}, + {"SYS_JAIL_GET", Const, 0}, + {"SYS_JAIL_REMOVE", Const, 0}, + {"SYS_JAIL_SET", Const, 0}, + {"SYS_KAS_INFO", Const, 16}, + {"SYS_KDEBUG_TRACE", Const, 0}, + {"SYS_KENV", Const, 0}, + {"SYS_KEVENT", Const, 0}, + {"SYS_KEVENT64", Const, 0}, + {"SYS_KEXEC_LOAD", Const, 0}, + {"SYS_KEYCTL", Const, 0}, + {"SYS_KILL", Const, 0}, + {"SYS_KLDFIND", Const, 0}, + {"SYS_KLDFIRSTMOD", Const, 0}, + {"SYS_KLDLOAD", Const, 0}, + {"SYS_KLDNEXT", Const, 0}, + {"SYS_KLDSTAT", Const, 0}, + {"SYS_KLDSYM", Const, 0}, + {"SYS_KLDUNLOAD", Const, 0}, + {"SYS_KLDUNLOADF", Const, 0}, + {"SYS_KMQ_NOTIFY", Const, 14}, + {"SYS_KMQ_OPEN", Const, 14}, + {"SYS_KMQ_SETATTR", Const, 14}, + {"SYS_KMQ_TIMEDRECEIVE", Const, 14}, + {"SYS_KMQ_TIMEDSEND", Const, 14}, + {"SYS_KMQ_UNLINK", Const, 14}, + {"SYS_KQUEUE", Const, 0}, + {"SYS_KQUEUE1", Const, 1}, + {"SYS_KSEM_CLOSE", Const, 14}, + {"SYS_KSEM_DESTROY", Const, 14}, + {"SYS_KSEM_GETVALUE", Const, 14}, + {"SYS_KSEM_INIT", Const, 14}, + {"SYS_KSEM_OPEN", Const, 14}, + {"SYS_KSEM_POST", Const, 14}, + {"SYS_KSEM_TIMEDWAIT", Const, 14}, + {"SYS_KSEM_TRYWAIT", Const, 14}, + {"SYS_KSEM_UNLINK", Const, 14}, + {"SYS_KSEM_WAIT", Const, 14}, + {"SYS_KTIMER_CREATE", Const, 0}, + {"SYS_KTIMER_DELETE", Const, 0}, + {"SYS_KTIMER_GETOVERRUN", Const, 0}, + {"SYS_KTIMER_GETTIME", Const, 0}, + {"SYS_KTIMER_SETTIME", Const, 0}, + {"SYS_KTRACE", Const, 0}, + {"SYS_LCHFLAGS", Const, 0}, + {"SYS_LCHMOD", Const, 0}, + {"SYS_LCHOWN", Const, 0}, + {"SYS_LCHOWN32", Const, 0}, + {"SYS_LEDGER", Const, 16}, + {"SYS_LGETFH", Const, 0}, + {"SYS_LGETXATTR", Const, 0}, + {"SYS_LINK", Const, 0}, + {"SYS_LINKAT", Const, 0}, + {"SYS_LIO_LISTIO", Const, 0}, + {"SYS_LISTEN", Const, 0}, + {"SYS_LISTXATTR", Const, 0}, + {"SYS_LLISTXATTR", Const, 0}, + {"SYS_LOCK", Const, 0}, + {"SYS_LOOKUP_DCOOKIE", Const, 0}, + {"SYS_LPATHCONF", Const, 0}, + {"SYS_LREMOVEXATTR", Const, 0}, + {"SYS_LSEEK", Const, 0}, + {"SYS_LSETXATTR", Const, 0}, + {"SYS_LSTAT", Const, 0}, + {"SYS_LSTAT64", Const, 0}, + {"SYS_LSTAT64_EXTENDED", Const, 0}, + {"SYS_LSTATV", Const, 0}, + {"SYS_LSTAT_EXTENDED", Const, 0}, + {"SYS_LUTIMES", Const, 0}, + {"SYS_MAC_SYSCALL", Const, 0}, + {"SYS_MADVISE", Const, 0}, + {"SYS_MADVISE1", Const, 0}, + {"SYS_MAXSYSCALL", Const, 0}, + {"SYS_MBIND", Const, 0}, + {"SYS_MIGRATE_PAGES", Const, 0}, + {"SYS_MINCORE", Const, 0}, + {"SYS_MINHERIT", Const, 0}, + {"SYS_MKCOMPLEX", Const, 0}, + {"SYS_MKDIR", Const, 0}, + {"SYS_MKDIRAT", Const, 0}, + {"SYS_MKDIR_EXTENDED", Const, 0}, + {"SYS_MKFIFO", Const, 0}, + {"SYS_MKFIFOAT", Const, 0}, + {"SYS_MKFIFO_EXTENDED", Const, 0}, + {"SYS_MKNOD", Const, 0}, + {"SYS_MKNODAT", Const, 0}, + {"SYS_MLOCK", Const, 0}, + {"SYS_MLOCKALL", Const, 0}, + {"SYS_MMAP", Const, 0}, + {"SYS_MMAP2", Const, 0}, + {"SYS_MODCTL", Const, 1}, + {"SYS_MODFIND", Const, 0}, + {"SYS_MODFNEXT", Const, 0}, + {"SYS_MODIFY_LDT", Const, 0}, + {"SYS_MODNEXT", Const, 0}, + {"SYS_MODSTAT", Const, 0}, + {"SYS_MODWATCH", Const, 0}, + {"SYS_MOUNT", Const, 0}, + {"SYS_MOVE_PAGES", Const, 0}, + {"SYS_MPROTECT", Const, 0}, + {"SYS_MPX", Const, 0}, + {"SYS_MQUERY", Const, 1}, + {"SYS_MQ_GETSETATTR", Const, 0}, + {"SYS_MQ_NOTIFY", Const, 0}, + {"SYS_MQ_OPEN", Const, 0}, + {"SYS_MQ_TIMEDRECEIVE", Const, 0}, + {"SYS_MQ_TIMEDSEND", Const, 0}, + {"SYS_MQ_UNLINK", Const, 0}, + {"SYS_MREMAP", Const, 0}, + {"SYS_MSGCTL", Const, 0}, + {"SYS_MSGGET", Const, 0}, + {"SYS_MSGRCV", Const, 0}, + {"SYS_MSGRCV_NOCANCEL", Const, 0}, + {"SYS_MSGSND", Const, 0}, + {"SYS_MSGSND_NOCANCEL", Const, 0}, + {"SYS_MSGSYS", Const, 0}, + {"SYS_MSYNC", Const, 0}, + {"SYS_MSYNC_NOCANCEL", Const, 0}, + {"SYS_MUNLOCK", Const, 0}, + {"SYS_MUNLOCKALL", Const, 0}, + {"SYS_MUNMAP", Const, 0}, + {"SYS_NAME_TO_HANDLE_AT", Const, 0}, + {"SYS_NANOSLEEP", Const, 0}, + {"SYS_NEWFSTATAT", Const, 0}, + {"SYS_NFSCLNT", Const, 0}, + {"SYS_NFSSERVCTL", Const, 0}, + {"SYS_NFSSVC", Const, 0}, + {"SYS_NFSTAT", Const, 0}, + {"SYS_NICE", Const, 0}, + {"SYS_NLM_SYSCALL", Const, 14}, + {"SYS_NLSTAT", Const, 0}, + {"SYS_NMOUNT", Const, 0}, + {"SYS_NSTAT", Const, 0}, + {"SYS_NTP_ADJTIME", Const, 0}, + {"SYS_NTP_GETTIME", Const, 0}, + {"SYS_NUMA_GETAFFINITY", Const, 14}, + {"SYS_NUMA_SETAFFINITY", Const, 14}, + {"SYS_OABI_SYSCALL_BASE", Const, 0}, + {"SYS_OBREAK", Const, 0}, + {"SYS_OLDFSTAT", Const, 0}, + {"SYS_OLDLSTAT", Const, 0}, + {"SYS_OLDOLDUNAME", Const, 0}, + {"SYS_OLDSTAT", Const, 0}, + {"SYS_OLDUNAME", Const, 0}, + {"SYS_OPEN", Const, 0}, + {"SYS_OPENAT", Const, 0}, + {"SYS_OPENBSD_POLL", Const, 0}, + {"SYS_OPEN_BY_HANDLE_AT", Const, 0}, + {"SYS_OPEN_DPROTECTED_NP", Const, 16}, + {"SYS_OPEN_EXTENDED", Const, 0}, + {"SYS_OPEN_NOCANCEL", Const, 0}, + {"SYS_OVADVISE", Const, 0}, + {"SYS_PACCEPT", Const, 1}, + {"SYS_PATHCONF", Const, 0}, + {"SYS_PAUSE", Const, 0}, + {"SYS_PCICONFIG_IOBASE", Const, 0}, + {"SYS_PCICONFIG_READ", Const, 0}, + {"SYS_PCICONFIG_WRITE", Const, 0}, + {"SYS_PDFORK", Const, 0}, + {"SYS_PDGETPID", Const, 0}, + {"SYS_PDKILL", Const, 0}, + {"SYS_PERF_EVENT_OPEN", Const, 0}, + {"SYS_PERSONALITY", Const, 0}, + {"SYS_PID_HIBERNATE", Const, 0}, + {"SYS_PID_RESUME", Const, 0}, + {"SYS_PID_SHUTDOWN_SOCKETS", Const, 0}, + {"SYS_PID_SUSPEND", Const, 0}, + {"SYS_PIPE", Const, 0}, + {"SYS_PIPE2", Const, 0}, + {"SYS_PIVOT_ROOT", Const, 0}, + {"SYS_PMC_CONTROL", Const, 1}, + {"SYS_PMC_GET_INFO", Const, 1}, + {"SYS_POLL", Const, 0}, + {"SYS_POLLTS", Const, 1}, + {"SYS_POLL_NOCANCEL", Const, 0}, + {"SYS_POSIX_FADVISE", Const, 0}, + {"SYS_POSIX_FALLOCATE", Const, 0}, + {"SYS_POSIX_OPENPT", Const, 0}, + {"SYS_POSIX_SPAWN", Const, 0}, + {"SYS_PPOLL", Const, 0}, + {"SYS_PRCTL", Const, 0}, + {"SYS_PREAD", Const, 0}, + {"SYS_PREAD64", Const, 0}, + {"SYS_PREADV", Const, 0}, + {"SYS_PREAD_NOCANCEL", Const, 0}, + {"SYS_PRLIMIT64", Const, 0}, + {"SYS_PROCCTL", Const, 3}, + {"SYS_PROCESS_POLICY", Const, 0}, + {"SYS_PROCESS_VM_READV", Const, 0}, + {"SYS_PROCESS_VM_WRITEV", Const, 0}, + {"SYS_PROC_INFO", Const, 0}, + {"SYS_PROF", Const, 0}, + {"SYS_PROFIL", Const, 0}, + {"SYS_PSELECT", Const, 0}, + {"SYS_PSELECT6", Const, 0}, + {"SYS_PSET_ASSIGN", Const, 1}, + {"SYS_PSET_CREATE", Const, 1}, + {"SYS_PSET_DESTROY", Const, 1}, + {"SYS_PSYNCH_CVBROAD", Const, 0}, + {"SYS_PSYNCH_CVCLRPREPOST", Const, 0}, + {"SYS_PSYNCH_CVSIGNAL", Const, 0}, + {"SYS_PSYNCH_CVWAIT", Const, 0}, + {"SYS_PSYNCH_MUTEXDROP", Const, 0}, + {"SYS_PSYNCH_MUTEXWAIT", Const, 0}, + {"SYS_PSYNCH_RW_DOWNGRADE", Const, 0}, + {"SYS_PSYNCH_RW_LONGRDLOCK", Const, 0}, + {"SYS_PSYNCH_RW_RDLOCK", Const, 0}, + {"SYS_PSYNCH_RW_UNLOCK", Const, 0}, + {"SYS_PSYNCH_RW_UNLOCK2", Const, 0}, + {"SYS_PSYNCH_RW_UPGRADE", Const, 0}, + {"SYS_PSYNCH_RW_WRLOCK", Const, 0}, + {"SYS_PSYNCH_RW_YIELDWRLOCK", Const, 0}, + {"SYS_PTRACE", Const, 0}, + {"SYS_PUTPMSG", Const, 0}, + {"SYS_PWRITE", Const, 0}, + {"SYS_PWRITE64", Const, 0}, + {"SYS_PWRITEV", Const, 0}, + {"SYS_PWRITE_NOCANCEL", Const, 0}, + {"SYS_QUERY_MODULE", Const, 0}, + {"SYS_QUOTACTL", Const, 0}, + {"SYS_RASCTL", Const, 1}, + {"SYS_RCTL_ADD_RULE", Const, 0}, + {"SYS_RCTL_GET_LIMITS", Const, 0}, + {"SYS_RCTL_GET_RACCT", Const, 0}, + {"SYS_RCTL_GET_RULES", Const, 0}, + {"SYS_RCTL_REMOVE_RULE", Const, 0}, + {"SYS_READ", Const, 0}, + {"SYS_READAHEAD", Const, 0}, + {"SYS_READDIR", Const, 0}, + {"SYS_READLINK", Const, 0}, + {"SYS_READLINKAT", Const, 0}, + {"SYS_READV", Const, 0}, + {"SYS_READV_NOCANCEL", Const, 0}, + {"SYS_READ_NOCANCEL", Const, 0}, + {"SYS_REBOOT", Const, 0}, + {"SYS_RECV", Const, 0}, + {"SYS_RECVFROM", Const, 0}, + {"SYS_RECVFROM_NOCANCEL", Const, 0}, + {"SYS_RECVMMSG", Const, 0}, + {"SYS_RECVMSG", Const, 0}, + {"SYS_RECVMSG_NOCANCEL", Const, 0}, + {"SYS_REMAP_FILE_PAGES", Const, 0}, + {"SYS_REMOVEXATTR", Const, 0}, + {"SYS_RENAME", Const, 0}, + {"SYS_RENAMEAT", Const, 0}, + {"SYS_REQUEST_KEY", Const, 0}, + {"SYS_RESTART_SYSCALL", Const, 0}, + {"SYS_REVOKE", Const, 0}, + {"SYS_RFORK", Const, 0}, + {"SYS_RMDIR", Const, 0}, + {"SYS_RTPRIO", Const, 0}, + {"SYS_RTPRIO_THREAD", Const, 0}, + {"SYS_RT_SIGACTION", Const, 0}, + {"SYS_RT_SIGPENDING", Const, 0}, + {"SYS_RT_SIGPROCMASK", Const, 0}, + {"SYS_RT_SIGQUEUEINFO", Const, 0}, + {"SYS_RT_SIGRETURN", Const, 0}, + {"SYS_RT_SIGSUSPEND", Const, 0}, + {"SYS_RT_SIGTIMEDWAIT", Const, 0}, + {"SYS_RT_TGSIGQUEUEINFO", Const, 0}, + {"SYS_SBRK", Const, 0}, + {"SYS_SCHED_GETAFFINITY", Const, 0}, + {"SYS_SCHED_GETPARAM", Const, 0}, + {"SYS_SCHED_GETSCHEDULER", Const, 0}, + {"SYS_SCHED_GET_PRIORITY_MAX", Const, 0}, + {"SYS_SCHED_GET_PRIORITY_MIN", Const, 0}, + {"SYS_SCHED_RR_GET_INTERVAL", Const, 0}, + {"SYS_SCHED_SETAFFINITY", Const, 0}, + {"SYS_SCHED_SETPARAM", Const, 0}, + {"SYS_SCHED_SETSCHEDULER", Const, 0}, + {"SYS_SCHED_YIELD", Const, 0}, + {"SYS_SCTP_GENERIC_RECVMSG", Const, 0}, + {"SYS_SCTP_GENERIC_SENDMSG", Const, 0}, + {"SYS_SCTP_GENERIC_SENDMSG_IOV", Const, 0}, + {"SYS_SCTP_PEELOFF", Const, 0}, + {"SYS_SEARCHFS", Const, 0}, + {"SYS_SECURITY", Const, 0}, + {"SYS_SELECT", Const, 0}, + {"SYS_SELECT_NOCANCEL", Const, 0}, + {"SYS_SEMCONFIG", Const, 1}, + {"SYS_SEMCTL", Const, 0}, + {"SYS_SEMGET", Const, 0}, + {"SYS_SEMOP", Const, 0}, + {"SYS_SEMSYS", Const, 0}, + {"SYS_SEMTIMEDOP", Const, 0}, + {"SYS_SEM_CLOSE", Const, 0}, + {"SYS_SEM_DESTROY", Const, 0}, + {"SYS_SEM_GETVALUE", Const, 0}, + {"SYS_SEM_INIT", Const, 0}, + {"SYS_SEM_OPEN", Const, 0}, + {"SYS_SEM_POST", Const, 0}, + {"SYS_SEM_TRYWAIT", Const, 0}, + {"SYS_SEM_UNLINK", Const, 0}, + {"SYS_SEM_WAIT", Const, 0}, + {"SYS_SEM_WAIT_NOCANCEL", Const, 0}, + {"SYS_SEND", Const, 0}, + {"SYS_SENDFILE", Const, 0}, + {"SYS_SENDFILE64", Const, 0}, + {"SYS_SENDMMSG", Const, 0}, + {"SYS_SENDMSG", Const, 0}, + {"SYS_SENDMSG_NOCANCEL", Const, 0}, + {"SYS_SENDTO", Const, 0}, + {"SYS_SENDTO_NOCANCEL", Const, 0}, + {"SYS_SETATTRLIST", Const, 0}, + {"SYS_SETAUDIT", Const, 0}, + {"SYS_SETAUDIT_ADDR", Const, 0}, + {"SYS_SETAUID", Const, 0}, + {"SYS_SETCONTEXT", Const, 0}, + {"SYS_SETDOMAINNAME", Const, 0}, + {"SYS_SETEGID", Const, 0}, + {"SYS_SETEUID", Const, 0}, + {"SYS_SETFIB", Const, 0}, + {"SYS_SETFSGID", Const, 0}, + {"SYS_SETFSGID32", Const, 0}, + {"SYS_SETFSUID", Const, 0}, + {"SYS_SETFSUID32", Const, 0}, + {"SYS_SETGID", Const, 0}, + {"SYS_SETGID32", Const, 0}, + {"SYS_SETGROUPS", Const, 0}, + {"SYS_SETGROUPS32", Const, 0}, + {"SYS_SETHOSTNAME", Const, 0}, + {"SYS_SETITIMER", Const, 0}, + {"SYS_SETLCID", Const, 0}, + {"SYS_SETLOGIN", Const, 0}, + {"SYS_SETLOGINCLASS", Const, 0}, + {"SYS_SETNS", Const, 0}, + {"SYS_SETPGID", Const, 0}, + {"SYS_SETPRIORITY", Const, 0}, + {"SYS_SETPRIVEXEC", Const, 0}, + {"SYS_SETREGID", Const, 0}, + {"SYS_SETREGID32", Const, 0}, + {"SYS_SETRESGID", Const, 0}, + {"SYS_SETRESGID32", Const, 0}, + {"SYS_SETRESUID", Const, 0}, + {"SYS_SETRESUID32", Const, 0}, + {"SYS_SETREUID", Const, 0}, + {"SYS_SETREUID32", Const, 0}, + {"SYS_SETRLIMIT", Const, 0}, + {"SYS_SETRTABLE", Const, 1}, + {"SYS_SETSGROUPS", Const, 0}, + {"SYS_SETSID", Const, 0}, + {"SYS_SETSOCKOPT", Const, 0}, + {"SYS_SETTID", Const, 0}, + {"SYS_SETTID_WITH_PID", Const, 0}, + {"SYS_SETTIMEOFDAY", Const, 0}, + {"SYS_SETUID", Const, 0}, + {"SYS_SETUID32", Const, 0}, + {"SYS_SETWGROUPS", Const, 0}, + {"SYS_SETXATTR", Const, 0}, + {"SYS_SET_MEMPOLICY", Const, 0}, + {"SYS_SET_ROBUST_LIST", Const, 0}, + {"SYS_SET_THREAD_AREA", Const, 0}, + {"SYS_SET_TID_ADDRESS", Const, 0}, + {"SYS_SGETMASK", Const, 0}, + {"SYS_SHARED_REGION_CHECK_NP", Const, 0}, + {"SYS_SHARED_REGION_MAP_AND_SLIDE_NP", Const, 0}, + {"SYS_SHMAT", Const, 0}, + {"SYS_SHMCTL", Const, 0}, + {"SYS_SHMDT", Const, 0}, + {"SYS_SHMGET", Const, 0}, + {"SYS_SHMSYS", Const, 0}, + {"SYS_SHM_OPEN", Const, 0}, + {"SYS_SHM_UNLINK", Const, 0}, + {"SYS_SHUTDOWN", Const, 0}, + {"SYS_SIGACTION", Const, 0}, + {"SYS_SIGALTSTACK", Const, 0}, + {"SYS_SIGNAL", Const, 0}, + {"SYS_SIGNALFD", Const, 0}, + {"SYS_SIGNALFD4", Const, 0}, + {"SYS_SIGPENDING", Const, 0}, + {"SYS_SIGPROCMASK", Const, 0}, + {"SYS_SIGQUEUE", Const, 0}, + {"SYS_SIGQUEUEINFO", Const, 1}, + {"SYS_SIGRETURN", Const, 0}, + {"SYS_SIGSUSPEND", Const, 0}, + {"SYS_SIGSUSPEND_NOCANCEL", Const, 0}, + {"SYS_SIGTIMEDWAIT", Const, 0}, + {"SYS_SIGWAIT", Const, 0}, + {"SYS_SIGWAITINFO", Const, 0}, + {"SYS_SOCKET", Const, 0}, + {"SYS_SOCKETCALL", Const, 0}, + {"SYS_SOCKETPAIR", Const, 0}, + {"SYS_SPLICE", Const, 0}, + {"SYS_SSETMASK", Const, 0}, + {"SYS_SSTK", Const, 0}, + {"SYS_STACK_SNAPSHOT", Const, 0}, + {"SYS_STAT", Const, 0}, + {"SYS_STAT64", Const, 0}, + {"SYS_STAT64_EXTENDED", Const, 0}, + {"SYS_STATFS", Const, 0}, + {"SYS_STATFS64", Const, 0}, + {"SYS_STATV", Const, 0}, + {"SYS_STATVFS1", Const, 1}, + {"SYS_STAT_EXTENDED", Const, 0}, + {"SYS_STIME", Const, 0}, + {"SYS_STTY", Const, 0}, + {"SYS_SWAPCONTEXT", Const, 0}, + {"SYS_SWAPCTL", Const, 1}, + {"SYS_SWAPOFF", Const, 0}, + {"SYS_SWAPON", Const, 0}, + {"SYS_SYMLINK", Const, 0}, + {"SYS_SYMLINKAT", Const, 0}, + {"SYS_SYNC", Const, 0}, + {"SYS_SYNCFS", Const, 0}, + {"SYS_SYNC_FILE_RANGE", Const, 0}, + {"SYS_SYSARCH", Const, 0}, + {"SYS_SYSCALL", Const, 0}, + {"SYS_SYSCALL_BASE", Const, 0}, + {"SYS_SYSFS", Const, 0}, + {"SYS_SYSINFO", Const, 0}, + {"SYS_SYSLOG", Const, 0}, + {"SYS_TEE", Const, 0}, + {"SYS_TGKILL", Const, 0}, + {"SYS_THREAD_SELFID", Const, 0}, + {"SYS_THR_CREATE", Const, 0}, + {"SYS_THR_EXIT", Const, 0}, + {"SYS_THR_KILL", Const, 0}, + {"SYS_THR_KILL2", Const, 0}, + {"SYS_THR_NEW", Const, 0}, + {"SYS_THR_SELF", Const, 0}, + {"SYS_THR_SET_NAME", Const, 0}, + {"SYS_THR_SUSPEND", Const, 0}, + {"SYS_THR_WAKE", Const, 0}, + {"SYS_TIME", Const, 0}, + {"SYS_TIMERFD_CREATE", Const, 0}, + {"SYS_TIMERFD_GETTIME", Const, 0}, + {"SYS_TIMERFD_SETTIME", Const, 0}, + {"SYS_TIMER_CREATE", Const, 0}, + {"SYS_TIMER_DELETE", Const, 0}, + {"SYS_TIMER_GETOVERRUN", Const, 0}, + {"SYS_TIMER_GETTIME", Const, 0}, + {"SYS_TIMER_SETTIME", Const, 0}, + {"SYS_TIMES", Const, 0}, + {"SYS_TKILL", Const, 0}, + {"SYS_TRUNCATE", Const, 0}, + {"SYS_TRUNCATE64", Const, 0}, + {"SYS_TUXCALL", Const, 0}, + {"SYS_UGETRLIMIT", Const, 0}, + {"SYS_ULIMIT", Const, 0}, + {"SYS_UMASK", Const, 0}, + {"SYS_UMASK_EXTENDED", Const, 0}, + {"SYS_UMOUNT", Const, 0}, + {"SYS_UMOUNT2", Const, 0}, + {"SYS_UNAME", Const, 0}, + {"SYS_UNDELETE", Const, 0}, + {"SYS_UNLINK", Const, 0}, + {"SYS_UNLINKAT", Const, 0}, + {"SYS_UNMOUNT", Const, 0}, + {"SYS_UNSHARE", Const, 0}, + {"SYS_USELIB", Const, 0}, + {"SYS_USTAT", Const, 0}, + {"SYS_UTIME", Const, 0}, + {"SYS_UTIMENSAT", Const, 0}, + {"SYS_UTIMES", Const, 0}, + {"SYS_UTRACE", Const, 0}, + {"SYS_UUIDGEN", Const, 0}, + {"SYS_VADVISE", Const, 1}, + {"SYS_VFORK", Const, 0}, + {"SYS_VHANGUP", Const, 0}, + {"SYS_VM86", Const, 0}, + {"SYS_VM86OLD", Const, 0}, + {"SYS_VMSPLICE", Const, 0}, + {"SYS_VM_PRESSURE_MONITOR", Const, 0}, + {"SYS_VSERVER", Const, 0}, + {"SYS_WAIT4", Const, 0}, + {"SYS_WAIT4_NOCANCEL", Const, 0}, + {"SYS_WAIT6", Const, 1}, + {"SYS_WAITEVENT", Const, 0}, + {"SYS_WAITID", Const, 0}, + {"SYS_WAITID_NOCANCEL", Const, 0}, + {"SYS_WAITPID", Const, 0}, + {"SYS_WATCHEVENT", Const, 0}, + {"SYS_WORKQ_KERNRETURN", Const, 0}, + {"SYS_WORKQ_OPEN", Const, 0}, + {"SYS_WRITE", Const, 0}, + {"SYS_WRITEV", Const, 0}, + {"SYS_WRITEV_NOCANCEL", Const, 0}, + {"SYS_WRITE_NOCANCEL", Const, 0}, + {"SYS_YIELD", Const, 0}, + {"SYS__LLSEEK", Const, 0}, + {"SYS__LWP_CONTINUE", Const, 1}, + {"SYS__LWP_CREATE", Const, 1}, + {"SYS__LWP_CTL", Const, 1}, + {"SYS__LWP_DETACH", Const, 1}, + {"SYS__LWP_EXIT", Const, 1}, + {"SYS__LWP_GETNAME", Const, 1}, + {"SYS__LWP_GETPRIVATE", Const, 1}, + {"SYS__LWP_KILL", Const, 1}, + {"SYS__LWP_PARK", Const, 1}, + {"SYS__LWP_SELF", Const, 1}, + {"SYS__LWP_SETNAME", Const, 1}, + {"SYS__LWP_SETPRIVATE", Const, 1}, + {"SYS__LWP_SUSPEND", Const, 1}, + {"SYS__LWP_UNPARK", Const, 1}, + {"SYS__LWP_UNPARK_ALL", Const, 1}, + {"SYS__LWP_WAIT", Const, 1}, + {"SYS__LWP_WAKEUP", Const, 1}, + {"SYS__NEWSELECT", Const, 0}, + {"SYS__PSET_BIND", Const, 1}, + {"SYS__SCHED_GETAFFINITY", Const, 1}, + {"SYS__SCHED_GETPARAM", Const, 1}, + {"SYS__SCHED_SETAFFINITY", Const, 1}, + {"SYS__SCHED_SETPARAM", Const, 1}, + {"SYS__SYSCTL", Const, 0}, + {"SYS__UMTX_LOCK", Const, 0}, + {"SYS__UMTX_OP", Const, 0}, + {"SYS__UMTX_UNLOCK", Const, 0}, + {"SYS___ACL_ACLCHECK_FD", Const, 0}, + {"SYS___ACL_ACLCHECK_FILE", Const, 0}, + {"SYS___ACL_ACLCHECK_LINK", Const, 0}, + {"SYS___ACL_DELETE_FD", Const, 0}, + {"SYS___ACL_DELETE_FILE", Const, 0}, + {"SYS___ACL_DELETE_LINK", Const, 0}, + {"SYS___ACL_GET_FD", Const, 0}, + {"SYS___ACL_GET_FILE", Const, 0}, + {"SYS___ACL_GET_LINK", Const, 0}, + {"SYS___ACL_SET_FD", Const, 0}, + {"SYS___ACL_SET_FILE", Const, 0}, + {"SYS___ACL_SET_LINK", Const, 0}, + {"SYS___CAP_RIGHTS_GET", Const, 14}, + {"SYS___CLONE", Const, 1}, + {"SYS___DISABLE_THREADSIGNAL", Const, 0}, + {"SYS___GETCWD", Const, 0}, + {"SYS___GETLOGIN", Const, 1}, + {"SYS___GET_TCB", Const, 1}, + {"SYS___MAC_EXECVE", Const, 0}, + {"SYS___MAC_GETFSSTAT", Const, 0}, + {"SYS___MAC_GET_FD", Const, 0}, + {"SYS___MAC_GET_FILE", Const, 0}, + {"SYS___MAC_GET_LCID", Const, 0}, + {"SYS___MAC_GET_LCTX", Const, 0}, + {"SYS___MAC_GET_LINK", Const, 0}, + {"SYS___MAC_GET_MOUNT", Const, 0}, + {"SYS___MAC_GET_PID", Const, 0}, + {"SYS___MAC_GET_PROC", Const, 0}, + {"SYS___MAC_MOUNT", Const, 0}, + {"SYS___MAC_SET_FD", Const, 0}, + {"SYS___MAC_SET_FILE", Const, 0}, + {"SYS___MAC_SET_LCTX", Const, 0}, + {"SYS___MAC_SET_LINK", Const, 0}, + {"SYS___MAC_SET_PROC", Const, 0}, + {"SYS___MAC_SYSCALL", Const, 0}, + {"SYS___OLD_SEMWAIT_SIGNAL", Const, 0}, + {"SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL", Const, 0}, + {"SYS___POSIX_CHOWN", Const, 1}, + {"SYS___POSIX_FCHOWN", Const, 1}, + {"SYS___POSIX_LCHOWN", Const, 1}, + {"SYS___POSIX_RENAME", Const, 1}, + {"SYS___PTHREAD_CANCELED", Const, 0}, + {"SYS___PTHREAD_CHDIR", Const, 0}, + {"SYS___PTHREAD_FCHDIR", Const, 0}, + {"SYS___PTHREAD_KILL", Const, 0}, + {"SYS___PTHREAD_MARKCANCEL", Const, 0}, + {"SYS___PTHREAD_SIGMASK", Const, 0}, + {"SYS___QUOTACTL", Const, 1}, + {"SYS___SEMCTL", Const, 1}, + {"SYS___SEMWAIT_SIGNAL", Const, 0}, + {"SYS___SEMWAIT_SIGNAL_NOCANCEL", Const, 0}, + {"SYS___SETLOGIN", Const, 1}, + {"SYS___SETUGID", Const, 0}, + {"SYS___SET_TCB", Const, 1}, + {"SYS___SIGACTION_SIGTRAMP", Const, 1}, + {"SYS___SIGTIMEDWAIT", Const, 1}, + {"SYS___SIGWAIT", Const, 0}, + {"SYS___SIGWAIT_NOCANCEL", Const, 0}, + {"SYS___SYSCTL", Const, 0}, + {"SYS___TFORK", Const, 1}, + {"SYS___THREXIT", Const, 1}, + {"SYS___THRSIGDIVERT", Const, 1}, + {"SYS___THRSLEEP", Const, 1}, + {"SYS___THRWAKEUP", Const, 1}, + {"S_ARCH1", Const, 1}, + {"S_ARCH2", Const, 1}, + {"S_BLKSIZE", Const, 0}, + {"S_IEXEC", Const, 0}, + {"S_IFBLK", Const, 0}, + {"S_IFCHR", Const, 0}, + {"S_IFDIR", Const, 0}, + {"S_IFIFO", Const, 0}, + {"S_IFLNK", Const, 0}, + {"S_IFMT", Const, 0}, + {"S_IFREG", Const, 0}, + {"S_IFSOCK", Const, 0}, + {"S_IFWHT", Const, 0}, + {"S_IREAD", Const, 0}, + {"S_IRGRP", Const, 0}, + {"S_IROTH", Const, 0}, + {"S_IRUSR", Const, 0}, + {"S_IRWXG", Const, 0}, + {"S_IRWXO", Const, 0}, + {"S_IRWXU", Const, 0}, + {"S_ISGID", Const, 0}, + {"S_ISTXT", Const, 0}, + {"S_ISUID", Const, 0}, + {"S_ISVTX", Const, 0}, + {"S_IWGRP", Const, 0}, + {"S_IWOTH", Const, 0}, + {"S_IWRITE", Const, 0}, + {"S_IWUSR", Const, 0}, + {"S_IXGRP", Const, 0}, + {"S_IXOTH", Const, 0}, + {"S_IXUSR", Const, 0}, + {"S_LOGIN_SET", Const, 1}, + {"SecurityAttributes", Type, 0}, + {"SecurityAttributes.InheritHandle", Field, 0}, + {"SecurityAttributes.Length", Field, 0}, + {"SecurityAttributes.SecurityDescriptor", Field, 0}, + {"Seek", Func, 0}, + {"Select", Func, 0}, + {"Sendfile", Func, 0}, + {"Sendmsg", Func, 0}, + {"SendmsgN", Func, 3}, + {"Sendto", Func, 0}, + {"Servent", Type, 0}, + {"Servent.Aliases", Field, 0}, + {"Servent.Name", Field, 0}, + {"Servent.Port", Field, 0}, + {"Servent.Proto", Field, 0}, + {"SetBpf", Func, 0}, + {"SetBpfBuflen", Func, 0}, + {"SetBpfDatalink", Func, 0}, + {"SetBpfHeadercmpl", Func, 0}, + {"SetBpfImmediate", Func, 0}, + {"SetBpfInterface", Func, 0}, + {"SetBpfPromisc", Func, 0}, + {"SetBpfTimeout", Func, 0}, + {"SetCurrentDirectory", Func, 0}, + {"SetEndOfFile", Func, 0}, + {"SetEnvironmentVariable", Func, 0}, + {"SetFileAttributes", Func, 0}, + {"SetFileCompletionNotificationModes", Func, 2}, + {"SetFilePointer", Func, 0}, + {"SetFileTime", Func, 0}, + {"SetHandleInformation", Func, 0}, + {"SetKevent", Func, 0}, + {"SetLsfPromisc", Func, 0}, + {"SetNonblock", Func, 0}, + {"Setdomainname", Func, 0}, + {"Setegid", Func, 0}, + {"Setenv", Func, 0}, + {"Seteuid", Func, 0}, + {"Setfsgid", Func, 0}, + {"Setfsuid", Func, 0}, + {"Setgid", Func, 0}, + {"Setgroups", Func, 0}, + {"Sethostname", Func, 0}, + {"Setlogin", Func, 0}, + {"Setpgid", Func, 0}, + {"Setpriority", Func, 0}, + {"Setprivexec", Func, 0}, + {"Setregid", Func, 0}, + {"Setresgid", Func, 0}, + {"Setresuid", Func, 0}, + {"Setreuid", Func, 0}, + {"Setrlimit", Func, 0}, + {"Setsid", Func, 0}, + {"Setsockopt", Func, 0}, + {"SetsockoptByte", Func, 0}, + {"SetsockoptICMPv6Filter", Func, 2}, + {"SetsockoptIPMreq", Func, 0}, + {"SetsockoptIPMreqn", Func, 0}, + {"SetsockoptIPv6Mreq", Func, 0}, + {"SetsockoptInet4Addr", Func, 0}, + {"SetsockoptInt", Func, 0}, + {"SetsockoptLinger", Func, 0}, + {"SetsockoptString", Func, 0}, + {"SetsockoptTimeval", Func, 0}, + {"Settimeofday", Func, 0}, + {"Setuid", Func, 0}, + {"Setxattr", Func, 1}, + {"Shutdown", Func, 0}, + {"SidTypeAlias", Const, 0}, + {"SidTypeComputer", Const, 0}, + {"SidTypeDeletedAccount", Const, 0}, + {"SidTypeDomain", Const, 0}, + {"SidTypeGroup", Const, 0}, + {"SidTypeInvalid", Const, 0}, + {"SidTypeLabel", Const, 0}, + {"SidTypeUnknown", Const, 0}, + {"SidTypeUser", Const, 0}, + {"SidTypeWellKnownGroup", Const, 0}, + {"Signal", Type, 0}, + {"SizeofBpfHdr", Const, 0}, + {"SizeofBpfInsn", Const, 0}, + {"SizeofBpfProgram", Const, 0}, + {"SizeofBpfStat", Const, 0}, + {"SizeofBpfVersion", Const, 0}, + {"SizeofBpfZbuf", Const, 0}, + {"SizeofBpfZbufHeader", Const, 0}, + {"SizeofCmsghdr", Const, 0}, + {"SizeofICMPv6Filter", Const, 2}, + {"SizeofIPMreq", Const, 0}, + {"SizeofIPMreqn", Const, 0}, + {"SizeofIPv6MTUInfo", Const, 2}, + {"SizeofIPv6Mreq", Const, 0}, + {"SizeofIfAddrmsg", Const, 0}, + {"SizeofIfAnnounceMsghdr", Const, 1}, + {"SizeofIfData", Const, 0}, + {"SizeofIfInfomsg", Const, 0}, + {"SizeofIfMsghdr", Const, 0}, + {"SizeofIfaMsghdr", Const, 0}, + {"SizeofIfmaMsghdr", Const, 0}, + {"SizeofIfmaMsghdr2", Const, 0}, + {"SizeofInet4Pktinfo", Const, 0}, + {"SizeofInet6Pktinfo", Const, 0}, + {"SizeofInotifyEvent", Const, 0}, + {"SizeofLinger", Const, 0}, + {"SizeofMsghdr", Const, 0}, + {"SizeofNlAttr", Const, 0}, + {"SizeofNlMsgerr", Const, 0}, + {"SizeofNlMsghdr", Const, 0}, + {"SizeofRtAttr", Const, 0}, + {"SizeofRtGenmsg", Const, 0}, + {"SizeofRtMetrics", Const, 0}, + {"SizeofRtMsg", Const, 0}, + {"SizeofRtMsghdr", Const, 0}, + {"SizeofRtNexthop", Const, 0}, + {"SizeofSockFilter", Const, 0}, + {"SizeofSockFprog", Const, 0}, + {"SizeofSockaddrAny", Const, 0}, + {"SizeofSockaddrDatalink", Const, 0}, + {"SizeofSockaddrInet4", Const, 0}, + {"SizeofSockaddrInet6", Const, 0}, + {"SizeofSockaddrLinklayer", Const, 0}, + {"SizeofSockaddrNetlink", Const, 0}, + {"SizeofSockaddrUnix", Const, 0}, + {"SizeofTCPInfo", Const, 1}, + {"SizeofUcred", Const, 0}, + {"SlicePtrFromStrings", Func, 1}, + {"SockFilter", Type, 0}, + {"SockFilter.Code", Field, 0}, + {"SockFilter.Jf", Field, 0}, + {"SockFilter.Jt", Field, 0}, + {"SockFilter.K", Field, 0}, + {"SockFprog", Type, 0}, + {"SockFprog.Filter", Field, 0}, + {"SockFprog.Len", Field, 0}, + {"SockFprog.Pad_cgo_0", Field, 0}, + {"Sockaddr", Type, 0}, + {"SockaddrDatalink", Type, 0}, + {"SockaddrDatalink.Alen", Field, 0}, + {"SockaddrDatalink.Data", Field, 0}, + {"SockaddrDatalink.Family", Field, 0}, + {"SockaddrDatalink.Index", Field, 0}, + {"SockaddrDatalink.Len", Field, 0}, + {"SockaddrDatalink.Nlen", Field, 0}, + {"SockaddrDatalink.Slen", Field, 0}, + {"SockaddrDatalink.Type", Field, 0}, + {"SockaddrGen", Type, 0}, + {"SockaddrInet4", Type, 0}, + {"SockaddrInet4.Addr", Field, 0}, + {"SockaddrInet4.Port", Field, 0}, + {"SockaddrInet6", Type, 0}, + {"SockaddrInet6.Addr", Field, 0}, + {"SockaddrInet6.Port", Field, 0}, + {"SockaddrInet6.ZoneId", Field, 0}, + {"SockaddrLinklayer", Type, 0}, + {"SockaddrLinklayer.Addr", Field, 0}, + {"SockaddrLinklayer.Halen", Field, 0}, + {"SockaddrLinklayer.Hatype", Field, 0}, + {"SockaddrLinklayer.Ifindex", Field, 0}, + {"SockaddrLinklayer.Pkttype", Field, 0}, + {"SockaddrLinklayer.Protocol", Field, 0}, + {"SockaddrNetlink", Type, 0}, + {"SockaddrNetlink.Family", Field, 0}, + {"SockaddrNetlink.Groups", Field, 0}, + {"SockaddrNetlink.Pad", Field, 0}, + {"SockaddrNetlink.Pid", Field, 0}, + {"SockaddrUnix", Type, 0}, + {"SockaddrUnix.Name", Field, 0}, + {"Socket", Func, 0}, + {"SocketControlMessage", Type, 0}, + {"SocketControlMessage.Data", Field, 0}, + {"SocketControlMessage.Header", Field, 0}, + {"SocketDisableIPv6", Var, 0}, + {"Socketpair", Func, 0}, + {"Splice", Func, 0}, + {"StartProcess", Func, 0}, + {"StartupInfo", Type, 0}, + {"StartupInfo.Cb", Field, 0}, + {"StartupInfo.Desktop", Field, 0}, + {"StartupInfo.FillAttribute", Field, 0}, + {"StartupInfo.Flags", Field, 0}, + {"StartupInfo.ShowWindow", Field, 0}, + {"StartupInfo.StdErr", Field, 0}, + {"StartupInfo.StdInput", Field, 0}, + {"StartupInfo.StdOutput", Field, 0}, + {"StartupInfo.Title", Field, 0}, + {"StartupInfo.X", Field, 0}, + {"StartupInfo.XCountChars", Field, 0}, + {"StartupInfo.XSize", Field, 0}, + {"StartupInfo.Y", Field, 0}, + {"StartupInfo.YCountChars", Field, 0}, + {"StartupInfo.YSize", Field, 0}, + {"Stat", Func, 0}, + {"Stat_t", Type, 0}, + {"Stat_t.Atim", Field, 0}, + {"Stat_t.Atim_ext", Field, 12}, + {"Stat_t.Atimespec", Field, 0}, + {"Stat_t.Birthtimespec", Field, 0}, + {"Stat_t.Blksize", Field, 0}, + {"Stat_t.Blocks", Field, 0}, + {"Stat_t.Btim_ext", Field, 12}, + {"Stat_t.Ctim", Field, 0}, + {"Stat_t.Ctim_ext", Field, 12}, + {"Stat_t.Ctimespec", Field, 0}, + {"Stat_t.Dev", Field, 0}, + {"Stat_t.Flags", Field, 0}, + {"Stat_t.Gen", Field, 0}, + {"Stat_t.Gid", Field, 0}, + {"Stat_t.Ino", Field, 0}, + {"Stat_t.Lspare", Field, 0}, + {"Stat_t.Lspare0", Field, 2}, + {"Stat_t.Lspare1", Field, 2}, + {"Stat_t.Mode", Field, 0}, + {"Stat_t.Mtim", Field, 0}, + {"Stat_t.Mtim_ext", Field, 12}, + {"Stat_t.Mtimespec", Field, 0}, + {"Stat_t.Nlink", Field, 0}, + {"Stat_t.Pad_cgo_0", Field, 0}, + {"Stat_t.Pad_cgo_1", Field, 0}, + {"Stat_t.Pad_cgo_2", Field, 0}, + {"Stat_t.Padding0", Field, 12}, + {"Stat_t.Padding1", Field, 12}, + {"Stat_t.Qspare", Field, 0}, + {"Stat_t.Rdev", Field, 0}, + {"Stat_t.Size", Field, 0}, + {"Stat_t.Spare", Field, 2}, + {"Stat_t.Uid", Field, 0}, + {"Stat_t.X__pad0", Field, 0}, + {"Stat_t.X__pad1", Field, 0}, + {"Stat_t.X__pad2", Field, 0}, + {"Stat_t.X__st_birthtim", Field, 2}, + {"Stat_t.X__st_ino", Field, 0}, + {"Stat_t.X__unused", Field, 0}, + {"Statfs", Func, 0}, + {"Statfs_t", Type, 0}, + {"Statfs_t.Asyncreads", Field, 0}, + {"Statfs_t.Asyncwrites", Field, 0}, + {"Statfs_t.Bavail", Field, 0}, + {"Statfs_t.Bfree", Field, 0}, + {"Statfs_t.Blocks", Field, 0}, + {"Statfs_t.Bsize", Field, 0}, + {"Statfs_t.Charspare", Field, 0}, + {"Statfs_t.F_asyncreads", Field, 2}, + {"Statfs_t.F_asyncwrites", Field, 2}, + {"Statfs_t.F_bavail", Field, 2}, + {"Statfs_t.F_bfree", Field, 2}, + {"Statfs_t.F_blocks", Field, 2}, + {"Statfs_t.F_bsize", Field, 2}, + {"Statfs_t.F_ctime", Field, 2}, + {"Statfs_t.F_favail", Field, 2}, + {"Statfs_t.F_ffree", Field, 2}, + {"Statfs_t.F_files", Field, 2}, + {"Statfs_t.F_flags", Field, 2}, + {"Statfs_t.F_fsid", Field, 2}, + {"Statfs_t.F_fstypename", Field, 2}, + {"Statfs_t.F_iosize", Field, 2}, + {"Statfs_t.F_mntfromname", Field, 2}, + {"Statfs_t.F_mntfromspec", Field, 3}, + {"Statfs_t.F_mntonname", Field, 2}, + {"Statfs_t.F_namemax", Field, 2}, + {"Statfs_t.F_owner", Field, 2}, + {"Statfs_t.F_spare", Field, 2}, + {"Statfs_t.F_syncreads", Field, 2}, + {"Statfs_t.F_syncwrites", Field, 2}, + {"Statfs_t.Ffree", Field, 0}, + {"Statfs_t.Files", Field, 0}, + {"Statfs_t.Flags", Field, 0}, + {"Statfs_t.Frsize", Field, 0}, + {"Statfs_t.Fsid", Field, 0}, + {"Statfs_t.Fssubtype", Field, 0}, + {"Statfs_t.Fstypename", Field, 0}, + {"Statfs_t.Iosize", Field, 0}, + {"Statfs_t.Mntfromname", Field, 0}, + {"Statfs_t.Mntonname", Field, 0}, + {"Statfs_t.Mount_info", Field, 2}, + {"Statfs_t.Namelen", Field, 0}, + {"Statfs_t.Namemax", Field, 0}, + {"Statfs_t.Owner", Field, 0}, + {"Statfs_t.Pad_cgo_0", Field, 0}, + {"Statfs_t.Pad_cgo_1", Field, 2}, + {"Statfs_t.Reserved", Field, 0}, + {"Statfs_t.Spare", Field, 0}, + {"Statfs_t.Syncreads", Field, 0}, + {"Statfs_t.Syncwrites", Field, 0}, + {"Statfs_t.Type", Field, 0}, + {"Statfs_t.Version", Field, 0}, + {"Stderr", Var, 0}, + {"Stdin", Var, 0}, + {"Stdout", Var, 0}, + {"StringBytePtr", Func, 0}, + {"StringByteSlice", Func, 0}, + {"StringSlicePtr", Func, 0}, + {"StringToSid", Func, 0}, + {"StringToUTF16", Func, 0}, + {"StringToUTF16Ptr", Func, 0}, + {"Symlink", Func, 0}, + {"Sync", Func, 0}, + {"SyncFileRange", Func, 0}, + {"SysProcAttr", Type, 0}, + {"SysProcAttr.AdditionalInheritedHandles", Field, 17}, + {"SysProcAttr.AmbientCaps", Field, 9}, + {"SysProcAttr.CgroupFD", Field, 20}, + {"SysProcAttr.Chroot", Field, 0}, + {"SysProcAttr.Cloneflags", Field, 2}, + {"SysProcAttr.CmdLine", Field, 0}, + {"SysProcAttr.CreationFlags", Field, 1}, + {"SysProcAttr.Credential", Field, 0}, + {"SysProcAttr.Ctty", Field, 1}, + {"SysProcAttr.Foreground", Field, 5}, + {"SysProcAttr.GidMappings", Field, 4}, + {"SysProcAttr.GidMappingsEnableSetgroups", Field, 5}, + {"SysProcAttr.HideWindow", Field, 0}, + {"SysProcAttr.Jail", Field, 21}, + {"SysProcAttr.NoInheritHandles", Field, 16}, + {"SysProcAttr.Noctty", Field, 0}, + {"SysProcAttr.ParentProcess", Field, 17}, + {"SysProcAttr.Pdeathsig", Field, 0}, + {"SysProcAttr.Pgid", Field, 5}, + {"SysProcAttr.PidFD", Field, 22}, + {"SysProcAttr.ProcessAttributes", Field, 13}, + {"SysProcAttr.Ptrace", Field, 0}, + {"SysProcAttr.Setctty", Field, 0}, + {"SysProcAttr.Setpgid", Field, 0}, + {"SysProcAttr.Setsid", Field, 0}, + {"SysProcAttr.ThreadAttributes", Field, 13}, + {"SysProcAttr.Token", Field, 10}, + {"SysProcAttr.UidMappings", Field, 4}, + {"SysProcAttr.Unshareflags", Field, 7}, + {"SysProcAttr.UseCgroupFD", Field, 20}, + {"SysProcIDMap", Type, 4}, + {"SysProcIDMap.ContainerID", Field, 4}, + {"SysProcIDMap.HostID", Field, 4}, + {"SysProcIDMap.Size", Field, 4}, + {"Syscall", Func, 0}, + {"Syscall12", Func, 0}, + {"Syscall15", Func, 0}, + {"Syscall18", Func, 12}, + {"Syscall6", Func, 0}, + {"Syscall9", Func, 0}, + {"SyscallN", Func, 18}, + {"Sysctl", Func, 0}, + {"SysctlUint32", Func, 0}, + {"Sysctlnode", Type, 2}, + {"Sysctlnode.Flags", Field, 2}, + {"Sysctlnode.Name", Field, 2}, + {"Sysctlnode.Num", Field, 2}, + {"Sysctlnode.Un", Field, 2}, + {"Sysctlnode.Ver", Field, 2}, + {"Sysctlnode.X__rsvd", Field, 2}, + {"Sysctlnode.X_sysctl_desc", Field, 2}, + {"Sysctlnode.X_sysctl_func", Field, 2}, + {"Sysctlnode.X_sysctl_parent", Field, 2}, + {"Sysctlnode.X_sysctl_size", Field, 2}, + {"Sysinfo", Func, 0}, + {"Sysinfo_t", Type, 0}, + {"Sysinfo_t.Bufferram", Field, 0}, + {"Sysinfo_t.Freehigh", Field, 0}, + {"Sysinfo_t.Freeram", Field, 0}, + {"Sysinfo_t.Freeswap", Field, 0}, + {"Sysinfo_t.Loads", Field, 0}, + {"Sysinfo_t.Pad", Field, 0}, + {"Sysinfo_t.Pad_cgo_0", Field, 0}, + {"Sysinfo_t.Pad_cgo_1", Field, 0}, + {"Sysinfo_t.Procs", Field, 0}, + {"Sysinfo_t.Sharedram", Field, 0}, + {"Sysinfo_t.Totalhigh", Field, 0}, + {"Sysinfo_t.Totalram", Field, 0}, + {"Sysinfo_t.Totalswap", Field, 0}, + {"Sysinfo_t.Unit", Field, 0}, + {"Sysinfo_t.Uptime", Field, 0}, + {"Sysinfo_t.X_f", Field, 0}, + {"Systemtime", Type, 0}, + {"Systemtime.Day", Field, 0}, + {"Systemtime.DayOfWeek", Field, 0}, + {"Systemtime.Hour", Field, 0}, + {"Systemtime.Milliseconds", Field, 0}, + {"Systemtime.Minute", Field, 0}, + {"Systemtime.Month", Field, 0}, + {"Systemtime.Second", Field, 0}, + {"Systemtime.Year", Field, 0}, + {"TCGETS", Const, 0}, + {"TCIFLUSH", Const, 1}, + {"TCIOFLUSH", Const, 1}, + {"TCOFLUSH", Const, 1}, + {"TCPInfo", Type, 1}, + {"TCPInfo.Advmss", Field, 1}, + {"TCPInfo.Ato", Field, 1}, + {"TCPInfo.Backoff", Field, 1}, + {"TCPInfo.Ca_state", Field, 1}, + {"TCPInfo.Fackets", Field, 1}, + {"TCPInfo.Last_ack_recv", Field, 1}, + {"TCPInfo.Last_ack_sent", Field, 1}, + {"TCPInfo.Last_data_recv", Field, 1}, + {"TCPInfo.Last_data_sent", Field, 1}, + {"TCPInfo.Lost", Field, 1}, + {"TCPInfo.Options", Field, 1}, + {"TCPInfo.Pad_cgo_0", Field, 1}, + {"TCPInfo.Pmtu", Field, 1}, + {"TCPInfo.Probes", Field, 1}, + {"TCPInfo.Rcv_mss", Field, 1}, + {"TCPInfo.Rcv_rtt", Field, 1}, + {"TCPInfo.Rcv_space", Field, 1}, + {"TCPInfo.Rcv_ssthresh", Field, 1}, + {"TCPInfo.Reordering", Field, 1}, + {"TCPInfo.Retrans", Field, 1}, + {"TCPInfo.Retransmits", Field, 1}, + {"TCPInfo.Rto", Field, 1}, + {"TCPInfo.Rtt", Field, 1}, + {"TCPInfo.Rttvar", Field, 1}, + {"TCPInfo.Sacked", Field, 1}, + {"TCPInfo.Snd_cwnd", Field, 1}, + {"TCPInfo.Snd_mss", Field, 1}, + {"TCPInfo.Snd_ssthresh", Field, 1}, + {"TCPInfo.State", Field, 1}, + {"TCPInfo.Total_retrans", Field, 1}, + {"TCPInfo.Unacked", Field, 1}, + {"TCPKeepalive", Type, 3}, + {"TCPKeepalive.Interval", Field, 3}, + {"TCPKeepalive.OnOff", Field, 3}, + {"TCPKeepalive.Time", Field, 3}, + {"TCP_CA_NAME_MAX", Const, 0}, + {"TCP_CONGCTL", Const, 1}, + {"TCP_CONGESTION", Const, 0}, + {"TCP_CONNECTIONTIMEOUT", Const, 0}, + {"TCP_CORK", Const, 0}, + {"TCP_DEFER_ACCEPT", Const, 0}, + {"TCP_ENABLE_ECN", Const, 16}, + {"TCP_INFO", Const, 0}, + {"TCP_KEEPALIVE", Const, 0}, + {"TCP_KEEPCNT", Const, 0}, + {"TCP_KEEPIDLE", Const, 0}, + {"TCP_KEEPINIT", Const, 1}, + {"TCP_KEEPINTVL", Const, 0}, + {"TCP_LINGER2", Const, 0}, + {"TCP_MAXBURST", Const, 0}, + {"TCP_MAXHLEN", Const, 0}, + {"TCP_MAXOLEN", Const, 0}, + {"TCP_MAXSEG", Const, 0}, + {"TCP_MAXWIN", Const, 0}, + {"TCP_MAX_SACK", Const, 0}, + {"TCP_MAX_WINSHIFT", Const, 0}, + {"TCP_MD5SIG", Const, 0}, + {"TCP_MD5SIG_MAXKEYLEN", Const, 0}, + {"TCP_MINMSS", Const, 0}, + {"TCP_MINMSSOVERLOAD", Const, 0}, + {"TCP_MSS", Const, 0}, + {"TCP_NODELAY", Const, 0}, + {"TCP_NOOPT", Const, 0}, + {"TCP_NOPUSH", Const, 0}, + {"TCP_NOTSENT_LOWAT", Const, 16}, + {"TCP_NSTATES", Const, 1}, + {"TCP_QUICKACK", Const, 0}, + {"TCP_RXT_CONNDROPTIME", Const, 0}, + {"TCP_RXT_FINDROP", Const, 0}, + {"TCP_SACK_ENABLE", Const, 1}, + {"TCP_SENDMOREACKS", Const, 16}, + {"TCP_SYNCNT", Const, 0}, + {"TCP_VENDOR", Const, 3}, + {"TCP_WINDOW_CLAMP", Const, 0}, + {"TCSAFLUSH", Const, 1}, + {"TCSETS", Const, 0}, + {"TF_DISCONNECT", Const, 0}, + {"TF_REUSE_SOCKET", Const, 0}, + {"TF_USE_DEFAULT_WORKER", Const, 0}, + {"TF_USE_KERNEL_APC", Const, 0}, + {"TF_USE_SYSTEM_THREAD", Const, 0}, + {"TF_WRITE_BEHIND", Const, 0}, + {"TH32CS_INHERIT", Const, 4}, + {"TH32CS_SNAPALL", Const, 4}, + {"TH32CS_SNAPHEAPLIST", Const, 4}, + {"TH32CS_SNAPMODULE", Const, 4}, + {"TH32CS_SNAPMODULE32", Const, 4}, + {"TH32CS_SNAPPROCESS", Const, 4}, + {"TH32CS_SNAPTHREAD", Const, 4}, + {"TIME_ZONE_ID_DAYLIGHT", Const, 0}, + {"TIME_ZONE_ID_STANDARD", Const, 0}, + {"TIME_ZONE_ID_UNKNOWN", Const, 0}, + {"TIOCCBRK", Const, 0}, + {"TIOCCDTR", Const, 0}, + {"TIOCCONS", Const, 0}, + {"TIOCDCDTIMESTAMP", Const, 0}, + {"TIOCDRAIN", Const, 0}, + {"TIOCDSIMICROCODE", Const, 0}, + {"TIOCEXCL", Const, 0}, + {"TIOCEXT", Const, 0}, + {"TIOCFLAG_CDTRCTS", Const, 1}, + {"TIOCFLAG_CLOCAL", Const, 1}, + {"TIOCFLAG_CRTSCTS", Const, 1}, + {"TIOCFLAG_MDMBUF", Const, 1}, + {"TIOCFLAG_PPS", Const, 1}, + {"TIOCFLAG_SOFTCAR", Const, 1}, + {"TIOCFLUSH", Const, 0}, + {"TIOCGDEV", Const, 0}, + {"TIOCGDRAINWAIT", Const, 0}, + {"TIOCGETA", Const, 0}, + {"TIOCGETD", Const, 0}, + {"TIOCGFLAGS", Const, 1}, + {"TIOCGICOUNT", Const, 0}, + {"TIOCGLCKTRMIOS", Const, 0}, + {"TIOCGLINED", Const, 1}, + {"TIOCGPGRP", Const, 0}, + {"TIOCGPTN", Const, 0}, + {"TIOCGQSIZE", Const, 1}, + {"TIOCGRANTPT", Const, 1}, + {"TIOCGRS485", Const, 0}, + {"TIOCGSERIAL", Const, 0}, + {"TIOCGSID", Const, 0}, + {"TIOCGSIZE", Const, 1}, + {"TIOCGSOFTCAR", Const, 0}, + {"TIOCGTSTAMP", Const, 1}, + {"TIOCGWINSZ", Const, 0}, + {"TIOCINQ", Const, 0}, + {"TIOCIXOFF", Const, 0}, + {"TIOCIXON", Const, 0}, + {"TIOCLINUX", Const, 0}, + {"TIOCMBIC", Const, 0}, + {"TIOCMBIS", Const, 0}, + {"TIOCMGDTRWAIT", Const, 0}, + {"TIOCMGET", Const, 0}, + {"TIOCMIWAIT", Const, 0}, + {"TIOCMODG", Const, 0}, + {"TIOCMODS", Const, 0}, + {"TIOCMSDTRWAIT", Const, 0}, + {"TIOCMSET", Const, 0}, + {"TIOCM_CAR", Const, 0}, + {"TIOCM_CD", Const, 0}, + {"TIOCM_CTS", Const, 0}, + {"TIOCM_DCD", Const, 0}, + {"TIOCM_DSR", Const, 0}, + {"TIOCM_DTR", Const, 0}, + {"TIOCM_LE", Const, 0}, + {"TIOCM_RI", Const, 0}, + {"TIOCM_RNG", Const, 0}, + {"TIOCM_RTS", Const, 0}, + {"TIOCM_SR", Const, 0}, + {"TIOCM_ST", Const, 0}, + {"TIOCNOTTY", Const, 0}, + {"TIOCNXCL", Const, 0}, + {"TIOCOUTQ", Const, 0}, + {"TIOCPKT", Const, 0}, + {"TIOCPKT_DATA", Const, 0}, + {"TIOCPKT_DOSTOP", Const, 0}, + {"TIOCPKT_FLUSHREAD", Const, 0}, + {"TIOCPKT_FLUSHWRITE", Const, 0}, + {"TIOCPKT_IOCTL", Const, 0}, + {"TIOCPKT_NOSTOP", Const, 0}, + {"TIOCPKT_START", Const, 0}, + {"TIOCPKT_STOP", Const, 0}, + {"TIOCPTMASTER", Const, 0}, + {"TIOCPTMGET", Const, 1}, + {"TIOCPTSNAME", Const, 1}, + {"TIOCPTYGNAME", Const, 0}, + {"TIOCPTYGRANT", Const, 0}, + {"TIOCPTYUNLK", Const, 0}, + {"TIOCRCVFRAME", Const, 1}, + {"TIOCREMOTE", Const, 0}, + {"TIOCSBRK", Const, 0}, + {"TIOCSCONS", Const, 0}, + {"TIOCSCTTY", Const, 0}, + {"TIOCSDRAINWAIT", Const, 0}, + {"TIOCSDTR", Const, 0}, + {"TIOCSERCONFIG", Const, 0}, + {"TIOCSERGETLSR", Const, 0}, + {"TIOCSERGETMULTI", Const, 0}, + {"TIOCSERGSTRUCT", Const, 0}, + {"TIOCSERGWILD", Const, 0}, + {"TIOCSERSETMULTI", Const, 0}, + {"TIOCSERSWILD", Const, 0}, + {"TIOCSER_TEMT", Const, 0}, + {"TIOCSETA", Const, 0}, + {"TIOCSETAF", Const, 0}, + {"TIOCSETAW", Const, 0}, + {"TIOCSETD", Const, 0}, + {"TIOCSFLAGS", Const, 1}, + {"TIOCSIG", Const, 0}, + {"TIOCSLCKTRMIOS", Const, 0}, + {"TIOCSLINED", Const, 1}, + {"TIOCSPGRP", Const, 0}, + {"TIOCSPTLCK", Const, 0}, + {"TIOCSQSIZE", Const, 1}, + {"TIOCSRS485", Const, 0}, + {"TIOCSSERIAL", Const, 0}, + {"TIOCSSIZE", Const, 1}, + {"TIOCSSOFTCAR", Const, 0}, + {"TIOCSTART", Const, 0}, + {"TIOCSTAT", Const, 0}, + {"TIOCSTI", Const, 0}, + {"TIOCSTOP", Const, 0}, + {"TIOCSTSTAMP", Const, 1}, + {"TIOCSWINSZ", Const, 0}, + {"TIOCTIMESTAMP", Const, 0}, + {"TIOCUCNTL", Const, 0}, + {"TIOCVHANGUP", Const, 0}, + {"TIOCXMTFRAME", Const, 1}, + {"TOKEN_ADJUST_DEFAULT", Const, 0}, + {"TOKEN_ADJUST_GROUPS", Const, 0}, + {"TOKEN_ADJUST_PRIVILEGES", Const, 0}, + {"TOKEN_ADJUST_SESSIONID", Const, 11}, + {"TOKEN_ALL_ACCESS", Const, 0}, + {"TOKEN_ASSIGN_PRIMARY", Const, 0}, + {"TOKEN_DUPLICATE", Const, 0}, + {"TOKEN_EXECUTE", Const, 0}, + {"TOKEN_IMPERSONATE", Const, 0}, + {"TOKEN_QUERY", Const, 0}, + {"TOKEN_QUERY_SOURCE", Const, 0}, + {"TOKEN_READ", Const, 0}, + {"TOKEN_WRITE", Const, 0}, + {"TOSTOP", Const, 0}, + {"TRUNCATE_EXISTING", Const, 0}, + {"TUNATTACHFILTER", Const, 0}, + {"TUNDETACHFILTER", Const, 0}, + {"TUNGETFEATURES", Const, 0}, + {"TUNGETIFF", Const, 0}, + {"TUNGETSNDBUF", Const, 0}, + {"TUNGETVNETHDRSZ", Const, 0}, + {"TUNSETDEBUG", Const, 0}, + {"TUNSETGROUP", Const, 0}, + {"TUNSETIFF", Const, 0}, + {"TUNSETLINK", Const, 0}, + {"TUNSETNOCSUM", Const, 0}, + {"TUNSETOFFLOAD", Const, 0}, + {"TUNSETOWNER", Const, 0}, + {"TUNSETPERSIST", Const, 0}, + {"TUNSETSNDBUF", Const, 0}, + {"TUNSETTXFILTER", Const, 0}, + {"TUNSETVNETHDRSZ", Const, 0}, + {"Tee", Func, 0}, + {"TerminateProcess", Func, 0}, + {"Termios", Type, 0}, + {"Termios.Cc", Field, 0}, + {"Termios.Cflag", Field, 0}, + {"Termios.Iflag", Field, 0}, + {"Termios.Ispeed", Field, 0}, + {"Termios.Lflag", Field, 0}, + {"Termios.Line", Field, 0}, + {"Termios.Oflag", Field, 0}, + {"Termios.Ospeed", Field, 0}, + {"Termios.Pad_cgo_0", Field, 0}, + {"Tgkill", Func, 0}, + {"Time", Func, 0}, + {"Time_t", Type, 0}, + {"Times", Func, 0}, + {"Timespec", Type, 0}, + {"Timespec.Nsec", Field, 0}, + {"Timespec.Pad_cgo_0", Field, 2}, + {"Timespec.Sec", Field, 0}, + {"TimespecToNsec", Func, 0}, + {"Timeval", Type, 0}, + {"Timeval.Pad_cgo_0", Field, 0}, + {"Timeval.Sec", Field, 0}, + {"Timeval.Usec", Field, 0}, + {"Timeval32", Type, 0}, + {"Timeval32.Sec", Field, 0}, + {"Timeval32.Usec", Field, 0}, + {"TimevalToNsec", Func, 0}, + {"Timex", Type, 0}, + {"Timex.Calcnt", Field, 0}, + {"Timex.Constant", Field, 0}, + {"Timex.Errcnt", Field, 0}, + {"Timex.Esterror", Field, 0}, + {"Timex.Freq", Field, 0}, + {"Timex.Jitcnt", Field, 0}, + {"Timex.Jitter", Field, 0}, + {"Timex.Maxerror", Field, 0}, + {"Timex.Modes", Field, 0}, + {"Timex.Offset", Field, 0}, + {"Timex.Pad_cgo_0", Field, 0}, + {"Timex.Pad_cgo_1", Field, 0}, + {"Timex.Pad_cgo_2", Field, 0}, + {"Timex.Pad_cgo_3", Field, 0}, + {"Timex.Ppsfreq", Field, 0}, + {"Timex.Precision", Field, 0}, + {"Timex.Shift", Field, 0}, + {"Timex.Stabil", Field, 0}, + {"Timex.Status", Field, 0}, + {"Timex.Stbcnt", Field, 0}, + {"Timex.Tai", Field, 0}, + {"Timex.Tick", Field, 0}, + {"Timex.Time", Field, 0}, + {"Timex.Tolerance", Field, 0}, + {"Timezoneinformation", Type, 0}, + {"Timezoneinformation.Bias", Field, 0}, + {"Timezoneinformation.DaylightBias", Field, 0}, + {"Timezoneinformation.DaylightDate", Field, 0}, + {"Timezoneinformation.DaylightName", Field, 0}, + {"Timezoneinformation.StandardBias", Field, 0}, + {"Timezoneinformation.StandardDate", Field, 0}, + {"Timezoneinformation.StandardName", Field, 0}, + {"Tms", Type, 0}, + {"Tms.Cstime", Field, 0}, + {"Tms.Cutime", Field, 0}, + {"Tms.Stime", Field, 0}, + {"Tms.Utime", Field, 0}, + {"Token", Type, 0}, + {"TokenAccessInformation", Const, 0}, + {"TokenAuditPolicy", Const, 0}, + {"TokenDefaultDacl", Const, 0}, + {"TokenElevation", Const, 0}, + {"TokenElevationType", Const, 0}, + {"TokenGroups", Const, 0}, + {"TokenGroupsAndPrivileges", Const, 0}, + {"TokenHasRestrictions", Const, 0}, + {"TokenImpersonationLevel", Const, 0}, + {"TokenIntegrityLevel", Const, 0}, + {"TokenLinkedToken", Const, 0}, + {"TokenLogonSid", Const, 0}, + {"TokenMandatoryPolicy", Const, 0}, + {"TokenOrigin", Const, 0}, + {"TokenOwner", Const, 0}, + {"TokenPrimaryGroup", Const, 0}, + {"TokenPrivileges", Const, 0}, + {"TokenRestrictedSids", Const, 0}, + {"TokenSandBoxInert", Const, 0}, + {"TokenSessionId", Const, 0}, + {"TokenSessionReference", Const, 0}, + {"TokenSource", Const, 0}, + {"TokenStatistics", Const, 0}, + {"TokenType", Const, 0}, + {"TokenUIAccess", Const, 0}, + {"TokenUser", Const, 0}, + {"TokenVirtualizationAllowed", Const, 0}, + {"TokenVirtualizationEnabled", Const, 0}, + {"Tokenprimarygroup", Type, 0}, + {"Tokenprimarygroup.PrimaryGroup", Field, 0}, + {"Tokenuser", Type, 0}, + {"Tokenuser.User", Field, 0}, + {"TranslateAccountName", Func, 0}, + {"TranslateName", Func, 0}, + {"TransmitFile", Func, 0}, + {"TransmitFileBuffers", Type, 0}, + {"TransmitFileBuffers.Head", Field, 0}, + {"TransmitFileBuffers.HeadLength", Field, 0}, + {"TransmitFileBuffers.Tail", Field, 0}, + {"TransmitFileBuffers.TailLength", Field, 0}, + {"Truncate", Func, 0}, + {"UNIX_PATH_MAX", Const, 12}, + {"USAGE_MATCH_TYPE_AND", Const, 0}, + {"USAGE_MATCH_TYPE_OR", Const, 0}, + {"UTF16FromString", Func, 1}, + {"UTF16PtrFromString", Func, 1}, + {"UTF16ToString", Func, 0}, + {"Ucred", Type, 0}, + {"Ucred.Gid", Field, 0}, + {"Ucred.Pid", Field, 0}, + {"Ucred.Uid", Field, 0}, + {"Umask", Func, 0}, + {"Uname", Func, 0}, + {"Undelete", Func, 0}, + {"UnixCredentials", Func, 0}, + {"UnixRights", Func, 0}, + {"Unlink", Func, 0}, + {"Unlinkat", Func, 0}, + {"UnmapViewOfFile", Func, 0}, + {"Unmount", Func, 0}, + {"Unsetenv", Func, 4}, + {"Unshare", Func, 0}, + {"UserInfo10", Type, 0}, + {"UserInfo10.Comment", Field, 0}, + {"UserInfo10.FullName", Field, 0}, + {"UserInfo10.Name", Field, 0}, + {"UserInfo10.UsrComment", Field, 0}, + {"Ustat", Func, 0}, + {"Ustat_t", Type, 0}, + {"Ustat_t.Fname", Field, 0}, + {"Ustat_t.Fpack", Field, 0}, + {"Ustat_t.Pad_cgo_0", Field, 0}, + {"Ustat_t.Pad_cgo_1", Field, 0}, + {"Ustat_t.Tfree", Field, 0}, + {"Ustat_t.Tinode", Field, 0}, + {"Utimbuf", Type, 0}, + {"Utimbuf.Actime", Field, 0}, + {"Utimbuf.Modtime", Field, 0}, + {"Utime", Func, 0}, + {"Utimes", Func, 0}, + {"UtimesNano", Func, 1}, + {"Utsname", Type, 0}, + {"Utsname.Domainname", Field, 0}, + {"Utsname.Machine", Field, 0}, + {"Utsname.Nodename", Field, 0}, + {"Utsname.Release", Field, 0}, + {"Utsname.Sysname", Field, 0}, + {"Utsname.Version", Field, 0}, + {"VDISCARD", Const, 0}, + {"VDSUSP", Const, 1}, + {"VEOF", Const, 0}, + {"VEOL", Const, 0}, + {"VEOL2", Const, 0}, + {"VERASE", Const, 0}, + {"VERASE2", Const, 1}, + {"VINTR", Const, 0}, + {"VKILL", Const, 0}, + {"VLNEXT", Const, 0}, + {"VMIN", Const, 0}, + {"VQUIT", Const, 0}, + {"VREPRINT", Const, 0}, + {"VSTART", Const, 0}, + {"VSTATUS", Const, 1}, + {"VSTOP", Const, 0}, + {"VSUSP", Const, 0}, + {"VSWTC", Const, 0}, + {"VT0", Const, 1}, + {"VT1", Const, 1}, + {"VTDLY", Const, 1}, + {"VTIME", Const, 0}, + {"VWERASE", Const, 0}, + {"VirtualLock", Func, 0}, + {"VirtualUnlock", Func, 0}, + {"WAIT_ABANDONED", Const, 0}, + {"WAIT_FAILED", Const, 0}, + {"WAIT_OBJECT_0", Const, 0}, + {"WAIT_TIMEOUT", Const, 0}, + {"WALL", Const, 0}, + {"WALLSIG", Const, 1}, + {"WALTSIG", Const, 1}, + {"WCLONE", Const, 0}, + {"WCONTINUED", Const, 0}, + {"WCOREFLAG", Const, 0}, + {"WEXITED", Const, 0}, + {"WLINUXCLONE", Const, 0}, + {"WNOHANG", Const, 0}, + {"WNOTHREAD", Const, 0}, + {"WNOWAIT", Const, 0}, + {"WNOZOMBIE", Const, 1}, + {"WOPTSCHECKED", Const, 1}, + {"WORDSIZE", Const, 0}, + {"WSABuf", Type, 0}, + {"WSABuf.Buf", Field, 0}, + {"WSABuf.Len", Field, 0}, + {"WSACleanup", Func, 0}, + {"WSADESCRIPTION_LEN", Const, 0}, + {"WSAData", Type, 0}, + {"WSAData.Description", Field, 0}, + {"WSAData.HighVersion", Field, 0}, + {"WSAData.MaxSockets", Field, 0}, + {"WSAData.MaxUdpDg", Field, 0}, + {"WSAData.SystemStatus", Field, 0}, + {"WSAData.VendorInfo", Field, 0}, + {"WSAData.Version", Field, 0}, + {"WSAEACCES", Const, 2}, + {"WSAECONNABORTED", Const, 9}, + {"WSAECONNRESET", Const, 3}, + {"WSAEnumProtocols", Func, 2}, + {"WSAID_CONNECTEX", Var, 1}, + {"WSAIoctl", Func, 0}, + {"WSAPROTOCOL_LEN", Const, 2}, + {"WSAProtocolChain", Type, 2}, + {"WSAProtocolChain.ChainEntries", Field, 2}, + {"WSAProtocolChain.ChainLen", Field, 2}, + {"WSAProtocolInfo", Type, 2}, + {"WSAProtocolInfo.AddressFamily", Field, 2}, + {"WSAProtocolInfo.CatalogEntryId", Field, 2}, + {"WSAProtocolInfo.MaxSockAddr", Field, 2}, + {"WSAProtocolInfo.MessageSize", Field, 2}, + {"WSAProtocolInfo.MinSockAddr", Field, 2}, + {"WSAProtocolInfo.NetworkByteOrder", Field, 2}, + {"WSAProtocolInfo.Protocol", Field, 2}, + {"WSAProtocolInfo.ProtocolChain", Field, 2}, + {"WSAProtocolInfo.ProtocolMaxOffset", Field, 2}, + {"WSAProtocolInfo.ProtocolName", Field, 2}, + {"WSAProtocolInfo.ProviderFlags", Field, 2}, + {"WSAProtocolInfo.ProviderId", Field, 2}, + {"WSAProtocolInfo.ProviderReserved", Field, 2}, + {"WSAProtocolInfo.SecurityScheme", Field, 2}, + {"WSAProtocolInfo.ServiceFlags1", Field, 2}, + {"WSAProtocolInfo.ServiceFlags2", Field, 2}, + {"WSAProtocolInfo.ServiceFlags3", Field, 2}, + {"WSAProtocolInfo.ServiceFlags4", Field, 2}, + {"WSAProtocolInfo.SocketType", Field, 2}, + {"WSAProtocolInfo.Version", Field, 2}, + {"WSARecv", Func, 0}, + {"WSARecvFrom", Func, 0}, + {"WSASYS_STATUS_LEN", Const, 0}, + {"WSASend", Func, 0}, + {"WSASendTo", Func, 0}, + {"WSASendto", Func, 0}, + {"WSAStartup", Func, 0}, + {"WSTOPPED", Const, 0}, + {"WTRAPPED", Const, 1}, + {"WUNTRACED", Const, 0}, + {"Wait4", Func, 0}, + {"WaitForSingleObject", Func, 0}, + {"WaitStatus", Type, 0}, + {"WaitStatus.ExitCode", Field, 0}, + {"Win32FileAttributeData", Type, 0}, + {"Win32FileAttributeData.CreationTime", Field, 0}, + {"Win32FileAttributeData.FileAttributes", Field, 0}, + {"Win32FileAttributeData.FileSizeHigh", Field, 0}, + {"Win32FileAttributeData.FileSizeLow", Field, 0}, + {"Win32FileAttributeData.LastAccessTime", Field, 0}, + {"Win32FileAttributeData.LastWriteTime", Field, 0}, + {"Win32finddata", Type, 0}, + {"Win32finddata.AlternateFileName", Field, 0}, + {"Win32finddata.CreationTime", Field, 0}, + {"Win32finddata.FileAttributes", Field, 0}, + {"Win32finddata.FileName", Field, 0}, + {"Win32finddata.FileSizeHigh", Field, 0}, + {"Win32finddata.FileSizeLow", Field, 0}, + {"Win32finddata.LastAccessTime", Field, 0}, + {"Win32finddata.LastWriteTime", Field, 0}, + {"Win32finddata.Reserved0", Field, 0}, + {"Win32finddata.Reserved1", Field, 0}, + {"Write", Func, 0}, + {"WriteConsole", Func, 1}, + {"WriteFile", Func, 0}, + {"X509_ASN_ENCODING", Const, 0}, + {"XCASE", Const, 0}, + {"XP1_CONNECTIONLESS", Const, 2}, + {"XP1_CONNECT_DATA", Const, 2}, + {"XP1_DISCONNECT_DATA", Const, 2}, + {"XP1_EXPEDITED_DATA", Const, 2}, + {"XP1_GRACEFUL_CLOSE", Const, 2}, + {"XP1_GUARANTEED_DELIVERY", Const, 2}, + {"XP1_GUARANTEED_ORDER", Const, 2}, + {"XP1_IFS_HANDLES", Const, 2}, + {"XP1_MESSAGE_ORIENTED", Const, 2}, + {"XP1_MULTIPOINT_CONTROL_PLANE", Const, 2}, + {"XP1_MULTIPOINT_DATA_PLANE", Const, 2}, + {"XP1_PARTIAL_MESSAGE", Const, 2}, + {"XP1_PSEUDO_STREAM", Const, 2}, + {"XP1_QOS_SUPPORTED", Const, 2}, + {"XP1_SAN_SUPPORT_SDP", Const, 2}, + {"XP1_SUPPORT_BROADCAST", Const, 2}, + {"XP1_SUPPORT_MULTIPOINT", Const, 2}, + {"XP1_UNI_RECV", Const, 2}, + {"XP1_UNI_SEND", Const, 2}, + }, + "syscall/js": { + {"CopyBytesToGo", Func, 0}, + {"CopyBytesToJS", Func, 0}, + {"Error", Type, 0}, + {"Func", Type, 0}, + {"FuncOf", Func, 0}, + {"Global", Func, 0}, + {"Null", Func, 0}, + {"Type", Type, 0}, + {"TypeBoolean", Const, 0}, + {"TypeFunction", Const, 0}, + {"TypeNull", Const, 0}, + {"TypeNumber", Const, 0}, + {"TypeObject", Const, 0}, + {"TypeString", Const, 0}, + {"TypeSymbol", Const, 0}, + {"TypeUndefined", Const, 0}, + {"Undefined", Func, 0}, + {"Value", Type, 0}, + {"ValueError", Type, 0}, + {"ValueOf", Func, 0}, + }, + "testing": { + {"(*B).Cleanup", Method, 14}, + {"(*B).Elapsed", Method, 20}, + {"(*B).Error", Method, 0}, + {"(*B).Errorf", Method, 0}, + {"(*B).Fail", Method, 0}, + {"(*B).FailNow", Method, 0}, + {"(*B).Failed", Method, 0}, + {"(*B).Fatal", Method, 0}, + {"(*B).Fatalf", Method, 0}, + {"(*B).Helper", Method, 9}, + {"(*B).Log", Method, 0}, + {"(*B).Logf", Method, 0}, + {"(*B).Name", Method, 8}, + {"(*B).ReportAllocs", Method, 1}, + {"(*B).ReportMetric", Method, 13}, + {"(*B).ResetTimer", Method, 0}, + {"(*B).Run", Method, 7}, + {"(*B).RunParallel", Method, 3}, + {"(*B).SetBytes", Method, 0}, + {"(*B).SetParallelism", Method, 3}, + {"(*B).Setenv", Method, 17}, + {"(*B).Skip", Method, 1}, + {"(*B).SkipNow", Method, 1}, + {"(*B).Skipf", Method, 1}, + {"(*B).Skipped", Method, 1}, + {"(*B).StartTimer", Method, 0}, + {"(*B).StopTimer", Method, 0}, + {"(*B).TempDir", Method, 15}, + {"(*F).Add", Method, 18}, + {"(*F).Cleanup", Method, 18}, + {"(*F).Error", Method, 18}, + {"(*F).Errorf", Method, 18}, + {"(*F).Fail", Method, 18}, + {"(*F).FailNow", Method, 18}, + {"(*F).Failed", Method, 18}, + {"(*F).Fatal", Method, 18}, + {"(*F).Fatalf", Method, 18}, + {"(*F).Fuzz", Method, 18}, + {"(*F).Helper", Method, 18}, + {"(*F).Log", Method, 18}, + {"(*F).Logf", Method, 18}, + {"(*F).Name", Method, 18}, + {"(*F).Setenv", Method, 18}, + {"(*F).Skip", Method, 18}, + {"(*F).SkipNow", Method, 18}, + {"(*F).Skipf", Method, 18}, + {"(*F).Skipped", Method, 18}, + {"(*F).TempDir", Method, 18}, + {"(*M).Run", Method, 4}, + {"(*PB).Next", Method, 3}, + {"(*T).Cleanup", Method, 14}, + {"(*T).Deadline", Method, 15}, + {"(*T).Error", Method, 0}, + {"(*T).Errorf", Method, 0}, + {"(*T).Fail", Method, 0}, + {"(*T).FailNow", Method, 0}, + {"(*T).Failed", Method, 0}, + {"(*T).Fatal", Method, 0}, + {"(*T).Fatalf", Method, 0}, + {"(*T).Helper", Method, 9}, + {"(*T).Log", Method, 0}, + {"(*T).Logf", Method, 0}, + {"(*T).Name", Method, 8}, + {"(*T).Parallel", Method, 0}, + {"(*T).Run", Method, 7}, + {"(*T).Setenv", Method, 17}, + {"(*T).Skip", Method, 1}, + {"(*T).SkipNow", Method, 1}, + {"(*T).Skipf", Method, 1}, + {"(*T).Skipped", Method, 1}, + {"(*T).TempDir", Method, 15}, + {"(BenchmarkResult).AllocedBytesPerOp", Method, 1}, + {"(BenchmarkResult).AllocsPerOp", Method, 1}, + {"(BenchmarkResult).MemString", Method, 1}, + {"(BenchmarkResult).NsPerOp", Method, 0}, + {"(BenchmarkResult).String", Method, 0}, + {"AllocsPerRun", Func, 1}, + {"B", Type, 0}, + {"B.N", Field, 0}, + {"Benchmark", Func, 0}, + {"BenchmarkResult", Type, 0}, + {"BenchmarkResult.Bytes", Field, 0}, + {"BenchmarkResult.Extra", Field, 13}, + {"BenchmarkResult.MemAllocs", Field, 1}, + {"BenchmarkResult.MemBytes", Field, 1}, + {"BenchmarkResult.N", Field, 0}, + {"BenchmarkResult.T", Field, 0}, + {"Cover", Type, 2}, + {"Cover.Blocks", Field, 2}, + {"Cover.Counters", Field, 2}, + {"Cover.CoveredPackages", Field, 2}, + {"Cover.Mode", Field, 2}, + {"CoverBlock", Type, 2}, + {"CoverBlock.Col0", Field, 2}, + {"CoverBlock.Col1", Field, 2}, + {"CoverBlock.Line0", Field, 2}, + {"CoverBlock.Line1", Field, 2}, + {"CoverBlock.Stmts", Field, 2}, + {"CoverMode", Func, 8}, + {"Coverage", Func, 4}, + {"F", Type, 18}, + {"Init", Func, 13}, + {"InternalBenchmark", Type, 0}, + {"InternalBenchmark.F", Field, 0}, + {"InternalBenchmark.Name", Field, 0}, + {"InternalExample", Type, 0}, + {"InternalExample.F", Field, 0}, + {"InternalExample.Name", Field, 0}, + {"InternalExample.Output", Field, 0}, + {"InternalExample.Unordered", Field, 7}, + {"InternalFuzzTarget", Type, 18}, + {"InternalFuzzTarget.Fn", Field, 18}, + {"InternalFuzzTarget.Name", Field, 18}, + {"InternalTest", Type, 0}, + {"InternalTest.F", Field, 0}, + {"InternalTest.Name", Field, 0}, + {"M", Type, 4}, + {"Main", Func, 0}, + {"MainStart", Func, 4}, + {"PB", Type, 3}, + {"RegisterCover", Func, 2}, + {"RunBenchmarks", Func, 0}, + {"RunExamples", Func, 0}, + {"RunTests", Func, 0}, + {"Short", Func, 0}, + {"T", Type, 0}, + {"TB", Type, 2}, + {"Testing", Func, 21}, + {"Verbose", Func, 1}, + }, + "testing/fstest": { + {"(MapFS).Glob", Method, 16}, + {"(MapFS).Open", Method, 16}, + {"(MapFS).ReadDir", Method, 16}, + {"(MapFS).ReadFile", Method, 16}, + {"(MapFS).Stat", Method, 16}, + {"(MapFS).Sub", Method, 16}, + {"MapFS", Type, 16}, + {"MapFile", Type, 16}, + {"MapFile.Data", Field, 16}, + {"MapFile.ModTime", Field, 16}, + {"MapFile.Mode", Field, 16}, + {"MapFile.Sys", Field, 16}, + {"TestFS", Func, 16}, + }, + "testing/iotest": { + {"DataErrReader", Func, 0}, + {"ErrReader", Func, 16}, + {"ErrTimeout", Var, 0}, + {"HalfReader", Func, 0}, + {"NewReadLogger", Func, 0}, + {"NewWriteLogger", Func, 0}, + {"OneByteReader", Func, 0}, + {"TestReader", Func, 16}, + {"TimeoutReader", Func, 0}, + {"TruncateWriter", Func, 0}, + }, + "testing/quick": { + {"(*CheckEqualError).Error", Method, 0}, + {"(*CheckError).Error", Method, 0}, + {"(SetupError).Error", Method, 0}, + {"Check", Func, 0}, + {"CheckEqual", Func, 0}, + {"CheckEqualError", Type, 0}, + {"CheckEqualError.CheckError", Field, 0}, + {"CheckEqualError.Out1", Field, 0}, + {"CheckEqualError.Out2", Field, 0}, + {"CheckError", Type, 0}, + {"CheckError.Count", Field, 0}, + {"CheckError.In", Field, 0}, + {"Config", Type, 0}, + {"Config.MaxCount", Field, 0}, + {"Config.MaxCountScale", Field, 0}, + {"Config.Rand", Field, 0}, + {"Config.Values", Field, 0}, + {"Generator", Type, 0}, + {"SetupError", Type, 0}, + {"Value", Func, 0}, + }, + "testing/slogtest": { + {"Run", Func, 22}, + {"TestHandler", Func, 21}, + }, + "text/scanner": { + {"(*Position).IsValid", Method, 0}, + {"(*Scanner).Init", Method, 0}, + {"(*Scanner).IsValid", Method, 0}, + {"(*Scanner).Next", Method, 0}, + {"(*Scanner).Peek", Method, 0}, + {"(*Scanner).Pos", Method, 0}, + {"(*Scanner).Scan", Method, 0}, + {"(*Scanner).TokenText", Method, 0}, + {"(Position).String", Method, 0}, + {"(Scanner).String", Method, 0}, + {"Char", Const, 0}, + {"Comment", Const, 0}, + {"EOF", Const, 0}, + {"Float", Const, 0}, + {"GoTokens", Const, 0}, + {"GoWhitespace", Const, 0}, + {"Ident", Const, 0}, + {"Int", Const, 0}, + {"Position", Type, 0}, + {"Position.Column", Field, 0}, + {"Position.Filename", Field, 0}, + {"Position.Line", Field, 0}, + {"Position.Offset", Field, 0}, + {"RawString", Const, 0}, + {"ScanChars", Const, 0}, + {"ScanComments", Const, 0}, + {"ScanFloats", Const, 0}, + {"ScanIdents", Const, 0}, + {"ScanInts", Const, 0}, + {"ScanRawStrings", Const, 0}, + {"ScanStrings", Const, 0}, + {"Scanner", Type, 0}, + {"Scanner.Error", Field, 0}, + {"Scanner.ErrorCount", Field, 0}, + {"Scanner.IsIdentRune", Field, 4}, + {"Scanner.Mode", Field, 0}, + {"Scanner.Position", Field, 0}, + {"Scanner.Whitespace", Field, 0}, + {"SkipComments", Const, 0}, + {"String", Const, 0}, + {"TokenString", Func, 0}, + }, + "text/tabwriter": { + {"(*Writer).Flush", Method, 0}, + {"(*Writer).Init", Method, 0}, + {"(*Writer).Write", Method, 0}, + {"AlignRight", Const, 0}, + {"Debug", Const, 0}, + {"DiscardEmptyColumns", Const, 0}, + {"Escape", Const, 0}, + {"FilterHTML", Const, 0}, + {"NewWriter", Func, 0}, + {"StripEscape", Const, 0}, + {"TabIndent", Const, 0}, + {"Writer", Type, 0}, + }, + "text/template": { + {"(*Template).AddParseTree", Method, 0}, + {"(*Template).Clone", Method, 0}, + {"(*Template).DefinedTemplates", Method, 5}, + {"(*Template).Delims", Method, 0}, + {"(*Template).Execute", Method, 0}, + {"(*Template).ExecuteTemplate", Method, 0}, + {"(*Template).Funcs", Method, 0}, + {"(*Template).Lookup", Method, 0}, + {"(*Template).Name", Method, 0}, + {"(*Template).New", Method, 0}, + {"(*Template).Option", Method, 5}, + {"(*Template).Parse", Method, 0}, + {"(*Template).ParseFS", Method, 16}, + {"(*Template).ParseFiles", Method, 0}, + {"(*Template).ParseGlob", Method, 0}, + {"(*Template).Templates", Method, 0}, + {"(ExecError).Error", Method, 6}, + {"(ExecError).Unwrap", Method, 13}, + {"(Template).Copy", Method, 2}, + {"(Template).ErrorContext", Method, 1}, + {"ExecError", Type, 6}, + {"ExecError.Err", Field, 6}, + {"ExecError.Name", Field, 6}, + {"FuncMap", Type, 0}, + {"HTMLEscape", Func, 0}, + {"HTMLEscapeString", Func, 0}, + {"HTMLEscaper", Func, 0}, + {"IsTrue", Func, 6}, + {"JSEscape", Func, 0}, + {"JSEscapeString", Func, 0}, + {"JSEscaper", Func, 0}, + {"Must", Func, 0}, + {"New", Func, 0}, + {"ParseFS", Func, 16}, + {"ParseFiles", Func, 0}, + {"ParseGlob", Func, 0}, + {"Template", Type, 0}, + {"Template.Tree", Field, 0}, + {"URLQueryEscaper", Func, 0}, + }, + "text/template/parse": { + {"(*ActionNode).Copy", Method, 0}, + {"(*ActionNode).String", Method, 0}, + {"(*BoolNode).Copy", Method, 0}, + {"(*BoolNode).String", Method, 0}, + {"(*BranchNode).Copy", Method, 4}, + {"(*BranchNode).String", Method, 0}, + {"(*BreakNode).Copy", Method, 18}, + {"(*BreakNode).String", Method, 18}, + {"(*ChainNode).Add", Method, 1}, + {"(*ChainNode).Copy", Method, 1}, + {"(*ChainNode).String", Method, 1}, + {"(*CommandNode).Copy", Method, 0}, + {"(*CommandNode).String", Method, 0}, + {"(*CommentNode).Copy", Method, 16}, + {"(*CommentNode).String", Method, 16}, + {"(*ContinueNode).Copy", Method, 18}, + {"(*ContinueNode).String", Method, 18}, + {"(*DotNode).Copy", Method, 0}, + {"(*DotNode).String", Method, 0}, + {"(*DotNode).Type", Method, 0}, + {"(*FieldNode).Copy", Method, 0}, + {"(*FieldNode).String", Method, 0}, + {"(*IdentifierNode).Copy", Method, 0}, + {"(*IdentifierNode).SetPos", Method, 1}, + {"(*IdentifierNode).SetTree", Method, 4}, + {"(*IdentifierNode).String", Method, 0}, + {"(*IfNode).Copy", Method, 0}, + {"(*IfNode).String", Method, 0}, + {"(*ListNode).Copy", Method, 0}, + {"(*ListNode).CopyList", Method, 0}, + {"(*ListNode).String", Method, 0}, + {"(*NilNode).Copy", Method, 1}, + {"(*NilNode).String", Method, 1}, + {"(*NilNode).Type", Method, 1}, + {"(*NumberNode).Copy", Method, 0}, + {"(*NumberNode).String", Method, 0}, + {"(*PipeNode).Copy", Method, 0}, + {"(*PipeNode).CopyPipe", Method, 0}, + {"(*PipeNode).String", Method, 0}, + {"(*RangeNode).Copy", Method, 0}, + {"(*RangeNode).String", Method, 0}, + {"(*StringNode).Copy", Method, 0}, + {"(*StringNode).String", Method, 0}, + {"(*TemplateNode).Copy", Method, 0}, + {"(*TemplateNode).String", Method, 0}, + {"(*TextNode).Copy", Method, 0}, + {"(*TextNode).String", Method, 0}, + {"(*Tree).Copy", Method, 2}, + {"(*Tree).ErrorContext", Method, 1}, + {"(*Tree).Parse", Method, 0}, + {"(*VariableNode).Copy", Method, 0}, + {"(*VariableNode).String", Method, 0}, + {"(*WithNode).Copy", Method, 0}, + {"(*WithNode).String", Method, 0}, + {"(ActionNode).Position", Method, 1}, + {"(ActionNode).Type", Method, 0}, + {"(BoolNode).Position", Method, 1}, + {"(BoolNode).Type", Method, 0}, + {"(BranchNode).Position", Method, 1}, + {"(BranchNode).Type", Method, 0}, + {"(BreakNode).Position", Method, 18}, + {"(BreakNode).Type", Method, 18}, + {"(ChainNode).Position", Method, 1}, + {"(ChainNode).Type", Method, 1}, + {"(CommandNode).Position", Method, 1}, + {"(CommandNode).Type", Method, 0}, + {"(CommentNode).Position", Method, 16}, + {"(CommentNode).Type", Method, 16}, + {"(ContinueNode).Position", Method, 18}, + {"(ContinueNode).Type", Method, 18}, + {"(DotNode).Position", Method, 1}, + {"(FieldNode).Position", Method, 1}, + {"(FieldNode).Type", Method, 0}, + {"(IdentifierNode).Position", Method, 1}, + {"(IdentifierNode).Type", Method, 0}, + {"(IfNode).Position", Method, 1}, + {"(IfNode).Type", Method, 0}, + {"(ListNode).Position", Method, 1}, + {"(ListNode).Type", Method, 0}, + {"(NilNode).Position", Method, 1}, + {"(NodeType).Type", Method, 0}, + {"(NumberNode).Position", Method, 1}, + {"(NumberNode).Type", Method, 0}, + {"(PipeNode).Position", Method, 1}, + {"(PipeNode).Type", Method, 0}, + {"(Pos).Position", Method, 1}, + {"(RangeNode).Position", Method, 1}, + {"(RangeNode).Type", Method, 0}, + {"(StringNode).Position", Method, 1}, + {"(StringNode).Type", Method, 0}, + {"(TemplateNode).Position", Method, 1}, + {"(TemplateNode).Type", Method, 0}, + {"(TextNode).Position", Method, 1}, + {"(TextNode).Type", Method, 0}, + {"(VariableNode).Position", Method, 1}, + {"(VariableNode).Type", Method, 0}, + {"(WithNode).Position", Method, 1}, + {"(WithNode).Type", Method, 0}, + {"ActionNode", Type, 0}, + {"ActionNode.Line", Field, 0}, + {"ActionNode.NodeType", Field, 0}, + {"ActionNode.Pipe", Field, 0}, + {"ActionNode.Pos", Field, 1}, + {"BoolNode", Type, 0}, + {"BoolNode.NodeType", Field, 0}, + {"BoolNode.Pos", Field, 1}, + {"BoolNode.True", Field, 0}, + {"BranchNode", Type, 0}, + {"BranchNode.ElseList", Field, 0}, + {"BranchNode.Line", Field, 0}, + {"BranchNode.List", Field, 0}, + {"BranchNode.NodeType", Field, 0}, + {"BranchNode.Pipe", Field, 0}, + {"BranchNode.Pos", Field, 1}, + {"BreakNode", Type, 18}, + {"BreakNode.Line", Field, 18}, + {"BreakNode.NodeType", Field, 18}, + {"BreakNode.Pos", Field, 18}, + {"ChainNode", Type, 1}, + {"ChainNode.Field", Field, 1}, + {"ChainNode.Node", Field, 1}, + {"ChainNode.NodeType", Field, 1}, + {"ChainNode.Pos", Field, 1}, + {"CommandNode", Type, 0}, + {"CommandNode.Args", Field, 0}, + {"CommandNode.NodeType", Field, 0}, + {"CommandNode.Pos", Field, 1}, + {"CommentNode", Type, 16}, + {"CommentNode.NodeType", Field, 16}, + {"CommentNode.Pos", Field, 16}, + {"CommentNode.Text", Field, 16}, + {"ContinueNode", Type, 18}, + {"ContinueNode.Line", Field, 18}, + {"ContinueNode.NodeType", Field, 18}, + {"ContinueNode.Pos", Field, 18}, + {"DotNode", Type, 0}, + {"DotNode.NodeType", Field, 4}, + {"DotNode.Pos", Field, 1}, + {"FieldNode", Type, 0}, + {"FieldNode.Ident", Field, 0}, + {"FieldNode.NodeType", Field, 0}, + {"FieldNode.Pos", Field, 1}, + {"IdentifierNode", Type, 0}, + {"IdentifierNode.Ident", Field, 0}, + {"IdentifierNode.NodeType", Field, 0}, + {"IdentifierNode.Pos", Field, 1}, + {"IfNode", Type, 0}, + {"IfNode.BranchNode", Field, 0}, + {"IsEmptyTree", Func, 0}, + {"ListNode", Type, 0}, + {"ListNode.NodeType", Field, 0}, + {"ListNode.Nodes", Field, 0}, + {"ListNode.Pos", Field, 1}, + {"Mode", Type, 16}, + {"New", Func, 0}, + {"NewIdentifier", Func, 0}, + {"NilNode", Type, 1}, + {"NilNode.NodeType", Field, 4}, + {"NilNode.Pos", Field, 1}, + {"Node", Type, 0}, + {"NodeAction", Const, 0}, + {"NodeBool", Const, 0}, + {"NodeBreak", Const, 18}, + {"NodeChain", Const, 1}, + {"NodeCommand", Const, 0}, + {"NodeComment", Const, 16}, + {"NodeContinue", Const, 18}, + {"NodeDot", Const, 0}, + {"NodeField", Const, 0}, + {"NodeIdentifier", Const, 0}, + {"NodeIf", Const, 0}, + {"NodeList", Const, 0}, + {"NodeNil", Const, 1}, + {"NodeNumber", Const, 0}, + {"NodePipe", Const, 0}, + {"NodeRange", Const, 0}, + {"NodeString", Const, 0}, + {"NodeTemplate", Const, 0}, + {"NodeText", Const, 0}, + {"NodeType", Type, 0}, + {"NodeVariable", Const, 0}, + {"NodeWith", Const, 0}, + {"NumberNode", Type, 0}, + {"NumberNode.Complex128", Field, 0}, + {"NumberNode.Float64", Field, 0}, + {"NumberNode.Int64", Field, 0}, + {"NumberNode.IsComplex", Field, 0}, + {"NumberNode.IsFloat", Field, 0}, + {"NumberNode.IsInt", Field, 0}, + {"NumberNode.IsUint", Field, 0}, + {"NumberNode.NodeType", Field, 0}, + {"NumberNode.Pos", Field, 1}, + {"NumberNode.Text", Field, 0}, + {"NumberNode.Uint64", Field, 0}, + {"Parse", Func, 0}, + {"ParseComments", Const, 16}, + {"PipeNode", Type, 0}, + {"PipeNode.Cmds", Field, 0}, + {"PipeNode.Decl", Field, 0}, + {"PipeNode.IsAssign", Field, 11}, + {"PipeNode.Line", Field, 0}, + {"PipeNode.NodeType", Field, 0}, + {"PipeNode.Pos", Field, 1}, + {"Pos", Type, 1}, + {"RangeNode", Type, 0}, + {"RangeNode.BranchNode", Field, 0}, + {"SkipFuncCheck", Const, 17}, + {"StringNode", Type, 0}, + {"StringNode.NodeType", Field, 0}, + {"StringNode.Pos", Field, 1}, + {"StringNode.Quoted", Field, 0}, + {"StringNode.Text", Field, 0}, + {"TemplateNode", Type, 0}, + {"TemplateNode.Line", Field, 0}, + {"TemplateNode.Name", Field, 0}, + {"TemplateNode.NodeType", Field, 0}, + {"TemplateNode.Pipe", Field, 0}, + {"TemplateNode.Pos", Field, 1}, + {"TextNode", Type, 0}, + {"TextNode.NodeType", Field, 0}, + {"TextNode.Pos", Field, 1}, + {"TextNode.Text", Field, 0}, + {"Tree", Type, 0}, + {"Tree.Mode", Field, 16}, + {"Tree.Name", Field, 0}, + {"Tree.ParseName", Field, 1}, + {"Tree.Root", Field, 0}, + {"VariableNode", Type, 0}, + {"VariableNode.Ident", Field, 0}, + {"VariableNode.NodeType", Field, 0}, + {"VariableNode.Pos", Field, 1}, + {"WithNode", Type, 0}, + {"WithNode.BranchNode", Field, 0}, + }, + "time": { + {"(*Location).String", Method, 0}, + {"(*ParseError).Error", Method, 0}, + {"(*Ticker).Reset", Method, 15}, + {"(*Ticker).Stop", Method, 0}, + {"(*Time).GobDecode", Method, 0}, + {"(*Time).UnmarshalBinary", Method, 2}, + {"(*Time).UnmarshalJSON", Method, 0}, + {"(*Time).UnmarshalText", Method, 2}, + {"(*Timer).Reset", Method, 1}, + {"(*Timer).Stop", Method, 0}, + {"(Duration).Abs", Method, 19}, + {"(Duration).Hours", Method, 0}, + {"(Duration).Microseconds", Method, 13}, + {"(Duration).Milliseconds", Method, 13}, + {"(Duration).Minutes", Method, 0}, + {"(Duration).Nanoseconds", Method, 0}, + {"(Duration).Round", Method, 9}, + {"(Duration).Seconds", Method, 0}, + {"(Duration).String", Method, 0}, + {"(Duration).Truncate", Method, 9}, + {"(Month).String", Method, 0}, + {"(Time).Add", Method, 0}, + {"(Time).AddDate", Method, 0}, + {"(Time).After", Method, 0}, + {"(Time).AppendFormat", Method, 5}, + {"(Time).Before", Method, 0}, + {"(Time).Clock", Method, 0}, + {"(Time).Compare", Method, 20}, + {"(Time).Date", Method, 0}, + {"(Time).Day", Method, 0}, + {"(Time).Equal", Method, 0}, + {"(Time).Format", Method, 0}, + {"(Time).GoString", Method, 17}, + {"(Time).GobEncode", Method, 0}, + {"(Time).Hour", Method, 0}, + {"(Time).ISOWeek", Method, 0}, + {"(Time).In", Method, 0}, + {"(Time).IsDST", Method, 17}, + {"(Time).IsZero", Method, 0}, + {"(Time).Local", Method, 0}, + {"(Time).Location", Method, 0}, + {"(Time).MarshalBinary", Method, 2}, + {"(Time).MarshalJSON", Method, 0}, + {"(Time).MarshalText", Method, 2}, + {"(Time).Minute", Method, 0}, + {"(Time).Month", Method, 0}, + {"(Time).Nanosecond", Method, 0}, + {"(Time).Round", Method, 1}, + {"(Time).Second", Method, 0}, + {"(Time).String", Method, 0}, + {"(Time).Sub", Method, 0}, + {"(Time).Truncate", Method, 1}, + {"(Time).UTC", Method, 0}, + {"(Time).Unix", Method, 0}, + {"(Time).UnixMicro", Method, 17}, + {"(Time).UnixMilli", Method, 17}, + {"(Time).UnixNano", Method, 0}, + {"(Time).Weekday", Method, 0}, + {"(Time).Year", Method, 0}, + {"(Time).YearDay", Method, 1}, + {"(Time).Zone", Method, 0}, + {"(Time).ZoneBounds", Method, 19}, + {"(Weekday).String", Method, 0}, + {"ANSIC", Const, 0}, + {"After", Func, 0}, + {"AfterFunc", Func, 0}, + {"April", Const, 0}, + {"August", Const, 0}, + {"Date", Func, 0}, + {"DateOnly", Const, 20}, + {"DateTime", Const, 20}, + {"December", Const, 0}, + {"Duration", Type, 0}, + {"February", Const, 0}, + {"FixedZone", Func, 0}, + {"Friday", Const, 0}, + {"Hour", Const, 0}, + {"January", Const, 0}, + {"July", Const, 0}, + {"June", Const, 0}, + {"Kitchen", Const, 0}, + {"Layout", Const, 17}, + {"LoadLocation", Func, 0}, + {"LoadLocationFromTZData", Func, 10}, + {"Local", Var, 0}, + {"Location", Type, 0}, + {"March", Const, 0}, + {"May", Const, 0}, + {"Microsecond", Const, 0}, + {"Millisecond", Const, 0}, + {"Minute", Const, 0}, + {"Monday", Const, 0}, + {"Month", Type, 0}, + {"Nanosecond", Const, 0}, + {"NewTicker", Func, 0}, + {"NewTimer", Func, 0}, + {"November", Const, 0}, + {"Now", Func, 0}, + {"October", Const, 0}, + {"Parse", Func, 0}, + {"ParseDuration", Func, 0}, + {"ParseError", Type, 0}, + {"ParseError.Layout", Field, 0}, + {"ParseError.LayoutElem", Field, 0}, + {"ParseError.Message", Field, 0}, + {"ParseError.Value", Field, 0}, + {"ParseError.ValueElem", Field, 0}, + {"ParseInLocation", Func, 1}, + {"RFC1123", Const, 0}, + {"RFC1123Z", Const, 0}, + {"RFC3339", Const, 0}, + {"RFC3339Nano", Const, 0}, + {"RFC822", Const, 0}, + {"RFC822Z", Const, 0}, + {"RFC850", Const, 0}, + {"RubyDate", Const, 0}, + {"Saturday", Const, 0}, + {"Second", Const, 0}, + {"September", Const, 0}, + {"Since", Func, 0}, + {"Sleep", Func, 0}, + {"Stamp", Const, 0}, + {"StampMicro", Const, 0}, + {"StampMilli", Const, 0}, + {"StampNano", Const, 0}, + {"Sunday", Const, 0}, + {"Thursday", Const, 0}, + {"Tick", Func, 0}, + {"Ticker", Type, 0}, + {"Ticker.C", Field, 0}, + {"Time", Type, 0}, + {"TimeOnly", Const, 20}, + {"Timer", Type, 0}, + {"Timer.C", Field, 0}, + {"Tuesday", Const, 0}, + {"UTC", Var, 0}, + {"Unix", Func, 0}, + {"UnixDate", Const, 0}, + {"UnixMicro", Func, 17}, + {"UnixMilli", Func, 17}, + {"Until", Func, 8}, + {"Wednesday", Const, 0}, + {"Weekday", Type, 0}, + }, + "unicode": { + {"(SpecialCase).ToLower", Method, 0}, + {"(SpecialCase).ToTitle", Method, 0}, + {"(SpecialCase).ToUpper", Method, 0}, + {"ASCII_Hex_Digit", Var, 0}, + {"Adlam", Var, 7}, + {"Ahom", Var, 5}, + {"Anatolian_Hieroglyphs", Var, 5}, + {"Arabic", Var, 0}, + {"Armenian", Var, 0}, + {"Avestan", Var, 0}, + {"AzeriCase", Var, 0}, + {"Balinese", Var, 0}, + {"Bamum", Var, 0}, + {"Bassa_Vah", Var, 4}, + {"Batak", Var, 0}, + {"Bengali", Var, 0}, + {"Bhaiksuki", Var, 7}, + {"Bidi_Control", Var, 0}, + {"Bopomofo", Var, 0}, + {"Brahmi", Var, 0}, + {"Braille", Var, 0}, + {"Buginese", Var, 0}, + {"Buhid", Var, 0}, + {"C", Var, 0}, + {"Canadian_Aboriginal", Var, 0}, + {"Carian", Var, 0}, + {"CaseRange", Type, 0}, + {"CaseRange.Delta", Field, 0}, + {"CaseRange.Hi", Field, 0}, + {"CaseRange.Lo", Field, 0}, + {"CaseRanges", Var, 0}, + {"Categories", Var, 0}, + {"Caucasian_Albanian", Var, 4}, + {"Cc", Var, 0}, + {"Cf", Var, 0}, + {"Chakma", Var, 1}, + {"Cham", Var, 0}, + {"Cherokee", Var, 0}, + {"Chorasmian", Var, 16}, + {"Co", Var, 0}, + {"Common", Var, 0}, + {"Coptic", Var, 0}, + {"Cs", Var, 0}, + {"Cuneiform", Var, 0}, + {"Cypriot", Var, 0}, + {"Cypro_Minoan", Var, 21}, + {"Cyrillic", Var, 0}, + {"Dash", Var, 0}, + {"Deprecated", Var, 0}, + {"Deseret", Var, 0}, + {"Devanagari", Var, 0}, + {"Diacritic", Var, 0}, + {"Digit", Var, 0}, + {"Dives_Akuru", Var, 16}, + {"Dogra", Var, 13}, + {"Duployan", Var, 4}, + {"Egyptian_Hieroglyphs", Var, 0}, + {"Elbasan", Var, 4}, + {"Elymaic", Var, 14}, + {"Ethiopic", Var, 0}, + {"Extender", Var, 0}, + {"FoldCategory", Var, 0}, + {"FoldScript", Var, 0}, + {"Georgian", Var, 0}, + {"Glagolitic", Var, 0}, + {"Gothic", Var, 0}, + {"Grantha", Var, 4}, + {"GraphicRanges", Var, 0}, + {"Greek", Var, 0}, + {"Gujarati", Var, 0}, + {"Gunjala_Gondi", Var, 13}, + {"Gurmukhi", Var, 0}, + {"Han", Var, 0}, + {"Hangul", Var, 0}, + {"Hanifi_Rohingya", Var, 13}, + {"Hanunoo", Var, 0}, + {"Hatran", Var, 5}, + {"Hebrew", Var, 0}, + {"Hex_Digit", Var, 0}, + {"Hiragana", Var, 0}, + {"Hyphen", Var, 0}, + {"IDS_Binary_Operator", Var, 0}, + {"IDS_Trinary_Operator", Var, 0}, + {"Ideographic", Var, 0}, + {"Imperial_Aramaic", Var, 0}, + {"In", Func, 2}, + {"Inherited", Var, 0}, + {"Inscriptional_Pahlavi", Var, 0}, + {"Inscriptional_Parthian", Var, 0}, + {"Is", Func, 0}, + {"IsControl", Func, 0}, + {"IsDigit", Func, 0}, + {"IsGraphic", Func, 0}, + {"IsLetter", Func, 0}, + {"IsLower", Func, 0}, + {"IsMark", Func, 0}, + {"IsNumber", Func, 0}, + {"IsOneOf", Func, 0}, + {"IsPrint", Func, 0}, + {"IsPunct", Func, 0}, + {"IsSpace", Func, 0}, + {"IsSymbol", Func, 0}, + {"IsTitle", Func, 0}, + {"IsUpper", Func, 0}, + {"Javanese", Var, 0}, + {"Join_Control", Var, 0}, + {"Kaithi", Var, 0}, + {"Kannada", Var, 0}, + {"Katakana", Var, 0}, + {"Kawi", Var, 21}, + {"Kayah_Li", Var, 0}, + {"Kharoshthi", Var, 0}, + {"Khitan_Small_Script", Var, 16}, + {"Khmer", Var, 0}, + {"Khojki", Var, 4}, + {"Khudawadi", Var, 4}, + {"L", Var, 0}, + {"Lao", Var, 0}, + {"Latin", Var, 0}, + {"Lepcha", Var, 0}, + {"Letter", Var, 0}, + {"Limbu", Var, 0}, + {"Linear_A", Var, 4}, + {"Linear_B", Var, 0}, + {"Lisu", Var, 0}, + {"Ll", Var, 0}, + {"Lm", Var, 0}, + {"Lo", Var, 0}, + {"Logical_Order_Exception", Var, 0}, + {"Lower", Var, 0}, + {"LowerCase", Const, 0}, + {"Lt", Var, 0}, + {"Lu", Var, 0}, + {"Lycian", Var, 0}, + {"Lydian", Var, 0}, + {"M", Var, 0}, + {"Mahajani", Var, 4}, + {"Makasar", Var, 13}, + {"Malayalam", Var, 0}, + {"Mandaic", Var, 0}, + {"Manichaean", Var, 4}, + {"Marchen", Var, 7}, + {"Mark", Var, 0}, + {"Masaram_Gondi", Var, 10}, + {"MaxASCII", Const, 0}, + {"MaxCase", Const, 0}, + {"MaxLatin1", Const, 0}, + {"MaxRune", Const, 0}, + {"Mc", Var, 0}, + {"Me", Var, 0}, + {"Medefaidrin", Var, 13}, + {"Meetei_Mayek", Var, 0}, + {"Mende_Kikakui", Var, 4}, + {"Meroitic_Cursive", Var, 1}, + {"Meroitic_Hieroglyphs", Var, 1}, + {"Miao", Var, 1}, + {"Mn", Var, 0}, + {"Modi", Var, 4}, + {"Mongolian", Var, 0}, + {"Mro", Var, 4}, + {"Multani", Var, 5}, + {"Myanmar", Var, 0}, + {"N", Var, 0}, + {"Nabataean", Var, 4}, + {"Nag_Mundari", Var, 21}, + {"Nandinagari", Var, 14}, + {"Nd", Var, 0}, + {"New_Tai_Lue", Var, 0}, + {"Newa", Var, 7}, + {"Nko", Var, 0}, + {"Nl", Var, 0}, + {"No", Var, 0}, + {"Noncharacter_Code_Point", Var, 0}, + {"Number", Var, 0}, + {"Nushu", Var, 10}, + {"Nyiakeng_Puachue_Hmong", Var, 14}, + {"Ogham", Var, 0}, + {"Ol_Chiki", Var, 0}, + {"Old_Hungarian", Var, 5}, + {"Old_Italic", Var, 0}, + {"Old_North_Arabian", Var, 4}, + {"Old_Permic", Var, 4}, + {"Old_Persian", Var, 0}, + {"Old_Sogdian", Var, 13}, + {"Old_South_Arabian", Var, 0}, + {"Old_Turkic", Var, 0}, + {"Old_Uyghur", Var, 21}, + {"Oriya", Var, 0}, + {"Osage", Var, 7}, + {"Osmanya", Var, 0}, + {"Other", Var, 0}, + {"Other_Alphabetic", Var, 0}, + {"Other_Default_Ignorable_Code_Point", Var, 0}, + {"Other_Grapheme_Extend", Var, 0}, + {"Other_ID_Continue", Var, 0}, + {"Other_ID_Start", Var, 0}, + {"Other_Lowercase", Var, 0}, + {"Other_Math", Var, 0}, + {"Other_Uppercase", Var, 0}, + {"P", Var, 0}, + {"Pahawh_Hmong", Var, 4}, + {"Palmyrene", Var, 4}, + {"Pattern_Syntax", Var, 0}, + {"Pattern_White_Space", Var, 0}, + {"Pau_Cin_Hau", Var, 4}, + {"Pc", Var, 0}, + {"Pd", Var, 0}, + {"Pe", Var, 0}, + {"Pf", Var, 0}, + {"Phags_Pa", Var, 0}, + {"Phoenician", Var, 0}, + {"Pi", Var, 0}, + {"Po", Var, 0}, + {"Prepended_Concatenation_Mark", Var, 7}, + {"PrintRanges", Var, 0}, + {"Properties", Var, 0}, + {"Ps", Var, 0}, + {"Psalter_Pahlavi", Var, 4}, + {"Punct", Var, 0}, + {"Quotation_Mark", Var, 0}, + {"Radical", Var, 0}, + {"Range16", Type, 0}, + {"Range16.Hi", Field, 0}, + {"Range16.Lo", Field, 0}, + {"Range16.Stride", Field, 0}, + {"Range32", Type, 0}, + {"Range32.Hi", Field, 0}, + {"Range32.Lo", Field, 0}, + {"Range32.Stride", Field, 0}, + {"RangeTable", Type, 0}, + {"RangeTable.LatinOffset", Field, 1}, + {"RangeTable.R16", Field, 0}, + {"RangeTable.R32", Field, 0}, + {"Regional_Indicator", Var, 10}, + {"Rejang", Var, 0}, + {"ReplacementChar", Const, 0}, + {"Runic", Var, 0}, + {"S", Var, 0}, + {"STerm", Var, 0}, + {"Samaritan", Var, 0}, + {"Saurashtra", Var, 0}, + {"Sc", Var, 0}, + {"Scripts", Var, 0}, + {"Sentence_Terminal", Var, 7}, + {"Sharada", Var, 1}, + {"Shavian", Var, 0}, + {"Siddham", Var, 4}, + {"SignWriting", Var, 5}, + {"SimpleFold", Func, 0}, + {"Sinhala", Var, 0}, + {"Sk", Var, 0}, + {"Sm", Var, 0}, + {"So", Var, 0}, + {"Soft_Dotted", Var, 0}, + {"Sogdian", Var, 13}, + {"Sora_Sompeng", Var, 1}, + {"Soyombo", Var, 10}, + {"Space", Var, 0}, + {"SpecialCase", Type, 0}, + {"Sundanese", Var, 0}, + {"Syloti_Nagri", Var, 0}, + {"Symbol", Var, 0}, + {"Syriac", Var, 0}, + {"Tagalog", Var, 0}, + {"Tagbanwa", Var, 0}, + {"Tai_Le", Var, 0}, + {"Tai_Tham", Var, 0}, + {"Tai_Viet", Var, 0}, + {"Takri", Var, 1}, + {"Tamil", Var, 0}, + {"Tangsa", Var, 21}, + {"Tangut", Var, 7}, + {"Telugu", Var, 0}, + {"Terminal_Punctuation", Var, 0}, + {"Thaana", Var, 0}, + {"Thai", Var, 0}, + {"Tibetan", Var, 0}, + {"Tifinagh", Var, 0}, + {"Tirhuta", Var, 4}, + {"Title", Var, 0}, + {"TitleCase", Const, 0}, + {"To", Func, 0}, + {"ToLower", Func, 0}, + {"ToTitle", Func, 0}, + {"ToUpper", Func, 0}, + {"Toto", Var, 21}, + {"TurkishCase", Var, 0}, + {"Ugaritic", Var, 0}, + {"Unified_Ideograph", Var, 0}, + {"Upper", Var, 0}, + {"UpperCase", Const, 0}, + {"UpperLower", Const, 0}, + {"Vai", Var, 0}, + {"Variation_Selector", Var, 0}, + {"Version", Const, 0}, + {"Vithkuqi", Var, 21}, + {"Wancho", Var, 14}, + {"Warang_Citi", Var, 4}, + {"White_Space", Var, 0}, + {"Yezidi", Var, 16}, + {"Yi", Var, 0}, + {"Z", Var, 0}, + {"Zanabazar_Square", Var, 10}, + {"Zl", Var, 0}, + {"Zp", Var, 0}, + {"Zs", Var, 0}, + }, + "unicode/utf16": { + {"AppendRune", Func, 20}, + {"Decode", Func, 0}, + {"DecodeRune", Func, 0}, + {"Encode", Func, 0}, + {"EncodeRune", Func, 0}, + {"IsSurrogate", Func, 0}, + }, + "unicode/utf8": { + {"AppendRune", Func, 18}, + {"DecodeLastRune", Func, 0}, + {"DecodeLastRuneInString", Func, 0}, + {"DecodeRune", Func, 0}, + {"DecodeRuneInString", Func, 0}, + {"EncodeRune", Func, 0}, + {"FullRune", Func, 0}, + {"FullRuneInString", Func, 0}, + {"MaxRune", Const, 0}, + {"RuneCount", Func, 0}, + {"RuneCountInString", Func, 0}, + {"RuneError", Const, 0}, + {"RuneLen", Func, 0}, + {"RuneSelf", Const, 0}, + {"RuneStart", Func, 0}, + {"UTFMax", Const, 0}, + {"Valid", Func, 0}, + {"ValidRune", Func, 1}, + {"ValidString", Func, 0}, + }, + "unsafe": { + {"Add", Func, 0}, + {"Alignof", Func, 0}, + {"Offsetof", Func, 0}, + {"Pointer", Type, 0}, + {"Sizeof", Func, 0}, + {"Slice", Func, 0}, + {"SliceData", Func, 0}, + {"String", Func, 0}, + {"StringData", Func, 0}, + }, +} diff --git a/vendor/golang.org/x/tools/internal/stdlib/stdlib.go b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go new file mode 100644 index 00000000..98904017 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go @@ -0,0 +1,97 @@ +// 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. + +//go:generate go run generate.go + +// Package stdlib provides a table of all exported symbols in the +// standard library, along with the version at which they first +// appeared. +package stdlib + +import ( + "fmt" + "strings" +) + +type Symbol struct { + Name string + Kind Kind + Version Version // Go version that first included the symbol +} + +// A Kind indicates the kind of a symbol: +// function, variable, constant, type, and so on. +type Kind int8 + +const ( + Invalid Kind = iota // Example name: + Type // "Buffer" + Func // "Println" + Var // "EOF" + Const // "Pi" + Field // "Point.X" + Method // "(*Buffer).Grow" +) + +func (kind Kind) String() string { + return [...]string{ + Invalid: "invalid", + Type: "type", + Func: "func", + Var: "var", + Const: "const", + Field: "field", + Method: "method", + }[kind] +} + +// A Version represents a version of Go of the form "go1.%d". +type Version int8 + +// String returns a version string of the form "go1.23", without allocating. +func (v Version) String() string { return versions[v] } + +var versions [30]string // (increase constant as needed) + +func init() { + for i := range versions { + versions[i] = fmt.Sprintf("go1.%d", i) + } +} + +// HasPackage reports whether the specified package path is part of +// the standard library's public API. +func HasPackage(path string) bool { + _, ok := PackageSymbols[path] + return ok +} + +// SplitField splits the field symbol name into type and field +// components. It must be called only on Field symbols. +// +// Example: "File.Package" -> ("File", "Package") +func (sym *Symbol) SplitField() (typename, name string) { + if sym.Kind != Field { + panic("not a field") + } + typename, name, _ = strings.Cut(sym.Name, ".") + return +} + +// SplitMethod splits the method symbol name into pointer, receiver, +// and method components. It must be called only on Method symbols. +// +// Example: "(*Buffer).Grow" -> (true, "Buffer", "Grow") +func (sym *Symbol) SplitMethod() (ptr bool, recv, name string) { + if sym.Kind != Method { + panic("not a method") + } + recv, name, _ = strings.Cut(sym.Name, ".") + recv = recv[len("(") : len(recv)-len(")")] + ptr = recv[0] == '*' + if ptr { + recv = recv[len("*"):] + } + return +} diff --git a/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go b/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go new file mode 100644 index 00000000..ff9437a3 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go @@ -0,0 +1,137 @@ +// 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 tokeninternal provides access to some internal features of the token +// package. +package tokeninternal + +import ( + "fmt" + "go/token" + "sort" + "sync" + "unsafe" +) + +// GetLines returns the table of line-start offsets from a token.File. +func GetLines(file *token.File) []int { + // token.File has a Lines method on Go 1.21 and later. + if file, ok := (interface{})(file).(interface{ Lines() []int }); ok { + return file.Lines() + } + + // This declaration must match that of token.File. + // This creates a risk of dependency skew. + // For now we check that the size of the two + // declarations is the same, on the (fragile) assumption + // that future changes would add fields. + type tokenFile119 struct { + _ string + _ int + _ int + mu sync.Mutex // we're not complete monsters + lines []int + _ []struct{} + } + + if unsafe.Sizeof(*file) != unsafe.Sizeof(tokenFile119{}) { + panic("unexpected token.File size") + } + var ptr *tokenFile119 + type uP = unsafe.Pointer + *(*uP)(uP(&ptr)) = uP(file) + ptr.mu.Lock() + defer ptr.mu.Unlock() + return ptr.lines +} + +// AddExistingFiles adds the specified files to the FileSet if they +// are not already present. It panics if any pair of files in the +// resulting FileSet would overlap. +func AddExistingFiles(fset *token.FileSet, files []*token.File) { + // Punch through the FileSet encapsulation. + type tokenFileSet struct { + // This type remained essentially consistent from go1.16 to go1.21. + mutex sync.RWMutex + base int + files []*token.File + _ *token.File // changed to atomic.Pointer[token.File] in go1.19 + } + + // If the size of token.FileSet changes, this will fail to compile. + const delta = int64(unsafe.Sizeof(tokenFileSet{})) - int64(unsafe.Sizeof(token.FileSet{})) + var _ [-delta * delta]int + + type uP = unsafe.Pointer + var ptr *tokenFileSet + *(*uP)(uP(&ptr)) = uP(fset) + ptr.mutex.Lock() + defer ptr.mutex.Unlock() + + // Merge and sort. + newFiles := append(ptr.files, files...) + sort.Slice(newFiles, func(i, j int) bool { + return newFiles[i].Base() < newFiles[j].Base() + }) + + // Reject overlapping files. + // Discard adjacent identical files. + out := newFiles[:0] + for i, file := range newFiles { + if i > 0 { + prev := newFiles[i-1] + if file == prev { + continue + } + if prev.Base()+prev.Size()+1 > file.Base() { + panic(fmt.Sprintf("file %s (%d-%d) overlaps with file %s (%d-%d)", + prev.Name(), prev.Base(), prev.Base()+prev.Size(), + file.Name(), file.Base(), file.Base()+file.Size())) + } + } + out = append(out, file) + } + newFiles = out + + ptr.files = newFiles + + // Advance FileSet.Base(). + if len(newFiles) > 0 { + last := newFiles[len(newFiles)-1] + newBase := last.Base() + last.Size() + 1 + if ptr.base < newBase { + ptr.base = newBase + } + } +} + +// FileSetFor returns a new FileSet containing a sequence of new Files with +// the same base, size, and line as the input files, for use in APIs that +// require a FileSet. +// +// Precondition: the input files must be non-overlapping, and sorted in order +// of their Base. +func FileSetFor(files ...*token.File) *token.FileSet { + fset := token.NewFileSet() + for _, f := range files { + f2 := fset.AddFile(f.Name(), f.Base(), f.Size()) + lines := GetLines(f) + f2.SetLines(lines) + } + return fset +} + +// CloneFileSet creates a new FileSet holding all files in fset. It does not +// create copies of the token.Files in fset: they are added to the resulting +// FileSet unmodified. +func CloneFileSet(fset *token.FileSet) *token.FileSet { + var files []*token.File + fset.Iterate(func(f *token.File) bool { + files = append(files, f) + return true + }) + newFileSet := token.NewFileSet() + AddExistingFiles(newFileSet, files) + return newFileSet +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go new file mode 100644 index 00000000..e0c27ed2 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go @@ -0,0 +1,1560 @@ +// 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 typesinternal + +//go:generate stringer -type=ErrorCode + +type ErrorCode int + +// This file defines the error codes that can be produced during type-checking. +// Collectively, these codes provide an identifier that may be used to +// implement special handling for certain types of errors. +// +// Error codes should be fine-grained enough that the exact nature of the error +// can be easily determined, but coarse enough that they are not an +// implementation detail of the type checking algorithm. As a rule-of-thumb, +// errors should be considered equivalent if there is a theoretical refactoring +// of the type checker in which they are emitted in exactly one place. For +// example, the type checker emits different error messages for "too many +// arguments" and "too few arguments", but one can imagine an alternative type +// checker where this check instead just emits a single "wrong number of +// arguments", so these errors should have the same code. +// +// Error code names should be as brief as possible while retaining accuracy and +// distinctiveness. In most cases names should start with an adjective +// describing the nature of the error (e.g. "invalid", "unused", "misplaced"), +// and end with a noun identifying the relevant language object. For example, +// "DuplicateDecl" or "InvalidSliceExpr". For brevity, naming follows the +// convention that "bad" implies a problem with syntax, and "invalid" implies a +// problem with types. + +const ( + // InvalidSyntaxTree occurs if an invalid syntax tree is provided + // to the type checker. It should never happen. + InvalidSyntaxTree ErrorCode = -1 +) + +const ( + _ ErrorCode = iota + + // Test is reserved for errors that only apply while in self-test mode. + Test + + /* package names */ + + // BlankPkgName occurs when a package name is the blank identifier "_". + // + // Per the spec: + // "The PackageName must not be the blank identifier." + BlankPkgName + + // MismatchedPkgName occurs when a file's package name doesn't match the + // package name already established by other files. + MismatchedPkgName + + // InvalidPkgUse occurs when a package identifier is used outside of a + // selector expression. + // + // Example: + // import "fmt" + // + // var _ = fmt + InvalidPkgUse + + /* imports */ + + // BadImportPath occurs when an import path is not valid. + BadImportPath + + // BrokenImport occurs when importing a package fails. + // + // Example: + // import "amissingpackage" + BrokenImport + + // ImportCRenamed occurs when the special import "C" is renamed. "C" is a + // pseudo-package, and must not be renamed. + // + // Example: + // import _ "C" + ImportCRenamed + + // UnusedImport occurs when an import is unused. + // + // Example: + // import "fmt" + // + // func main() {} + UnusedImport + + /* initialization */ + + // InvalidInitCycle occurs when an invalid cycle is detected within the + // initialization graph. + // + // Example: + // var x int = f() + // + // func f() int { return x } + InvalidInitCycle + + /* decls */ + + // DuplicateDecl occurs when an identifier is declared multiple times. + // + // Example: + // var x = 1 + // var x = 2 + DuplicateDecl + + // InvalidDeclCycle occurs when a declaration cycle is not valid. + // + // Example: + // import "unsafe" + // + // type T struct { + // a [n]int + // } + // + // var n = unsafe.Sizeof(T{}) + InvalidDeclCycle + + // InvalidTypeCycle occurs when a cycle in type definitions results in a + // type that is not well-defined. + // + // Example: + // import "unsafe" + // + // type T [unsafe.Sizeof(T{})]int + InvalidTypeCycle + + /* decls > const */ + + // InvalidConstInit occurs when a const declaration has a non-constant + // initializer. + // + // Example: + // var x int + // const _ = x + InvalidConstInit + + // InvalidConstVal occurs when a const value cannot be converted to its + // target type. + // + // TODO(findleyr): this error code and example are not very clear. Consider + // removing it. + // + // Example: + // const _ = 1 << "hello" + InvalidConstVal + + // InvalidConstType occurs when the underlying type in a const declaration + // is not a valid constant type. + // + // Example: + // const c *int = 4 + InvalidConstType + + /* decls > var (+ other variable assignment codes) */ + + // UntypedNilUse occurs when the predeclared (untyped) value nil is used to + // initialize a variable declared without an explicit type. + // + // Example: + // var x = nil + UntypedNilUse + + // WrongAssignCount occurs when the number of values on the right-hand side + // of an assignment or initialization expression does not match the number + // of variables on the left-hand side. + // + // Example: + // var x = 1, 2 + WrongAssignCount + + // UnassignableOperand occurs when the left-hand side of an assignment is + // not assignable. + // + // Example: + // func f() { + // const c = 1 + // c = 2 + // } + UnassignableOperand + + // NoNewVar occurs when a short variable declaration (':=') does not declare + // new variables. + // + // Example: + // func f() { + // x := 1 + // x := 2 + // } + NoNewVar + + // MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does + // not have single-valued left-hand or right-hand side. + // + // Per the spec: + // "In assignment operations, both the left- and right-hand expression lists + // must contain exactly one single-valued expression" + // + // Example: + // func f() int { + // x, y := 1, 2 + // x, y += 1 + // return x + y + // } + MultiValAssignOp + + // InvalidIfaceAssign occurs when a value of type T is used as an + // interface, but T does not implement a method of the expected interface. + // + // Example: + // type I interface { + // f() + // } + // + // type T int + // + // var x I = T(1) + InvalidIfaceAssign + + // InvalidChanAssign occurs when a chan assignment is invalid. + // + // Per the spec, a value x is assignable to a channel type T if: + // "x is a bidirectional channel value, T is a channel type, x's type V and + // T have identical element types, and at least one of V or T is not a + // defined type." + // + // Example: + // type T1 chan int + // type T2 chan int + // + // var x T1 + // // Invalid assignment because both types are named + // var _ T2 = x + InvalidChanAssign + + // IncompatibleAssign occurs when the type of the right-hand side expression + // in an assignment cannot be assigned to the type of the variable being + // assigned. + // + // Example: + // var x []int + // var _ int = x + IncompatibleAssign + + // UnaddressableFieldAssign occurs when trying to assign to a struct field + // in a map value. + // + // Example: + // func f() { + // m := make(map[string]struct{i int}) + // m["foo"].i = 42 + // } + UnaddressableFieldAssign + + /* decls > type (+ other type expression codes) */ + + // NotAType occurs when the identifier used as the underlying type in a type + // declaration or the right-hand side of a type alias does not denote a type. + // + // Example: + // var S = 2 + // + // type T S + NotAType + + // InvalidArrayLen occurs when an array length is not a constant value. + // + // Example: + // var n = 3 + // var _ = [n]int{} + InvalidArrayLen + + // BlankIfaceMethod occurs when a method name is '_'. + // + // Per the spec: + // "The name of each explicitly specified method must be unique and not + // blank." + // + // Example: + // type T interface { + // _(int) + // } + BlankIfaceMethod + + // IncomparableMapKey occurs when a map key type does not support the == and + // != operators. + // + // Per the spec: + // "The comparison operators == and != must be fully defined for operands of + // the key type; thus the key type must not be a function, map, or slice." + // + // Example: + // var x map[T]int + // + // type T []int + IncomparableMapKey + + // InvalidIfaceEmbed occurs when a non-interface type is embedded in an + // interface. + // + // Example: + // type T struct {} + // + // func (T) m() + // + // type I interface { + // T + // } + InvalidIfaceEmbed + + // InvalidPtrEmbed occurs when an embedded field is of the pointer form *T, + // and T itself is itself a pointer, an unsafe.Pointer, or an interface. + // + // Per the spec: + // "An embedded field must be specified as a type name T or as a pointer to + // a non-interface type name *T, and T itself may not be a pointer type." + // + // Example: + // type T *int + // + // type S struct { + // *T + // } + InvalidPtrEmbed + + /* decls > func and method */ + + // BadRecv occurs when a method declaration does not have exactly one + // receiver parameter. + // + // Example: + // func () _() {} + BadRecv + + // InvalidRecv occurs when a receiver type expression is not of the form T + // or *T, or T is a pointer type. + // + // Example: + // type T struct {} + // + // func (**T) m() {} + InvalidRecv + + // DuplicateFieldAndMethod occurs when an identifier appears as both a field + // and method name. + // + // Example: + // type T struct { + // m int + // } + // + // func (T) m() {} + DuplicateFieldAndMethod + + // DuplicateMethod occurs when two methods on the same receiver type have + // the same name. + // + // Example: + // type T struct {} + // func (T) m() {} + // func (T) m(i int) int { return i } + DuplicateMethod + + /* decls > special */ + + // InvalidBlank occurs when a blank identifier is used as a value or type. + // + // Per the spec: + // "The blank identifier may appear as an operand only on the left-hand side + // of an assignment." + // + // Example: + // var x = _ + InvalidBlank + + // InvalidIota occurs when the predeclared identifier iota is used outside + // of a constant declaration. + // + // Example: + // var x = iota + InvalidIota + + // MissingInitBody occurs when an init function is missing its body. + // + // Example: + // func init() + MissingInitBody + + // InvalidInitSig occurs when an init function declares parameters or + // results. + // + // Example: + // func init() int { return 1 } + InvalidInitSig + + // InvalidInitDecl occurs when init is declared as anything other than a + // function. + // + // Example: + // var init = 1 + InvalidInitDecl + + // InvalidMainDecl occurs when main is declared as anything other than a + // function, in a main package. + InvalidMainDecl + + /* exprs */ + + // TooManyValues occurs when a function returns too many values for the + // expression context in which it is used. + // + // Example: + // func ReturnTwo() (int, int) { + // return 1, 2 + // } + // + // var x = ReturnTwo() + TooManyValues + + // NotAnExpr occurs when a type expression is used where a value expression + // is expected. + // + // Example: + // type T struct {} + // + // func f() { + // T + // } + NotAnExpr + + /* exprs > const */ + + // TruncatedFloat occurs when a float constant is truncated to an integer + // value. + // + // Example: + // var _ int = 98.6 + TruncatedFloat + + // NumericOverflow occurs when a numeric constant overflows its target type. + // + // Example: + // var x int8 = 1000 + NumericOverflow + + /* exprs > operation */ + + // UndefinedOp occurs when an operator is not defined for the type(s) used + // in an operation. + // + // Example: + // var c = "a" - "b" + UndefinedOp + + // MismatchedTypes occurs when operand types are incompatible in a binary + // operation. + // + // Example: + // var a = "hello" + // var b = 1 + // var c = a - b + MismatchedTypes + + // DivByZero occurs when a division operation is provable at compile + // time to be a division by zero. + // + // Example: + // const divisor = 0 + // var x int = 1/divisor + DivByZero + + // NonNumericIncDec occurs when an increment or decrement operator is + // applied to a non-numeric value. + // + // Example: + // func f() { + // var c = "c" + // c++ + // } + NonNumericIncDec + + /* exprs > ptr */ + + // UnaddressableOperand occurs when the & operator is applied to an + // unaddressable expression. + // + // Example: + // var x = &1 + UnaddressableOperand + + // InvalidIndirection occurs when a non-pointer value is indirected via the + // '*' operator. + // + // Example: + // var x int + // var y = *x + InvalidIndirection + + /* exprs > [] */ + + // NonIndexableOperand occurs when an index operation is applied to a value + // that cannot be indexed. + // + // Example: + // var x = 1 + // var y = x[1] + NonIndexableOperand + + // InvalidIndex occurs when an index argument is not of integer type, + // negative, or out-of-bounds. + // + // Example: + // var s = [...]int{1,2,3} + // var x = s[5] + // + // Example: + // var s = []int{1,2,3} + // var _ = s[-1] + // + // Example: + // var s = []int{1,2,3} + // var i string + // var _ = s[i] + InvalidIndex + + // SwappedSliceIndices occurs when constant indices in a slice expression + // are decreasing in value. + // + // Example: + // var _ = []int{1,2,3}[2:1] + SwappedSliceIndices + + /* operators > slice */ + + // NonSliceableOperand occurs when a slice operation is applied to a value + // whose type is not sliceable, or is unaddressable. + // + // Example: + // var x = [...]int{1, 2, 3}[:1] + // + // Example: + // var x = 1 + // var y = 1[:1] + NonSliceableOperand + + // InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is + // applied to a string. + // + // Example: + // var s = "hello" + // var x = s[1:2:3] + InvalidSliceExpr + + /* exprs > shift */ + + // InvalidShiftCount occurs when the right-hand side of a shift operation is + // either non-integer, negative, or too large. + // + // Example: + // var ( + // x string + // y int = 1 << x + // ) + InvalidShiftCount + + // InvalidShiftOperand occurs when the shifted operand is not an integer. + // + // Example: + // var s = "hello" + // var x = s << 2 + InvalidShiftOperand + + /* exprs > chan */ + + // InvalidReceive occurs when there is a channel receive from a value that + // is either not a channel, or is a send-only channel. + // + // Example: + // func f() { + // var x = 1 + // <-x + // } + InvalidReceive + + // InvalidSend occurs when there is a channel send to a value that is not a + // channel, or is a receive-only channel. + // + // Example: + // func f() { + // var x = 1 + // x <- "hello!" + // } + InvalidSend + + /* exprs > literal */ + + // DuplicateLitKey occurs when an index is duplicated in a slice, array, or + // map literal. + // + // Example: + // var _ = []int{0:1, 0:2} + // + // Example: + // var _ = map[string]int{"a": 1, "a": 2} + DuplicateLitKey + + // MissingLitKey occurs when a map literal is missing a key expression. + // + // Example: + // var _ = map[string]int{1} + MissingLitKey + + // InvalidLitIndex occurs when the key in a key-value element of a slice or + // array literal is not an integer constant. + // + // Example: + // var i = 0 + // var x = []string{i: "world"} + InvalidLitIndex + + // OversizeArrayLit occurs when an array literal exceeds its length. + // + // Example: + // var _ = [2]int{1,2,3} + OversizeArrayLit + + // MixedStructLit occurs when a struct literal contains a mix of positional + // and named elements. + // + // Example: + // var _ = struct{i, j int}{i: 1, 2} + MixedStructLit + + // InvalidStructLit occurs when a positional struct literal has an incorrect + // number of values. + // + // Example: + // var _ = struct{i, j int}{1,2,3} + InvalidStructLit + + // MissingLitField occurs when a struct literal refers to a field that does + // not exist on the struct type. + // + // Example: + // var _ = struct{i int}{j: 2} + MissingLitField + + // DuplicateLitField occurs when a struct literal contains duplicated + // fields. + // + // Example: + // var _ = struct{i int}{i: 1, i: 2} + DuplicateLitField + + // UnexportedLitField occurs when a positional struct literal implicitly + // assigns an unexported field of an imported type. + UnexportedLitField + + // InvalidLitField occurs when a field name is not a valid identifier. + // + // Example: + // var _ = struct{i int}{1: 1} + InvalidLitField + + // UntypedLit occurs when a composite literal omits a required type + // identifier. + // + // Example: + // type outer struct{ + // inner struct { i int } + // } + // + // var _ = outer{inner: {1}} + UntypedLit + + // InvalidLit occurs when a composite literal expression does not match its + // type. + // + // Example: + // type P *struct{ + // x int + // } + // var _ = P {} + InvalidLit + + /* exprs > selector */ + + // AmbiguousSelector occurs when a selector is ambiguous. + // + // Example: + // type E1 struct { i int } + // type E2 struct { i int } + // type T struct { E1; E2 } + // + // var x T + // var _ = x.i + AmbiguousSelector + + // UndeclaredImportedName occurs when a package-qualified identifier is + // undeclared by the imported package. + // + // Example: + // import "go/types" + // + // var _ = types.NotAnActualIdentifier + UndeclaredImportedName + + // UnexportedName occurs when a selector refers to an unexported identifier + // of an imported package. + // + // Example: + // import "reflect" + // + // type _ reflect.flag + UnexportedName + + // UndeclaredName occurs when an identifier is not declared in the current + // scope. + // + // Example: + // var x T + UndeclaredName + + // MissingFieldOrMethod occurs when a selector references a field or method + // that does not exist. + // + // Example: + // type T struct {} + // + // var x = T{}.f + MissingFieldOrMethod + + /* exprs > ... */ + + // BadDotDotDotSyntax occurs when a "..." occurs in a context where it is + // not valid. + // + // Example: + // var _ = map[int][...]int{0: {}} + BadDotDotDotSyntax + + // NonVariadicDotDotDot occurs when a "..." is used on the final argument to + // a non-variadic function. + // + // Example: + // func printArgs(s []string) { + // for _, a := range s { + // println(a) + // } + // } + // + // func f() { + // s := []string{"a", "b", "c"} + // printArgs(s...) + // } + NonVariadicDotDotDot + + // MisplacedDotDotDot occurs when a "..." is used somewhere other than the + // final argument to a function call. + // + // Example: + // func printArgs(args ...int) { + // for _, a := range args { + // println(a) + // } + // } + // + // func f() { + // a := []int{1,2,3} + // printArgs(0, a...) + // } + MisplacedDotDotDot + + // InvalidDotDotDotOperand occurs when a "..." operator is applied to a + // single-valued operand. + // + // Example: + // func printArgs(args ...int) { + // for _, a := range args { + // println(a) + // } + // } + // + // func f() { + // a := 1 + // printArgs(a...) + // } + // + // Example: + // func args() (int, int) { + // return 1, 2 + // } + // + // func printArgs(args ...int) { + // for _, a := range args { + // println(a) + // } + // } + // + // func g() { + // printArgs(args()...) + // } + InvalidDotDotDotOperand + + // InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in + // function. + // + // Example: + // var s = []int{1, 2, 3} + // var l = len(s...) + InvalidDotDotDot + + /* exprs > built-in */ + + // UncalledBuiltin occurs when a built-in function is used as a + // function-valued expression, instead of being called. + // + // Per the spec: + // "The built-in functions do not have standard Go types, so they can only + // appear in call expressions; they cannot be used as function values." + // + // Example: + // var _ = copy + UncalledBuiltin + + // InvalidAppend occurs when append is called with a first argument that is + // not a slice. + // + // Example: + // var _ = append(1, 2) + InvalidAppend + + // InvalidCap occurs when an argument to the cap built-in function is not of + // supported type. + // + // See https://golang.org/ref/spec#Lengthand_capacity for information on + // which underlying types are supported as arguments to cap and len. + // + // Example: + // var s = 2 + // var x = cap(s) + InvalidCap + + // InvalidClose occurs when close(...) is called with an argument that is + // not of channel type, or that is a receive-only channel. + // + // Example: + // func f() { + // var x int + // close(x) + // } + InvalidClose + + // InvalidCopy occurs when the arguments are not of slice type or do not + // have compatible type. + // + // See https://golang.org/ref/spec#Appendingand_copying_slices for more + // information on the type requirements for the copy built-in. + // + // Example: + // func f() { + // var x []int + // y := []int64{1,2,3} + // copy(x, y) + // } + InvalidCopy + + // InvalidComplex occurs when the complex built-in function is called with + // arguments with incompatible types. + // + // Example: + // var _ = complex(float32(1), float64(2)) + InvalidComplex + + // InvalidDelete occurs when the delete built-in function is called with a + // first argument that is not a map. + // + // Example: + // func f() { + // m := "hello" + // delete(m, "e") + // } + InvalidDelete + + // InvalidImag occurs when the imag built-in function is called with an + // argument that does not have complex type. + // + // Example: + // var _ = imag(int(1)) + InvalidImag + + // InvalidLen occurs when an argument to the len built-in function is not of + // supported type. + // + // See https://golang.org/ref/spec#Lengthand_capacity for information on + // which underlying types are supported as arguments to cap and len. + // + // Example: + // var s = 2 + // var x = len(s) + InvalidLen + + // SwappedMakeArgs occurs when make is called with three arguments, and its + // length argument is larger than its capacity argument. + // + // Example: + // var x = make([]int, 3, 2) + SwappedMakeArgs + + // InvalidMake occurs when make is called with an unsupported type argument. + // + // See https://golang.org/ref/spec#Makingslices_maps_and_channels for + // information on the types that may be created using make. + // + // Example: + // var x = make(int) + InvalidMake + + // InvalidReal occurs when the real built-in function is called with an + // argument that does not have complex type. + // + // Example: + // var _ = real(int(1)) + InvalidReal + + /* exprs > assertion */ + + // InvalidAssert occurs when a type assertion is applied to a + // value that is not of interface type. + // + // Example: + // var x = 1 + // var _ = x.(float64) + InvalidAssert + + // ImpossibleAssert occurs for a type assertion x.(T) when the value x of + // interface cannot have dynamic type T, due to a missing or mismatching + // method on T. + // + // Example: + // type T int + // + // func (t *T) m() int { return int(*t) } + // + // type I interface { m() int } + // + // var x I + // var _ = x.(T) + ImpossibleAssert + + /* exprs > conversion */ + + // InvalidConversion occurs when the argument type cannot be converted to the + // target. + // + // See https://golang.org/ref/spec#Conversions for the rules of + // convertibility. + // + // Example: + // var x float64 + // var _ = string(x) + InvalidConversion + + // InvalidUntypedConversion occurs when an there is no valid implicit + // conversion from an untyped value satisfying the type constraints of the + // context in which it is used. + // + // Example: + // var _ = 1 + "" + InvalidUntypedConversion + + /* offsetof */ + + // BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument + // that is not a selector expression. + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Offsetof(x) + BadOffsetofSyntax + + // InvalidOffsetof occurs when unsafe.Offsetof is called with a method + // selector, rather than a field selector, or when the field is embedded via + // a pointer. + // + // Per the spec: + // + // "If f is an embedded field, it must be reachable without pointer + // indirections through fields of the struct. " + // + // Example: + // import "unsafe" + // + // type T struct { f int } + // type S struct { *T } + // var s S + // var _ = unsafe.Offsetof(s.f) + // + // Example: + // import "unsafe" + // + // type S struct{} + // + // func (S) m() {} + // + // var s S + // var _ = unsafe.Offsetof(s.m) + InvalidOffsetof + + /* control flow > scope */ + + // UnusedExpr occurs when a side-effect free expression is used as a + // statement. Such a statement has no effect. + // + // Example: + // func f(i int) { + // i*i + // } + UnusedExpr + + // UnusedVar occurs when a variable is declared but unused. + // + // Example: + // func f() { + // x := 1 + // } + UnusedVar + + // MissingReturn occurs when a function with results is missing a return + // statement. + // + // Example: + // func f() int {} + MissingReturn + + // WrongResultCount occurs when a return statement returns an incorrect + // number of values. + // + // Example: + // func ReturnOne() int { + // return 1, 2 + // } + WrongResultCount + + // OutOfScopeResult occurs when the name of a value implicitly returned by + // an empty return statement is shadowed in a nested scope. + // + // Example: + // func factor(n int) (i int) { + // for i := 2; i < n; i++ { + // if n%i == 0 { + // return + // } + // } + // return 0 + // } + OutOfScopeResult + + /* control flow > if */ + + // InvalidCond occurs when an if condition is not a boolean expression. + // + // Example: + // func checkReturn(i int) { + // if i { + // panic("non-zero return") + // } + // } + InvalidCond + + /* control flow > for */ + + // InvalidPostDecl occurs when there is a declaration in a for-loop post + // statement. + // + // Example: + // func f() { + // for i := 0; i < 10; j := 0 {} + // } + InvalidPostDecl + + // InvalidChanRange occurs when a send-only channel used in a range + // expression. + // + // Example: + // func sum(c chan<- int) { + // s := 0 + // for i := range c { + // s += i + // } + // } + InvalidChanRange + + // InvalidIterVar occurs when two iteration variables are used while ranging + // over a channel. + // + // Example: + // func f(c chan int) { + // for k, v := range c { + // println(k, v) + // } + // } + InvalidIterVar + + // InvalidRangeExpr occurs when the type of a range expression is not array, + // slice, string, map, or channel. + // + // Example: + // func f(i int) { + // for j := range i { + // println(j) + // } + // } + InvalidRangeExpr + + /* control flow > switch */ + + // MisplacedBreak occurs when a break statement is not within a for, switch, + // or select statement of the innermost function definition. + // + // Example: + // func f() { + // break + // } + MisplacedBreak + + // MisplacedContinue occurs when a continue statement is not within a for + // loop of the innermost function definition. + // + // Example: + // func sumeven(n int) int { + // proceed := func() { + // continue + // } + // sum := 0 + // for i := 1; i <= n; i++ { + // if i % 2 != 0 { + // proceed() + // } + // sum += i + // } + // return sum + // } + MisplacedContinue + + // MisplacedFallthrough occurs when a fallthrough statement is not within an + // expression switch. + // + // Example: + // func typename(i interface{}) string { + // switch i.(type) { + // case int64: + // fallthrough + // case int: + // return "int" + // } + // return "unsupported" + // } + MisplacedFallthrough + + // DuplicateCase occurs when a type or expression switch has duplicate + // cases. + // + // Example: + // func printInt(i int) { + // switch i { + // case 1: + // println("one") + // case 1: + // println("One") + // } + // } + DuplicateCase + + // DuplicateDefault occurs when a type or expression switch has multiple + // default clauses. + // + // Example: + // func printInt(i int) { + // switch i { + // case 1: + // println("one") + // default: + // println("One") + // default: + // println("1") + // } + // } + DuplicateDefault + + // BadTypeKeyword occurs when a .(type) expression is used anywhere other + // than a type switch. + // + // Example: + // type I interface { + // m() + // } + // var t I + // var _ = t.(type) + BadTypeKeyword + + // InvalidTypeSwitch occurs when .(type) is used on an expression that is + // not of interface type. + // + // Example: + // func f(i int) { + // switch x := i.(type) {} + // } + InvalidTypeSwitch + + // InvalidExprSwitch occurs when a switch expression is not comparable. + // + // Example: + // func _() { + // var a struct{ _ func() } + // switch a /* ERROR cannot switch on a */ { + // } + // } + InvalidExprSwitch + + /* control flow > select */ + + // InvalidSelectCase occurs when a select case is not a channel send or + // receive. + // + // Example: + // func checkChan(c <-chan int) bool { + // select { + // case c: + // return true + // default: + // return false + // } + // } + InvalidSelectCase + + /* control flow > labels and jumps */ + + // UndeclaredLabel occurs when an undeclared label is jumped to. + // + // Example: + // func f() { + // goto L + // } + UndeclaredLabel + + // DuplicateLabel occurs when a label is declared more than once. + // + // Example: + // func f() int { + // L: + // L: + // return 1 + // } + DuplicateLabel + + // MisplacedLabel occurs when a break or continue label is not on a for, + // switch, or select statement. + // + // Example: + // func f() { + // L: + // a := []int{1,2,3} + // for _, e := range a { + // if e > 10 { + // break L + // } + // println(a) + // } + // } + MisplacedLabel + + // UnusedLabel occurs when a label is declared but not used. + // + // Example: + // func f() { + // L: + // } + UnusedLabel + + // JumpOverDecl occurs when a label jumps over a variable declaration. + // + // Example: + // func f() int { + // goto L + // x := 2 + // L: + // x++ + // return x + // } + JumpOverDecl + + // JumpIntoBlock occurs when a forward jump goes to a label inside a nested + // block. + // + // Example: + // func f(x int) { + // goto L + // if x > 0 { + // L: + // print("inside block") + // } + // } + JumpIntoBlock + + /* control flow > calls */ + + // InvalidMethodExpr occurs when a pointer method is called but the argument + // is not addressable. + // + // Example: + // type T struct {} + // + // func (*T) m() int { return 1 } + // + // var _ = T.m(T{}) + InvalidMethodExpr + + // WrongArgCount occurs when too few or too many arguments are passed by a + // function call. + // + // Example: + // func f(i int) {} + // var x = f() + WrongArgCount + + // InvalidCall occurs when an expression is called that is not of function + // type. + // + // Example: + // var x = "x" + // var y = x() + InvalidCall + + /* control flow > suspended */ + + // UnusedResults occurs when a restricted expression-only built-in function + // is suspended via go or defer. Such a suspension discards the results of + // these side-effect free built-in functions, and therefore is ineffectual. + // + // Example: + // func f(a []int) int { + // defer len(a) + // return i + // } + UnusedResults + + // InvalidDefer occurs when a deferred expression is not a function call, + // for example if the expression is a type conversion. + // + // Example: + // func f(i int) int { + // defer int32(i) + // return i + // } + InvalidDefer + + // InvalidGo occurs when a go expression is not a function call, for example + // if the expression is a type conversion. + // + // Example: + // func f(i int) int { + // go int32(i) + // return i + // } + InvalidGo + + // All codes below were added in Go 1.17. + + /* decl */ + + // BadDecl occurs when a declaration has invalid syntax. + BadDecl + + // RepeatedDecl occurs when an identifier occurs more than once on the left + // hand side of a short variable declaration. + // + // Example: + // func _() { + // x, y, y := 1, 2, 3 + // } + RepeatedDecl + + /* unsafe */ + + // InvalidUnsafeAdd occurs when unsafe.Add is called with a + // length argument that is not of integer type. + // + // Example: + // import "unsafe" + // + // var p unsafe.Pointer + // var _ = unsafe.Add(p, float64(1)) + InvalidUnsafeAdd + + // InvalidUnsafeSlice occurs when unsafe.Slice is called with a + // pointer argument that is not of pointer type or a length argument + // that is not of integer type, negative, or out of bounds. + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(x, 1) + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(&x, float64(1)) + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(&x, -1) + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(&x, uint64(1) << 63) + InvalidUnsafeSlice + + // All codes below were added in Go 1.18. + + /* features */ + + // UnsupportedFeature occurs when a language feature is used that is not + // supported at this Go version. + UnsupportedFeature + + /* type params */ + + // NotAGenericType occurs when a non-generic type is used where a generic + // type is expected: in type or function instantiation. + // + // Example: + // type T int + // + // var _ T[int] + NotAGenericType + + // WrongTypeArgCount occurs when a type or function is instantiated with an + // incorrent number of type arguments, including when a generic type or + // function is used without instantiation. + // + // Errors inolving failed type inference are assigned other error codes. + // + // Example: + // type T[p any] int + // + // var _ T[int, string] + // + // Example: + // func f[T any]() {} + // + // var x = f + WrongTypeArgCount + + // CannotInferTypeArgs occurs when type or function type argument inference + // fails to infer all type arguments. + // + // Example: + // func f[T any]() {} + // + // func _() { + // f() + // } + // + // Example: + // type N[P, Q any] struct{} + // + // var _ N[int] + CannotInferTypeArgs + + // InvalidTypeArg occurs when a type argument does not satisfy its + // corresponding type parameter constraints. + // + // Example: + // type T[P ~int] struct{} + // + // var _ T[string] + InvalidTypeArg // arguments? InferenceFailed + + // InvalidInstanceCycle occurs when an invalid cycle is detected + // within the instantiation graph. + // + // Example: + // func f[T any]() { f[*T]() } + InvalidInstanceCycle + + // InvalidUnion occurs when an embedded union or approximation element is + // not valid. + // + // Example: + // type _ interface { + // ~int | interface{ m() } + // } + InvalidUnion + + // MisplacedConstraintIface occurs when a constraint-type interface is used + // outside of constraint position. + // + // Example: + // type I interface { ~int } + // + // var _ I + MisplacedConstraintIface + + // InvalidMethodTypeParams occurs when methods have type parameters. + // + // It cannot be encountered with an AST parsed using go/parser. + InvalidMethodTypeParams + + // MisplacedTypeParam occurs when a type parameter is used in a place where + // it is not permitted. + // + // Example: + // type T[P any] P + // + // Example: + // type T[P any] struct{ *P } + MisplacedTypeParam + + // InvalidUnsafeSliceData occurs when unsafe.SliceData is called with + // an argument that is not of slice type. It also occurs if it is used + // in a package compiled for a language version before go1.20. + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.SliceData(x) + InvalidUnsafeSliceData + + // InvalidUnsafeString occurs when unsafe.String is called with + // a length argument that is not of integer type, negative, or + // out of bounds. It also occurs if it is used in a package + // compiled for a language version before go1.20. + // + // Example: + // import "unsafe" + // + // var b [10]byte + // var _ = unsafe.String(&b[0], -1) + InvalidUnsafeString + + // InvalidUnsafeStringData occurs if it is used in a package + // compiled for a language version before go1.20. + _ // not used anymore + +) diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go new file mode 100644 index 00000000..15ecf7c5 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go @@ -0,0 +1,179 @@ +// Code generated by "stringer -type=ErrorCode"; DO NOT EDIT. + +package typesinternal + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[InvalidSyntaxTree - -1] + _ = x[Test-1] + _ = x[BlankPkgName-2] + _ = x[MismatchedPkgName-3] + _ = x[InvalidPkgUse-4] + _ = x[BadImportPath-5] + _ = x[BrokenImport-6] + _ = x[ImportCRenamed-7] + _ = x[UnusedImport-8] + _ = x[InvalidInitCycle-9] + _ = x[DuplicateDecl-10] + _ = x[InvalidDeclCycle-11] + _ = x[InvalidTypeCycle-12] + _ = x[InvalidConstInit-13] + _ = x[InvalidConstVal-14] + _ = x[InvalidConstType-15] + _ = x[UntypedNilUse-16] + _ = x[WrongAssignCount-17] + _ = x[UnassignableOperand-18] + _ = x[NoNewVar-19] + _ = x[MultiValAssignOp-20] + _ = x[InvalidIfaceAssign-21] + _ = x[InvalidChanAssign-22] + _ = x[IncompatibleAssign-23] + _ = x[UnaddressableFieldAssign-24] + _ = x[NotAType-25] + _ = x[InvalidArrayLen-26] + _ = x[BlankIfaceMethod-27] + _ = x[IncomparableMapKey-28] + _ = x[InvalidIfaceEmbed-29] + _ = x[InvalidPtrEmbed-30] + _ = x[BadRecv-31] + _ = x[InvalidRecv-32] + _ = x[DuplicateFieldAndMethod-33] + _ = x[DuplicateMethod-34] + _ = x[InvalidBlank-35] + _ = x[InvalidIota-36] + _ = x[MissingInitBody-37] + _ = x[InvalidInitSig-38] + _ = x[InvalidInitDecl-39] + _ = x[InvalidMainDecl-40] + _ = x[TooManyValues-41] + _ = x[NotAnExpr-42] + _ = x[TruncatedFloat-43] + _ = x[NumericOverflow-44] + _ = x[UndefinedOp-45] + _ = x[MismatchedTypes-46] + _ = x[DivByZero-47] + _ = x[NonNumericIncDec-48] + _ = x[UnaddressableOperand-49] + _ = x[InvalidIndirection-50] + _ = x[NonIndexableOperand-51] + _ = x[InvalidIndex-52] + _ = x[SwappedSliceIndices-53] + _ = x[NonSliceableOperand-54] + _ = x[InvalidSliceExpr-55] + _ = x[InvalidShiftCount-56] + _ = x[InvalidShiftOperand-57] + _ = x[InvalidReceive-58] + _ = x[InvalidSend-59] + _ = x[DuplicateLitKey-60] + _ = x[MissingLitKey-61] + _ = x[InvalidLitIndex-62] + _ = x[OversizeArrayLit-63] + _ = x[MixedStructLit-64] + _ = x[InvalidStructLit-65] + _ = x[MissingLitField-66] + _ = x[DuplicateLitField-67] + _ = x[UnexportedLitField-68] + _ = x[InvalidLitField-69] + _ = x[UntypedLit-70] + _ = x[InvalidLit-71] + _ = x[AmbiguousSelector-72] + _ = x[UndeclaredImportedName-73] + _ = x[UnexportedName-74] + _ = x[UndeclaredName-75] + _ = x[MissingFieldOrMethod-76] + _ = x[BadDotDotDotSyntax-77] + _ = x[NonVariadicDotDotDot-78] + _ = x[MisplacedDotDotDot-79] + _ = x[InvalidDotDotDotOperand-80] + _ = x[InvalidDotDotDot-81] + _ = x[UncalledBuiltin-82] + _ = x[InvalidAppend-83] + _ = x[InvalidCap-84] + _ = x[InvalidClose-85] + _ = x[InvalidCopy-86] + _ = x[InvalidComplex-87] + _ = x[InvalidDelete-88] + _ = x[InvalidImag-89] + _ = x[InvalidLen-90] + _ = x[SwappedMakeArgs-91] + _ = x[InvalidMake-92] + _ = x[InvalidReal-93] + _ = x[InvalidAssert-94] + _ = x[ImpossibleAssert-95] + _ = x[InvalidConversion-96] + _ = x[InvalidUntypedConversion-97] + _ = x[BadOffsetofSyntax-98] + _ = x[InvalidOffsetof-99] + _ = x[UnusedExpr-100] + _ = x[UnusedVar-101] + _ = x[MissingReturn-102] + _ = x[WrongResultCount-103] + _ = x[OutOfScopeResult-104] + _ = x[InvalidCond-105] + _ = x[InvalidPostDecl-106] + _ = x[InvalidChanRange-107] + _ = x[InvalidIterVar-108] + _ = x[InvalidRangeExpr-109] + _ = x[MisplacedBreak-110] + _ = x[MisplacedContinue-111] + _ = x[MisplacedFallthrough-112] + _ = x[DuplicateCase-113] + _ = x[DuplicateDefault-114] + _ = x[BadTypeKeyword-115] + _ = x[InvalidTypeSwitch-116] + _ = x[InvalidExprSwitch-117] + _ = x[InvalidSelectCase-118] + _ = x[UndeclaredLabel-119] + _ = x[DuplicateLabel-120] + _ = x[MisplacedLabel-121] + _ = x[UnusedLabel-122] + _ = x[JumpOverDecl-123] + _ = x[JumpIntoBlock-124] + _ = x[InvalidMethodExpr-125] + _ = x[WrongArgCount-126] + _ = x[InvalidCall-127] + _ = x[UnusedResults-128] + _ = x[InvalidDefer-129] + _ = x[InvalidGo-130] + _ = x[BadDecl-131] + _ = x[RepeatedDecl-132] + _ = x[InvalidUnsafeAdd-133] + _ = x[InvalidUnsafeSlice-134] + _ = x[UnsupportedFeature-135] + _ = x[NotAGenericType-136] + _ = x[WrongTypeArgCount-137] + _ = x[CannotInferTypeArgs-138] + _ = x[InvalidTypeArg-139] + _ = x[InvalidInstanceCycle-140] + _ = x[InvalidUnion-141] + _ = x[MisplacedConstraintIface-142] + _ = x[InvalidMethodTypeParams-143] + _ = x[MisplacedTypeParam-144] + _ = x[InvalidUnsafeSliceData-145] + _ = x[InvalidUnsafeString-146] +} + +const ( + _ErrorCode_name_0 = "InvalidSyntaxTree" + _ErrorCode_name_1 = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilUseWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParamInvalidUnsafeSliceDataInvalidUnsafeString" +) + +var ( + _ErrorCode_index_1 = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 218, 234, 253, 261, 277, 295, 312, 330, 354, 362, 377, 393, 411, 428, 443, 450, 461, 484, 499, 511, 522, 537, 551, 566, 581, 594, 603, 617, 632, 643, 658, 667, 683, 703, 721, 740, 752, 771, 790, 806, 823, 842, 856, 867, 882, 895, 910, 926, 940, 956, 971, 988, 1006, 1021, 1031, 1041, 1058, 1080, 1094, 1108, 1128, 1146, 1166, 1184, 1207, 1223, 1238, 1251, 1261, 1273, 1284, 1298, 1311, 1322, 1332, 1347, 1358, 1369, 1382, 1398, 1415, 1439, 1456, 1471, 1481, 1490, 1503, 1519, 1535, 1546, 1561, 1577, 1591, 1607, 1621, 1638, 1658, 1671, 1687, 1701, 1718, 1735, 1752, 1767, 1781, 1795, 1806, 1818, 1831, 1848, 1861, 1872, 1885, 1897, 1906, 1913, 1925, 1941, 1959, 1977, 1992, 2009, 2028, 2042, 2062, 2074, 2098, 2121, 2139, 2161, 2180} +) + +func (i ErrorCode) String() string { + switch { + case i == -1: + return _ErrorCode_name_0 + case 1 <= i && i <= 146: + i -= 1 + return _ErrorCode_name_1[_ErrorCode_index_1[i]:_ErrorCode_index_1[i+1]] + default: + return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/recv.go b/vendor/golang.org/x/tools/internal/typesinternal/recv.go new file mode 100644 index 00000000..fea7c8b7 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/recv.go @@ -0,0 +1,43 @@ +// 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 typesinternal + +import ( + "go/types" + + "golang.org/x/tools/internal/aliases" +) + +// ReceiverNamed returns the named type (if any) associated with the +// type of recv, which may be of the form N or *N, or aliases thereof. +// It also reports whether a Pointer was present. +func ReceiverNamed(recv *types.Var) (isPtr bool, named *types.Named) { + t := recv.Type() + if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok { + isPtr = true + t = ptr.Elem() + } + named, _ = aliases.Unalias(t).(*types.Named) + return +} + +// Unpointer returns T given *T or an alias thereof. +// For all other types it is the identity function. +// It does not look at underlying types. +// The result may be an alias. +// +// Use this function to strip off the optional pointer on a receiver +// in a field or method selection, without losing the named type +// (which is needed to compute the method set). +// +// See also [typeparams.MustDeref], which removes one level of +// indirection from the type, regardless of named types (analogous to +// a LOAD instruction). +func Unpointer(t types.Type) types.Type { + if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok { + return ptr.Elem() + } + return t +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go new file mode 100644 index 00000000..cc86487e --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go @@ -0,0 +1,89 @@ +// 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 typesinternal + +import ( + "go/types" + + "golang.org/x/tools/internal/stdlib" + "golang.org/x/tools/internal/versions" +) + +// 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) + + // Pass 1: package-level symbols. + symbols := stdlib.PackageSymbols[pkg.Path()] + for _, sym := range symbols { + symver := sym.Version.String() + if versions.Before(version, symver) { + switch sym.Kind { + case stdlib.Func, stdlib.Var, stdlib.Const, stdlib.Type: + disallowed[pkg.Scope().Lookup(sym.Name)] = symver + } + } + } + + // Pass 2: fields and methods. + // + // We allow fields and methods if their associated type is + // disallowed, as otherwise we would report false positives + // for compatibility shims. Consider: + // + // //go:build go1.22 + // type T struct { F std.Real } // correct new API + // + // //go:build !go1.22 + // type T struct { F fake } // shim + // type fake struct { ... } + // func (fake) M () {} + // + // These alternative declarations of T use either the std.Real + // type, introduced in go1.22, or a fake type, for the field + // F. (The fakery could be arbitrarily deep, involving more + // nested fields and methods than are shown here.) Clients + // that use the compatibility shim T will compile with any + // version of go, whether older or newer than go1.22, but only + // the newer version will use the std.Real implementation. + // + // Now consider a reference to method M in new(T).F.M() in a + // module that requires a minimum of go1.21. The analysis may + // occur using a version of Go higher than 1.21, selecting the + // first version of T, so the method M is Real.M. This would + // 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. + for _, sym := range symbols { + symVersion := sym.Version.String() + if !versions.Before(version, symVersion) { + continue // allowed + } + + var obj types.Object + 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) + } + + 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 obj != nil { + disallowed[obj] = symVersion + } + } + + return disallowed +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go new file mode 100644 index 00000000..7c77c2fb --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go @@ -0,0 +1,50 @@ +// 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 typesinternal provides access to internal go/types APIs that are not +// yet exported. +package typesinternal + +import ( + "go/token" + "go/types" + "reflect" + "unsafe" +) + +func SetUsesCgo(conf *types.Config) bool { + v := reflect.ValueOf(conf).Elem() + + f := v.FieldByName("go115UsesCgo") + if !f.IsValid() { + f = v.FieldByName("UsesCgo") + if !f.IsValid() { + return false + } + } + + addr := unsafe.Pointer(f.UnsafeAddr()) + *(*bool)(addr) = true + + return true +} + +// ReadGo116ErrorData extracts additional information from types.Error values +// generated by Go version 1.16 and later: the error code, start position, and +// end position. If all positions are valid, start <= err.Pos <= end. +// +// If the data could not be read, the final result parameter will be false. +func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) { + var data [3]int + // By coincidence all of these fields are ints, which simplifies things. + v := reflect.ValueOf(err) + for i, name := range []string{"go116code", "go116start", "go116end"} { + f := v.FieldByName(name) + if !f.IsValid() { + return 0, 0, 0, false + } + data[i] = int(f.Int()) + } + return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true +} diff --git a/vendor/golang.org/x/tools/internal/versions/features.go b/vendor/golang.org/x/tools/internal/versions/features.go new file mode 100644 index 00000000..b53f1786 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/features.go @@ -0,0 +1,43 @@ +// 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 versions + +// This file contains predicates for working with file versions to +// decide when a tool should consider a language feature enabled. + +// GoVersions that features in x/tools can be gated to. +const ( + Go1_18 = "go1.18" + Go1_19 = "go1.19" + Go1_20 = "go1.20" + Go1_21 = "go1.21" + Go1_22 = "go1.22" +) + +// Future is an invalid unknown Go version sometime in the future. +// Do not use directly with Compare. +const Future = "" + +// AtLeast reports whether the file version v comes after a Go release. +// +// Use this predicate to enable a behavior once a certain Go release +// has happened (and stays enabled in the future). +func AtLeast(v, release string) bool { + if v == Future { + return true // an unknown future version is always after y. + } + return Compare(Lang(v), Lang(release)) >= 0 +} + +// Before reports whether the file version v is strictly before a Go release. +// +// Use this predicate to disable a behavior once a certain Go release +// has happened (and stays enabled in the future). +func Before(v, release string) bool { + if v == Future { + return false // an unknown future version happens after y. + } + return Compare(Lang(v), Lang(release)) < 0 +} diff --git a/vendor/golang.org/x/tools/internal/versions/gover.go b/vendor/golang.org/x/tools/internal/versions/gover.go new file mode 100644 index 00000000..bbabcd22 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/gover.go @@ -0,0 +1,172 @@ +// 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. + +// This is a fork of internal/gover for use by x/tools until +// go1.21 and earlier are no longer supported by x/tools. + +package versions + +import "strings" + +// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]] +// The numbers are the original decimal strings to avoid integer overflows +// and since there is very little actual math. (Probably overflow doesn't matter in practice, +// but at the time this code was written, there was an existing test that used +// go1.99999999999, which does not fit in an int on 32-bit platforms. +// The "big decimal" representation avoids the problem entirely.) +type gover struct { + major string // decimal + minor string // decimal or "" + patch string // decimal or "" + kind string // "", "alpha", "beta", "rc" + pre string // decimal or "" +} + +// compare returns -1, 0, or +1 depending on whether +// x < y, x == y, or x > y, interpreted as toolchain versions. +// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21". +// Malformed versions compare less than well-formed versions and equal to each other. +// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0". +func compare(x, y string) int { + vx := parse(x) + vy := parse(y) + + if c := cmpInt(vx.major, vy.major); c != 0 { + return c + } + if c := cmpInt(vx.minor, vy.minor); c != 0 { + return c + } + if c := cmpInt(vx.patch, vy.patch); c != 0 { + return c + } + if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc + return c + } + if c := cmpInt(vx.pre, vy.pre); c != 0 { + return c + } + return 0 +} + +// lang returns the Go language version. For example, lang("1.2.3") == "1.2". +func lang(x string) string { + v := parse(x) + if v.minor == "" || v.major == "1" && v.minor == "0" { + return v.major + } + return v.major + "." + v.minor +} + +// isValid reports whether the version x is valid. +func isValid(x string) bool { + return parse(x) != gover{} +} + +// parse parses the Go version string x into a version. +// It returns the zero version if x is malformed. +func parse(x string) gover { + var v gover + + // Parse major version. + var ok bool + v.major, x, ok = cutInt(x) + if !ok { + return gover{} + } + if x == "" { + // Interpret "1" as "1.0.0". + v.minor = "0" + v.patch = "0" + return v + } + + // Parse . before minor version. + if x[0] != '.' { + return gover{} + } + + // Parse minor version. + v.minor, x, ok = cutInt(x[1:]) + if !ok { + return gover{} + } + if x == "" { + // Patch missing is same as "0" for older versions. + // Starting in Go 1.21, patch missing is different from explicit .0. + if cmpInt(v.minor, "21") < 0 { + v.patch = "0" + } + return v + } + + // Parse patch if present. + if x[0] == '.' { + v.patch, x, ok = cutInt(x[1:]) + if !ok || x != "" { + // Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != ""). + // Allowing them would be a bit confusing because we already have: + // 1.21 < 1.21rc1 + // But a prerelease of a patch would have the opposite effect: + // 1.21.3rc1 < 1.21.3 + // We've never needed them before, so let's not start now. + return gover{} + } + return v + } + + // Parse prerelease. + i := 0 + for i < len(x) && (x[i] < '0' || '9' < x[i]) { + if x[i] < 'a' || 'z' < x[i] { + return gover{} + } + i++ + } + if i == 0 { + return gover{} + } + v.kind, x = x[:i], x[i:] + if x == "" { + return v + } + v.pre, x, ok = cutInt(x) + if !ok || x != "" { + return gover{} + } + + return v +} + +// cutInt scans the leading decimal number at the start of x to an integer +// and returns that value and the rest of the string. +func cutInt(x string) (n, rest string, ok bool) { + i := 0 + for i < len(x) && '0' <= x[i] && x[i] <= '9' { + i++ + } + if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero + return "", "", false + } + return x[:i], x[i:], true +} + +// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers. +// (Copied from golang.org/x/mod/semver's compareInt.) +func cmpInt(x, y string) int { + if x == y { + return 0 + } + if len(x) < len(y) { + return -1 + } + if len(x) > len(y) { + return +1 + } + if x < y { + return -1 + } else { + return +1 + } +} diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain.go b/vendor/golang.org/x/tools/internal/versions/toolchain.go new file mode 100644 index 00000000..377bf7a5 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/toolchain.go @@ -0,0 +1,14 @@ +// 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 versions + +// toolchain is maximum version (<1.22) that the go toolchain used +// to build the current tool is known to support. +// +// When a tool is built with >=1.22, the value of toolchain is unused. +// +// x/tools does not support building with go <1.18. So we take this +// as the minimum possible maximum. +var toolchain string = Go1_18 diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go b/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go new file mode 100644 index 00000000..f65beed9 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go @@ -0,0 +1,14 @@ +// 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. + +//go:build go1.19 +// +build go1.19 + +package versions + +func init() { + if Compare(toolchain, Go1_19) < 0 { + toolchain = Go1_19 + } +} diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go b/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go new file mode 100644 index 00000000..1a9efa12 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go @@ -0,0 +1,14 @@ +// 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. + +//go:build go1.20 +// +build go1.20 + +package versions + +func init() { + if Compare(toolchain, Go1_20) < 0 { + toolchain = Go1_20 + } +} diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go b/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go new file mode 100644 index 00000000..b7ef216d --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go @@ -0,0 +1,14 @@ +// 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. + +//go:build go1.21 +// +build go1.21 + +package versions + +func init() { + if Compare(toolchain, Go1_21) < 0 { + toolchain = Go1_21 + } +} diff --git a/vendor/golang.org/x/tools/internal/versions/types.go b/vendor/golang.org/x/tools/internal/versions/types.go new file mode 100644 index 00000000..562eef21 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/types.go @@ -0,0 +1,19 @@ +// 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 versions + +import ( + "go/types" +) + +// GoVersion returns the Go version of the type package. +// It returns zero if no version can be determined. +func GoVersion(pkg *types.Package) string { + // TODO(taking): x/tools can call GoVersion() [from 1.21] after 1.25. + if pkg, ok := any(pkg).(interface{ GoVersion() string }); ok { + return pkg.GoVersion() + } + return "" +} diff --git a/vendor/golang.org/x/tools/internal/versions/types_go121.go b/vendor/golang.org/x/tools/internal/versions/types_go121.go new file mode 100644 index 00000000..b4345d33 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/types_go121.go @@ -0,0 +1,30 @@ +// 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. + +//go:build !go1.22 +// +build !go1.22 + +package versions + +import ( + "go/ast" + "go/types" +) + +// FileVersion returns a language version (<=1.21) derived from runtime.Version() +// or an unknown future version. +func FileVersion(info *types.Info, file *ast.File) string { + // In x/tools built with Go <= 1.21, we do not have Info.FileVersions + // available. We use a go version derived from the toolchain used to + // compile the tool by default. + // This will be <= go1.21. We take this as the maximum version that + // this tool can support. + // + // There are no features currently in x/tools that need to tell fine grained + // differences for versions <1.22. + return toolchain +} + +// InitFileVersions is a noop when compiled with this Go version. +func InitFileVersions(*types.Info) {} diff --git a/vendor/golang.org/x/tools/internal/versions/types_go122.go b/vendor/golang.org/x/tools/internal/versions/types_go122.go new file mode 100644 index 00000000..e8180632 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/types_go122.go @@ -0,0 +1,41 @@ +// 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. + +//go:build go1.22 +// +build go1.22 + +package versions + +import ( + "go/ast" + "go/types" +) + +// FileVersions returns a file's Go version. +// The reported version is an unknown Future version if a +// version cannot be determined. +func FileVersion(info *types.Info, file *ast.File) string { + // In tools built with Go >= 1.22, the Go version of a file + // follow a cascades of sources: + // 1) types.Info.FileVersion, which follows the cascade: + // 1.a) file version (ast.File.GoVersion), + // 1.b) the package version (types.Config.GoVersion), or + // 2) is some unknown Future version. + // + // File versions require a valid package version to be provided to types + // in Config.GoVersion. Config.GoVersion is either from the package's module + // or the toolchain (go run). This value should be provided by go/packages + // or unitchecker.Config.GoVersion. + if v := info.FileVersions[file]; IsValid(v) { + return v + } + // Note: we could instead return runtime.Version() [if valid]. + // This would act as a max version on what a tool can support. + return Future +} + +// InitFileVersions initializes info to record Go versions for Go files. +func InitFileVersions(info *types.Info) { + info.FileVersions = make(map[*ast.File]string) +} diff --git a/vendor/golang.org/x/tools/internal/versions/versions.go b/vendor/golang.org/x/tools/internal/versions/versions.go new file mode 100644 index 00000000..8d1f7453 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/versions/versions.go @@ -0,0 +1,57 @@ +// 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 versions + +import ( + "strings" +) + +// Note: If we use build tags to use go/versions when go >=1.22, +// we run into go.dev/issue/53737. Under some operations users would see an +// import of "go/versions" even if they would not compile the file. +// For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include +// For this reason, this library just a clone of go/versions for the moment. + +// Lang returns the Go language version for version x. +// If x is not a valid version, Lang returns the empty string. +// For example: +// +// Lang("go1.21rc2") = "go1.21" +// Lang("go1.21.2") = "go1.21" +// Lang("go1.21") = "go1.21" +// Lang("go1") = "go1" +// Lang("bad") = "" +// Lang("1.21") = "" +func Lang(x string) string { + v := lang(stripGo(x)) + if v == "" { + return "" + } + return x[:2+len(v)] // "go"+v without allocation +} + +// Compare returns -1, 0, or +1 depending on whether +// x < y, x == y, or x > y, interpreted as Go versions. +// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21". +// Invalid versions, including the empty string, compare less than +// valid versions and equal to each other. +// The language version "go1.21" compares less than the +// release candidate and eventual releases "go1.21rc1" and "go1.21.0". +// Custom toolchain suffixes are ignored during comparison: +// "go1.21.0" and "go1.21.0-bigcorp" are equal. +func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) } + +// IsValid reports whether the version x is valid. +func IsValid(x string) bool { return isValid(stripGo(x)) } + +// stripGo converts from a "go1.21" version to a "1.21" version. +// If v does not start with "go", stripGo returns the empty string (a known invalid version). +func stripGo(v string) string { + v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix. + if len(v) < 2 || v[:2] != "go" { + return "" + } + return v[2:] +} diff --git a/vendor/google.golang.org/appengine/.travis.yml b/vendor/google.golang.org/appengine/.travis.yml deleted file mode 100644 index 6d03f4d3..00000000 --- a/vendor/google.golang.org/appengine/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: go - -go_import_path: google.golang.org/appengine - -install: - - ./travis_install.sh - -script: - - ./travis_test.sh - -matrix: - include: - - go: 1.9.x - env: GOAPP=true - - go: 1.10.x - env: GOAPP=false - - go: 1.11.x - env: GO111MODULE=on diff --git a/vendor/google.golang.org/appengine/CONTRIBUTING.md b/vendor/google.golang.org/appengine/CONTRIBUTING.md index ffc29852..28969361 100644 --- a/vendor/google.golang.org/appengine/CONTRIBUTING.md +++ b/vendor/google.golang.org/appengine/CONTRIBUTING.md @@ -19,14 +19,12 @@ ## Running system tests -Download and install the [Go App Engine SDK](https://cloud.google.com/appengine/docs/go/download). Make sure the `go_appengine` dir is in your `PATH`. - Set the `APPENGINE_DEV_APPSERVER` environment variable to `/path/to/go_appengine/dev_appserver.py`. -Run tests with `goapp test`: +Run tests with `go test`: ``` -goapp test -v google.golang.org/appengine/... +go test -v google.golang.org/appengine/... ``` ## Contributor License Agreements diff --git a/vendor/google.golang.org/appengine/README.md b/vendor/google.golang.org/appengine/README.md index 9fdbacd3..5ccddd99 100644 --- a/vendor/google.golang.org/appengine/README.md +++ b/vendor/google.golang.org/appengine/README.md @@ -1,6 +1,6 @@ # Go App Engine packages -[![Build Status](https://travis-ci.org/golang/appengine.svg)](https://travis-ci.org/golang/appengine) +[![CI Status](https://github.com/golang/appengine/actions/workflows/ci.yml/badge.svg)](https://github.com/golang/appengine/actions/workflows/ci.yml) This repository supports the Go runtime on *App Engine standard*. It provides APIs for interacting with App Engine services. @@ -51,7 +51,7 @@ code importing `appengine/datastore` will now need to import `google.golang.org/ Most App Engine services are available with exactly the same API. A few APIs were cleaned up, and there are some differences: -* `appengine.Context` has been replaced with the `Context` type from `golang.org/x/net/context`. +* `appengine.Context` has been replaced with the `Context` type from `context`. * Logging methods that were on `appengine.Context` are now functions in `google.golang.org/appengine/log`. * `appengine.Timeout` has been removed. Use `context.WithTimeout` instead. * `appengine.Datacenter` now takes a `context.Context` argument. @@ -72,7 +72,7 @@ A few APIs were cleaned up, and there are some differences: * `appengine/socket` is not required on App Engine flexible environment / Managed VMs. Use the standard `net` package instead. -## Key Encode/Decode compatibiltiy to help with datastore library migrations +## Key Encode/Decode compatibility to help with datastore library migrations Key compatibility updates have been added to help customers transition from google.golang.org/appengine/datastore to cloud.google.com/go/datastore. The `EnableKeyConversion` enables automatic conversion from a key encoded with cloud.google.com/go/datastore to google.golang.org/appengine/datastore key type. diff --git a/vendor/google.golang.org/appengine/appengine.go b/vendor/google.golang.org/appengine/appengine.go index 8c969767..35ba9c89 100644 --- a/vendor/google.golang.org/appengine/appengine.go +++ b/vendor/google.golang.org/appengine/appengine.go @@ -9,10 +9,10 @@ package appengine // import "google.golang.org/appengine" import ( + "context" "net/http" "github.com/golang/protobuf/proto" - "golang.org/x/net/context" "google.golang.org/appengine/internal" ) @@ -35,18 +35,18 @@ import ( // // Main is designed so that the app's main package looks like this: // -// package main +// package main // -// import ( -// "google.golang.org/appengine" +// import ( +// "google.golang.org/appengine" // -// _ "myapp/package0" -// _ "myapp/package1" -// ) +// _ "myapp/package0" +// _ "myapp/package1" +// ) // -// func main() { -// appengine.Main() -// } +// func main() { +// appengine.Main() +// } // // The "myapp/packageX" packages are expected to register HTTP handlers // in their init functions. @@ -54,6 +54,9 @@ func Main() { internal.Main() } +// Middleware wraps an http handler so that it can make GAE API calls +var Middleware func(http.Handler) http.Handler = internal.Middleware + // IsDevAppServer reports whether the App Engine app is running in the // development App Server. func IsDevAppServer() bool { diff --git a/vendor/google.golang.org/appengine/appengine_vm.go b/vendor/google.golang.org/appengine/appengine_vm.go index f4b645aa..6e1d041c 100644 --- a/vendor/google.golang.org/appengine/appengine_vm.go +++ b/vendor/google.golang.org/appengine/appengine_vm.go @@ -2,19 +2,19 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. +//go:build !appengine // +build !appengine package appengine import ( - "golang.org/x/net/context" - - "google.golang.org/appengine/internal" + "context" ) // BackgroundContext returns a context not associated with a request. -// This should only be used when not servicing a request. -// This only works in App Engine "flexible environment". +// +// Deprecated: App Engine no longer has a special background context. +// Just use context.Background(). func BackgroundContext() context.Context { - return internal.BackgroundContext() + return context.Background() } diff --git a/vendor/google.golang.org/appengine/datastore/datastore.go b/vendor/google.golang.org/appengine/datastore/datastore.go index 576bc501..790fca77 100644 --- a/vendor/google.golang.org/appengine/datastore/datastore.go +++ b/vendor/google.golang.org/appengine/datastore/datastore.go @@ -5,12 +5,12 @@ package datastore import ( + "context" "errors" "fmt" "reflect" "github.com/golang/protobuf/proto" - "golang.org/x/net/context" "google.golang.org/appengine" "google.golang.org/appengine/internal" diff --git a/vendor/google.golang.org/appengine/datastore/doc.go b/vendor/google.golang.org/appengine/datastore/doc.go index 85616cf2..1ecf5188 100644 --- a/vendor/google.golang.org/appengine/datastore/doc.go +++ b/vendor/google.golang.org/appengine/datastore/doc.go @@ -5,8 +5,7 @@ /* Package datastore provides a client for App Engine's datastore service. - -Basic Operations +# Basic Operations Entities are the unit of storage and are associated with a key. A key consists of an optional parent key, a string application ID, a string kind @@ -74,8 +73,7 @@ GetMulti, PutMulti and DeleteMulti are batch versions of the Get, Put and Delete functions. They take a []*Key instead of a *Key, and may return an appengine.MultiError when encountering partial failure. - -Properties +# Properties An entity's contents can be represented by a variety of types. These are typically struct pointers, but can also be any type that implements the @@ -137,8 +135,7 @@ Example code: J int `datastore:",noindex" json:"j"` } - -Structured Properties +# Structured Properties If the struct pointed to contains other structs, then the nested or embedded structs are flattened. For example, given these definitions: @@ -179,8 +176,7 @@ equivalent field would instead be: FooDotZ bool `datastore:"Foo.Z"`. If an outer struct is tagged "noindex" then all of its implicit flattened fields are effectively "noindex". - -The PropertyLoadSaver Interface +# The PropertyLoadSaver Interface An entity's contents can also be represented by any type that implements the PropertyLoadSaver interface. This type may be a struct pointer, but it does @@ -230,8 +226,7 @@ Example code: The *PropertyList type implements PropertyLoadSaver, and can therefore hold an arbitrary entity's contents. - -Queries +# Queries Queries retrieve entities based on their properties or key's ancestry. Running a query yields an iterator of results: either keys or (key, entity) pairs. @@ -284,8 +279,7 @@ Example code: io.Copy(w, b) } - -Transactions +# Transactions RunInTransaction runs a function in a transaction. @@ -323,8 +317,7 @@ Example code: fmt.Fprintf(w, "Count=%d", count) } - -Metadata +# Metadata The datastore package provides access to some of App Engine's datastore metadata. This metadata includes information about the entity groups, diff --git a/vendor/google.golang.org/appengine/datastore/key.go b/vendor/google.golang.org/appengine/datastore/key.go index fd598dc9..e312df51 100644 --- a/vendor/google.golang.org/appengine/datastore/key.go +++ b/vendor/google.golang.org/appengine/datastore/key.go @@ -6,6 +6,7 @@ package datastore import ( "bytes" + "context" "encoding/base64" "encoding/gob" "errors" @@ -14,7 +15,6 @@ import ( "strings" "github.com/golang/protobuf/proto" - "golang.org/x/net/context" "google.golang.org/appengine/internal" pb "google.golang.org/appengine/internal/datastore" diff --git a/vendor/google.golang.org/appengine/datastore/keycompat.go b/vendor/google.golang.org/appengine/datastore/keycompat.go index 371a64ee..e852f29c 100644 --- a/vendor/google.golang.org/appengine/datastore/keycompat.go +++ b/vendor/google.golang.org/appengine/datastore/keycompat.go @@ -5,10 +5,9 @@ package datastore import ( + "context" "sync" - "golang.org/x/net/context" - "google.golang.org/appengine/datastore/internal/cloudkey" "google.golang.org/appengine/internal" ) diff --git a/vendor/google.golang.org/appengine/datastore/metadata.go b/vendor/google.golang.org/appengine/datastore/metadata.go index 6acacc3d..e1b2d225 100644 --- a/vendor/google.golang.org/appengine/datastore/metadata.go +++ b/vendor/google.golang.org/appengine/datastore/metadata.go @@ -4,7 +4,7 @@ package datastore -import "golang.org/x/net/context" +import "context" // Datastore kinds for the metadata entities. const ( @@ -50,13 +50,14 @@ func keyNames(keys []*Key) []string { // The properties are returned as a map of property names to a slice of the // representation types. The representation types for the supported Go property // types are: -// "INT64": signed integers and time.Time -// "DOUBLE": float32 and float64 -// "BOOLEAN": bool -// "STRING": string, []byte and ByteString -// "POINT": appengine.GeoPoint -// "REFERENCE": *Key -// "USER": (not used in the Go runtime) +// +// "INT64": signed integers and time.Time +// "DOUBLE": float32 and float64 +// "BOOLEAN": bool +// "STRING": string, []byte and ByteString +// "POINT": appengine.GeoPoint +// "REFERENCE": *Key +// "USER": (not used in the Go runtime) func KindProperties(ctx context.Context, kind string) (map[string][]string, error) { // TODO(djd): Support range queries. kindKey := NewKey(ctx, kindKind, kind, 0, nil) diff --git a/vendor/google.golang.org/appengine/datastore/query.go b/vendor/google.golang.org/appengine/datastore/query.go index 4124534b..b1b80bf7 100644 --- a/vendor/google.golang.org/appengine/datastore/query.go +++ b/vendor/google.golang.org/appengine/datastore/query.go @@ -5,6 +5,7 @@ package datastore import ( + "context" "encoding/base64" "errors" "fmt" @@ -13,7 +14,6 @@ import ( "strings" "github.com/golang/protobuf/proto" - "golang.org/x/net/context" "google.golang.org/appengine/internal" pb "google.golang.org/appengine/internal/datastore" @@ -476,7 +476,7 @@ func callNext(c context.Context, res *pb.QueryResult, offset, count int32) error // The keys returned by GetAll will be in a 1-1 correspondence with the entities // added to dst. // -// If q is a ``keys-only'' query, GetAll ignores dst and only returns the keys. +// If q is a “keys-only” query, GetAll ignores dst and only returns the keys. // // The running time and number of API calls made by GetAll scale linearly with // the sum of the query's offset and limit. Unless the result count is @@ -754,7 +754,7 @@ func (c Cursor) String() string { return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=") } -// Decode decodes a cursor from its base-64 string representation. +// DecodeCursor decodes a cursor from its base-64 string representation. func DecodeCursor(s string) (Cursor, error) { if s == "" { return Cursor{&zeroCC}, nil diff --git a/vendor/google.golang.org/appengine/datastore/transaction.go b/vendor/google.golang.org/appengine/datastore/transaction.go index 2ae8428f..06deeb43 100644 --- a/vendor/google.golang.org/appengine/datastore/transaction.go +++ b/vendor/google.golang.org/appengine/datastore/transaction.go @@ -5,10 +5,9 @@ package datastore import ( + "context" "errors" - "golang.org/x/net/context" - "google.golang.org/appengine/internal" pb "google.golang.org/appengine/internal/datastore" ) diff --git a/vendor/google.golang.org/appengine/identity.go b/vendor/google.golang.org/appengine/identity.go index b8dcf8f3..1202fc1a 100644 --- a/vendor/google.golang.org/appengine/identity.go +++ b/vendor/google.golang.org/appengine/identity.go @@ -5,10 +5,9 @@ package appengine import ( + "context" "time" - "golang.org/x/net/context" - "google.golang.org/appengine/internal" pb "google.golang.org/appengine/internal/app_identity" modpb "google.golang.org/appengine/internal/modules" diff --git a/vendor/google.golang.org/appengine/internal/api.go b/vendor/google.golang.org/appengine/internal/api.go index 721053c2..0569f5dd 100644 --- a/vendor/google.golang.org/appengine/internal/api.go +++ b/vendor/google.golang.org/appengine/internal/api.go @@ -2,12 +2,14 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. +//go:build !appengine // +build !appengine package internal import ( "bytes" + "context" "errors" "fmt" "io/ioutil" @@ -24,7 +26,6 @@ import ( "time" "github.com/golang/protobuf/proto" - netcontext "golang.org/x/net/context" basepb "google.golang.org/appengine/internal/base" logpb "google.golang.org/appengine/internal/log" @@ -32,8 +33,7 @@ import ( ) const ( - apiPath = "/rpc_http" - defaultTicketSuffix = "/default.20150612t184001.0" + apiPath = "/rpc_http" ) var ( @@ -65,21 +65,22 @@ var ( IdleConnTimeout: 90 * time.Second, }, } - - defaultTicketOnce sync.Once - defaultTicket string - backgroundContextOnce sync.Once - backgroundContext netcontext.Context ) -func apiURL() *url.URL { +func apiURL(ctx context.Context) *url.URL { host, port := "appengine.googleapis.internal", "10001" if h := os.Getenv("API_HOST"); h != "" { host = h } + if hostOverride := ctx.Value(apiHostOverrideKey); hostOverride != nil { + host = hostOverride.(string) + } if p := os.Getenv("API_PORT"); p != "" { port = p } + if portOverride := ctx.Value(apiPortOverrideKey); portOverride != nil { + port = portOverride.(string) + } return &url.URL{ Scheme: "http", Host: host + ":" + port, @@ -87,82 +88,97 @@ func apiURL() *url.URL { } } -func handleHTTP(w http.ResponseWriter, r *http.Request) { - c := &context{ - req: r, - outHeader: w.Header(), - apiURL: apiURL(), - } - r = r.WithContext(withContext(r.Context(), c)) - c.req = r - - stopFlushing := make(chan int) +// Middleware wraps an http handler so that it can make GAE API calls +func Middleware(next http.Handler) http.Handler { + return handleHTTPMiddleware(executeRequestSafelyMiddleware(next)) +} - // Patch up RemoteAddr so it looks reasonable. - if addr := r.Header.Get(userIPHeader); addr != "" { - r.RemoteAddr = addr - } else if addr = r.Header.Get(remoteAddrHeader); addr != "" { - r.RemoteAddr = addr - } else { - // Should not normally reach here, but pick a sensible default anyway. - r.RemoteAddr = "127.0.0.1" - } - // The address in the headers will most likely be of these forms: - // 123.123.123.123 - // 2001:db8::1 - // net/http.Request.RemoteAddr is specified to be in "IP:port" form. - if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil { - // Assume the remote address is only a host; add a default port. - r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80") - } +func handleHTTPMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + c := &aeContext{ + req: r, + outHeader: w.Header(), + } + r = r.WithContext(withContext(r.Context(), c)) + c.req = r + + stopFlushing := make(chan int) + + // Patch up RemoteAddr so it looks reasonable. + if addr := r.Header.Get(userIPHeader); addr != "" { + r.RemoteAddr = addr + } else if addr = r.Header.Get(remoteAddrHeader); addr != "" { + r.RemoteAddr = addr + } else { + // Should not normally reach here, but pick a sensible default anyway. + r.RemoteAddr = "127.0.0.1" + } + // The address in the headers will most likely be of these forms: + // 123.123.123.123 + // 2001:db8::1 + // net/http.Request.RemoteAddr is specified to be in "IP:port" form. + if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil { + // Assume the remote address is only a host; add a default port. + r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80") + } - // Start goroutine responsible for flushing app logs. - // This is done after adding c to ctx.m (and stopped before removing it) - // because flushing logs requires making an API call. - go c.logFlusher(stopFlushing) + if logToLogservice() { + // Start goroutine responsible for flushing app logs. + // This is done after adding c to ctx.m (and stopped before removing it) + // because flushing logs requires making an API call. + go c.logFlusher(stopFlushing) + } - executeRequestSafely(c, r) - c.outHeader = nil // make sure header changes aren't respected any more + next.ServeHTTP(c, r) + c.outHeader = nil // make sure header changes aren't respected any more - stopFlushing <- 1 // any logging beyond this point will be dropped + flushed := make(chan struct{}) + if logToLogservice() { + stopFlushing <- 1 // any logging beyond this point will be dropped - // Flush any pending logs asynchronously. - c.pendingLogs.Lock() - flushes := c.pendingLogs.flushes - if len(c.pendingLogs.lines) > 0 { - flushes++ - } - c.pendingLogs.Unlock() - flushed := make(chan struct{}) - go func() { - defer close(flushed) - // Force a log flush, because with very short requests we - // may not ever flush logs. - c.flushLog(true) - }() - w.Header().Set(logFlushHeader, strconv.Itoa(flushes)) + // Flush any pending logs asynchronously. + c.pendingLogs.Lock() + flushes := c.pendingLogs.flushes + if len(c.pendingLogs.lines) > 0 { + flushes++ + } + c.pendingLogs.Unlock() + go func() { + defer close(flushed) + // Force a log flush, because with very short requests we + // may not ever flush logs. + c.flushLog(true) + }() + w.Header().Set(logFlushHeader, strconv.Itoa(flushes)) + } - // Avoid nil Write call if c.Write is never called. - if c.outCode != 0 { - w.WriteHeader(c.outCode) - } - if c.outBody != nil { - w.Write(c.outBody) - } - // Wait for the last flush to complete before returning, - // otherwise the security ticket will not be valid. - <-flushed + // Avoid nil Write call if c.Write is never called. + if c.outCode != 0 { + w.WriteHeader(c.outCode) + } + if c.outBody != nil { + w.Write(c.outBody) + } + if logToLogservice() { + // Wait for the last flush to complete before returning, + // otherwise the security ticket will not be valid. + <-flushed + } + }) } -func executeRequestSafely(c *context, r *http.Request) { - defer func() { - if x := recover(); x != nil { - logf(c, 4, "%s", renderPanic(x)) // 4 == critical - c.outCode = 500 - } - }() +func executeRequestSafelyMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer func() { + if x := recover(); x != nil { + c := w.(*aeContext) + logf(c, 4, "%s", renderPanic(x)) // 4 == critical + c.outCode = 500 + } + }() - http.DefaultServeMux.ServeHTTP(c, r) + next.ServeHTTP(w, r) + }) } func renderPanic(x interface{}) string { @@ -204,9 +220,9 @@ func renderPanic(x interface{}) string { return string(buf) } -// context represents the context of an in-flight HTTP request. +// aeContext represents the aeContext of an in-flight HTTP request. // It implements the appengine.Context and http.ResponseWriter interfaces. -type context struct { +type aeContext struct { req *http.Request outCode int @@ -218,8 +234,6 @@ type context struct { lines []*logpb.UserAppLogLine flushes int } - - apiURL *url.URL } var contextKey = "holds a *context" @@ -227,8 +241,8 @@ var contextKey = "holds a *context" // jointContext joins two contexts in a superficial way. // It takes values and timeouts from a base context, and only values from another context. type jointContext struct { - base netcontext.Context - valuesOnly netcontext.Context + base context.Context + valuesOnly context.Context } func (c jointContext) Deadline() (time.Time, bool) { @@ -252,94 +266,54 @@ func (c jointContext) Value(key interface{}) interface{} { // fromContext returns the App Engine context or nil if ctx is not // derived from an App Engine context. -func fromContext(ctx netcontext.Context) *context { - c, _ := ctx.Value(&contextKey).(*context) +func fromContext(ctx context.Context) *aeContext { + c, _ := ctx.Value(&contextKey).(*aeContext) return c } -func withContext(parent netcontext.Context, c *context) netcontext.Context { - ctx := netcontext.WithValue(parent, &contextKey, c) +func withContext(parent context.Context, c *aeContext) context.Context { + ctx := context.WithValue(parent, &contextKey, c) if ns := c.req.Header.Get(curNamespaceHeader); ns != "" { ctx = withNamespace(ctx, ns) } return ctx } -func toContext(c *context) netcontext.Context { - return withContext(netcontext.Background(), c) +func toContext(c *aeContext) context.Context { + return withContext(context.Background(), c) } -func IncomingHeaders(ctx netcontext.Context) http.Header { +func IncomingHeaders(ctx context.Context) http.Header { if c := fromContext(ctx); c != nil { return c.req.Header } return nil } -func ReqContext(req *http.Request) netcontext.Context { +func ReqContext(req *http.Request) context.Context { return req.Context() } -func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context { +func WithContext(parent context.Context, req *http.Request) context.Context { return jointContext{ base: parent, valuesOnly: req.Context(), } } -// DefaultTicket returns a ticket used for background context or dev_appserver. -func DefaultTicket() string { - defaultTicketOnce.Do(func() { - if IsDevAppServer() { - defaultTicket = "testapp" + defaultTicketSuffix - return - } - appID := partitionlessAppID() - escAppID := strings.Replace(strings.Replace(appID, ":", "_", -1), ".", "_", -1) - majVersion := VersionID(nil) - if i := strings.Index(majVersion, "."); i > 0 { - majVersion = majVersion[:i] - } - defaultTicket = fmt.Sprintf("%s/%s.%s.%s", escAppID, ModuleName(nil), majVersion, InstanceID()) - }) - return defaultTicket -} - -func BackgroundContext() netcontext.Context { - backgroundContextOnce.Do(func() { - // Compute background security ticket. - ticket := DefaultTicket() - - c := &context{ - req: &http.Request{ - Header: http.Header{ - ticketHeader: []string{ticket}, - }, - }, - apiURL: apiURL(), - } - backgroundContext = toContext(c) - - // TODO(dsymonds): Wire up the shutdown handler to do a final flush. - go c.logFlusher(make(chan int)) - }) - - return backgroundContext -} - // RegisterTestRequest registers the HTTP request req for testing, such that -// any API calls are sent to the provided URL. It returns a closure to delete -// the registration. +// any API calls are sent to the provided URL. // It should only be used by aetest package. -func RegisterTestRequest(req *http.Request, apiURL *url.URL, decorate func(netcontext.Context) netcontext.Context) (*http.Request, func()) { - c := &context{ - req: req, - apiURL: apiURL, - } - ctx := withContext(decorate(req.Context()), c) - req = req.WithContext(ctx) - c.req = req - return req, func() {} +func RegisterTestRequest(req *http.Request, apiURL *url.URL, appID string) *http.Request { + ctx := req.Context() + ctx = withAPIHostOverride(ctx, apiURL.Hostname()) + ctx = withAPIPortOverride(ctx, apiURL.Port()) + ctx = WithAppIDOverride(ctx, appID) + + // use the unregistered request as a placeholder so that withContext can read the headers + c := &aeContext{req: req} + c.req = req.WithContext(withContext(ctx, c)) + return c.req } var errTimeout = &CallError{ @@ -348,7 +322,7 @@ var errTimeout = &CallError{ Timeout: true, } -func (c *context) Header() http.Header { return c.outHeader } +func (c *aeContext) Header() http.Header { return c.outHeader } // Copied from $GOROOT/src/pkg/net/http/transfer.go. Some response status // codes do not permit a response body (nor response entity headers such as @@ -365,7 +339,7 @@ func bodyAllowedForStatus(status int) bool { return true } -func (c *context) Write(b []byte) (int, error) { +func (c *aeContext) Write(b []byte) (int, error) { if c.outCode == 0 { c.WriteHeader(http.StatusOK) } @@ -376,7 +350,7 @@ func (c *context) Write(b []byte) (int, error) { return len(b), nil } -func (c *context) WriteHeader(code int) { +func (c *aeContext) WriteHeader(code int) { if c.outCode != 0 { logf(c, 3, "WriteHeader called multiple times on request.") // error level return @@ -384,10 +358,11 @@ func (c *context) WriteHeader(code int) { c.outCode = code } -func (c *context) post(body []byte, timeout time.Duration) (b []byte, err error) { +func post(ctx context.Context, body []byte, timeout time.Duration) (b []byte, err error) { + apiURL := apiURL(ctx) hreq := &http.Request{ Method: "POST", - URL: c.apiURL, + URL: apiURL, Header: http.Header{ apiEndpointHeader: apiEndpointHeaderValue, apiMethodHeader: apiMethodHeaderValue, @@ -396,13 +371,16 @@ func (c *context) post(body []byte, timeout time.Duration) (b []byte, err error) }, Body: ioutil.NopCloser(bytes.NewReader(body)), ContentLength: int64(len(body)), - Host: c.apiURL.Host, - } - if info := c.req.Header.Get(dapperHeader); info != "" { - hreq.Header.Set(dapperHeader, info) + Host: apiURL.Host, } - if info := c.req.Header.Get(traceHeader); info != "" { - hreq.Header.Set(traceHeader, info) + c := fromContext(ctx) + if c != nil { + if info := c.req.Header.Get(dapperHeader); info != "" { + hreq.Header.Set(dapperHeader, info) + } + if info := c.req.Header.Get(traceHeader); info != "" { + hreq.Header.Set(traceHeader, info) + } } tr := apiHTTPClient.Transport.(*http.Transport) @@ -444,7 +422,7 @@ func (c *context) post(body []byte, timeout time.Duration) (b []byte, err error) return hrespBody, nil } -func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error { +func Call(ctx context.Context, service, method string, in, out proto.Message) error { if ns := NamespaceFromContext(ctx); ns != "" { if fn, ok := NamespaceMods[service]; ok { fn(in, ns) @@ -463,15 +441,11 @@ func Call(ctx netcontext.Context, service, method string, in, out proto.Message) } c := fromContext(ctx) - if c == nil { - // Give a good error message rather than a panic lower down. - return errNotAppEngineContext - } // Apply transaction modifications if we're in a transaction. if t := transactionFromContext(ctx); t != nil { if t.finished { - return errors.New("transaction context has expired") + return errors.New("transaction aeContext has expired") } applyTransaction(in, &t.transaction) } @@ -487,20 +461,13 @@ func Call(ctx netcontext.Context, service, method string, in, out proto.Message) return err } - ticket := c.req.Header.Get(ticketHeader) - // Use a test ticket under test environment. - if ticket == "" { - if appid := ctx.Value(&appIDOverrideKey); appid != nil { - ticket = appid.(string) + defaultTicketSuffix + ticket := "" + if c != nil { + ticket = c.req.Header.Get(ticketHeader) + if dri := c.req.Header.Get(devRequestIdHeader); IsDevAppServer() && dri != "" { + ticket = dri } } - // Fall back to use background ticket when the request ticket is not available in Flex or dev_appserver. - if ticket == "" { - ticket = DefaultTicket() - } - if dri := c.req.Header.Get(devRequestIdHeader); IsDevAppServer() && dri != "" { - ticket = dri - } req := &remotepb.Request{ ServiceName: &service, Method: &method, @@ -512,7 +479,7 @@ func Call(ctx netcontext.Context, service, method string, in, out proto.Message) return err } - hrespBody, err := c.post(hreqBody, timeout) + hrespBody, err := post(ctx, hreqBody, timeout) if err != nil { return err } @@ -549,11 +516,11 @@ func Call(ctx netcontext.Context, service, method string, in, out proto.Message) return proto.Unmarshal(res.Response, out) } -func (c *context) Request() *http.Request { +func (c *aeContext) Request() *http.Request { return c.req } -func (c *context) addLogLine(ll *logpb.UserAppLogLine) { +func (c *aeContext) addLogLine(ll *logpb.UserAppLogLine) { // Truncate long log lines. // TODO(dsymonds): Check if this is still necessary. const lim = 8 << 10 @@ -575,18 +542,20 @@ var logLevelName = map[int64]string{ 4: "CRITICAL", } -func logf(c *context, level int64, format string, args ...interface{}) { +func logf(c *aeContext, level int64, format string, args ...interface{}) { if c == nil { - panic("not an App Engine context") + panic("not an App Engine aeContext") } s := fmt.Sprintf(format, args...) s = strings.TrimRight(s, "\n") // Remove any trailing newline characters. - c.addLogLine(&logpb.UserAppLogLine{ - TimestampUsec: proto.Int64(time.Now().UnixNano() / 1e3), - Level: &level, - Message: &s, - }) - // Only duplicate log to stderr if not running on App Engine second generation + if logToLogservice() { + c.addLogLine(&logpb.UserAppLogLine{ + TimestampUsec: proto.Int64(time.Now().UnixNano() / 1e3), + Level: &level, + Message: &s, + }) + } + // Log to stdout if not deployed if !IsSecondGen() { log.Print(logLevelName[level] + ": " + s) } @@ -594,7 +563,7 @@ func logf(c *context, level int64, format string, args ...interface{}) { // flushLog attempts to flush any pending logs to the appserver. // It should not be called concurrently. -func (c *context) flushLog(force bool) (flushed bool) { +func (c *aeContext) flushLog(force bool) (flushed bool) { c.pendingLogs.Lock() // Grab up to 30 MB. We can get away with up to 32 MB, but let's be cautious. n, rem := 0, 30<<20 @@ -655,7 +624,7 @@ const ( forceFlushInterval = 60 * time.Second ) -func (c *context) logFlusher(stop <-chan int) { +func (c *aeContext) logFlusher(stop <-chan int) { lastFlush := time.Now() tick := time.NewTicker(flushInterval) for { @@ -673,6 +642,12 @@ func (c *context) logFlusher(stop <-chan int) { } } -func ContextForTesting(req *http.Request) netcontext.Context { - return toContext(&context{req: req}) +func ContextForTesting(req *http.Request) context.Context { + return toContext(&aeContext{req: req}) +} + +func logToLogservice() bool { + // TODO: replace logservice with json structured logs to $LOG_DIR/app.log.json + // where $LOG_DIR is /var/log in prod and some tmpdir in dev + return os.Getenv("LOG_TO_LOGSERVICE") != "0" } diff --git a/vendor/google.golang.org/appengine/internal/api_classic.go b/vendor/google.golang.org/appengine/internal/api_classic.go index f0f40b2e..87c33c79 100644 --- a/vendor/google.golang.org/appengine/internal/api_classic.go +++ b/vendor/google.golang.org/appengine/internal/api_classic.go @@ -2,11 +2,13 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. +//go:build appengine // +build appengine package internal import ( + "context" "errors" "fmt" "net/http" @@ -17,20 +19,19 @@ import ( basepb "appengine_internal/base" "github.com/golang/protobuf/proto" - netcontext "golang.org/x/net/context" ) var contextKey = "holds an appengine.Context" // fromContext returns the App Engine context or nil if ctx is not // derived from an App Engine context. -func fromContext(ctx netcontext.Context) appengine.Context { +func fromContext(ctx context.Context) appengine.Context { c, _ := ctx.Value(&contextKey).(appengine.Context) return c } // This is only for classic App Engine adapters. -func ClassicContextFromContext(ctx netcontext.Context) (appengine.Context, error) { +func ClassicContextFromContext(ctx context.Context) (appengine.Context, error) { c := fromContext(ctx) if c == nil { return nil, errNotAppEngineContext @@ -38,8 +39,8 @@ func ClassicContextFromContext(ctx netcontext.Context) (appengine.Context, error return c, nil } -func withContext(parent netcontext.Context, c appengine.Context) netcontext.Context { - ctx := netcontext.WithValue(parent, &contextKey, c) +func withContext(parent context.Context, c appengine.Context) context.Context { + ctx := context.WithValue(parent, &contextKey, c) s := &basepb.StringProto{} c.Call("__go__", "GetNamespace", &basepb.VoidProto{}, s, nil) @@ -50,7 +51,7 @@ func withContext(parent netcontext.Context, c appengine.Context) netcontext.Cont return ctx } -func IncomingHeaders(ctx netcontext.Context) http.Header { +func IncomingHeaders(ctx context.Context) http.Header { if c := fromContext(ctx); c != nil { if req, ok := c.Request().(*http.Request); ok { return req.Header @@ -59,11 +60,11 @@ func IncomingHeaders(ctx netcontext.Context) http.Header { return nil } -func ReqContext(req *http.Request) netcontext.Context { - return WithContext(netcontext.Background(), req) +func ReqContext(req *http.Request) context.Context { + return WithContext(context.Background(), req) } -func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context { +func WithContext(parent context.Context, req *http.Request) context.Context { c := appengine.NewContext(req) return withContext(parent, c) } @@ -83,11 +84,11 @@ func (t *testingContext) Call(service, method string, _, _ appengine_internal.Pr } func (t *testingContext) Request() interface{} { return t.req } -func ContextForTesting(req *http.Request) netcontext.Context { - return withContext(netcontext.Background(), &testingContext{req: req}) +func ContextForTesting(req *http.Request) context.Context { + return withContext(context.Background(), &testingContext{req: req}) } -func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error { +func Call(ctx context.Context, service, method string, in, out proto.Message) error { if ns := NamespaceFromContext(ctx); ns != "" { if fn, ok := NamespaceMods[service]; ok { fn(in, ns) @@ -144,8 +145,8 @@ func Call(ctx netcontext.Context, service, method string, in, out proto.Message) return err } -func handleHTTP(w http.ResponseWriter, r *http.Request) { - panic("handleHTTP called; this should be impossible") +func Middleware(next http.Handler) http.Handler { + panic("Middleware called; this should be impossible") } func logf(c appengine.Context, level int64, format string, args ...interface{}) { diff --git a/vendor/google.golang.org/appengine/internal/api_common.go b/vendor/google.golang.org/appengine/internal/api_common.go index e0c0b214..5b95c13d 100644 --- a/vendor/google.golang.org/appengine/internal/api_common.go +++ b/vendor/google.golang.org/appengine/internal/api_common.go @@ -5,20 +5,26 @@ package internal import ( + "context" "errors" "os" "github.com/golang/protobuf/proto" - netcontext "golang.org/x/net/context" ) +type ctxKey string + +func (c ctxKey) String() string { + return "appengine context key: " + string(c) +} + var errNotAppEngineContext = errors.New("not an App Engine context") -type CallOverrideFunc func(ctx netcontext.Context, service, method string, in, out proto.Message) error +type CallOverrideFunc func(ctx context.Context, service, method string, in, out proto.Message) error var callOverrideKey = "holds []CallOverrideFunc" -func WithCallOverride(ctx netcontext.Context, f CallOverrideFunc) netcontext.Context { +func WithCallOverride(ctx context.Context, f CallOverrideFunc) context.Context { // We avoid appending to any existing call override // so we don't risk overwriting a popped stack below. var cofs []CallOverrideFunc @@ -26,10 +32,10 @@ func WithCallOverride(ctx netcontext.Context, f CallOverrideFunc) netcontext.Con cofs = append(cofs, uf...) } cofs = append(cofs, f) - return netcontext.WithValue(ctx, &callOverrideKey, cofs) + return context.WithValue(ctx, &callOverrideKey, cofs) } -func callOverrideFromContext(ctx netcontext.Context) (CallOverrideFunc, netcontext.Context, bool) { +func callOverrideFromContext(ctx context.Context) (CallOverrideFunc, context.Context, bool) { cofs, _ := ctx.Value(&callOverrideKey).([]CallOverrideFunc) if len(cofs) == 0 { return nil, nil, false @@ -37,7 +43,7 @@ func callOverrideFromContext(ctx netcontext.Context) (CallOverrideFunc, netconte // We found a list of overrides; grab the last, and reconstitute a // context that will hide it. f := cofs[len(cofs)-1] - ctx = netcontext.WithValue(ctx, &callOverrideKey, cofs[:len(cofs)-1]) + ctx = context.WithValue(ctx, &callOverrideKey, cofs[:len(cofs)-1]) return f, ctx, true } @@ -45,23 +51,35 @@ type logOverrideFunc func(level int64, format string, args ...interface{}) var logOverrideKey = "holds a logOverrideFunc" -func WithLogOverride(ctx netcontext.Context, f logOverrideFunc) netcontext.Context { - return netcontext.WithValue(ctx, &logOverrideKey, f) +func WithLogOverride(ctx context.Context, f logOverrideFunc) context.Context { + return context.WithValue(ctx, &logOverrideKey, f) } var appIDOverrideKey = "holds a string, being the full app ID" -func WithAppIDOverride(ctx netcontext.Context, appID string) netcontext.Context { - return netcontext.WithValue(ctx, &appIDOverrideKey, appID) +func WithAppIDOverride(ctx context.Context, appID string) context.Context { + return context.WithValue(ctx, &appIDOverrideKey, appID) +} + +var apiHostOverrideKey = ctxKey("holds a string, being the alternate API_HOST") + +func withAPIHostOverride(ctx context.Context, apiHost string) context.Context { + return context.WithValue(ctx, apiHostOverrideKey, apiHost) +} + +var apiPortOverrideKey = ctxKey("holds a string, being the alternate API_PORT") + +func withAPIPortOverride(ctx context.Context, apiPort string) context.Context { + return context.WithValue(ctx, apiPortOverrideKey, apiPort) } var namespaceKey = "holds the namespace string" -func withNamespace(ctx netcontext.Context, ns string) netcontext.Context { - return netcontext.WithValue(ctx, &namespaceKey, ns) +func withNamespace(ctx context.Context, ns string) context.Context { + return context.WithValue(ctx, &namespaceKey, ns) } -func NamespaceFromContext(ctx netcontext.Context) string { +func NamespaceFromContext(ctx context.Context) string { // If there's no namespace, return the empty string. ns, _ := ctx.Value(&namespaceKey).(string) return ns @@ -70,14 +88,14 @@ func NamespaceFromContext(ctx netcontext.Context) string { // FullyQualifiedAppID returns the fully-qualified application ID. // This may contain a partition prefix (e.g. "s~" for High Replication apps), // or a domain prefix (e.g. "example.com:"). -func FullyQualifiedAppID(ctx netcontext.Context) string { +func FullyQualifiedAppID(ctx context.Context) string { if id, ok := ctx.Value(&appIDOverrideKey).(string); ok { return id } return fullyQualifiedAppID(ctx) } -func Logf(ctx netcontext.Context, level int64, format string, args ...interface{}) { +func Logf(ctx context.Context, level int64, format string, args ...interface{}) { if f, ok := ctx.Value(&logOverrideKey).(logOverrideFunc); ok { f(level, format, args...) return @@ -90,7 +108,7 @@ func Logf(ctx netcontext.Context, level int64, format string, args ...interface{ } // NamespacedContext wraps a Context to support namespaces. -func NamespacedContext(ctx netcontext.Context, namespace string) netcontext.Context { +func NamespacedContext(ctx context.Context, namespace string) context.Context { return withNamespace(ctx, namespace) } diff --git a/vendor/google.golang.org/appengine/internal/identity.go b/vendor/google.golang.org/appengine/internal/identity.go index 9b4134e4..0f95aa91 100644 --- a/vendor/google.golang.org/appengine/internal/identity.go +++ b/vendor/google.golang.org/appengine/internal/identity.go @@ -5,9 +5,8 @@ package internal import ( + "context" "os" - - netcontext "golang.org/x/net/context" ) var ( @@ -23,7 +22,7 @@ var ( // AppID is the implementation of the wrapper function of the same name in // ../identity.go. See that file for commentary. -func AppID(c netcontext.Context) string { +func AppID(c context.Context) string { return appID(FullyQualifiedAppID(c)) } @@ -35,7 +34,7 @@ func IsStandard() bool { return appengineStandard || IsSecondGen() } -// IsStandard is the implementation of the wrapper function of the same name in +// IsSecondGen is the implementation of the wrapper function of the same name in // ../appengine.go. See that file for commentary. func IsSecondGen() bool { // Second-gen runtimes set $GAE_ENV so we use that to check if we're on a second-gen runtime. diff --git a/vendor/google.golang.org/appengine/internal/identity_classic.go b/vendor/google.golang.org/appengine/internal/identity_classic.go index 4e979f45..5ad3548b 100644 --- a/vendor/google.golang.org/appengine/internal/identity_classic.go +++ b/vendor/google.golang.org/appengine/internal/identity_classic.go @@ -2,21 +2,22 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. +//go:build appengine // +build appengine package internal import ( - "appengine" + "context" - netcontext "golang.org/x/net/context" + "appengine" ) func init() { appengineStandard = true } -func DefaultVersionHostname(ctx netcontext.Context) string { +func DefaultVersionHostname(ctx context.Context) string { c := fromContext(ctx) if c == nil { panic(errNotAppEngineContext) @@ -24,12 +25,12 @@ func DefaultVersionHostname(ctx netcontext.Context) string { return appengine.DefaultVersionHostname(c) } -func Datacenter(_ netcontext.Context) string { return appengine.Datacenter() } -func ServerSoftware() string { return appengine.ServerSoftware() } -func InstanceID() string { return appengine.InstanceID() } -func IsDevAppServer() bool { return appengine.IsDevAppServer() } +func Datacenter(_ context.Context) string { return appengine.Datacenter() } +func ServerSoftware() string { return appengine.ServerSoftware() } +func InstanceID() string { return appengine.InstanceID() } +func IsDevAppServer() bool { return appengine.IsDevAppServer() } -func RequestID(ctx netcontext.Context) string { +func RequestID(ctx context.Context) string { c := fromContext(ctx) if c == nil { panic(errNotAppEngineContext) @@ -37,14 +38,14 @@ func RequestID(ctx netcontext.Context) string { return appengine.RequestID(c) } -func ModuleName(ctx netcontext.Context) string { +func ModuleName(ctx context.Context) string { c := fromContext(ctx) if c == nil { panic(errNotAppEngineContext) } return appengine.ModuleName(c) } -func VersionID(ctx netcontext.Context) string { +func VersionID(ctx context.Context) string { c := fromContext(ctx) if c == nil { panic(errNotAppEngineContext) @@ -52,7 +53,7 @@ func VersionID(ctx netcontext.Context) string { return appengine.VersionID(c) } -func fullyQualifiedAppID(ctx netcontext.Context) string { +func fullyQualifiedAppID(ctx context.Context) string { c := fromContext(ctx) if c == nil { panic(errNotAppEngineContext) diff --git a/vendor/google.golang.org/appengine/internal/identity_flex.go b/vendor/google.golang.org/appengine/internal/identity_flex.go index d5e2e7b5..4201b6b5 100644 --- a/vendor/google.golang.org/appengine/internal/identity_flex.go +++ b/vendor/google.golang.org/appengine/internal/identity_flex.go @@ -2,6 +2,7 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. +//go:build appenginevm // +build appenginevm package internal diff --git a/vendor/google.golang.org/appengine/internal/identity_vm.go b/vendor/google.golang.org/appengine/internal/identity_vm.go index 5d806726..18ddda3a 100644 --- a/vendor/google.golang.org/appengine/internal/identity_vm.go +++ b/vendor/google.golang.org/appengine/internal/identity_vm.go @@ -2,17 +2,17 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. +//go:build !appengine // +build !appengine package internal import ( + "context" "log" "net/http" "os" "strings" - - netcontext "golang.org/x/net/context" ) // These functions are implementations of the wrapper functions @@ -24,7 +24,7 @@ const ( hDatacenter = "X-AppEngine-Datacenter" ) -func ctxHeaders(ctx netcontext.Context) http.Header { +func ctxHeaders(ctx context.Context) http.Header { c := fromContext(ctx) if c == nil { return nil @@ -32,15 +32,15 @@ func ctxHeaders(ctx netcontext.Context) http.Header { return c.Request().Header } -func DefaultVersionHostname(ctx netcontext.Context) string { +func DefaultVersionHostname(ctx context.Context) string { return ctxHeaders(ctx).Get(hDefaultVersionHostname) } -func RequestID(ctx netcontext.Context) string { +func RequestID(ctx context.Context) string { return ctxHeaders(ctx).Get(hRequestLogId) } -func Datacenter(ctx netcontext.Context) string { +func Datacenter(ctx context.Context) string { if dc := ctxHeaders(ctx).Get(hDatacenter); dc != "" { return dc } @@ -71,7 +71,7 @@ func ServerSoftware() string { // TODO(dsymonds): Remove the metadata fetches. -func ModuleName(_ netcontext.Context) string { +func ModuleName(_ context.Context) string { if s := os.Getenv("GAE_MODULE_NAME"); s != "" { return s } @@ -81,7 +81,7 @@ func ModuleName(_ netcontext.Context) string { return string(mustGetMetadata("instance/attributes/gae_backend_name")) } -func VersionID(_ netcontext.Context) string { +func VersionID(_ context.Context) string { if s1, s2 := os.Getenv("GAE_MODULE_VERSION"), os.Getenv("GAE_MINOR_VERSION"); s1 != "" && s2 != "" { return s1 + "." + s2 } @@ -112,7 +112,7 @@ func partitionlessAppID() string { return string(mustGetMetadata("instance/attributes/gae_project")) } -func fullyQualifiedAppID(_ netcontext.Context) string { +func fullyQualifiedAppID(_ context.Context) string { if s := os.Getenv("GAE_APPLICATION"); s != "" { return s } @@ -130,5 +130,5 @@ func fullyQualifiedAppID(_ netcontext.Context) string { } func IsDevAppServer() bool { - return os.Getenv("RUN_WITH_DEVAPPSERVER") != "" + return os.Getenv("RUN_WITH_DEVAPPSERVER") != "" || os.Getenv("GAE_ENV") == "localdev" } diff --git a/vendor/google.golang.org/appengine/internal/main.go b/vendor/google.golang.org/appengine/internal/main.go index 1e765312..afd0ae84 100644 --- a/vendor/google.golang.org/appengine/internal/main.go +++ b/vendor/google.golang.org/appengine/internal/main.go @@ -2,6 +2,7 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. +//go:build appengine // +build appengine package internal diff --git a/vendor/google.golang.org/appengine/internal/main_vm.go b/vendor/google.golang.org/appengine/internal/main_vm.go index ddb79a33..86a8caf0 100644 --- a/vendor/google.golang.org/appengine/internal/main_vm.go +++ b/vendor/google.golang.org/appengine/internal/main_vm.go @@ -2,6 +2,7 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. +//go:build !appengine // +build !appengine package internal @@ -29,7 +30,7 @@ func Main() { if IsDevAppServer() { host = "127.0.0.1" } - if err := http.ListenAndServe(host+":"+port, http.HandlerFunc(handleHTTP)); err != nil { + if err := http.ListenAndServe(host+":"+port, Middleware(http.DefaultServeMux)); err != nil { log.Fatalf("http.ListenAndServe: %v", err) } } diff --git a/vendor/google.golang.org/appengine/internal/transaction.go b/vendor/google.golang.org/appengine/internal/transaction.go index 9006ae65..2ae8ab9f 100644 --- a/vendor/google.golang.org/appengine/internal/transaction.go +++ b/vendor/google.golang.org/appengine/internal/transaction.go @@ -7,11 +7,11 @@ package internal // This file implements hooks for applying datastore transactions. import ( + "context" "errors" "reflect" "github.com/golang/protobuf/proto" - netcontext "golang.org/x/net/context" basepb "google.golang.org/appengine/internal/base" pb "google.golang.org/appengine/internal/datastore" @@ -38,13 +38,13 @@ func applyTransaction(pb proto.Message, t *pb.Transaction) { var transactionKey = "used for *Transaction" -func transactionFromContext(ctx netcontext.Context) *transaction { +func transactionFromContext(ctx context.Context) *transaction { t, _ := ctx.Value(&transactionKey).(*transaction) return t } -func withTransaction(ctx netcontext.Context, t *transaction) netcontext.Context { - return netcontext.WithValue(ctx, &transactionKey, t) +func withTransaction(ctx context.Context, t *transaction) context.Context { + return context.WithValue(ctx, &transactionKey, t) } type transaction struct { @@ -54,7 +54,7 @@ type transaction struct { var ErrConcurrentTransaction = errors.New("internal: concurrent transaction") -func RunTransactionOnce(c netcontext.Context, f func(netcontext.Context) error, xg bool, readOnly bool, previousTransaction *pb.Transaction) (*pb.Transaction, error) { +func RunTransactionOnce(c context.Context, f func(context.Context) error, xg bool, readOnly bool, previousTransaction *pb.Transaction) (*pb.Transaction, error) { if transactionFromContext(c) != nil { return nil, errors.New("nested transactions are not supported") } diff --git a/vendor/google.golang.org/appengine/namespace.go b/vendor/google.golang.org/appengine/namespace.go index 21860ca0..6f169be4 100644 --- a/vendor/google.golang.org/appengine/namespace.go +++ b/vendor/google.golang.org/appengine/namespace.go @@ -5,11 +5,10 @@ package appengine import ( + "context" "fmt" "regexp" - "golang.org/x/net/context" - "google.golang.org/appengine/internal" ) diff --git a/vendor/google.golang.org/appengine/timeout.go b/vendor/google.golang.org/appengine/timeout.go index 05642a99..fcf3ad0a 100644 --- a/vendor/google.golang.org/appengine/timeout.go +++ b/vendor/google.golang.org/appengine/timeout.go @@ -4,7 +4,7 @@ package appengine -import "golang.org/x/net/context" +import "context" // IsTimeoutError reports whether err is a timeout error. func IsTimeoutError(err error) bool { diff --git a/vendor/google.golang.org/appengine/travis_install.sh b/vendor/google.golang.org/appengine/travis_install.sh deleted file mode 100644 index 785b62f4..00000000 --- a/vendor/google.golang.org/appengine/travis_install.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -e - -if [[ $GO111MODULE == "on" ]]; then - go get . -else - go get -u -v $(go list -f '{{join .Imports "\n"}}{{"\n"}}{{join .TestImports "\n"}}' ./... | sort | uniq | grep -v appengine) -fi - -if [[ $GOAPP == "true" ]]; then - mkdir /tmp/sdk - curl -o /tmp/sdk.zip "https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.68.zip" - unzip -q /tmp/sdk.zip -d /tmp/sdk - # NOTE: Set the following env vars in the test script: - # export PATH="$PATH:/tmp/sdk/go_appengine" - # export APPENGINE_DEV_APPSERVER=/tmp/sdk/go_appengine/dev_appserver.py -fi - diff --git a/vendor/google.golang.org/appengine/travis_test.sh b/vendor/google.golang.org/appengine/travis_test.sh deleted file mode 100644 index d4390f04..00000000 --- a/vendor/google.golang.org/appengine/travis_test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -set -e - -go version -go test -v google.golang.org/appengine/... -go test -v -race google.golang.org/appengine/... -if [[ $GOAPP == "true" ]]; then - export PATH="$PATH:/tmp/sdk/go_appengine" - export APPENGINE_DEV_APPSERVER=/tmp/sdk/go_appengine/dev_appserver.py - goapp version - goapp test -v google.golang.org/appengine/... -fi diff --git a/vendor/google.golang.org/grpc/README.md b/vendor/google.golang.org/grpc/README.md index 0e6ae69a..ab0fbb79 100644 --- a/vendor/google.golang.org/grpc/README.md +++ b/vendor/google.golang.org/grpc/README.md @@ -1,8 +1,8 @@ # gRPC-Go -[![Build Status](https://travis-ci.org/grpc/grpc-go.svg)](https://travis-ci.org/grpc/grpc-go) [![GoDoc](https://pkg.go.dev/badge/google.golang.org/grpc)][API] [![GoReportCard](https://goreportcard.com/badge/grpc/grpc-go)](https://goreportcard.com/report/github.com/grpc/grpc-go) +[![codecov](https://codecov.io/gh/grpc/grpc-go/graph/badge.svg)](https://codecov.io/gh/grpc/grpc-go) The [Go][] implementation of [gRPC][]: A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information see the @@ -14,21 +14,14 @@ RPC framework that puts mobile and HTTP/2 first. For more information see the ## Installation -With [Go module][] support (Go 1.11+), simply add the following import +Simply add the following import to your code, and then `go [build|run|test]` +will automatically fetch the necessary dependencies: + ```go import "google.golang.org/grpc" ``` -to your code, and then `go [build|run|test]` will automatically fetch the -necessary dependencies. - -Otherwise, to install the `grpc-go` package, run the following command: - -```console -$ go get -u google.golang.org/grpc -``` - > **Note:** If you are trying to access `grpc-go` from **China**, see the > [FAQ](#FAQ) below. @@ -56,15 +49,6 @@ To build Go code, there are several options: - Set up a VPN and access google.golang.org through that. -- Without Go module support: `git clone` the repo manually: - - ```sh - git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc - ``` - - You will need to do the same for all of grpc's dependencies in `golang.org`, - e.g. `golang.org/x/net`. - - With Go module support: it is possible to use the `replace` feature of `go mod` to create aliases for golang.org packages. In your project's directory: @@ -76,33 +60,13 @@ To build Go code, there are several options: ``` Again, this will need to be done for all transitive dependencies hosted on - golang.org as well. For details, refer to [golang/go issue #28652](https://github.com/golang/go/issues/28652). + golang.org as well. For details, refer to [golang/go issue + #28652](https://github.com/golang/go/issues/28652). ### Compiling error, undefined: grpc.SupportPackageIsVersion -#### If you are using Go modules: - -Ensure your gRPC-Go version is `require`d at the appropriate version in -the same module containing the generated `.pb.go` files. For example, -`SupportPackageIsVersion6` needs `v1.27.0`, so in your `go.mod` file: - -```go -module - -require ( - google.golang.org/grpc v1.27.0 -) -``` - -#### If you are *not* using Go modules: - -Update the `proto` package, gRPC package, and rebuild the `.proto` files: - -```sh -go get -u github.com/golang/protobuf/{proto,protoc-gen-go} -go get -u google.golang.org/grpc -protoc --go_out=plugins=grpc:. *.proto -``` +Please update to the latest version of gRPC-Go using +`go get google.golang.org/grpc`. ### How to turn on logging @@ -121,9 +85,11 @@ possible reasons, including: 1. mis-configured transport credentials, connection failed on handshaking 1. bytes disrupted, possibly by a proxy in between 1. server shutdown - 1. Keepalive parameters caused connection shutdown, for example if you have configured - your server to terminate connections regularly to [trigger DNS lookups](https://github.com/grpc/grpc-go/issues/3170#issuecomment-552517779). - If this is the case, you may want to increase your [MaxConnectionAgeGrace](https://pkg.go.dev/google.golang.org/grpc/keepalive?tab=doc#ServerParameters), + 1. Keepalive parameters caused connection shutdown, for example if you have + configured your server to terminate connections regularly to [trigger DNS + lookups](https://github.com/grpc/grpc-go/issues/3170#issuecomment-552517779). + If this is the case, you may want to increase your + [MaxConnectionAgeGrace](https://pkg.go.dev/google.golang.org/grpc/keepalive?tab=doc#ServerParameters), to allow longer RPC calls to finish. It can be tricky to debug this because the error happens on the client side but diff --git a/vendor/google.golang.org/grpc/attributes/attributes.go b/vendor/google.golang.org/grpc/attributes/attributes.go index 3efca459..52d530d7 100644 --- a/vendor/google.golang.org/grpc/attributes/attributes.go +++ b/vendor/google.golang.org/grpc/attributes/attributes.go @@ -34,26 +34,26 @@ import ( // key/value pairs. Keys must be hashable, and users should define their own // types for keys. Values should not be modified after they are added to an // Attributes or if they were received from one. If values implement 'Equal(o -// interface{}) bool', it will be called by (*Attributes).Equal to determine -// whether two values with the same key should be considered equal. +// any) bool', it will be called by (*Attributes).Equal to determine whether +// two values with the same key should be considered equal. type Attributes struct { - m map[interface{}]interface{} + m map[any]any } // New returns a new Attributes containing the key/value pair. -func New(key, value interface{}) *Attributes { - return &Attributes{m: map[interface{}]interface{}{key: value}} +func New(key, value any) *Attributes { + return &Attributes{m: map[any]any{key: value}} } // WithValue returns a new Attributes containing the previous keys and values // and the new key/value pair. If the same key appears multiple times, the // last value overwrites all previous values for that key. To remove an // existing key, use a nil value. value should not be modified later. -func (a *Attributes) WithValue(key, value interface{}) *Attributes { +func (a *Attributes) WithValue(key, value any) *Attributes { if a == nil { return New(key, value) } - n := &Attributes{m: make(map[interface{}]interface{}, len(a.m)+1)} + n := &Attributes{m: make(map[any]any, len(a.m)+1)} for k, v := range a.m { n.m[k] = v } @@ -63,20 +63,19 @@ func (a *Attributes) WithValue(key, value interface{}) *Attributes { // Value returns the value associated with these attributes for key, or nil if // no value is associated with key. The returned value should not be modified. -func (a *Attributes) Value(key interface{}) interface{} { +func (a *Attributes) Value(key any) any { if a == nil { return nil } return a.m[key] } -// Equal returns whether a and o are equivalent. If 'Equal(o interface{}) -// bool' is implemented for a value in the attributes, it is called to -// determine if the value matches the one stored in the other attributes. If -// Equal is not implemented, standard equality is used to determine if the two -// values are equal. Note that some types (e.g. maps) aren't comparable by -// default, so they must be wrapped in a struct, or in an alias type, with Equal -// defined. +// Equal returns whether a and o are equivalent. If 'Equal(o any) bool' is +// implemented for a value in the attributes, it is called to determine if the +// value matches the one stored in the other attributes. If Equal is not +// implemented, standard equality is used to determine if the two values are +// equal. Note that some types (e.g. maps) aren't comparable by default, so +// they must be wrapped in a struct, or in an alias type, with Equal defined. func (a *Attributes) Equal(o *Attributes) bool { if a == nil && o == nil { return true @@ -93,7 +92,7 @@ func (a *Attributes) Equal(o *Attributes) bool { // o missing element of a return false } - if eq, ok := v.(interface{ Equal(o interface{}) bool }); ok { + if eq, ok := v.(interface{ Equal(o any) bool }); ok { if !eq.Equal(ov) { return false } @@ -112,19 +111,31 @@ func (a *Attributes) String() string { sb.WriteString("{") first := true for k, v := range a.m { - var key, val string - if str, ok := k.(interface{ String() string }); ok { - key = str.String() - } - if str, ok := v.(interface{ String() string }); ok { - val = str.String() - } if !first { sb.WriteString(", ") } - sb.WriteString(fmt.Sprintf("%q: %q, ", key, val)) + sb.WriteString(fmt.Sprintf("%q: %q ", str(k), str(v))) first = false } sb.WriteString("}") return sb.String() } + +func str(x any) (s string) { + if v, ok := x.(fmt.Stringer); ok { + return fmt.Sprint(v) + } else if v, ok := x.(string); ok { + return v + } + return fmt.Sprintf("<%p>", x) +} + +// MarshalJSON helps implement the json.Marshaler interface, thereby rendering +// the Attributes correctly when printing (via pretty.JSON) structs containing +// Attributes as fields. +// +// Is it impossible to unmarshal attributes from a JSON representation and this +// method is meant only for debugging purposes. +func (a *Attributes) MarshalJSON() ([]byte, error) { + return []byte(a.String()), nil +} diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go index 8f00523c..f391744f 100644 --- a/vendor/google.golang.org/grpc/balancer/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/balancer.go @@ -30,6 +30,7 @@ import ( "google.golang.org/grpc/channelz" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal" "google.golang.org/grpc/metadata" "google.golang.org/grpc/resolver" @@ -39,6 +40,8 @@ import ( var ( // m is a map from name to balancer builder. m = make(map[string]Builder) + + logger = grpclog.Component("balancer") ) // Register registers the balancer builder to the balancer map. b.Name @@ -51,7 +54,14 @@ var ( // an init() function), and is not thread-safe. If multiple Balancers are // registered with the same name, the one registered last will take effect. func Register(b Builder) { - m[strings.ToLower(b.Name())] = b + name := strings.ToLower(b.Name()) + if name != b.Name() { + // TODO: Skip the use of strings.ToLower() to index the map after v1.59 + // is released to switch to case sensitive balancer registry. Also, + // remove this warning and update the docstrings for Register and Get. + logger.Warningf("Balancer registered with name %q. grpc-go will be switching to case sensitive balancer registries soon", b.Name()) + } + m[name] = b } // unregisterForTesting deletes the balancer with the given name from the @@ -70,6 +80,12 @@ func init() { // Note that the compare is done in a case-insensitive fashion. // If no builder is register with the name, nil will be returned. func Get(name string) Builder { + if strings.ToLower(name) != name { + // TODO: Skip the use of strings.ToLower() to index the map after v1.59 + // is released to switch to case sensitive balancer registry. Also, + // remove this warning and update the docstrings for Register and Get. + logger.Warningf("Balancer retrieved for name %q. grpc-go will be switching to case sensitive balancer registries soon", name) + } if b, ok := m[strings.ToLower(name)]; ok { return b } @@ -105,8 +121,8 @@ type SubConn interface { // // This will trigger a state transition for the SubConn. // - // Deprecated: This method is now part of the ClientConn interface and will - // eventually be removed from here. + // Deprecated: this method will be removed. Create new SubConns for new + // addresses instead. UpdateAddresses([]resolver.Address) // Connect starts the connecting for this SubConn. Connect() @@ -115,6 +131,13 @@ type SubConn interface { // creates a new one and returns it. Returns a close function which must // be called when the Producer is no longer needed. GetOrBuildProducer(ProducerBuilder) (p Producer, close func()) + // Shutdown shuts down the SubConn gracefully. Any started RPCs will be + // allowed to complete. No future calls should be made on the SubConn. + // One final state update will be delivered to the StateListener (or + // UpdateSubConnState; deprecated) with ConnectivityState of Shutdown to + // indicate the shutdown operation. This may be delivered before + // in-progress RPCs are complete and the actual connection is closed. + Shutdown() } // NewSubConnOptions contains options to create new SubConn. @@ -129,6 +152,11 @@ type NewSubConnOptions struct { // HealthCheckEnabled indicates whether health check service should be // enabled on this SubConn HealthCheckEnabled bool + // StateListener is called when the state of the subconn changes. If nil, + // Balancer.UpdateSubConnState will be called instead. Will never be + // invoked until after Connect() is called on the SubConn created with + // these options. + StateListener func(SubConnState) } // State contains the balancer's state relevant to the gRPC ClientConn. @@ -150,16 +178,24 @@ type ClientConn interface { // NewSubConn is called by balancer to create a new SubConn. // It doesn't block and wait for the connections to be established. // Behaviors of the SubConn can be controlled by options. + // + // Deprecated: please be aware that in a future version, SubConns will only + // support one address per SubConn. NewSubConn([]resolver.Address, NewSubConnOptions) (SubConn, error) // RemoveSubConn removes the SubConn from ClientConn. // The SubConn will be shutdown. + // + // Deprecated: use SubConn.Shutdown instead. RemoveSubConn(SubConn) // UpdateAddresses updates the addresses used in the passed in SubConn. // gRPC checks if the currently connected address is still in the new list. // If so, the connection will be kept. Else, the connection will be // gracefully closed, and a new connection will be created. // - // This will trigger a state transition for the SubConn. + // This may trigger a state transition for the SubConn. + // + // Deprecated: this method will be removed. Create new SubConns for new + // addresses instead. UpdateAddresses(SubConn, []resolver.Address) // UpdateState notifies gRPC that the balancer's internal state has @@ -197,8 +233,8 @@ type BuildOptions struct { // implementations which do not communicate with a remote load balancer // server can ignore this field. Authority string - // ChannelzParentID is the parent ClientConn's channelz ID. - ChannelzParentID *channelz.Identifier + // ChannelzParent is the parent ClientConn's channelz channel. + ChannelzParent channelz.Identifier // CustomUserAgent is the custom user agent set on the parent ClientConn. // The balancer should set the same custom user agent if it creates a // ClientConn. @@ -250,7 +286,7 @@ type DoneInfo struct { // trailing metadata. // // The only supported type now is *orca_v3.LoadReport. - ServerLoad interface{} + ServerLoad any } var ( @@ -343,9 +379,13 @@ type Balancer interface { ResolverError(error) // UpdateSubConnState is called by gRPC when the state of a SubConn // changes. + // + // Deprecated: Use NewSubConnOptions.StateListener when creating the + // SubConn instead. UpdateSubConnState(SubConn, SubConnState) - // Close closes the balancer. The balancer is not required to call - // ClientConn.RemoveSubConn for its existing SubConns. + // Close closes the balancer. The balancer is not currently required to + // call SubConn.Shutdown for its existing SubConns; however, this will be + // required in a future release, so it is recommended. Close() } @@ -390,15 +430,14 @@ var ErrBadResolverState = errors.New("bad resolver state") type ProducerBuilder interface { // Build creates a Producer. The first parameter is always a // grpc.ClientConnInterface (a type to allow creating RPCs/streams on the - // associated SubConn), but is declared as interface{} to avoid a - // dependency cycle. Should also return a close function that will be - // called when all references to the Producer have been given up. - Build(grpcClientConnInterface interface{}) (p Producer, close func()) + // associated SubConn), but is declared as `any` to avoid a dependency + // cycle. Should also return a close function that will be called when all + // references to the Producer have been given up. + Build(grpcClientConnInterface any) (p Producer, close func()) } // A Producer is a type shared among potentially many consumers. It is // associated with a SubConn, and an implementation will typically contain // other methods to provide additional functionality, e.g. configuration or // subscription registration. -type Producer interface { -} +type Producer any diff --git a/vendor/google.golang.org/grpc/balancer/base/balancer.go b/vendor/google.golang.org/grpc/balancer/base/balancer.go index 3929c26d..a7f1eeec 100644 --- a/vendor/google.golang.org/grpc/balancer/base/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/base/balancer.go @@ -105,7 +105,12 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error { addrsSet.Set(a, nil) if _, ok := b.subConns.Get(a); !ok { // a is a new address (not existing in b.subConns). - sc, err := b.cc.NewSubConn([]resolver.Address{a}, balancer.NewSubConnOptions{HealthCheckEnabled: b.config.HealthCheck}) + var sc balancer.SubConn + opts := balancer.NewSubConnOptions{ + HealthCheckEnabled: b.config.HealthCheck, + StateListener: func(scs balancer.SubConnState) { b.updateSubConnState(sc, scs) }, + } + sc, err := b.cc.NewSubConn([]resolver.Address{a}, opts) if err != nil { logger.Warningf("base.baseBalancer: failed to create new SubConn: %v", err) continue @@ -121,10 +126,10 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error { sc := sci.(balancer.SubConn) // a was removed by resolver. if _, ok := addrsSet.Get(a); !ok { - b.cc.RemoveSubConn(sc) + sc.Shutdown() b.subConns.Delete(a) // Keep the state of this sc in b.scStates until sc's state becomes Shutdown. - // The entry will be deleted in UpdateSubConnState. + // The entry will be deleted in updateSubConnState. } } // If resolver state contains no addresses, return an error so ClientConn @@ -177,7 +182,12 @@ func (b *baseBalancer) regeneratePicker() { b.picker = b.pickerBuilder.Build(PickerBuildInfo{ReadySCs: readySCs}) } +// UpdateSubConnState is a nop because a StateListener is always set in NewSubConn. func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { + logger.Errorf("base.baseBalancer: UpdateSubConnState(%v, %+v) called unexpectedly", sc, state) +} + +func (b *baseBalancer) updateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { s := state.ConnectivityState if logger.V(2) { logger.Infof("base.baseBalancer: handle SubConn state change: %p, %v", sc, s) @@ -204,8 +214,8 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su case connectivity.Idle: sc.Connect() case connectivity.Shutdown: - // When an address was removed by resolver, b called RemoveSubConn but - // kept the sc's state in scStates. Remove state for this sc here. + // When an address was removed by resolver, b called Shutdown but kept + // the sc's state in scStates. Remove state for this sc here. delete(b.scStates, sc) case connectivity.TransientFailure: // Save error to be reported via picker. @@ -226,7 +236,7 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su } // Close is a nop because base balancer doesn't have internal state to clean up, -// and it doesn't need to call RemoveSubConn for the SubConns. +// and it doesn't need to call Shutdown for the SubConns. func (b *baseBalancer) Close() { } diff --git a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go deleted file mode 100644 index 04b9ad41..00000000 --- a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go +++ /dev/null @@ -1,459 +0,0 @@ -/* - * - * Copyright 2017 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 grpc - -import ( - "context" - "fmt" - "strings" - "sync" - - "google.golang.org/grpc/balancer" - "google.golang.org/grpc/connectivity" - "google.golang.org/grpc/internal/balancer/gracefulswitch" - "google.golang.org/grpc/internal/channelz" - "google.golang.org/grpc/internal/grpcsync" - "google.golang.org/grpc/resolver" -) - -type ccbMode int - -const ( - ccbModeActive = iota - ccbModeIdle - ccbModeClosed - ccbModeExitingIdle -) - -// ccBalancerWrapper sits between the ClientConn and the Balancer. -// -// ccBalancerWrapper implements methods corresponding to the ones on the -// balancer.Balancer interface. The ClientConn is free to call these methods -// concurrently and the ccBalancerWrapper ensures that calls from the ClientConn -// to the Balancer happen synchronously and in order. -// -// ccBalancerWrapper also implements the balancer.ClientConn interface and is -// passed to the Balancer implementations. It invokes unexported methods on the -// ClientConn to handle these calls from the Balancer. -// -// It uses the gracefulswitch.Balancer internally to ensure that balancer -// switches happen in a graceful manner. -type ccBalancerWrapper struct { - // The following fields are initialized when the wrapper is created and are - // read-only afterwards, and therefore can be accessed without a mutex. - cc *ClientConn - opts balancer.BuildOptions - - // Outgoing (gRPC --> balancer) calls are guaranteed to execute in a - // mutually exclusive manner as they are scheduled in the serializer. Fields - // accessed *only* in these serializer callbacks, can therefore be accessed - // without a mutex. - balancer *gracefulswitch.Balancer - curBalancerName string - - // mu guards access to the below fields. Access to the serializer and its - // cancel function needs to be mutex protected because they are overwritten - // when the wrapper exits idle mode. - mu sync.Mutex - serializer *grpcsync.CallbackSerializer // To serialize all outoing calls. - serializerCancel context.CancelFunc // To close the seralizer at close/enterIdle time. - mode ccbMode // Tracks the current mode of the wrapper. -} - -// newCCBalancerWrapper creates a new balancer wrapper. The underlying balancer -// is not created until the switchTo() method is invoked. -func newCCBalancerWrapper(cc *ClientConn, bopts balancer.BuildOptions) *ccBalancerWrapper { - ctx, cancel := context.WithCancel(context.Background()) - ccb := &ccBalancerWrapper{ - cc: cc, - opts: bopts, - serializer: grpcsync.NewCallbackSerializer(ctx), - serializerCancel: cancel, - } - ccb.balancer = gracefulswitch.NewBalancer(ccb, bopts) - return ccb -} - -// updateClientConnState is invoked by grpc to push a ClientConnState update to -// the underlying balancer. -func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) error { - ccb.mu.Lock() - errCh := make(chan error, 1) - // Here and everywhere else where Schedule() is called, it is done with the - // lock held. But the lock guards only the scheduling part. The actual - // callback is called asynchronously without the lock being held. - ok := ccb.serializer.Schedule(func(_ context.Context) { - // If the addresses specified in the update contain addresses of type - // "grpclb" and the selected LB policy is not "grpclb", these addresses - // will be filtered out and ccs will be modified with the updated - // address list. - if ccb.curBalancerName != grpclbName { - var addrs []resolver.Address - for _, addr := range ccs.ResolverState.Addresses { - if addr.Type == resolver.GRPCLB { - continue - } - addrs = append(addrs, addr) - } - ccs.ResolverState.Addresses = addrs - } - errCh <- ccb.balancer.UpdateClientConnState(*ccs) - }) - if !ok { - // If we are unable to schedule a function with the serializer, it - // indicates that it has been closed. A serializer is only closed when - // the wrapper is closed or is in idle. - ccb.mu.Unlock() - return fmt.Errorf("grpc: cannot send state update to a closed or idle balancer") - } - ccb.mu.Unlock() - - // We get here only if the above call to Schedule succeeds, in which case it - // is guaranteed that the scheduled function will run. Therefore it is safe - // to block on this channel. - err := <-errCh - if logger.V(2) && err != nil { - logger.Infof("error from balancer.UpdateClientConnState: %v", err) - } - return err -} - -// updateSubConnState is invoked by grpc to push a subConn state update to the -// underlying balancer. -func (ccb *ccBalancerWrapper) updateSubConnState(sc balancer.SubConn, s connectivity.State, err error) { - ccb.mu.Lock() - ccb.serializer.Schedule(func(_ context.Context) { - ccb.balancer.UpdateSubConnState(sc, balancer.SubConnState{ConnectivityState: s, ConnectionError: err}) - }) - ccb.mu.Unlock() -} - -func (ccb *ccBalancerWrapper) resolverError(err error) { - ccb.mu.Lock() - ccb.serializer.Schedule(func(_ context.Context) { - ccb.balancer.ResolverError(err) - }) - ccb.mu.Unlock() -} - -// switchTo is invoked by grpc to instruct the balancer wrapper to switch to the -// LB policy identified by name. -// -// ClientConn calls newCCBalancerWrapper() at creation time. Upon receipt of the -// first good update from the name resolver, it determines the LB policy to use -// and invokes the switchTo() method. Upon receipt of every subsequent update -// from the name resolver, it invokes this method. -// -// the ccBalancerWrapper keeps track of the current LB policy name, and skips -// the graceful balancer switching process if the name does not change. -func (ccb *ccBalancerWrapper) switchTo(name string) { - ccb.mu.Lock() - ccb.serializer.Schedule(func(_ context.Context) { - // TODO: Other languages use case-sensitive balancer registries. We should - // switch as well. See: https://github.com/grpc/grpc-go/issues/5288. - if strings.EqualFold(ccb.curBalancerName, name) { - return - } - ccb.buildLoadBalancingPolicy(name) - }) - ccb.mu.Unlock() -} - -// buildLoadBalancingPolicy performs the following: -// - retrieve a balancer builder for the given name. Use the default LB -// policy, pick_first, if no LB policy with name is found in the registry. -// - instruct the gracefulswitch balancer to switch to the above builder. This -// will actually build the new balancer. -// - update the `curBalancerName` field -// -// Must be called from a serializer callback. -func (ccb *ccBalancerWrapper) buildLoadBalancingPolicy(name string) { - builder := balancer.Get(name) - if builder == nil { - channelz.Warningf(logger, ccb.cc.channelzID, "Channel switches to new LB policy %q, since the specified LB policy %q was not registered", PickFirstBalancerName, name) - builder = newPickfirstBuilder() - } else { - channelz.Infof(logger, ccb.cc.channelzID, "Channel switches to new LB policy %q", name) - } - - if err := ccb.balancer.SwitchTo(builder); err != nil { - channelz.Errorf(logger, ccb.cc.channelzID, "Channel failed to build new LB policy %q: %v", name, err) - return - } - ccb.curBalancerName = builder.Name() -} - -func (ccb *ccBalancerWrapper) close() { - channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: closing") - ccb.closeBalancer(ccbModeClosed) -} - -// enterIdleMode is invoked by grpc when the channel enters idle mode upon -// expiry of idle_timeout. This call blocks until the balancer is closed. -func (ccb *ccBalancerWrapper) enterIdleMode() { - channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: entering idle mode") - ccb.closeBalancer(ccbModeIdle) -} - -// closeBalancer is invoked when the channel is being closed or when it enters -// idle mode upon expiry of idle_timeout. -func (ccb *ccBalancerWrapper) closeBalancer(m ccbMode) { - ccb.mu.Lock() - if ccb.mode == ccbModeClosed || ccb.mode == ccbModeIdle { - ccb.mu.Unlock() - return - } - - ccb.mode = m - done := ccb.serializer.Done - b := ccb.balancer - ok := ccb.serializer.Schedule(func(_ context.Context) { - // Close the serializer to ensure that no more calls from gRPC are sent - // to the balancer. - ccb.serializerCancel() - // Empty the current balancer name because we don't have a balancer - // anymore and also so that we act on the next call to switchTo by - // creating a new balancer specified by the new resolver. - ccb.curBalancerName = "" - }) - if !ok { - ccb.mu.Unlock() - return - } - ccb.mu.Unlock() - - // Give enqueued callbacks a chance to finish. - <-done - // Spawn a goroutine to close the balancer (since it may block trying to - // cleanup all allocated resources) and return early. - go b.Close() -} - -// exitIdleMode is invoked by grpc when the channel exits idle mode either -// because of an RPC or because of an invocation of the Connect() API. This -// recreates the balancer that was closed previously when entering idle mode. -// -// If the channel is not in idle mode, we know for a fact that we are here as a -// result of the user calling the Connect() method on the ClientConn. In this -// case, we can simply forward the call to the underlying balancer, instructing -// it to reconnect to the backends. -func (ccb *ccBalancerWrapper) exitIdleMode() { - ccb.mu.Lock() - if ccb.mode == ccbModeClosed { - // Request to exit idle is a no-op when wrapper is already closed. - ccb.mu.Unlock() - return - } - - if ccb.mode == ccbModeIdle { - // Recreate the serializer which was closed when we entered idle. - ctx, cancel := context.WithCancel(context.Background()) - ccb.serializer = grpcsync.NewCallbackSerializer(ctx) - ccb.serializerCancel = cancel - } - - // The ClientConn guarantees that mutual exclusion between close() and - // exitIdleMode(), and since we just created a new serializer, we can be - // sure that the below function will be scheduled. - done := make(chan struct{}) - ccb.serializer.Schedule(func(_ context.Context) { - defer close(done) - - ccb.mu.Lock() - defer ccb.mu.Unlock() - - if ccb.mode != ccbModeIdle { - ccb.balancer.ExitIdle() - return - } - - // Gracefulswitch balancer does not support a switchTo operation after - // being closed. Hence we need to create a new one here. - ccb.balancer = gracefulswitch.NewBalancer(ccb, ccb.opts) - ccb.mode = ccbModeActive - channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: exiting idle mode") - - }) - ccb.mu.Unlock() - - <-done -} - -func (ccb *ccBalancerWrapper) isIdleOrClosed() bool { - ccb.mu.Lock() - defer ccb.mu.Unlock() - return ccb.mode == ccbModeIdle || ccb.mode == ccbModeClosed -} - -func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { - if ccb.isIdleOrClosed() { - return nil, fmt.Errorf("grpc: cannot create SubConn when balancer is closed or idle") - } - - if len(addrs) == 0 { - return nil, fmt.Errorf("grpc: cannot create SubConn with empty address list") - } - ac, err := ccb.cc.newAddrConn(addrs, opts) - if err != nil { - channelz.Warningf(logger, ccb.cc.channelzID, "acBalancerWrapper: NewSubConn: failed to newAddrConn: %v", err) - return nil, err - } - acbw := &acBalancerWrapper{ac: ac, producers: make(map[balancer.ProducerBuilder]*refCountedProducer)} - ac.acbw = acbw - return acbw, nil -} - -func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) { - if ccb.isIdleOrClosed() { - // It it safe to ignore this call when the balancer is closed or in idle - // because the ClientConn takes care of closing the connections. - // - // Not returning early from here when the balancer is closed or in idle - // leads to a deadlock though, because of the following sequence of - // calls when holding cc.mu: - // cc.exitIdleMode --> ccb.enterIdleMode --> gsw.Close --> - // ccb.RemoveAddrConn --> cc.removeAddrConn - return - } - - acbw, ok := sc.(*acBalancerWrapper) - if !ok { - return - } - ccb.cc.removeAddrConn(acbw.ac, errConnDrain) -} - -func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) { - if ccb.isIdleOrClosed() { - return - } - - acbw, ok := sc.(*acBalancerWrapper) - if !ok { - return - } - acbw.UpdateAddresses(addrs) -} - -func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) { - if ccb.isIdleOrClosed() { - return - } - - // Update picker before updating state. Even though the ordering here does - // not matter, it can lead to multiple calls of Pick in the common start-up - // case where we wait for ready and then perform an RPC. If the picker is - // updated later, we could call the "connecting" picker when the state is - // updated, and then call the "ready" picker after the picker gets updated. - ccb.cc.blockingpicker.updatePicker(s.Picker) - ccb.cc.csMgr.updateState(s.ConnectivityState) -} - -func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOptions) { - if ccb.isIdleOrClosed() { - return - } - - ccb.cc.resolveNow(o) -} - -func (ccb *ccBalancerWrapper) Target() string { - return ccb.cc.target -} - -// acBalancerWrapper is a wrapper on top of ac for balancers. -// It implements balancer.SubConn interface. -type acBalancerWrapper struct { - ac *addrConn // read-only - - mu sync.Mutex - producers map[balancer.ProducerBuilder]*refCountedProducer -} - -func (acbw *acBalancerWrapper) String() string { - return fmt.Sprintf("SubConn(id:%d)", acbw.ac.channelzID.Int()) -} - -func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { - acbw.ac.updateAddrs(addrs) -} - -func (acbw *acBalancerWrapper) Connect() { - go acbw.ac.connect() -} - -// NewStream begins a streaming RPC on the addrConn. If the addrConn is not -// ready, blocks until it is or ctx expires. Returns an error when the context -// expires or the addrConn is shut down. -func (acbw *acBalancerWrapper) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) { - transport, err := acbw.ac.getTransport(ctx) - if err != nil { - return nil, err - } - return newNonRetryClientStream(ctx, desc, method, transport, acbw.ac, opts...) -} - -// Invoke performs a unary RPC. If the addrConn is not ready, returns -// errSubConnNotReady. -func (acbw *acBalancerWrapper) Invoke(ctx context.Context, method string, args interface{}, reply interface{}, opts ...CallOption) error { - cs, err := acbw.NewStream(ctx, unaryStreamDesc, method, opts...) - if err != nil { - return err - } - if err := cs.SendMsg(args); err != nil { - return err - } - return cs.RecvMsg(reply) -} - -type refCountedProducer struct { - producer balancer.Producer - refs int // number of current refs to the producer - close func() // underlying producer's close function -} - -func (acbw *acBalancerWrapper) GetOrBuildProducer(pb balancer.ProducerBuilder) (balancer.Producer, func()) { - acbw.mu.Lock() - defer acbw.mu.Unlock() - - // Look up existing producer from this builder. - pData := acbw.producers[pb] - if pData == nil { - // Not found; create a new one and add it to the producers map. - p, close := pb.Build(acbw) - pData = &refCountedProducer{producer: p, close: close} - acbw.producers[pb] = pData - } - // Account for this new reference. - pData.refs++ - - // Return a cleanup function wrapped in a OnceFunc to remove this reference - // and delete the refCountedProducer from the map if the total reference - // count goes to zero. - unref := func() { - acbw.mu.Lock() - pData.refs-- - if pData.refs == 0 { - defer pData.close() // Run outside the acbw mutex - delete(acbw.producers, pb) - } - acbw.mu.Unlock() - } - return pData.producer, grpcsync.OnceFunc(unref) -} diff --git a/vendor/google.golang.org/grpc/balancer_wrapper.go b/vendor/google.golang.org/grpc/balancer_wrapper.go new file mode 100644 index 00000000..af39b8a4 --- /dev/null +++ b/vendor/google.golang.org/grpc/balancer_wrapper.go @@ -0,0 +1,337 @@ +/* + * + * Copyright 2017 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 grpc + +import ( + "context" + "fmt" + "sync" + + "google.golang.org/grpc/balancer" + "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/internal/balancer/gracefulswitch" + "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/grpcsync" + "google.golang.org/grpc/resolver" +) + +// ccBalancerWrapper sits between the ClientConn and the Balancer. +// +// ccBalancerWrapper implements methods corresponding to the ones on the +// balancer.Balancer interface. The ClientConn is free to call these methods +// concurrently and the ccBalancerWrapper ensures that calls from the ClientConn +// to the Balancer happen in order by performing them in the serializer, without +// any mutexes held. +// +// ccBalancerWrapper also implements the balancer.ClientConn interface and is +// passed to the Balancer implementations. It invokes unexported methods on the +// ClientConn to handle these calls from the Balancer. +// +// It uses the gracefulswitch.Balancer internally to ensure that balancer +// switches happen in a graceful manner. +type ccBalancerWrapper struct { + // The following fields are initialized when the wrapper is created and are + // read-only afterwards, and therefore can be accessed without a mutex. + cc *ClientConn + opts balancer.BuildOptions + serializer *grpcsync.CallbackSerializer + serializerCancel context.CancelFunc + + // The following fields are only accessed within the serializer or during + // initialization. + curBalancerName string + balancer *gracefulswitch.Balancer + + // The following field is protected by mu. Caller must take cc.mu before + // taking mu. + mu sync.Mutex + closed bool +} + +// newCCBalancerWrapper creates a new balancer wrapper in idle state. The +// underlying balancer is not created until the updateClientConnState() method +// is invoked. +func newCCBalancerWrapper(cc *ClientConn) *ccBalancerWrapper { + ctx, cancel := context.WithCancel(cc.ctx) + ccb := &ccBalancerWrapper{ + cc: cc, + opts: balancer.BuildOptions{ + DialCreds: cc.dopts.copts.TransportCredentials, + CredsBundle: cc.dopts.copts.CredsBundle, + Dialer: cc.dopts.copts.Dialer, + Authority: cc.authority, + CustomUserAgent: cc.dopts.copts.UserAgent, + ChannelzParent: cc.channelz, + Target: cc.parsedTarget, + }, + serializer: grpcsync.NewCallbackSerializer(ctx), + serializerCancel: cancel, + } + ccb.balancer = gracefulswitch.NewBalancer(ccb, ccb.opts) + return ccb +} + +// updateClientConnState is invoked by grpc to push a ClientConnState update to +// the underlying balancer. This is always executed from the serializer, so +// it is safe to call into the balancer here. +func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) error { + errCh := make(chan error) + ok := ccb.serializer.Schedule(func(ctx context.Context) { + defer close(errCh) + if ctx.Err() != nil || ccb.balancer == nil { + return + } + name := gracefulswitch.ChildName(ccs.BalancerConfig) + if ccb.curBalancerName != name { + ccb.curBalancerName = name + channelz.Infof(logger, ccb.cc.channelz, "Channel switches to new LB policy %q", name) + } + err := ccb.balancer.UpdateClientConnState(*ccs) + if logger.V(2) && err != nil { + logger.Infof("error from balancer.UpdateClientConnState: %v", err) + } + errCh <- err + }) + if !ok { + return nil + } + return <-errCh +} + +// resolverError is invoked by grpc to push a resolver error to the underlying +// balancer. The call to the balancer is executed from the serializer. +func (ccb *ccBalancerWrapper) resolverError(err error) { + ccb.serializer.Schedule(func(ctx context.Context) { + if ctx.Err() != nil || ccb.balancer == nil { + return + } + ccb.balancer.ResolverError(err) + }) +} + +// close initiates async shutdown of the wrapper. cc.mu must be held when +// calling this function. To determine the wrapper has finished shutting down, +// the channel should block on ccb.serializer.Done() without cc.mu held. +func (ccb *ccBalancerWrapper) close() { + ccb.mu.Lock() + ccb.closed = true + ccb.mu.Unlock() + channelz.Info(logger, ccb.cc.channelz, "ccBalancerWrapper: closing") + ccb.serializer.Schedule(func(context.Context) { + if ccb.balancer == nil { + return + } + ccb.balancer.Close() + ccb.balancer = nil + }) + ccb.serializerCancel() +} + +// exitIdle invokes the balancer's exitIdle method in the serializer. +func (ccb *ccBalancerWrapper) exitIdle() { + ccb.serializer.Schedule(func(ctx context.Context) { + if ctx.Err() != nil || ccb.balancer == nil { + return + } + ccb.balancer.ExitIdle() + }) +} + +func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { + ccb.cc.mu.Lock() + defer ccb.cc.mu.Unlock() + + ccb.mu.Lock() + if ccb.closed { + ccb.mu.Unlock() + return nil, fmt.Errorf("balancer is being closed; no new SubConns allowed") + } + ccb.mu.Unlock() + + if len(addrs) == 0 { + return nil, fmt.Errorf("grpc: cannot create SubConn with empty address list") + } + ac, err := ccb.cc.newAddrConnLocked(addrs, opts) + if err != nil { + channelz.Warningf(logger, ccb.cc.channelz, "acBalancerWrapper: NewSubConn: failed to newAddrConn: %v", err) + return nil, err + } + acbw := &acBalancerWrapper{ + ccb: ccb, + ac: ac, + producers: make(map[balancer.ProducerBuilder]*refCountedProducer), + stateListener: opts.StateListener, + } + ac.acbw = acbw + return acbw, nil +} + +func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) { + // The graceful switch balancer will never call this. + logger.Errorf("ccb RemoveSubConn(%v) called unexpectedly, sc") +} + +func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) { + acbw, ok := sc.(*acBalancerWrapper) + if !ok { + return + } + acbw.UpdateAddresses(addrs) +} + +func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) { + ccb.cc.mu.Lock() + defer ccb.cc.mu.Unlock() + + ccb.mu.Lock() + if ccb.closed { + ccb.mu.Unlock() + return + } + ccb.mu.Unlock() + // Update picker before updating state. Even though the ordering here does + // not matter, it can lead to multiple calls of Pick in the common start-up + // case where we wait for ready and then perform an RPC. If the picker is + // updated later, we could call the "connecting" picker when the state is + // updated, and then call the "ready" picker after the picker gets updated. + + // Note that there is no need to check if the balancer wrapper was closed, + // as we know the graceful switch LB policy will not call cc if it has been + // closed. + ccb.cc.pickerWrapper.updatePicker(s.Picker) + ccb.cc.csMgr.updateState(s.ConnectivityState) +} + +func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOptions) { + ccb.cc.mu.RLock() + defer ccb.cc.mu.RUnlock() + + ccb.mu.Lock() + if ccb.closed { + ccb.mu.Unlock() + return + } + ccb.mu.Unlock() + ccb.cc.resolveNowLocked(o) +} + +func (ccb *ccBalancerWrapper) Target() string { + return ccb.cc.target +} + +// acBalancerWrapper is a wrapper on top of ac for balancers. +// It implements balancer.SubConn interface. +type acBalancerWrapper struct { + ac *addrConn // read-only + ccb *ccBalancerWrapper // read-only + stateListener func(balancer.SubConnState) + + mu sync.Mutex + producers map[balancer.ProducerBuilder]*refCountedProducer +} + +// updateState is invoked by grpc to push a subConn state update to the +// underlying balancer. +func (acbw *acBalancerWrapper) updateState(s connectivity.State, err error) { + acbw.ccb.serializer.Schedule(func(ctx context.Context) { + if ctx.Err() != nil || acbw.ccb.balancer == nil { + return + } + // Even though it is optional for balancers, gracefulswitch ensures + // opts.StateListener is set, so this cannot ever be nil. + // TODO: delete this comment when UpdateSubConnState is removed. + acbw.stateListener(balancer.SubConnState{ConnectivityState: s, ConnectionError: err}) + }) +} + +func (acbw *acBalancerWrapper) String() string { + return fmt.Sprintf("SubConn(id:%d)", acbw.ac.channelz.ID) +} + +func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { + acbw.ac.updateAddrs(addrs) +} + +func (acbw *acBalancerWrapper) Connect() { + go acbw.ac.connect() +} + +func (acbw *acBalancerWrapper) Shutdown() { + acbw.ccb.cc.removeAddrConn(acbw.ac, errConnDrain) +} + +// NewStream begins a streaming RPC on the addrConn. If the addrConn is not +// ready, blocks until it is or ctx expires. Returns an error when the context +// expires or the addrConn is shut down. +func (acbw *acBalancerWrapper) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) { + transport, err := acbw.ac.getTransport(ctx) + if err != nil { + return nil, err + } + return newNonRetryClientStream(ctx, desc, method, transport, acbw.ac, opts...) +} + +// Invoke performs a unary RPC. If the addrConn is not ready, returns +// errSubConnNotReady. +func (acbw *acBalancerWrapper) Invoke(ctx context.Context, method string, args any, reply any, opts ...CallOption) error { + cs, err := acbw.NewStream(ctx, unaryStreamDesc, method, opts...) + if err != nil { + return err + } + if err := cs.SendMsg(args); err != nil { + return err + } + return cs.RecvMsg(reply) +} + +type refCountedProducer struct { + producer balancer.Producer + refs int // number of current refs to the producer + close func() // underlying producer's close function +} + +func (acbw *acBalancerWrapper) GetOrBuildProducer(pb balancer.ProducerBuilder) (balancer.Producer, func()) { + acbw.mu.Lock() + defer acbw.mu.Unlock() + + // Look up existing producer from this builder. + pData := acbw.producers[pb] + if pData == nil { + // Not found; create a new one and add it to the producers map. + p, close := pb.Build(acbw) + pData = &refCountedProducer{producer: p, close: close} + acbw.producers[pb] = pData + } + // Account for this new reference. + pData.refs++ + + // Return a cleanup function wrapped in a OnceFunc to remove this reference + // and delete the refCountedProducer from the map if the total reference + // count goes to zero. + unref := func() { + acbw.mu.Lock() + pData.refs-- + if pData.refs == 0 { + defer pData.close() // Run outside the acbw mutex + delete(acbw.producers, pb) + } + acbw.mu.Unlock() + } + return pData.producer, grpcsync.OnceFunc(unref) +} 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 ec2c2fa1..856c75dd 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 @@ -18,8 +18,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v4.22.0 +// protoc-gen-go v1.32.0 +// protoc v4.25.2 // source: grpc/binlog/v1/binarylog.proto package grpc_binarylog_v1 @@ -430,7 +430,7 @@ type ClientHeader struct { MethodName string `protobuf:"bytes,2,opt,name=method_name,json=methodName,proto3" json:"method_name,omitempty"` // A single process may be used to run multiple virtual // servers with different identities. - // The authority is the name of such a server identitiy. + // The authority is the name of such a server identity. // It is typically a portion of the URI in the form of // or : . Authority string `protobuf:"bytes,3,opt,name=authority,proto3" json:"authority,omitempty"` diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go index e6a1dc5d..788c89c1 100644 --- a/vendor/google.golang.org/grpc/call.go +++ b/vendor/google.golang.org/grpc/call.go @@ -26,12 +26,7 @@ import ( // received. This is typically called by generated code. // // All errors returned by Invoke are compatible with the status package. -func (cc *ClientConn) Invoke(ctx context.Context, method string, args, reply interface{}, opts ...CallOption) error { - if err := cc.idlenessMgr.onCallBegin(); err != nil { - return err - } - defer cc.idlenessMgr.onCallEnd() - +func (cc *ClientConn) Invoke(ctx context.Context, method string, args, reply any, opts ...CallOption) error { // allow interceptor to see all applicable call options, which means those // configured as defaults from dial option as well as per-call options opts = combine(cc.dopts.callOptions, opts) @@ -61,13 +56,13 @@ func combine(o1 []CallOption, o2 []CallOption) []CallOption { // received. This is typically called by generated code. // // DEPRECATED: Use ClientConn.Invoke instead. -func Invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) error { +func Invoke(ctx context.Context, method string, args, reply any, cc *ClientConn, opts ...CallOption) error { return cc.Invoke(ctx, method, args, reply, opts...) } var unaryStreamDesc = &StreamDesc{ServerStreams: false, ClientStreams: false} -func invoke(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error { +func invoke(ctx context.Context, method string, req, reply any, cc *ClientConn, opts ...CallOption) error { cs, err := newClientStream(ctx, unaryStreamDesc, cc, method, opts...) if err != nil { return err diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index 95a7459b..c7f26071 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -33,10 +33,11 @@ import ( "google.golang.org/grpc/balancer/base" "google.golang.org/grpc/codes" "google.golang.org/grpc/connectivity" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/internal/backoff" + "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/grpcsync" + "google.golang.org/grpc/internal/idle" + "google.golang.org/grpc/internal/pretty" iresolver "google.golang.org/grpc/internal/resolver" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" @@ -45,16 +46,14 @@ import ( "google.golang.org/grpc/status" _ "google.golang.org/grpc/balancer/roundrobin" // To register roundrobin. - _ "google.golang.org/grpc/internal/resolver/dns" // To register dns resolver. _ "google.golang.org/grpc/internal/resolver/passthrough" // To register passthrough resolver. _ "google.golang.org/grpc/internal/resolver/unix" // To register unix resolver. + _ "google.golang.org/grpc/resolver/dns" // To register dns resolver. ) const ( // minimum time to give a connection to complete minConnectTimeout = 20 * time.Second - // must match grpclbName in grpclb/grpclb.go - grpclbName = "grpclb" ) var ( @@ -68,7 +67,7 @@ var ( errConnDrain = errors.New("grpc: the connection is drained") // errConnClosing indicates that the connection is closing. errConnClosing = errors.New("grpc: the connection is closing") - // errConnIdling indicates the the connection is being closed as the channel + // errConnIdling indicates the connection is being closed as the channel // is moving to an idle mode due to inactivity. errConnIdling = errors.New("grpc: the connection is closing due to channel idleness") // invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default @@ -102,11 +101,6 @@ const ( defaultReadBufSize = 32 * 1024 ) -// Dial creates a client connection to the given target. -func Dial(target string, opts ...DialOption) (*ClientConn, error) { - return DialContext(context.Background(), target, opts...) -} - type defaultConfigSelector struct { sc *ServiceConfig } @@ -118,48 +112,29 @@ func (dcs *defaultConfigSelector) SelectConfig(rpcInfo iresolver.RPCInfo) (*ires }, nil } -// DialContext creates a client connection to the given target. By default, it's -// a non-blocking dial (the function won't wait for connections to be -// established, and connecting happens in the background). To make it a blocking -// dial, use WithBlock() dial option. -// -// In the non-blocking case, the ctx does not act against the connection. It -// only controls the setup steps. -// -// In the blocking case, ctx can be used to cancel or expire the pending -// connection. Once this function returns, the cancellation and expiration of -// ctx will be noop. Users should call ClientConn.Close to terminate all the -// pending operations after this function returns. +// NewClient creates a new gRPC "channel" for the target URI provided. No I/O +// is performed. Use of the ClientConn for RPCs will automatically cause it to +// connect. Connect may be used to manually create a connection, but for most +// users this is unnecessary. // // The target name syntax is defined in -// https://github.com/grpc/grpc/blob/master/doc/naming.md. -// e.g. to use dns resolver, a "dns:///" prefix should be applied to the target. -func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) { +// https://github.com/grpc/grpc/blob/master/doc/naming.md. e.g. to use dns +// resolver, a "dns:///" prefix should be applied to the target. +// +// The DialOptions returned by WithBlock, WithTimeout, and +// WithReturnConnectionError are ignored by this function. +func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error) { cc := &ClientConn{ target: target, - csMgr: &connectivityStateManager{}, conns: make(map[*addrConn]struct{}), dopts: defaultDialOptions(), - czData: new(channelzData), } - // We start the channel off in idle mode, but kick it out of idle at the end - // of this method, instead of waiting for the first RPC. Other gRPC - // implementations do wait for the first RPC to kick the channel out of - // idle. But doing so would be a major behavior change for our users who are - // used to seeing the channel active after Dial. - // - // Taking this approach of kicking it out of idle at the end of this method - // allows us to share the code between channel creation and exiting idle - // mode. This will also make it easy for us to switch to starting the - // channel off in idle, if at all we ever get to do that. - cc.idlenessState = ccIdlenessStateIdle - cc.retryThrottler.Store((*retryThrottler)(nil)) cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{nil}) cc.ctx, cc.cancel = context.WithCancel(context.Background()) - cc.exitIdleCond = sync.NewCond(&cc.mu) + // Apply dial options. disableGlobalOpts := false for _, opt := range opts { if _, ok := opt.(*disableGlobalDialOptions); ok { @@ -177,19 +152,9 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * for _, opt := range opts { opt.apply(&cc.dopts) } - chainUnaryClientInterceptors(cc) chainStreamClientInterceptors(cc) - defer func() { - if err != nil { - cc.Close() - } - }() - - // Register ClientConn with channelz. - cc.channelzRegistration(target) - if err := cc.validateTransportCredentials(); err != nil { return nil, err } @@ -203,10 +168,73 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * } cc.mkp = cc.dopts.copts.KeepaliveParams - if cc.dopts.copts.UserAgent != "" { - cc.dopts.copts.UserAgent += " " + grpcUA - } else { - cc.dopts.copts.UserAgent = grpcUA + // Register ClientConn with channelz. + cc.channelzRegistration(target) + + // TODO: Ideally it should be impossible to error from this function after + // channelz registration. This will require removing some channelz logs + // from the following functions that can error. Errors can be returned to + // the user, and successful logs can be emitted here, after the checks have + // passed and channelz is subsequently registered. + + // Determine the resolver to use. + if err := cc.parseTargetAndFindResolver(); err != nil { + channelz.RemoveEntry(cc.channelz.ID) + return nil, err + } + if err = cc.determineAuthority(); err != nil { + channelz.RemoveEntry(cc.channelz.ID) + return nil, err + } + + cc.csMgr = newConnectivityStateManager(cc.ctx, cc.channelz) + cc.pickerWrapper = newPickerWrapper(cc.dopts.copts.StatsHandlers) + + cc.initIdleStateLocked() // Safe to call without the lock, since nothing else has a reference to cc. + cc.idlenessMgr = idle.NewManager((*idler)(cc), cc.dopts.idleTimeout) + return cc, nil +} + +// Dial calls DialContext(context.Background(), target, opts...). +func Dial(target string, opts ...DialOption) (*ClientConn, error) { + return DialContext(context.Background(), target, opts...) +} + +// DialContext calls NewClient and then exits idle mode. If WithBlock(true) is +// used, it calls Connect and WaitForStateChange until either the context +// expires or the state of the ClientConn is Ready. +// +// One subtle difference between NewClient and Dial and DialContext is that the +// former uses "dns" as the default name resolver, while the latter use +// "passthrough" for backward compatibility. This distinction should not matter +// to most users, but could matter to legacy users that specify a custom dialer +// and expect it to receive the target string directly. +func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) { + // At the end of this method, we kick the channel out of idle, rather than + // waiting for the first rpc. + opts = append([]DialOption{withDefaultScheme("passthrough")}, opts...) + cc, err := NewClient(target, opts...) + if err != nil { + return nil, err + } + + // We start the channel off in idle mode, but kick it out of idle now, + // instead of waiting for the first RPC. This is the legacy behavior of + // Dial. + defer func() { + if err != nil { + cc.Close() + } + }() + + // This creates the name resolver, load balancer, etc. + if err := cc.idlenessMgr.ExitIdleMode(); err != nil { + return nil, err + } + + // Return now for non-blocking dials. + if !cc.dopts.block { + return cc, nil } if cc.dopts.timeout > 0 { @@ -229,49 +257,6 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * } }() - if cc.dopts.bs == nil { - cc.dopts.bs = backoff.DefaultExponential - } - - // Determine the resolver to use. - if err := cc.parseTargetAndFindResolver(); err != nil { - return nil, err - } - if err = cc.determineAuthority(); err != nil { - return nil, err - } - - if cc.dopts.scChan != nil { - // Blocking wait for the initial service config. - select { - case sc, ok := <-cc.dopts.scChan: - if ok { - cc.sc = &sc - cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{&sc}) - } - case <-ctx.Done(): - return nil, ctx.Err() - } - } - if cc.dopts.scChan != nil { - go cc.scWatcher() - } - - // This creates the name resolver, load balancer, blocking picker etc. - if err := cc.exitIdleMode(); err != nil { - return nil, err - } - - // Configure idleness support with configured idle timeout or default idle - // timeout duration. Idleness can be explicitly disabled by the user, by - // setting the dial option to 0. - cc.idlenessMgr = newIdlenessManager(cc, cc.dopts.idleTimeout) - - // Return early for non-blocking dials. - if !cc.dopts.block { - return cc, nil - } - // A blocking dial blocks until the clientConn is ready. for { s := cc.GetState() @@ -303,130 +288,95 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * // addTraceEvent is a helper method to add a trace event on the channel. If the // channel is a nested one, the same event is also added on the parent channel. func (cc *ClientConn) addTraceEvent(msg string) { - ted := &channelz.TraceEventDesc{ + ted := &channelz.TraceEvent{ Desc: fmt.Sprintf("Channel %s", msg), Severity: channelz.CtInfo, } - if cc.dopts.channelzParentID != nil { - ted.Parent = &channelz.TraceEventDesc{ - Desc: fmt.Sprintf("Nested channel(id:%d) %s", cc.channelzID.Int(), msg), + if cc.dopts.channelzParent != nil { + ted.Parent = &channelz.TraceEvent{ + Desc: fmt.Sprintf("Nested channel(id:%d) %s", cc.channelz.ID, msg), Severity: channelz.CtInfo, } } - channelz.AddTraceEvent(logger, cc.channelzID, 0, ted) + channelz.AddTraceEvent(logger, cc.channelz, 0, ted) +} + +type idler ClientConn + +func (i *idler) EnterIdleMode() { + (*ClientConn)(i).enterIdleMode() +} + +func (i *idler) ExitIdleMode() error { + return (*ClientConn)(i).exitIdleMode() } // exitIdleMode moves the channel out of idle mode by recreating the name -// resolver and load balancer. -func (cc *ClientConn) exitIdleMode() error { +// resolver and load balancer. This should never be called directly; use +// cc.idlenessMgr.ExitIdleMode instead. +func (cc *ClientConn) exitIdleMode() (err error) { cc.mu.Lock() if cc.conns == nil { cc.mu.Unlock() return errConnClosing } - if cc.idlenessState != ccIdlenessStateIdle { - cc.mu.Unlock() - logger.Info("ClientConn asked to exit idle mode when not in idle mode") - return nil - } - - defer func() { - // When Close() and exitIdleMode() race against each other, one of the - // following two can happen: - // - Close() wins the race and runs first. exitIdleMode() runs after, and - // sees that the ClientConn is already closed and hence returns early. - // - exitIdleMode() wins the race and runs first and recreates the balancer - // and releases the lock before recreating the resolver. If Close() runs - // in this window, it will wait for exitIdleMode to complete. - // - // We achieve this synchronization using the below condition variable. - cc.mu.Lock() - cc.idlenessState = ccIdlenessStateActive - cc.exitIdleCond.Signal() - cc.mu.Unlock() - }() - - cc.idlenessState = ccIdlenessStateExitingIdle - exitedIdle := false - if cc.blockingpicker == nil { - cc.blockingpicker = newPickerWrapper() - } else { - cc.blockingpicker.exitIdleMode() - exitedIdle = true - } - - var credsClone credentials.TransportCredentials - if creds := cc.dopts.copts.TransportCredentials; creds != nil { - credsClone = creds.Clone() - } - if cc.balancerWrapper == nil { - cc.balancerWrapper = newCCBalancerWrapper(cc, balancer.BuildOptions{ - DialCreds: credsClone, - CredsBundle: cc.dopts.copts.CredsBundle, - Dialer: cc.dopts.copts.Dialer, - Authority: cc.authority, - CustomUserAgent: cc.dopts.copts.UserAgent, - ChannelzParentID: cc.channelzID, - Target: cc.parsedTarget, - }) - } else { - cc.balancerWrapper.exitIdleMode() - } - cc.firstResolveEvent = grpcsync.NewEvent() cc.mu.Unlock() // This needs to be called without cc.mu because this builds a new resolver - // which might update state or report error inline which needs to be handled - // by cc.updateResolverState() which also grabs cc.mu. - if err := cc.initResolverWrapper(credsClone); err != nil { + // which might update state or report error inline, which would then need to + // acquire cc.mu. + if err := cc.resolverWrapper.start(); err != nil { return err } - if exitedIdle { - cc.addTraceEvent("exiting idle mode") - } + cc.addTraceEvent("exiting idle mode") return nil } +// initIdleStateLocked initializes common state to how it should be while idle. +func (cc *ClientConn) initIdleStateLocked() { + cc.resolverWrapper = newCCResolverWrapper(cc) + cc.balancerWrapper = newCCBalancerWrapper(cc) + cc.firstResolveEvent = grpcsync.NewEvent() + // cc.conns == nil is a proxy for the ClientConn being closed. So, instead + // of setting it to nil here, we recreate the map. This also means that we + // don't have to do this when exiting idle mode. + cc.conns = make(map[*addrConn]struct{}) +} + // enterIdleMode puts the channel in idle mode, and as part of it shuts down the -// name resolver, load balancer and any subchannels. -func (cc *ClientConn) enterIdleMode() error { +// name resolver, load balancer, and any subchannels. This should never be +// called directly; use cc.idlenessMgr.EnterIdleMode instead. +func (cc *ClientConn) enterIdleMode() { cc.mu.Lock() + if cc.conns == nil { cc.mu.Unlock() - return ErrClientConnClosing - } - if cc.idlenessState != ccIdlenessStateActive { - logger.Error("ClientConn asked to enter idle mode when not active") - return nil + return } - // cc.conns == nil is a proxy for the ClientConn being closed. So, instead - // of setting it to nil here, we recreate the map. This also means that we - // don't have to do this when exiting idle mode. conns := cc.conns - cc.conns = make(map[*addrConn]struct{}) - // TODO: Currently, we close the resolver wrapper upon entering idle mode - // and create a new one upon exiting idle mode. This means that the - // `cc.resolverWrapper` field would be overwritten everytime we exit idle - // mode. While this means that we need to hold `cc.mu` when accessing - // `cc.resolverWrapper`, it makes the code simpler in the wrapper. We should - // try to do the same for the balancer and picker wrappers too. - cc.resolverWrapper.close() - cc.blockingpicker.enterIdleMode() - cc.balancerWrapper.enterIdleMode() + rWrapper := cc.resolverWrapper + rWrapper.close() + cc.pickerWrapper.reset() + bWrapper := cc.balancerWrapper + bWrapper.close() cc.csMgr.updateState(connectivity.Idle) - cc.idlenessState = ccIdlenessStateIdle + cc.addTraceEvent("entering idle mode") + + cc.initIdleStateLocked() + cc.mu.Unlock() - go func() { - cc.addTraceEvent("entering idle mode") - for ac := range conns { - ac.tearDown(errConnIdling) - } - }() - return nil + // Block until the name resolver and LB policy are closed. + <-rWrapper.serializer.Done() + <-bWrapper.serializer.Done() + + // Close all subchannels after the LB policy is closed. + for ac := range conns { + ac.tearDown(errConnIdling) + } } // validateTransportCredentials performs a series of checks on the configured @@ -465,16 +415,16 @@ func (cc *ClientConn) validateTransportCredentials() error { } // channelzRegistration registers the newly created ClientConn with channelz and -// stores the returned identifier in `cc.channelzID` and `cc.csMgr.channelzID`. -// A channelz trace event is emitted for ClientConn creation. If the newly -// created ClientConn is a nested one, i.e a valid parent ClientConn ID is -// specified via a dial option, the trace event is also added to the parent. +// stores the returned identifier in `cc.channelz`. A channelz trace event is +// emitted for ClientConn creation. If the newly created ClientConn is a nested +// one, i.e a valid parent ClientConn ID is specified via a dial option, the +// trace event is also added to the parent. // // Doesn't grab cc.mu as this method is expected to be called only at Dial time. func (cc *ClientConn) channelzRegistration(target string) { - cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, cc.dopts.channelzParentID, target) + parentChannel, _ := cc.dopts.channelzParent.(*channelz.Channel) + cc.channelz = channelz.RegisterChannel(parentChannel, target) cc.addTraceEvent("created") - cc.csMgr.channelzID = cc.channelzID } // chainUnaryClientInterceptors chains all unary client interceptors into one. @@ -491,7 +441,7 @@ func chainUnaryClientInterceptors(cc *ClientConn) { } else if len(interceptors) == 1 { chainedInt = interceptors[0] } else { - chainedInt = func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error { + chainedInt = func(ctx context.Context, method string, req, reply any, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error { return interceptors[0](ctx, method, req, reply, cc, getChainUnaryInvoker(interceptors, 0, invoker), opts...) } } @@ -503,7 +453,7 @@ func getChainUnaryInvoker(interceptors []UnaryClientInterceptor, curr int, final if curr == len(interceptors)-1 { return finalInvoker } - return func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error { + return func(ctx context.Context, method string, req, reply any, cc *ClientConn, opts ...CallOption) error { return interceptors[curr+1](ctx, method, req, reply, cc, getChainUnaryInvoker(interceptors, curr+1, finalInvoker), opts...) } } @@ -539,13 +489,27 @@ func getChainStreamer(interceptors []StreamClientInterceptor, curr int, finalStr } } +// newConnectivityStateManager creates an connectivityStateManager with +// the specified channel. +func newConnectivityStateManager(ctx context.Context, channel *channelz.Channel) *connectivityStateManager { + return &connectivityStateManager{ + channelz: channel, + pubSub: grpcsync.NewPubSub(ctx), + } +} + // connectivityStateManager keeps the connectivity.State of ClientConn. // This struct will eventually be exported so the balancers can access it. +// +// TODO: If possible, get rid of the `connectivityStateManager` type, and +// provide this functionality using the `PubSub`, to avoid keeping track of +// the connectivity state at two places. type connectivityStateManager struct { mu sync.Mutex state connectivity.State notifyChan chan struct{} - channelzID *channelz.Identifier + channelz *channelz.Channel + pubSub *grpcsync.PubSub } // updateState updates the connectivity.State of ClientConn. @@ -561,7 +525,10 @@ func (csm *connectivityStateManager) updateState(state connectivity.State) { return } csm.state = state - channelz.Infof(logger, csm.channelzID, "Channel Connectivity change to %v", state) + csm.channelz.ChannelMetrics.State.Store(&state) + csm.pubSub.Publish(state) + + channelz.Infof(logger, csm.channelz, "Channel Connectivity change to %v", state) if csm.notifyChan != nil { // There are other goroutines waiting on this channel. close(csm.notifyChan) @@ -590,7 +557,7 @@ func (csm *connectivityStateManager) getNotifyChan() <-chan struct{} { type ClientConnInterface interface { // Invoke performs a unary RPC and returns after the response is received // into reply. - Invoke(ctx context.Context, method string, args interface{}, reply interface{}, opts ...CallOption) error + Invoke(ctx context.Context, method string, args any, reply any, opts ...CallOption) error // NewStream begins a streaming RPC. NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) } @@ -615,59 +582,40 @@ type ClientConn struct { cancel context.CancelFunc // Cancelled on close. // The following are initialized at dial time, and are read-only after that. - target string // User's dial target. - parsedTarget resolver.Target // See parseTargetAndFindResolver(). - authority string // See determineAuthority(). - dopts dialOptions // Default and user specified dial options. - channelzID *channelz.Identifier // Channelz identifier for the channel. - resolverBuilder resolver.Builder // See parseTargetAndFindResolver(). - balancerWrapper *ccBalancerWrapper // Uses gracefulswitch.balancer underneath. - idlenessMgr idlenessManager + target string // User's dial target. + parsedTarget resolver.Target // See parseTargetAndFindResolver(). + authority string // See determineAuthority(). + dopts dialOptions // Default and user specified dial options. + channelz *channelz.Channel // Channelz object. + resolverBuilder resolver.Builder // See parseTargetAndFindResolver(). + idlenessMgr *idle.Manager // The following provide their own synchronization, and therefore don't // require cc.mu to be held to access them. csMgr *connectivityStateManager - blockingpicker *pickerWrapper + pickerWrapper *pickerWrapper safeConfigSelector iresolver.SafeConfigSelector - czData *channelzData retryThrottler atomic.Value // Updated from service config. - // firstResolveEvent is used to track whether the name resolver sent us at - // least one update. RPCs block on this event. - firstResolveEvent *grpcsync.Event - // mu protects the following fields. // TODO: split mu so the same mutex isn't used for everything. mu sync.RWMutex - resolverWrapper *ccResolverWrapper // Initialized in Dial; cleared in Close. + resolverWrapper *ccResolverWrapper // Always recreated whenever entering idle to simplify Close. + balancerWrapper *ccBalancerWrapper // Always recreated whenever entering idle to simplify Close. sc *ServiceConfig // Latest service config received from the resolver. conns map[*addrConn]struct{} // Set to nil on close. mkp keepalive.ClientParameters // May be updated upon receipt of a GoAway. - idlenessState ccIdlenessState // Tracks idleness state of the channel. - exitIdleCond *sync.Cond // Signalled when channel exits idle. + // firstResolveEvent is used to track whether the name resolver sent us at + // least one update. RPCs block on this event. May be accessed without mu + // if we know we cannot be asked to enter idle mode while accessing it (e.g. + // when the idle manager has already been closed, or if we are already + // entering idle mode). + firstResolveEvent *grpcsync.Event lceMu sync.Mutex // protects lastConnectionError lastConnectionError error } -// ccIdlenessState tracks the idleness state of the channel. -// -// Channels start off in `active` and move to `idle` after a period of -// inactivity. When moving back to `active` upon an incoming RPC, they -// transition through `exiting_idle`. This state is useful for synchronization -// with Close(). -// -// This state tracking is mostly for self-protection. The idlenessManager is -// expected to keep track of the state as well, and is expected not to call into -// the ClientConn unnecessarily. -type ccIdlenessState int8 - -const ( - ccIdlenessStateActive ccIdlenessState = iota - ccIdlenessStateIdle - ccIdlenessStateExitingIdle -) - // WaitForStateChange waits until the connectivity.State of ClientConn changes from sourceState or // ctx expires. A true value is returned in former case and false in latter. // @@ -707,29 +655,15 @@ func (cc *ClientConn) GetState() connectivity.State { // Notice: This API is EXPERIMENTAL and may be changed or removed in a later // release. func (cc *ClientConn) Connect() { - cc.exitIdleMode() + if err := cc.idlenessMgr.ExitIdleMode(); err != nil { + cc.addTraceEvent(err.Error()) + return + } // If the ClientConn was not in idle mode, we need to call ExitIdle on the // LB policy so that connections can be created. - cc.balancerWrapper.exitIdleMode() -} - -func (cc *ClientConn) scWatcher() { - for { - select { - case sc, ok := <-cc.dopts.scChan: - if !ok { - return - } - cc.mu.Lock() - // TODO: load balance policy runtime change is ignored. - // We may revisit this decision in the future. - cc.sc = &sc - cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{&sc}) - cc.mu.Unlock() - case <-cc.ctx.Done(): - return - } - } + cc.mu.Lock() + cc.balancerWrapper.exitIdle() + cc.mu.Unlock() } // waitForResolvedAddrs blocks until the resolver has provided addresses or the @@ -754,28 +688,38 @@ func (cc *ClientConn) waitForResolvedAddrs(ctx context.Context) error { var emptyServiceConfig *ServiceConfig func init() { + balancer.Register(pickfirstBuilder{}) cfg := parseServiceConfig("{}") if cfg.Err != nil { panic(fmt.Sprintf("impossible error parsing empty service config: %v", cfg.Err)) } emptyServiceConfig = cfg.Config.(*ServiceConfig) + + internal.SubscribeToConnectivityStateChanges = func(cc *ClientConn, s grpcsync.Subscriber) func() { + return cc.csMgr.pubSub.Subscribe(s) + } + internal.EnterIdleModeForTesting = func(cc *ClientConn) { + cc.idlenessMgr.EnterIdleModeForTesting() + } + internal.ExitIdleModeForTesting = func(cc *ClientConn) error { + return cc.idlenessMgr.ExitIdleMode() + } } -func (cc *ClientConn) maybeApplyDefaultServiceConfig(addrs []resolver.Address) { +func (cc *ClientConn) maybeApplyDefaultServiceConfig() { if cc.sc != nil { - cc.applyServiceConfigAndBalancer(cc.sc, nil, addrs) + cc.applyServiceConfigAndBalancer(cc.sc, nil) return } if cc.dopts.defaultServiceConfig != nil { - cc.applyServiceConfigAndBalancer(cc.dopts.defaultServiceConfig, &defaultConfigSelector{cc.dopts.defaultServiceConfig}, addrs) + cc.applyServiceConfigAndBalancer(cc.dopts.defaultServiceConfig, &defaultConfigSelector{cc.dopts.defaultServiceConfig}) } else { - cc.applyServiceConfigAndBalancer(emptyServiceConfig, &defaultConfigSelector{emptyServiceConfig}, addrs) + cc.applyServiceConfigAndBalancer(emptyServiceConfig, &defaultConfigSelector{emptyServiceConfig}) } } -func (cc *ClientConn) updateResolverState(s resolver.State, err error) error { +func (cc *ClientConn) updateResolverStateAndUnlock(s resolver.State, err error) error { defer cc.firstResolveEvent.Fire() - cc.mu.Lock() // Check if the ClientConn is already closed. Some fields (e.g. // balancerWrapper) are set to nil when closing the ClientConn, and could // cause nil pointer panic if we don't have this check. @@ -788,7 +732,7 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error { // May need to apply the initial service config in case the resolver // doesn't support service configs, or doesn't provide a service config // with the new addresses. - cc.maybeApplyDefaultServiceConfig(nil) + cc.maybeApplyDefaultServiceConfig() cc.balancerWrapper.resolverError(err) @@ -799,10 +743,10 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error { var ret error if cc.dopts.disableServiceConfig { - channelz.Infof(logger, cc.channelzID, "ignoring service config from resolver (%v) and applying the default because service config is disabled", s.ServiceConfig) - cc.maybeApplyDefaultServiceConfig(s.Addresses) + channelz.Infof(logger, cc.channelz, "ignoring service config from resolver (%v) and applying the default because service config is disabled", s.ServiceConfig) + cc.maybeApplyDefaultServiceConfig() } else if s.ServiceConfig == nil { - cc.maybeApplyDefaultServiceConfig(s.Addresses) + cc.maybeApplyDefaultServiceConfig() // TODO: do we need to apply a failing LB policy if there is no // default, per the error handling design? } else { @@ -810,18 +754,18 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error { configSelector := iresolver.GetConfigSelector(s) if configSelector != nil { if len(s.ServiceConfig.Config.(*ServiceConfig).Methods) != 0 { - channelz.Infof(logger, cc.channelzID, "method configs in service config will be ignored due to presence of config selector") + channelz.Infof(logger, cc.channelz, "method configs in service config will be ignored due to presence of config selector") } } else { configSelector = &defaultConfigSelector{sc} } - cc.applyServiceConfigAndBalancer(sc, configSelector, s.Addresses) + cc.applyServiceConfigAndBalancer(sc, configSelector) } else { ret = balancer.ErrBadResolverState if cc.sc == nil { // Apply the failing LB only if we haven't received valid service config // from the name resolver in the past. - cc.applyFailingLB(s.ServiceConfig) + cc.applyFailingLBLocked(s.ServiceConfig) cc.mu.Unlock() return ret } @@ -830,7 +774,7 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error { var balCfg serviceconfig.LoadBalancingConfig if cc.sc != nil && cc.sc.lbConfig != nil { - balCfg = cc.sc.lbConfig.cfg + balCfg = cc.sc.lbConfig } bw := cc.balancerWrapper cc.mu.Unlock() @@ -843,15 +787,13 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error { return ret } -// applyFailingLB is akin to configuring an LB policy on the channel which +// applyFailingLBLocked is akin to configuring an LB policy on the channel which // always fails RPCs. Here, an actual LB policy is not configured, but an always // erroring picker is configured, which returns errors with information about // what was invalid in the received service config. A config selector with no // service config is configured, and the connectivity state of the channel is // set to TransientFailure. -// -// Caller must hold cc.mu. -func (cc *ClientConn) applyFailingLB(sc *serviceconfig.ParseResult) { +func (cc *ClientConn) applyFailingLBLocked(sc *serviceconfig.ParseResult) { var err error if sc.Err != nil { err = status.Errorf(codes.Unavailable, "error parsing service config: %v", sc.Err) @@ -859,50 +801,54 @@ func (cc *ClientConn) applyFailingLB(sc *serviceconfig.ParseResult) { err = status.Errorf(codes.Unavailable, "illegal service config type: %T", sc.Config) } cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{nil}) - cc.blockingpicker.updatePicker(base.NewErrPicker(err)) + cc.pickerWrapper.updatePicker(base.NewErrPicker(err)) cc.csMgr.updateState(connectivity.TransientFailure) } -func (cc *ClientConn) handleSubConnStateChange(sc balancer.SubConn, s connectivity.State, err error) { - cc.balancerWrapper.updateSubConnState(sc, s, err) +// Makes a copy of the input addresses slice and clears out the balancer +// attributes field. Addresses are passed during subconn creation and address +// update operations. In both cases, we will clear the balancer attributes by +// calling this function, and therefore we will be able to use the Equal method +// provided by the resolver.Address type for comparison. +func copyAddressesWithoutBalancerAttributes(in []resolver.Address) []resolver.Address { + out := make([]resolver.Address, len(in)) + for i := range in { + out[i] = in[i] + out[i].BalancerAttributes = nil + } + return out } -// newAddrConn creates an addrConn for addrs and adds it to cc.conns. +// newAddrConnLocked creates an addrConn for addrs and adds it to cc.conns. // // Caller needs to make sure len(addrs) > 0. -func (cc *ClientConn) newAddrConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (*addrConn, error) { +func (cc *ClientConn) newAddrConnLocked(addrs []resolver.Address, opts balancer.NewSubConnOptions) (*addrConn, error) { + if cc.conns == nil { + return nil, ErrClientConnClosing + } + ac := &addrConn{ state: connectivity.Idle, cc: cc, - addrs: addrs, + addrs: copyAddressesWithoutBalancerAttributes(addrs), scopts: opts, dopts: cc.dopts, - czData: new(channelzData), + channelz: channelz.RegisterSubChannel(cc.channelz, ""), resetBackoff: make(chan struct{}), stateChan: make(chan struct{}), } ac.ctx, ac.cancel = context.WithCancel(cc.ctx) - // Track ac in cc. This needs to be done before any getTransport(...) is called. - cc.mu.Lock() - defer cc.mu.Unlock() - if cc.conns == nil { - return nil, ErrClientConnClosing - } - var err error - ac.channelzID, err = channelz.RegisterSubChannel(ac, cc.channelzID, "") - if err != nil { - return nil, err - } - channelz.AddTraceEvent(logger, ac.channelzID, 0, &channelz.TraceEventDesc{ + channelz.AddTraceEvent(logger, ac.channelz, 0, &channelz.TraceEvent{ Desc: "Subchannel created", Severity: channelz.CtInfo, - Parent: &channelz.TraceEventDesc{ - Desc: fmt.Sprintf("Subchannel(id:%d) created", ac.channelzID.Int()), + Parent: &channelz.TraceEvent{ + Desc: fmt.Sprintf("Subchannel(id:%d) created", ac.channelz.ID), Severity: channelz.CtInfo, }, }) + // Track ac in cc. This needs to be done before any getTransport(...) is called. cc.conns[ac] = struct{}{} return ac, nil } @@ -920,38 +866,27 @@ func (cc *ClientConn) removeAddrConn(ac *addrConn, err error) { ac.tearDown(err) } -func (cc *ClientConn) channelzMetric() *channelz.ChannelInternalMetric { - return &channelz.ChannelInternalMetric{ - State: cc.GetState(), - Target: cc.target, - CallsStarted: atomic.LoadInt64(&cc.czData.callsStarted), - CallsSucceeded: atomic.LoadInt64(&cc.czData.callsSucceeded), - CallsFailed: atomic.LoadInt64(&cc.czData.callsFailed), - LastCallStartedTimestamp: time.Unix(0, atomic.LoadInt64(&cc.czData.lastCallStartedTime)), - } -} - // Target returns the target string of the ClientConn. -// -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. func (cc *ClientConn) Target() string { return cc.target } +// CanonicalTarget returns the canonical target string of the ClientConn. +func (cc *ClientConn) CanonicalTarget() string { + return cc.parsedTarget.String() +} + func (cc *ClientConn) incrCallsStarted() { - atomic.AddInt64(&cc.czData.callsStarted, 1) - atomic.StoreInt64(&cc.czData.lastCallStartedTime, time.Now().UnixNano()) + cc.channelz.ChannelMetrics.CallsStarted.Add(1) + cc.channelz.ChannelMetrics.LastCallStartedTimestamp.Store(time.Now().UnixNano()) } func (cc *ClientConn) incrCallsSucceeded() { - atomic.AddInt64(&cc.czData.callsSucceeded, 1) + cc.channelz.ChannelMetrics.CallsSucceeded.Add(1) } func (cc *ClientConn) incrCallsFailed() { - atomic.AddInt64(&cc.czData.callsFailed, 1) + cc.channelz.ChannelMetrics.CallsFailed.Add(1) } // connect starts creating a transport. @@ -995,8 +930,9 @@ func equalAddresses(a, b []resolver.Address) bool { // connections or connection attempts. func (ac *addrConn) updateAddrs(addrs []resolver.Address) { ac.mu.Lock() - channelz.Infof(logger, ac.channelzID, "addrConn: updateAddrs curAddr: %v, addrs: %v", ac.curAddr, addrs) + channelz.Infof(logger, ac.channelz, "addrConn: updateAddrs curAddr: %v, addrs: %v", pretty.ToJSON(ac.curAddr), pretty.ToJSON(addrs)) + addrs = copyAddressesWithoutBalancerAttributes(addrs) if equalAddresses(ac.addrs, addrs) { ac.mu.Unlock() return @@ -1031,8 +967,8 @@ func (ac *addrConn) updateAddrs(addrs []resolver.Address) { ac.cancel() ac.ctx, ac.cancel = context.WithCancel(ac.cc.ctx) - // We have to defer here because GracefulClose => Close => onClose, which - // requires locking ac.mu. + // We have to defer here because GracefulClose => onClose, which requires + // locking ac.mu. if ac.transport != nil { defer ac.transport.GracefulClose() ac.transport = nil @@ -1108,13 +1044,13 @@ func (cc *ClientConn) healthCheckConfig() *healthCheckConfig { } func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method string) (transport.ClientTransport, balancer.PickResult, error) { - return cc.blockingpicker.pick(ctx, failfast, balancer.PickInfo{ + return cc.pickerWrapper.pick(ctx, failfast, balancer.PickInfo{ Ctx: ctx, FullMethodName: method, }) } -func (cc *ClientConn) applyServiceConfigAndBalancer(sc *ServiceConfig, configSelector iresolver.ConfigSelector, addrs []resolver.Address) { +func (cc *ClientConn) applyServiceConfigAndBalancer(sc *ServiceConfig, configSelector iresolver.ConfigSelector) { if sc == nil { // should never reach here. return @@ -1135,37 +1071,16 @@ func (cc *ClientConn) applyServiceConfigAndBalancer(sc *ServiceConfig, configSel } else { cc.retryThrottler.Store((*retryThrottler)(nil)) } - - var newBalancerName string - if cc.sc != nil && cc.sc.lbConfig != nil { - newBalancerName = cc.sc.lbConfig.name - } else { - var isGRPCLB bool - for _, a := range addrs { - if a.Type == resolver.GRPCLB { - isGRPCLB = true - break - } - } - if isGRPCLB { - newBalancerName = grpclbName - } else if cc.sc != nil && cc.sc.LB != nil { - newBalancerName = *cc.sc.LB - } else { - newBalancerName = PickFirstBalancerName - } - } - cc.balancerWrapper.switchTo(newBalancerName) } func (cc *ClientConn) resolveNow(o resolver.ResolveNowOptions) { cc.mu.RLock() - r := cc.resolverWrapper + cc.resolverWrapper.resolveNow(o) cc.mu.RUnlock() - if r == nil { - return - } - go r.resolveNow(o) +} + +func (cc *ClientConn) resolveNowLocked(o resolver.ResolveNowOptions) { + cc.resolverWrapper.resolveNow(o) } // ResetConnectBackoff wakes up all subchannels in transient failure and causes @@ -1192,7 +1107,14 @@ func (cc *ClientConn) ResetConnectBackoff() { // Close tears down the ClientConn and all underlying connections. func (cc *ClientConn) Close() error { - defer cc.cancel() + defer func() { + cc.cancel() + <-cc.csMgr.pubSub.Done() + }() + + // Prevent calls to enter/exit idle immediately, and ensure we are not + // currently entering/exiting idle mode. + cc.idlenessMgr.Close() cc.mu.Lock() if cc.conns == nil { @@ -1200,34 +1122,22 @@ func (cc *ClientConn) Close() error { return ErrClientConnClosing } - for cc.idlenessState == ccIdlenessStateExitingIdle { - cc.exitIdleCond.Wait() - } - conns := cc.conns cc.conns = nil cc.csMgr.updateState(connectivity.Shutdown) - pWrapper := cc.blockingpicker - rWrapper := cc.resolverWrapper - bWrapper := cc.balancerWrapper - idlenessMgr := cc.idlenessMgr + // We can safely unlock and continue to access all fields now as + // cc.conns==nil, preventing any further operations on cc. cc.mu.Unlock() + cc.resolverWrapper.close() // The order of closing matters here since the balancer wrapper assumes the // picker is closed before it is closed. - if pWrapper != nil { - pWrapper.close() - } - if bWrapper != nil { - bWrapper.close() - } - if rWrapper != nil { - rWrapper.close() - } - if idlenessMgr != nil { - idlenessMgr.close() - } + cc.pickerWrapper.close() + cc.balancerWrapper.close() + + <-cc.resolverWrapper.serializer.Done() + <-cc.balancerWrapper.serializer.Done() for ac := range conns { ac.tearDown(ErrClientConnClosing) @@ -1236,7 +1146,7 @@ func (cc *ClientConn) Close() error { // TraceEvent needs to be called before RemoveEntry, as TraceEvent may add // trace reference to the entity being deleted, and thus prevent it from being // deleted right away. - channelz.RemoveEntry(cc.channelzID) + channelz.RemoveEntry(cc.channelz.ID) return nil } @@ -1248,7 +1158,7 @@ type addrConn struct { cc *ClientConn dopts dialOptions - acbw balancer.SubConn + acbw *acBalancerWrapper scopts balancer.NewSubConnOptions // transport is set when there's a viable transport (note: ac state may not be READY as LB channel @@ -1268,8 +1178,7 @@ type addrConn struct { backoffIdx int // Needs to be stateful for resetConnectBackoff. resetBackoff chan struct{} - channelzID *channelz.Identifier - czData *channelzData + channelz *channelz.SubChannel } // Note: this requires a lock on ac.mu. @@ -1281,12 +1190,13 @@ func (ac *addrConn) updateConnectivityState(s connectivity.State, lastErr error) close(ac.stateChan) ac.stateChan = make(chan struct{}) ac.state = s + ac.channelz.ChannelMetrics.State.Store(&s) if lastErr == nil { - channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v", s) + channelz.Infof(logger, ac.channelz, "Subchannel Connectivity change to %v", s) } else { - channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v, last error: %s", s, lastErr) + channelz.Infof(logger, ac.channelz, "Subchannel Connectivity change to %v, last error: %s", s, lastErr) } - ac.cc.handleSubConnStateChange(ac.acbw, s, lastErr) + ac.acbw.updateState(s, lastErr) } // adjustParams updates parameters used to create transports upon @@ -1336,12 +1246,14 @@ func (ac *addrConn) resetTransport() { if err := ac.tryAllAddrs(acCtx, addrs, connectDeadline); err != nil { ac.cc.resolveNow(resolver.ResolveNowOptions{}) - // After exhausting all addresses, the addrConn enters - // TRANSIENT_FAILURE. + ac.mu.Lock() if acCtx.Err() != nil { + // addrConn was torn down. + ac.mu.Unlock() return } - ac.mu.Lock() + // After exhausting all addresses, the addrConn enters + // TRANSIENT_FAILURE. ac.updateConnectivityState(connectivity.TransientFailure, err) // Backoff. @@ -1395,7 +1307,7 @@ func (ac *addrConn) tryAllAddrs(ctx context.Context, addrs []resolver.Address, c } ac.mu.Unlock() - channelz.Infof(logger, ac.channelzID, "Subchannel picks a new address %q to connect", addr.Addr) + channelz.Infof(logger, ac.channelz, "Subchannel picks a new address %q to connect", addr.Addr) err := ac.createTransport(ctx, addr, copts, connectDeadline) if err == nil { @@ -1448,7 +1360,7 @@ func (ac *addrConn) createTransport(ctx context.Context, addr resolver.Address, connectCtx, cancel := context.WithDeadline(ctx, connectDeadline) defer cancel() - copts.ChannelzParentID = ac.channelzID + copts.ChannelzParent = ac.channelz newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, onClose) if err != nil { @@ -1457,7 +1369,7 @@ func (ac *addrConn) createTransport(ctx context.Context, addr resolver.Address, } // newTr is either nil, or closed. hcancel() - channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %s. Err: %v", addr, err) + channelz.Warningf(logger, ac.channelz, "grpc: addrConn.createTransport failed to connect to %s. Err: %v", addr, err) return err } @@ -1529,7 +1441,7 @@ func (ac *addrConn) startHealthCheck(ctx context.Context) { // The health package is not imported to set health check function. // // TODO: add a link to the health check doc in the error message. - channelz.Error(logger, ac.channelzID, "Health check is requested but health check function is not set.") + channelz.Error(logger, ac.channelz, "Health check is requested but health check function is not set.") return } @@ -1537,7 +1449,7 @@ func (ac *addrConn) startHealthCheck(ctx context.Context) { // Set up the health check helper functions. currentTr := ac.transport - newStream := func(method string) (interface{}, error) { + newStream := func(method string) (any, error) { ac.mu.Lock() if ac.transport != currentTr { ac.mu.Unlock() @@ -1559,9 +1471,9 @@ func (ac *addrConn) startHealthCheck(ctx context.Context) { err := ac.cc.dopts.healthCheckFunc(ctx, newStream, setConnectivityState, healthCheckConfig.ServiceName) if err != nil { if status.Code(err) == codes.Unimplemented { - channelz.Error(logger, ac.channelzID, "Subchannel health check is unimplemented at server side, thus health check is disabled") + channelz.Error(logger, ac.channelz, "Subchannel health check is unimplemented at server side, thus health check is disabled") } else { - channelz.Errorf(logger, ac.channelzID, "Health checking failed: %v", err) + channelz.Errorf(logger, ac.channelz, "Health checking failed: %v", err) } } }() @@ -1625,64 +1537,45 @@ func (ac *addrConn) tearDown(err error) { ac.updateConnectivityState(connectivity.Shutdown, nil) ac.cancel() ac.curAddr = resolver.Address{} - if err == errConnDrain && curTr != nil { - // GracefulClose(...) may be executed multiple times when - // i) receiving multiple GoAway frames from the server; or - // ii) there are concurrent name resolver/Balancer triggered - // address removal and GoAway. - // We have to unlock and re-lock here because GracefulClose => Close => onClose, which requires locking ac.mu. - ac.mu.Unlock() - curTr.GracefulClose() - ac.mu.Lock() - } - channelz.AddTraceEvent(logger, ac.channelzID, 0, &channelz.TraceEventDesc{ + + channelz.AddTraceEvent(logger, ac.channelz, 0, &channelz.TraceEvent{ Desc: "Subchannel deleted", Severity: channelz.CtInfo, - Parent: &channelz.TraceEventDesc{ - Desc: fmt.Sprintf("Subchannel(id:%d) deleted", ac.channelzID.Int()), + Parent: &channelz.TraceEvent{ + Desc: fmt.Sprintf("Subchannel(id:%d) deleted", ac.channelz.ID), Severity: channelz.CtInfo, }, }) // TraceEvent needs to be called before RemoveEntry, as TraceEvent may add // trace reference to the entity being deleted, and thus prevent it from // being deleted right away. - channelz.RemoveEntry(ac.channelzID) + channelz.RemoveEntry(ac.channelz.ID) ac.mu.Unlock() -} -func (ac *addrConn) getState() connectivity.State { - ac.mu.Lock() - defer ac.mu.Unlock() - return ac.state -} - -func (ac *addrConn) ChannelzMetric() *channelz.ChannelInternalMetric { - ac.mu.Lock() - addr := ac.curAddr.Addr - ac.mu.Unlock() - return &channelz.ChannelInternalMetric{ - State: ac.getState(), - Target: addr, - CallsStarted: atomic.LoadInt64(&ac.czData.callsStarted), - CallsSucceeded: atomic.LoadInt64(&ac.czData.callsSucceeded), - CallsFailed: atomic.LoadInt64(&ac.czData.callsFailed), - LastCallStartedTimestamp: time.Unix(0, atomic.LoadInt64(&ac.czData.lastCallStartedTime)), + // We have to release the lock before the call to GracefulClose/Close here + // because both of them call onClose(), which requires locking ac.mu. + if curTr != nil { + if err == errConnDrain { + // Close the transport gracefully when the subConn is being shutdown. + // + // GracefulClose() may be executed multiple times if: + // - multiple GoAway frames are received from the server + // - there are concurrent name resolver or balancer triggered + // address removal and GoAway + curTr.GracefulClose() + } else { + // Hard close the transport when the channel is entering idle or is + // being shutdown. In the case where the channel is being shutdown, + // closing of transports is also taken care of by cancelation of cc.ctx. + // But in the case where the channel is entering idle, we need to + // explicitly close the transports here. Instead of distinguishing + // between these two cases, it is simpler to close the transport + // unconditionally here. + curTr.Close(err) + } } } -func (ac *addrConn) incrCallsStarted() { - atomic.AddInt64(&ac.czData.callsStarted, 1) - atomic.StoreInt64(&ac.czData.lastCallStartedTime, time.Now().UnixNano()) -} - -func (ac *addrConn) incrCallsSucceeded() { - atomic.AddInt64(&ac.czData.callsSucceeded, 1) -} - -func (ac *addrConn) incrCallsFailed() { - atomic.AddInt64(&ac.czData.callsFailed, 1) -} - type retryThrottler struct { max float64 thresh float64 @@ -1720,12 +1613,17 @@ func (rt *retryThrottler) successfulRPC() { } } -type channelzChannel struct { - cc *ClientConn +func (ac *addrConn) incrCallsStarted() { + ac.channelz.ChannelMetrics.CallsStarted.Add(1) + ac.channelz.ChannelMetrics.LastCallStartedTimestamp.Store(time.Now().UnixNano()) +} + +func (ac *addrConn) incrCallsSucceeded() { + ac.channelz.ChannelMetrics.CallsSucceeded.Add(1) } -func (c *channelzChannel) ChannelzMetric() *channelz.ChannelInternalMetric { - return c.cc.channelzMetric() +func (ac *addrConn) incrCallsFailed() { + ac.channelz.ChannelMetrics.CallsFailed.Add(1) } // ErrClientConnTimeout indicates that the ClientConn cannot establish the @@ -1767,14 +1665,14 @@ func (cc *ClientConn) connectionError() error { // // Doesn't grab cc.mu as this method is expected to be called only at Dial time. func (cc *ClientConn) parseTargetAndFindResolver() error { - channelz.Infof(logger, cc.channelzID, "original dial target is: %q", cc.target) + channelz.Infof(logger, cc.channelz, "original dial target is: %q", cc.target) var rb resolver.Builder parsedTarget, err := parseTarget(cc.target) if err != nil { - channelz.Infof(logger, cc.channelzID, "dial target %q parse failed: %v", cc.target, err) + channelz.Infof(logger, cc.channelz, "dial target %q parse failed: %v", cc.target, err) } else { - channelz.Infof(logger, cc.channelzID, "parsed dial target is: %+v", parsedTarget) + channelz.Infof(logger, cc.channelz, "parsed dial target is: %#v", parsedTarget) rb = cc.getResolver(parsedTarget.URL.Scheme) if rb != nil { cc.parsedTarget = parsedTarget @@ -1786,17 +1684,22 @@ func (cc *ClientConn) parseTargetAndFindResolver() error { // We are here because the user's dial target did not contain a scheme or // specified an unregistered scheme. We should fallback to the default // scheme, except when a custom dialer is specified in which case, we should - // always use passthrough scheme. - defScheme := resolver.GetDefaultScheme() - channelz.Infof(logger, cc.channelzID, "fallback to scheme %q", defScheme) + // always use passthrough scheme. For either case, we need to respect any overridden + // global defaults set by the user. + defScheme := cc.dopts.defaultScheme + if internal.UserSetDefaultScheme { + defScheme = resolver.GetDefaultScheme() + } + + channelz.Infof(logger, cc.channelz, "fallback to scheme %q", defScheme) canonicalTarget := defScheme + ":///" + cc.target parsedTarget, err = parseTarget(canonicalTarget) if err != nil { - channelz.Infof(logger, cc.channelzID, "dial target %q parse failed: %v", canonicalTarget, err) + channelz.Infof(logger, cc.channelz, "dial target %q parse failed: %v", canonicalTarget, err) return err } - channelz.Infof(logger, cc.channelzID, "parsed dial target is: %+v", parsedTarget) + channelz.Infof(logger, cc.channelz, "parsed dial target is: %+v", parsedTarget) rb = cc.getResolver(parsedTarget.URL.Scheme) if rb == nil { return fmt.Errorf("could not get resolver for default scheme: %q", parsedTarget.URL.Scheme) @@ -1807,19 +1710,72 @@ func (cc *ClientConn) parseTargetAndFindResolver() error { } // parseTarget uses RFC 3986 semantics to parse the given target into a -// resolver.Target struct containing scheme, authority and url. Query -// params are stripped from the endpoint. +// resolver.Target struct containing url. Query params are stripped from the +// endpoint. func parseTarget(target string) (resolver.Target, error) { u, err := url.Parse(target) if err != nil { return resolver.Target{}, err } - return resolver.Target{ - Scheme: u.Scheme, - Authority: u.Host, - URL: *u, - }, nil + return resolver.Target{URL: *u}, nil +} + +// encodeAuthority escapes the authority string based on valid chars defined in +// https://datatracker.ietf.org/doc/html/rfc3986#section-3.2. +func encodeAuthority(authority string) string { + const upperhex = "0123456789ABCDEF" + + // Return for characters that must be escaped as per + // Valid chars are mentioned here: + // https://datatracker.ietf.org/doc/html/rfc3986#section-3.2 + shouldEscape := func(c byte) bool { + // Alphanum are always allowed. + if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' { + return false + } + switch c { + case '-', '_', '.', '~': // Unreserved characters + return false + case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=': // Subdelim characters + return false + case ':', '[', ']', '@': // Authority related delimeters + return false + } + // Everything else must be escaped. + return true + } + + hexCount := 0 + for i := 0; i < len(authority); i++ { + c := authority[i] + if shouldEscape(c) { + hexCount++ + } + } + + if hexCount == 0 { + return authority + } + + required := len(authority) + 2*hexCount + t := make([]byte, required) + + j := 0 + // This logic is a barebones version of escape in the go net/url library. + for i := 0; i < len(authority); i++ { + switch c := authority[i]; { + case shouldEscape(c): + t[j] = '%' + t[j+1] = upperhex[c>>4] + t[j+2] = upperhex[c&15] + j += 3 + default: + t[j] = authority[i] + j++ + } + } + return string(t) } // Determine channel authority. The order of precedence is as follows: @@ -1855,54 +1811,17 @@ func (cc *ClientConn) determineAuthority() error { } endpoint := cc.parsedTarget.Endpoint() - target := cc.target - switch { - case authorityFromDialOption != "": + if authorityFromDialOption != "" { cc.authority = authorityFromDialOption - case authorityFromCreds != "": + } else if authorityFromCreds != "" { cc.authority = authorityFromCreds - case strings.HasPrefix(target, "unix:") || strings.HasPrefix(target, "unix-abstract:"): - // TODO: remove when the unix resolver implements optional interface to - // return channel authority. - cc.authority = "localhost" - case strings.HasPrefix(endpoint, ":"): + } else if auth, ok := cc.resolverBuilder.(resolver.AuthorityOverrider); ok { + cc.authority = auth.OverrideAuthority(cc.parsedTarget) + } else if strings.HasPrefix(endpoint, ":") { cc.authority = "localhost" + endpoint - default: - // TODO: Define an optional interface on the resolver builder to return - // the channel authority given the user's dial target. For resolvers - // which don't implement this interface, we will use the endpoint from - // "scheme://authority/endpoint" as the default authority. - cc.authority = endpoint - } - channelz.Infof(logger, cc.channelzID, "Channel authority set to %q", cc.authority) - return nil -} - -// initResolverWrapper creates a ccResolverWrapper, which builds the name -// resolver. This method grabs the lock to assign the newly built resolver -// wrapper to the cc.resolverWrapper field. -func (cc *ClientConn) initResolverWrapper(creds credentials.TransportCredentials) error { - rw, err := newCCResolverWrapper(cc, ccResolverWrapperOpts{ - target: cc.parsedTarget, - builder: cc.resolverBuilder, - bOpts: resolver.BuildOptions{ - DisableServiceConfig: cc.dopts.disableServiceConfig, - DialCreds: creds, - CredsBundle: cc.dopts.copts.CredsBundle, - Dialer: cc.dopts.copts.Dialer, - }, - channelzID: cc.channelzID, - }) - if err != nil { - return fmt.Errorf("failed to build resolver: %v", err) + } else { + cc.authority = encodeAuthority(endpoint) } - // Resolver implementations may report state update or error inline when - // built (or right after), and this is handled in cc.updateResolverState. - // Also, an error from the resolver might lead to a re-resolution request - // from the balancer, which is handled in resolveNow() where - // `cc.resolverWrapper` is accessed. Hence, we need to hold the lock here. - cc.mu.Lock() - cc.resolverWrapper = rw - cc.mu.Unlock() + channelz.Infof(logger, cc.channelz, "Channel authority set to %q", cc.authority) return nil } diff --git a/vendor/google.golang.org/grpc/codec.go b/vendor/google.golang.org/grpc/codec.go index 12977654..411e3dfd 100644 --- a/vendor/google.golang.org/grpc/codec.go +++ b/vendor/google.golang.org/grpc/codec.go @@ -27,8 +27,8 @@ import ( // omits the name/string, which vary between the two and are not needed for // anything besides the registry in the encoding package. type baseCodec interface { - Marshal(v interface{}) ([]byte, error) - Unmarshal(data []byte, v interface{}) error + Marshal(v any) ([]byte, error) + Unmarshal(data []byte, v any) error } var _ baseCodec = Codec(nil) @@ -41,9 +41,9 @@ var _ baseCodec = encoding.Codec(nil) // Deprecated: use encoding.Codec instead. type Codec interface { // Marshal returns the wire format of v. - Marshal(v interface{}) ([]byte, error) + Marshal(v any) ([]byte, error) // Unmarshal parses the wire format into v. - Unmarshal(data []byte, v interface{}) error + Unmarshal(data []byte, v any) error // String returns the name of the Codec implementation. This is unused by // gRPC. String() string diff --git a/vendor/google.golang.org/grpc/codes/codes.go b/vendor/google.golang.org/grpc/codes/codes.go index 11b10618..08476ad1 100644 --- a/vendor/google.golang.org/grpc/codes/codes.go +++ b/vendor/google.golang.org/grpc/codes/codes.go @@ -25,7 +25,13 @@ import ( "strconv" ) -// A Code is an unsigned 32-bit error code as defined in the gRPC spec. +// A Code is a status code defined according to the [gRPC documentation]. +// +// Only the codes defined as consts in this package are valid codes. Do not use +// other code values. Behavior of other codes is implementation-specific and +// interoperability between implementations is not guaranteed. +// +// [gRPC documentation]: https://github.com/grpc/grpc/blob/master/doc/statuscodes.md type Code uint32 const ( diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index 5feac3aa..f6b55c68 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -28,9 +28,9 @@ import ( "fmt" "net" - "github.com/golang/protobuf/proto" "google.golang.org/grpc/attributes" icredentials "google.golang.org/grpc/internal/credentials" + "google.golang.org/protobuf/protoadapt" ) // PerRPCCredentials defines the common interface for the credentials which need to @@ -287,5 +287,5 @@ type ChannelzSecurityValue interface { type OtherChannelzSecurityValue struct { ChannelzSecurityValue Name string - Value proto.Message + Value protoadapt.MessageV1 } diff --git a/vendor/google.golang.org/grpc/credentials/tls.go b/vendor/google.golang.org/grpc/credentials/tls.go index 877b7cd2..5dafd34e 100644 --- a/vendor/google.golang.org/grpc/credentials/tls.go +++ b/vendor/google.golang.org/grpc/credentials/tls.go @@ -44,10 +44,25 @@ func (t TLSInfo) AuthType() string { return "tls" } +// cipherSuiteLookup returns the string version of a TLS cipher suite ID. +func cipherSuiteLookup(cipherSuiteID uint16) string { + for _, s := range tls.CipherSuites() { + if s.ID == cipherSuiteID { + return s.Name + } + } + for _, s := range tls.InsecureCipherSuites() { + if s.ID == cipherSuiteID { + return s.Name + } + } + return fmt.Sprintf("unknown ID: %v", cipherSuiteID) +} + // GetSecurityValue returns security info requested by channelz. func (t TLSInfo) GetSecurityValue() ChannelzSecurityValue { v := &TLSChannelzSecurityValue{ - StandardName: cipherSuiteLookup[t.State.CipherSuite], + StandardName: cipherSuiteLookup(t.State.CipherSuite), } // Currently there's no way to get LocalCertificate info from tls package. if len(t.State.PeerCertificates) > 0 { @@ -138,10 +153,39 @@ func (c *tlsCreds) OverrideServerName(serverNameOverride string) error { return nil } +// The following cipher suites are forbidden for use with HTTP/2 by +// https://datatracker.ietf.org/doc/html/rfc7540#appendix-A +var tls12ForbiddenCipherSuites = map[uint16]struct{}{ + tls.TLS_RSA_WITH_AES_128_CBC_SHA: {}, + tls.TLS_RSA_WITH_AES_256_CBC_SHA: {}, + tls.TLS_RSA_WITH_AES_128_GCM_SHA256: {}, + tls.TLS_RSA_WITH_AES_256_GCM_SHA384: {}, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: {}, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: {}, + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: {}, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: {}, +} + // NewTLS uses c to construct a TransportCredentials based on TLS. func NewTLS(c *tls.Config) TransportCredentials { tc := &tlsCreds{credinternal.CloneTLSConfig(c)} tc.config.NextProtos = credinternal.AppendH2ToNextProtos(tc.config.NextProtos) + // If the user did not configure a MinVersion and did not configure a + // MaxVersion < 1.2, use MinVersion=1.2, which is required by + // https://datatracker.ietf.org/doc/html/rfc7540#section-9.2 + if tc.config.MinVersion == 0 && (tc.config.MaxVersion == 0 || tc.config.MaxVersion >= tls.VersionTLS12) { + tc.config.MinVersion = tls.VersionTLS12 + } + // If the user did not configure CipherSuites, use all "secure" cipher + // suites reported by the TLS package, but remove some explicitly forbidden + // by https://datatracker.ietf.org/doc/html/rfc7540#appendix-A + if tc.config.CipherSuites == nil { + for _, cs := range tls.CipherSuites() { + if _, ok := tls12ForbiddenCipherSuites[cs.ID]; !ok { + tc.config.CipherSuites = append(tc.config.CipherSuites, cs.ID) + } + } + } return tc } @@ -205,32 +249,3 @@ type TLSChannelzSecurityValue struct { LocalCertificate []byte RemoteCertificate []byte } - -var cipherSuiteLookup = map[uint16]string{ - tls.TLS_RSA_WITH_RC4_128_SHA: "TLS_RSA_WITH_RC4_128_SHA", - tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA: "TLS_RSA_WITH_3DES_EDE_CBC_SHA", - tls.TLS_RSA_WITH_AES_128_CBC_SHA: "TLS_RSA_WITH_AES_128_CBC_SHA", - tls.TLS_RSA_WITH_AES_256_CBC_SHA: "TLS_RSA_WITH_AES_256_CBC_SHA", - tls.TLS_RSA_WITH_AES_128_GCM_SHA256: "TLS_RSA_WITH_AES_128_GCM_SHA256", - tls.TLS_RSA_WITH_AES_256_GCM_SHA384: "TLS_RSA_WITH_AES_256_GCM_SHA384", - tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", - tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", - tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA: "TLS_ECDHE_RSA_WITH_RC4_128_SHA", - tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", - tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - tls.TLS_FALLBACK_SCSV: "TLS_FALLBACK_SCSV", - tls.TLS_RSA_WITH_AES_128_CBC_SHA256: "TLS_RSA_WITH_AES_128_CBC_SHA256", - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", - tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", - tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", - tls.TLS_AES_128_GCM_SHA256: "TLS_AES_128_GCM_SHA256", - tls.TLS_AES_256_GCM_SHA384: "TLS_AES_256_GCM_SHA384", - tls.TLS_CHACHA20_POLY1305_SHA256: "TLS_CHACHA20_POLY1305_SHA256", -} diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go index 15a3d510..40249322 100644 --- a/vendor/google.golang.org/grpc/dialoptions.go +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -46,6 +46,7 @@ func init() { internal.WithBinaryLogger = withBinaryLogger internal.JoinDialOptions = newJoinDialOption internal.DisableGlobalDialOptions = newDisableGlobalDialOptions + internal.WithRecvBufferPool = withRecvBufferPool } // dialOptions configure a Dial call. dialOptions are set by the DialOption @@ -63,12 +64,11 @@ type dialOptions struct { block bool returnLastError bool timeout time.Duration - scChan <-chan ServiceConfig authority string binaryLogger binarylog.Logger copts transport.ConnectOptions callOptions []CallOption - channelzParentID *channelz.Identifier + channelzParent channelz.Identifier disableServiceConfig bool disableRetry bool disableHealthCheck bool @@ -78,6 +78,8 @@ type dialOptions struct { defaultServiceConfigRawJSON *string resolvers []resolver.Builder idleTimeout time.Duration + recvBufferPool SharedBufferPool + defaultScheme string } // DialOption configures how we set up the connection. @@ -138,10 +140,22 @@ func newJoinDialOption(opts ...DialOption) DialOption { return &joinDialOption{opts: opts} } +// WithSharedWriteBuffer allows reusing per-connection transport write buffer. +// If this option is set to true every connection will release the buffer after +// flushing the data on the wire. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func WithSharedWriteBuffer(val bool) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.SharedWriteBuffer = val + }) +} + // WithWriteBufferSize determines how much data can be batched before doing a -// write on the wire. The corresponding memory allocation for this buffer will -// be twice the size to keep syscalls low. The default value for this buffer is -// 32KB. +// write on the wire. The default value for this buffer is 32KB. // // Zero or negative values will disable the write buffer such that each write // will be on underlying connection. Note: A Send call may not directly @@ -235,19 +249,6 @@ func WithDecompressor(dc Decompressor) DialOption { }) } -// WithServiceConfig returns a DialOption which has a channel to read the -// service configuration. -// -// Deprecated: service config should be received through name resolver or via -// WithDefaultServiceConfig, as specified at -// https://github.com/grpc/grpc/blob/master/doc/service_config.md. Will be -// removed in a future 1.x release. -func WithServiceConfig(c <-chan ServiceConfig) DialOption { - return newFuncDialOption(func(o *dialOptions) { - o.scChan = c - }) -} - // WithConnectParams configures the ClientConn to use the provided ConnectParams // for creating and maintaining connections to servers. // @@ -398,6 +399,17 @@ func WithTimeout(d time.Duration) DialOption { // connections. If FailOnNonTempDialError() is set to true, and an error is // returned by f, gRPC checks the error's Temporary() method to decide if it // should try to reconnect to the network address. +// +// Note: All supported releases of Go (as of December 2023) override the OS +// defaults for TCP keepalive time and interval to 15s. To enable TCP keepalive +// with OS defaults for keepalive time and interval, use a net.Dialer that sets +// the KeepAlive field to a negative value, and sets the SO_KEEPALIVE socket +// option to true from the Control field. For a concrete example of how to do +// this, see internal.NetDialerWithTCPKeepalive(). +// +// For more information, please see [issue 23459] in the Go github repo. +// +// [issue 23459]: https://github.com/golang/go/issues/23459 func WithContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption { return newFuncDialOption(func(o *dialOptions) { o.copts.Dialer = f @@ -472,7 +484,7 @@ func FailOnNonTempDialError(f bool) DialOption { // the RPCs. func WithUserAgent(s string) DialOption { return newFuncDialOption(func(o *dialOptions) { - o.copts.UserAgent = s + o.copts.UserAgent = s + " " + grpcUA }) } @@ -542,9 +554,9 @@ func WithAuthority(a string) DialOption { // // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release. -func WithChannelzParentID(id *channelz.Identifier) DialOption { +func WithChannelzParentID(c channelz.Identifier) DialOption { return newFuncDialOption(func(o *dialOptions) { - o.channelzParentID = id + o.channelzParent = c }) } @@ -622,12 +634,17 @@ func withHealthCheckFunc(f internal.HealthChecker) DialOption { func defaultDialOptions() dialOptions { return dialOptions{ - healthCheckFunc: internal.HealthCheckFunc, copts: transport.ConnectOptions{ - WriteBufferSize: defaultWriteBufSize, ReadBufferSize: defaultReadBufSize, + WriteBufferSize: defaultWriteBufSize, UseProxy: true, + UserAgent: grpcUA, }, + bs: internalbackoff.DefaultExponential, + healthCheckFunc: internal.HealthCheckFunc, + idleTimeout: 30 * time.Minute, + recvBufferPool: nopBufferPool{}, + defaultScheme: "dns", } } @@ -642,6 +659,14 @@ func withMinConnectDeadline(f func() time.Duration) DialOption { }) } +// withDefaultScheme is used to allow Dial to use "passthrough" as the default +// name resolver, while NewClient uses "dns" otherwise. +func withDefaultScheme(s string) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.defaultScheme = s + }) +} + // WithResolvers allows a list of resolver implementations to be registered // locally with the ClientConn without needing to be globally registered via // resolver.Register. They will be matched against the scheme used for the @@ -664,8 +689,8 @@ func WithResolvers(rs ...resolver.Builder) DialOption { // channel will exit idle mode when the Connect() method is called or when an // RPC is initiated. // -// By default this feature is disabled, which can also be explicitly configured -// by passing zero to this function. +// A default timeout of 30 minutes will be used if this dial option is not set +// at dial time and idleness can be disabled by passing a timeout of zero. // // # Experimental // @@ -676,3 +701,26 @@ func WithIdleTimeout(d time.Duration) DialOption { o.idleTimeout = d }) } + +// WithRecvBufferPool returns a DialOption that configures the ClientConn +// to use the provided shared buffer pool for parsing incoming messages. Depending +// on the application's workload, this could result in reduced memory allocation. +// +// If you are unsure about how to implement a memory pool but want to utilize one, +// begin with grpc.NewSharedBufferPool. +// +// Note: The shared buffer pool feature will not be active if any of the following +// options are used: WithStatsHandler, EnableTracing, or binary logging. In such +// cases, the shared buffer pool will be ignored. +// +// Deprecated: use experimental.WithRecvBufferPool instead. Will be deleted in +// v1.60.0 or later. +func WithRecvBufferPool(bufferPool SharedBufferPool) DialOption { + return withRecvBufferPool(bufferPool) +} + +func withRecvBufferPool(bufferPool SharedBufferPool) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.recvBufferPool = bufferPool + }) +} diff --git a/vendor/google.golang.org/grpc/encoding/encoding.go b/vendor/google.golang.org/grpc/encoding/encoding.go index 07a58613..5ebf88d7 100644 --- a/vendor/google.golang.org/grpc/encoding/encoding.go +++ b/vendor/google.golang.org/grpc/encoding/encoding.go @@ -38,6 +38,10 @@ const Identity = "identity" // Compressor is used for compressing and decompressing when sending or // receiving messages. +// +// If a Compressor implements `DecompressedSize(compressedBytes []byte) int`, +// gRPC will invoke it to determine the size of the buffer allocated for the +// result of decompression. A return value of -1 indicates unknown size. type Compressor interface { // Compress writes the data written to wc to w after compressing it. If an // error occurs while initializing the compressor, that error is returned @@ -51,15 +55,6 @@ type Compressor interface { // coding header. The result must be static; the result cannot change // between calls. Name() string - // If a Compressor implements - // DecompressedSize(compressedBytes []byte) int, gRPC will call it - // to determine the size of the buffer allocated for the result of decompression. - // Return -1 to indicate unknown size. - // - // Experimental - // - // Notice: This API is EXPERIMENTAL and may be changed or removed in a - // later release. } var registeredCompressor = make(map[string]Compressor) @@ -90,9 +85,9 @@ func GetCompressor(name string) Compressor { // methods can be called from concurrent goroutines. type Codec interface { // Marshal returns the wire format of v. - Marshal(v interface{}) ([]byte, error) + Marshal(v any) ([]byte, error) // Unmarshal parses the wire format into v. - Unmarshal(data []byte, v interface{}) error + Unmarshal(data []byte, v any) error // Name returns the name of the Codec implementation. The returned string // will be used as part of content type in transmission. The result must be // static; the result cannot change between calls. diff --git a/vendor/google.golang.org/grpc/encoding/proto/proto.go b/vendor/google.golang.org/grpc/encoding/proto/proto.go index 3009b35a..66d5cdf0 100644 --- a/vendor/google.golang.org/grpc/encoding/proto/proto.go +++ b/vendor/google.golang.org/grpc/encoding/proto/proto.go @@ -23,8 +23,9 @@ package proto import ( "fmt" - "github.com/golang/protobuf/proto" "google.golang.org/grpc/encoding" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/protoadapt" ) // Name is the name registered for the proto compressor. @@ -37,22 +38,35 @@ func init() { // codec is a Codec implementation with protobuf. It is the default codec for gRPC. type codec struct{} -func (codec) Marshal(v interface{}) ([]byte, error) { - vv, ok := v.(proto.Message) - if !ok { +func (codec) Marshal(v any) ([]byte, error) { + vv := messageV2Of(v) + if vv == nil { return nil, fmt.Errorf("failed to marshal, message is %T, want proto.Message", v) } + return proto.Marshal(vv) } -func (codec) Unmarshal(data []byte, v interface{}) error { - vv, ok := v.(proto.Message) - if !ok { +func (codec) Unmarshal(data []byte, v any) error { + vv := messageV2Of(v) + if vv == nil { return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v) } + return proto.Unmarshal(data, vv) } +func messageV2Of(v any) proto.Message { + switch v := v.(type) { + case protoadapt.MessageV1: + return protoadapt.MessageV2Of(v) + case protoadapt.MessageV2: + return v + } + + return nil +} + func (codec) Name() string { return Name } diff --git a/vendor/google.golang.org/grpc/grpclog/component.go b/vendor/google.golang.org/grpc/grpclog/component.go index 8358dd6e..ac73c9ce 100644 --- a/vendor/google.golang.org/grpc/grpclog/component.go +++ b/vendor/google.golang.org/grpc/grpclog/component.go @@ -31,71 +31,71 @@ type componentData struct { var cache = map[string]*componentData{} -func (c *componentData) InfoDepth(depth int, args ...interface{}) { - args = append([]interface{}{"[" + string(c.name) + "]"}, args...) +func (c *componentData) InfoDepth(depth int, args ...any) { + args = append([]any{"[" + string(c.name) + "]"}, args...) grpclog.InfoDepth(depth+1, args...) } -func (c *componentData) WarningDepth(depth int, args ...interface{}) { - args = append([]interface{}{"[" + string(c.name) + "]"}, args...) +func (c *componentData) WarningDepth(depth int, args ...any) { + args = append([]any{"[" + string(c.name) + "]"}, args...) grpclog.WarningDepth(depth+1, args...) } -func (c *componentData) ErrorDepth(depth int, args ...interface{}) { - args = append([]interface{}{"[" + string(c.name) + "]"}, args...) +func (c *componentData) ErrorDepth(depth int, args ...any) { + args = append([]any{"[" + string(c.name) + "]"}, args...) grpclog.ErrorDepth(depth+1, args...) } -func (c *componentData) FatalDepth(depth int, args ...interface{}) { - args = append([]interface{}{"[" + string(c.name) + "]"}, args...) +func (c *componentData) FatalDepth(depth int, args ...any) { + args = append([]any{"[" + string(c.name) + "]"}, args...) grpclog.FatalDepth(depth+1, args...) } -func (c *componentData) Info(args ...interface{}) { +func (c *componentData) Info(args ...any) { c.InfoDepth(1, args...) } -func (c *componentData) Warning(args ...interface{}) { +func (c *componentData) Warning(args ...any) { c.WarningDepth(1, args...) } -func (c *componentData) Error(args ...interface{}) { +func (c *componentData) Error(args ...any) { c.ErrorDepth(1, args...) } -func (c *componentData) Fatal(args ...interface{}) { +func (c *componentData) Fatal(args ...any) { c.FatalDepth(1, args...) } -func (c *componentData) Infof(format string, args ...interface{}) { +func (c *componentData) Infof(format string, args ...any) { c.InfoDepth(1, fmt.Sprintf(format, args...)) } -func (c *componentData) Warningf(format string, args ...interface{}) { +func (c *componentData) Warningf(format string, args ...any) { c.WarningDepth(1, fmt.Sprintf(format, args...)) } -func (c *componentData) Errorf(format string, args ...interface{}) { +func (c *componentData) Errorf(format string, args ...any) { c.ErrorDepth(1, fmt.Sprintf(format, args...)) } -func (c *componentData) Fatalf(format string, args ...interface{}) { +func (c *componentData) Fatalf(format string, args ...any) { c.FatalDepth(1, fmt.Sprintf(format, args...)) } -func (c *componentData) Infoln(args ...interface{}) { +func (c *componentData) Infoln(args ...any) { c.InfoDepth(1, args...) } -func (c *componentData) Warningln(args ...interface{}) { +func (c *componentData) Warningln(args ...any) { c.WarningDepth(1, args...) } -func (c *componentData) Errorln(args ...interface{}) { +func (c *componentData) Errorln(args ...any) { c.ErrorDepth(1, args...) } -func (c *componentData) Fatalln(args ...interface{}) { +func (c *componentData) Fatalln(args ...any) { c.FatalDepth(1, args...) } diff --git a/vendor/google.golang.org/grpc/grpclog/grpclog.go b/vendor/google.golang.org/grpc/grpclog/grpclog.go index c8bb2be3..16928c9c 100644 --- a/vendor/google.golang.org/grpc/grpclog/grpclog.go +++ b/vendor/google.golang.org/grpc/grpclog/grpclog.go @@ -42,53 +42,53 @@ func V(l int) bool { } // Info logs to the INFO log. -func Info(args ...interface{}) { +func Info(args ...any) { grpclog.Logger.Info(args...) } // Infof logs to the INFO log. Arguments are handled in the manner of fmt.Printf. -func Infof(format string, args ...interface{}) { +func Infof(format string, args ...any) { grpclog.Logger.Infof(format, args...) } // Infoln logs to the INFO log. Arguments are handled in the manner of fmt.Println. -func Infoln(args ...interface{}) { +func Infoln(args ...any) { grpclog.Logger.Infoln(args...) } // Warning logs to the WARNING log. -func Warning(args ...interface{}) { +func Warning(args ...any) { grpclog.Logger.Warning(args...) } // Warningf logs to the WARNING log. Arguments are handled in the manner of fmt.Printf. -func Warningf(format string, args ...interface{}) { +func Warningf(format string, args ...any) { grpclog.Logger.Warningf(format, args...) } // Warningln logs to the WARNING log. Arguments are handled in the manner of fmt.Println. -func Warningln(args ...interface{}) { +func Warningln(args ...any) { grpclog.Logger.Warningln(args...) } // Error logs to the ERROR log. -func Error(args ...interface{}) { +func Error(args ...any) { grpclog.Logger.Error(args...) } // Errorf logs to the ERROR log. Arguments are handled in the manner of fmt.Printf. -func Errorf(format string, args ...interface{}) { +func Errorf(format string, args ...any) { grpclog.Logger.Errorf(format, args...) } // Errorln logs to the ERROR log. Arguments are handled in the manner of fmt.Println. -func Errorln(args ...interface{}) { +func Errorln(args ...any) { grpclog.Logger.Errorln(args...) } // Fatal logs to the FATAL log. Arguments are handled in the manner of fmt.Print. // It calls os.Exit() with exit code 1. -func Fatal(args ...interface{}) { +func Fatal(args ...any) { grpclog.Logger.Fatal(args...) // Make sure fatal logs will exit. os.Exit(1) @@ -96,7 +96,7 @@ func Fatal(args ...interface{}) { // Fatalf logs to the FATAL log. Arguments are handled in the manner of fmt.Printf. // It calls os.Exit() with exit code 1. -func Fatalf(format string, args ...interface{}) { +func Fatalf(format string, args ...any) { grpclog.Logger.Fatalf(format, args...) // Make sure fatal logs will exit. os.Exit(1) @@ -104,7 +104,7 @@ func Fatalf(format string, args ...interface{}) { // Fatalln logs to the FATAL log. Arguments are handled in the manner of fmt.Println. // It calle os.Exit()) with exit code 1. -func Fatalln(args ...interface{}) { +func Fatalln(args ...any) { grpclog.Logger.Fatalln(args...) // Make sure fatal logs will exit. os.Exit(1) @@ -113,20 +113,20 @@ func Fatalln(args ...interface{}) { // Print prints to the logger. Arguments are handled in the manner of fmt.Print. // // Deprecated: use Info. -func Print(args ...interface{}) { +func Print(args ...any) { grpclog.Logger.Info(args...) } // Printf prints to the logger. Arguments are handled in the manner of fmt.Printf. // // Deprecated: use Infof. -func Printf(format string, args ...interface{}) { +func Printf(format string, args ...any) { grpclog.Logger.Infof(format, args...) } // Println prints to the logger. Arguments are handled in the manner of fmt.Println. // // Deprecated: use Infoln. -func Println(args ...interface{}) { +func Println(args ...any) { grpclog.Logger.Infoln(args...) } diff --git a/vendor/google.golang.org/grpc/grpclog/logger.go b/vendor/google.golang.org/grpc/grpclog/logger.go index ef06a482..b1674d82 100644 --- a/vendor/google.golang.org/grpc/grpclog/logger.go +++ b/vendor/google.golang.org/grpc/grpclog/logger.go @@ -24,12 +24,12 @@ import "google.golang.org/grpc/internal/grpclog" // // Deprecated: use LoggerV2. type Logger interface { - Fatal(args ...interface{}) - Fatalf(format string, args ...interface{}) - Fatalln(args ...interface{}) - Print(args ...interface{}) - Printf(format string, args ...interface{}) - Println(args ...interface{}) + Fatal(args ...any) + Fatalf(format string, args ...any) + Fatalln(args ...any) + Print(args ...any) + Printf(format string, args ...any) + Println(args ...any) } // SetLogger sets the logger that is used in grpc. Call only from @@ -45,39 +45,39 @@ type loggerWrapper struct { Logger } -func (g *loggerWrapper) Info(args ...interface{}) { +func (g *loggerWrapper) Info(args ...any) { g.Logger.Print(args...) } -func (g *loggerWrapper) Infoln(args ...interface{}) { +func (g *loggerWrapper) Infoln(args ...any) { g.Logger.Println(args...) } -func (g *loggerWrapper) Infof(format string, args ...interface{}) { +func (g *loggerWrapper) Infof(format string, args ...any) { g.Logger.Printf(format, args...) } -func (g *loggerWrapper) Warning(args ...interface{}) { +func (g *loggerWrapper) Warning(args ...any) { g.Logger.Print(args...) } -func (g *loggerWrapper) Warningln(args ...interface{}) { +func (g *loggerWrapper) Warningln(args ...any) { g.Logger.Println(args...) } -func (g *loggerWrapper) Warningf(format string, args ...interface{}) { +func (g *loggerWrapper) Warningf(format string, args ...any) { g.Logger.Printf(format, args...) } -func (g *loggerWrapper) Error(args ...interface{}) { +func (g *loggerWrapper) Error(args ...any) { g.Logger.Print(args...) } -func (g *loggerWrapper) Errorln(args ...interface{}) { +func (g *loggerWrapper) Errorln(args ...any) { g.Logger.Println(args...) } -func (g *loggerWrapper) Errorf(format string, args ...interface{}) { +func (g *loggerWrapper) Errorf(format string, args ...any) { g.Logger.Printf(format, args...) } diff --git a/vendor/google.golang.org/grpc/grpclog/loggerv2.go b/vendor/google.golang.org/grpc/grpclog/loggerv2.go index 5de66e40..ecfd36d7 100644 --- a/vendor/google.golang.org/grpc/grpclog/loggerv2.go +++ b/vendor/google.golang.org/grpc/grpclog/loggerv2.go @@ -33,35 +33,35 @@ import ( // LoggerV2 does underlying logging work for grpclog. type LoggerV2 interface { // Info logs to INFO log. Arguments are handled in the manner of fmt.Print. - Info(args ...interface{}) + Info(args ...any) // Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println. - Infoln(args ...interface{}) + Infoln(args ...any) // Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf. - Infof(format string, args ...interface{}) + Infof(format string, args ...any) // Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print. - Warning(args ...interface{}) + Warning(args ...any) // Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println. - Warningln(args ...interface{}) + Warningln(args ...any) // Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf. - Warningf(format string, args ...interface{}) + Warningf(format string, args ...any) // Error logs to ERROR log. Arguments are handled in the manner of fmt.Print. - Error(args ...interface{}) + Error(args ...any) // Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println. - Errorln(args ...interface{}) + Errorln(args ...any) // Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. - Errorf(format string, args ...interface{}) + Errorf(format string, args ...any) // Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatal(args ...interface{}) + Fatal(args ...any) // Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatalln(args ...interface{}) + Fatalln(args ...any) // Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatalf(format string, args ...interface{}) + Fatalf(format string, args ...any) // V reports whether verbosity level l is at least the requested verbose level. V(l int) bool } @@ -182,53 +182,53 @@ func (g *loggerT) output(severity int, s string) { g.m[severity].Output(2, string(b)) } -func (g *loggerT) Info(args ...interface{}) { +func (g *loggerT) Info(args ...any) { g.output(infoLog, fmt.Sprint(args...)) } -func (g *loggerT) Infoln(args ...interface{}) { +func (g *loggerT) Infoln(args ...any) { g.output(infoLog, fmt.Sprintln(args...)) } -func (g *loggerT) Infof(format string, args ...interface{}) { +func (g *loggerT) Infof(format string, args ...any) { g.output(infoLog, fmt.Sprintf(format, args...)) } -func (g *loggerT) Warning(args ...interface{}) { +func (g *loggerT) Warning(args ...any) { g.output(warningLog, fmt.Sprint(args...)) } -func (g *loggerT) Warningln(args ...interface{}) { +func (g *loggerT) Warningln(args ...any) { g.output(warningLog, fmt.Sprintln(args...)) } -func (g *loggerT) Warningf(format string, args ...interface{}) { +func (g *loggerT) Warningf(format string, args ...any) { g.output(warningLog, fmt.Sprintf(format, args...)) } -func (g *loggerT) Error(args ...interface{}) { +func (g *loggerT) Error(args ...any) { g.output(errorLog, fmt.Sprint(args...)) } -func (g *loggerT) Errorln(args ...interface{}) { +func (g *loggerT) Errorln(args ...any) { g.output(errorLog, fmt.Sprintln(args...)) } -func (g *loggerT) Errorf(format string, args ...interface{}) { +func (g *loggerT) Errorf(format string, args ...any) { g.output(errorLog, fmt.Sprintf(format, args...)) } -func (g *loggerT) Fatal(args ...interface{}) { +func (g *loggerT) Fatal(args ...any) { g.output(fatalLog, fmt.Sprint(args...)) os.Exit(1) } -func (g *loggerT) Fatalln(args ...interface{}) { +func (g *loggerT) Fatalln(args ...any) { g.output(fatalLog, fmt.Sprintln(args...)) os.Exit(1) } -func (g *loggerT) Fatalf(format string, args ...interface{}) { +func (g *loggerT) Fatalf(format string, args ...any) { g.output(fatalLog, fmt.Sprintf(format, args...)) os.Exit(1) } @@ -248,11 +248,11 @@ func (g *loggerT) V(l int) bool { type DepthLoggerV2 interface { LoggerV2 // InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Println. - InfoDepth(depth int, args ...interface{}) + InfoDepth(depth int, args ...any) // WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Println. - WarningDepth(depth int, args ...interface{}) + WarningDepth(depth int, args ...any) // ErrorDepth logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Println. - ErrorDepth(depth int, args ...interface{}) + ErrorDepth(depth int, args ...any) // FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Println. - FatalDepth(depth int, args ...interface{}) + FatalDepth(depth int, args ...any) } diff --git a/vendor/google.golang.org/grpc/health/client.go b/vendor/google.golang.org/grpc/health/client.go index b5bee483..740745c4 100644 --- a/vendor/google.golang.org/grpc/health/client.go +++ b/vendor/google.golang.org/grpc/health/client.go @@ -56,7 +56,7 @@ const healthCheckMethod = "/grpc.health.v1.Health/Watch" // This function implements the protocol defined at: // https://github.com/grpc/grpc/blob/master/doc/health-checking.md -func clientHealthCheck(ctx context.Context, newStream func(string) (interface{}, error), setConnectivityState func(connectivity.State, error), service string) error { +func clientHealthCheck(ctx context.Context, newStream func(string) (any, error), setConnectivityState func(connectivity.State, error), service string) error { tryCnt := 0 retryConnection: diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go index 142d35f7..5bf880d4 100644 --- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go @@ -17,8 +17,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v4.22.0 +// protoc-gen-go v1.32.0 +// protoc v4.25.2 // source: grpc/health/v1/health.proto package grpc_health_v1 diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go index a01a1b4d..4c46c098 100644 --- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v4.22.0 +// - protoc v4.25.2 // source: grpc/health/v1/health.proto package grpc_health_v1 @@ -44,8 +44,15 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type HealthClient interface { - // If the requested service is unknown, the call will fail with status - // NOT_FOUND. + // Check gets the health of the specified service. If the requested service + // is unknown, the call will fail with status NOT_FOUND. If the caller does + // not specify a service name, the server should respond with its overall + // health status. + // + // Clients should set a deadline when calling Check, and can declare the + // server unhealthy if they do not receive a timely response. + // + // Check implementations should be idempotent and side effect free. Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) // Performs a watch for the serving status of the requested service. // The server will immediately send back a message indicating the current @@ -118,8 +125,15 @@ func (x *healthWatchClient) Recv() (*HealthCheckResponse, error) { // All implementations should embed UnimplementedHealthServer // for forward compatibility type HealthServer interface { - // If the requested service is unknown, the call will fail with status - // NOT_FOUND. + // Check gets the health of the specified service. If the requested service + // is unknown, the call will fail with status NOT_FOUND. If the caller does + // not specify a service name, the server should respond with its overall + // health status. + // + // Clients should set a deadline when calling Check, and can declare the + // server unhealthy if they do not receive a timely response. + // + // Check implementations should be idempotent and side effect free. Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) // Performs a watch for the serving status of the requested service. // The server will immediately send back a message indicating the current diff --git a/vendor/google.golang.org/grpc/idle.go b/vendor/google.golang.org/grpc/idle.go deleted file mode 100644 index dc3dc72f..00000000 --- a/vendor/google.golang.org/grpc/idle.go +++ /dev/null @@ -1,287 +0,0 @@ -/* - * - * Copyright 2023 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 grpc - -import ( - "fmt" - "math" - "sync" - "sync/atomic" - "time" -) - -// For overriding in unit tests. -var timeAfterFunc = func(d time.Duration, f func()) *time.Timer { - return time.AfterFunc(d, f) -} - -// idlenessEnforcer is the functionality provided by grpc.ClientConn to enter -// and exit from idle mode. -type idlenessEnforcer interface { - exitIdleMode() error - enterIdleMode() error -} - -// idlenessManager defines the functionality required to track RPC activity on a -// channel. -type idlenessManager interface { - onCallBegin() error - onCallEnd() - close() -} - -type noopIdlenessManager struct{} - -func (noopIdlenessManager) onCallBegin() error { return nil } -func (noopIdlenessManager) onCallEnd() {} -func (noopIdlenessManager) close() {} - -// idlenessManagerImpl implements the idlenessManager interface. It uses atomic -// operations to synchronize access to shared state and a mutex to guarantee -// mutual exclusion in a critical section. -type idlenessManagerImpl struct { - // State accessed atomically. - lastCallEndTime int64 // Unix timestamp in nanos; time when the most recent RPC completed. - activeCallsCount int32 // Count of active RPCs; -math.MaxInt32 means channel is idle or is trying to get there. - activeSinceLastTimerCheck int32 // Boolean; True if there was an RPC since the last timer callback. - closed int32 // Boolean; True when the manager is closed. - - // Can be accessed without atomics or mutex since these are set at creation - // time and read-only after that. - enforcer idlenessEnforcer // Functionality provided by grpc.ClientConn. - timeout int64 // Idle timeout duration nanos stored as an int64. - - // idleMu is used to guarantee mutual exclusion in two scenarios: - // - Opposing intentions: - // - a: Idle timeout has fired and handleIdleTimeout() is trying to put - // the channel in idle mode because the channel has been inactive. - // - b: At the same time an RPC is made on the channel, and onCallBegin() - // is trying to prevent the channel from going idle. - // - Competing intentions: - // - The channel is in idle mode and there are multiple RPCs starting at - // the same time, all trying to move the channel out of idle. Only one - // of them should succeed in doing so, while the other RPCs should - // piggyback on the first one and be successfully handled. - idleMu sync.RWMutex - actuallyIdle bool - timer *time.Timer -} - -// newIdlenessManager creates a new idleness manager implementation for the -// given idle timeout. -func newIdlenessManager(enforcer idlenessEnforcer, idleTimeout time.Duration) idlenessManager { - if idleTimeout == 0 { - return noopIdlenessManager{} - } - - i := &idlenessManagerImpl{ - enforcer: enforcer, - timeout: int64(idleTimeout), - } - i.timer = timeAfterFunc(idleTimeout, i.handleIdleTimeout) - return i -} - -// resetIdleTimer resets the idle timer to the given duration. This method -// should only be called from the timer callback. -func (i *idlenessManagerImpl) resetIdleTimer(d time.Duration) { - i.idleMu.Lock() - defer i.idleMu.Unlock() - - if i.timer == nil { - // Only close sets timer to nil. We are done. - return - } - - // It is safe to ignore the return value from Reset() because this method is - // only ever called from the timer callback, which means the timer has - // already fired. - i.timer.Reset(d) -} - -// handleIdleTimeout is the timer callback that is invoked upon expiry of the -// configured idle timeout. The channel is considered inactive if there are no -// ongoing calls and no RPC activity since the last time the timer fired. -func (i *idlenessManagerImpl) handleIdleTimeout() { - if i.isClosed() { - return - } - - if atomic.LoadInt32(&i.activeCallsCount) > 0 { - i.resetIdleTimer(time.Duration(i.timeout)) - return - } - - // There has been activity on the channel since we last got here. Reset the - // timer and return. - if atomic.LoadInt32(&i.activeSinceLastTimerCheck) == 1 { - // Set the timer to fire after a duration of idle timeout, calculated - // from the time the most recent RPC completed. - atomic.StoreInt32(&i.activeSinceLastTimerCheck, 0) - i.resetIdleTimer(time.Duration(atomic.LoadInt64(&i.lastCallEndTime) + i.timeout - time.Now().UnixNano())) - return - } - - // This CAS operation is extremely likely to succeed given that there has - // been no activity since the last time we were here. Setting the - // activeCallsCount to -math.MaxInt32 indicates to onCallBegin() that the - // channel is either in idle mode or is trying to get there. - if !atomic.CompareAndSwapInt32(&i.activeCallsCount, 0, -math.MaxInt32) { - // This CAS operation can fail if an RPC started after we checked for - // activity at the top of this method, or one was ongoing from before - // the last time we were here. In both case, reset the timer and return. - i.resetIdleTimer(time.Duration(i.timeout)) - return - } - - // Now that we've set the active calls count to -math.MaxInt32, it's time to - // actually move to idle mode. - if i.tryEnterIdleMode() { - // Successfully entered idle mode. No timer needed until we exit idle. - return - } - - // Failed to enter idle mode due to a concurrent RPC that kept the channel - // active, or because of an error from the channel. Undo the attempt to - // enter idle, and reset the timer to try again later. - atomic.AddInt32(&i.activeCallsCount, math.MaxInt32) - i.resetIdleTimer(time.Duration(i.timeout)) -} - -// tryEnterIdleMode instructs the channel to enter idle mode. But before -// that, it performs a last minute check to ensure that no new RPC has come in, -// making the channel active. -// -// Return value indicates whether or not the channel moved to idle mode. -// -// Holds idleMu which ensures mutual exclusion with exitIdleMode. -func (i *idlenessManagerImpl) tryEnterIdleMode() bool { - i.idleMu.Lock() - defer i.idleMu.Unlock() - - if atomic.LoadInt32(&i.activeCallsCount) != -math.MaxInt32 { - // We raced and lost to a new RPC. Very rare, but stop entering idle. - return false - } - if atomic.LoadInt32(&i.activeSinceLastTimerCheck) == 1 { - // An very short RPC could have come in (and also finished) after we - // checked for calls count and activity in handleIdleTimeout(), but - // before the CAS operation. So, we need to check for activity again. - return false - } - - // No new RPCs have come in since we last set the active calls count value - // -math.MaxInt32 in the timer callback. And since we have the lock, it is - // safe to enter idle mode now. - if err := i.enforcer.enterIdleMode(); err != nil { - logger.Errorf("Failed to enter idle mode: %v", err) - return false - } - - // Successfully entered idle mode. - i.actuallyIdle = true - return true -} - -// onCallBegin is invoked at the start of every RPC. -func (i *idlenessManagerImpl) onCallBegin() error { - if i.isClosed() { - return nil - } - - if atomic.AddInt32(&i.activeCallsCount, 1) > 0 { - // Channel is not idle now. Set the activity bit and allow the call. - atomic.StoreInt32(&i.activeSinceLastTimerCheck, 1) - return nil - } - - // Channel is either in idle mode or is in the process of moving to idle - // mode. Attempt to exit idle mode to allow this RPC. - if err := i.exitIdleMode(); err != nil { - // Undo the increment to calls count, and return an error causing the - // RPC to fail. - atomic.AddInt32(&i.activeCallsCount, -1) - return err - } - - atomic.StoreInt32(&i.activeSinceLastTimerCheck, 1) - return nil -} - -// exitIdleMode instructs the channel to exit idle mode. -// -// Holds idleMu which ensures mutual exclusion with tryEnterIdleMode. -func (i *idlenessManagerImpl) exitIdleMode() error { - i.idleMu.Lock() - defer i.idleMu.Unlock() - - if !i.actuallyIdle { - // This can happen in two scenarios: - // - handleIdleTimeout() set the calls count to -math.MaxInt32 and called - // tryEnterIdleMode(). But before the latter could grab the lock, an RPC - // came in and onCallBegin() noticed that the calls count is negative. - // - Channel is in idle mode, and multiple new RPCs come in at the same - // time, all of them notice a negative calls count in onCallBegin and get - // here. The first one to get the lock would got the channel to exit idle. - // - // Either way, nothing to do here. - return nil - } - - if err := i.enforcer.exitIdleMode(); err != nil { - return fmt.Errorf("channel failed to exit idle mode: %v", err) - } - - // Undo the idle entry process. This also respects any new RPC attempts. - atomic.AddInt32(&i.activeCallsCount, math.MaxInt32) - i.actuallyIdle = false - - // Start a new timer to fire after the configured idle timeout. - i.timer = timeAfterFunc(time.Duration(i.timeout), i.handleIdleTimeout) - return nil -} - -// onCallEnd is invoked at the end of every RPC. -func (i *idlenessManagerImpl) onCallEnd() { - if i.isClosed() { - return - } - - // Record the time at which the most recent call finished. - atomic.StoreInt64(&i.lastCallEndTime, time.Now().UnixNano()) - - // Decrement the active calls count. This count can temporarily go negative - // when the timer callback is in the process of moving the channel to idle - // mode, but one or more RPCs come in and complete before the timer callback - // can get done with the process of moving to idle mode. - atomic.AddInt32(&i.activeCallsCount, -1) -} - -func (i *idlenessManagerImpl) isClosed() bool { - return atomic.LoadInt32(&i.closed) == 1 -} - -func (i *idlenessManagerImpl) close() { - atomic.StoreInt32(&i.closed, 1) - - i.idleMu.Lock() - i.timer.Stop() - i.timer = nil - i.idleMu.Unlock() -} diff --git a/vendor/google.golang.org/grpc/interceptor.go b/vendor/google.golang.org/grpc/interceptor.go index bb96ef57..877d78fc 100644 --- a/vendor/google.golang.org/grpc/interceptor.go +++ b/vendor/google.golang.org/grpc/interceptor.go @@ -23,7 +23,7 @@ import ( ) // UnaryInvoker is called by UnaryClientInterceptor to complete RPCs. -type UnaryInvoker func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error +type UnaryInvoker func(ctx context.Context, method string, req, reply any, cc *ClientConn, opts ...CallOption) error // UnaryClientInterceptor intercepts the execution of a unary RPC on the client. // Unary interceptors can be specified as a DialOption, using @@ -40,7 +40,7 @@ type UnaryInvoker func(ctx context.Context, method string, req, reply interface{ // defaults from the ClientConn as well as per-call options. // // The returned error must be compatible with the status package. -type UnaryClientInterceptor func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error +type UnaryClientInterceptor func(ctx context.Context, method string, req, reply any, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error // Streamer is called by StreamClientInterceptor to create a ClientStream. type Streamer func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) @@ -66,7 +66,7 @@ type StreamClientInterceptor func(ctx context.Context, desc *StreamDesc, cc *Cli // server side. All per-rpc information may be mutated by the interceptor. type UnaryServerInfo struct { // Server is the service implementation the user provides. This is read-only. - Server interface{} + Server any // FullMethod is the full RPC method string, i.e., /package.service/method. FullMethod string } @@ -78,13 +78,13 @@ type UnaryServerInfo struct { // status package, or be one of the context errors. Otherwise, gRPC will use // codes.Unknown as the status code and err.Error() as the status message of the // RPC. -type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error) +type UnaryHandler func(ctx context.Context, req any) (any, error) // UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info // contains all the information of this RPC the interceptor can operate on. And handler is the wrapper // of the service method implementation. It is the responsibility of the interceptor to invoke handler // to complete the RPC. -type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error) +type UnaryServerInterceptor func(ctx context.Context, req any, info *UnaryServerInfo, handler UnaryHandler) (resp any, err error) // StreamServerInfo consists of various information about a streaming RPC on // server side. All per-rpc information may be mutated by the interceptor. @@ -101,4 +101,4 @@ type StreamServerInfo struct { // info contains all the information of this RPC the interceptor can operate on. And handler is the // service method implementation. It is the responsibility of the interceptor to invoke handler to // complete the RPC. -type StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error +type StreamServerInterceptor func(srv any, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error diff --git a/vendor/google.golang.org/grpc/internal/backoff/backoff.go b/vendor/google.golang.org/grpc/internal/backoff/backoff.go index 5fc0ee3d..fed1c011 100644 --- a/vendor/google.golang.org/grpc/internal/backoff/backoff.go +++ b/vendor/google.golang.org/grpc/internal/backoff/backoff.go @@ -23,6 +23,8 @@ package backoff import ( + "context" + "errors" "time" grpcbackoff "google.golang.org/grpc/backoff" @@ -71,3 +73,37 @@ func (bc Exponential) Backoff(retries int) time.Duration { } return time.Duration(backoff) } + +// ErrResetBackoff is the error to be returned by the function executed by RunF, +// to instruct the latter to reset its backoff state. +var ErrResetBackoff = errors.New("reset backoff state") + +// RunF provides a convenient way to run a function f repeatedly until the +// context expires or f returns a non-nil error that is not ErrResetBackoff. +// When f returns ErrResetBackoff, RunF continues to run f, but resets its +// backoff state before doing so. backoff accepts an integer representing the +// number of retries, and returns the amount of time to backoff. +func RunF(ctx context.Context, f func() error, backoff func(int) time.Duration) { + attempt := 0 + timer := time.NewTimer(0) + for ctx.Err() == nil { + select { + case <-timer.C: + case <-ctx.Done(): + timer.Stop() + return + } + + err := f() + if errors.Is(err, ErrResetBackoff) { + timer.Reset(0) + attempt = 0 + continue + } + if err != nil { + return + } + timer.Reset(backoff(attempt)) + attempt++ + } +} diff --git a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go new file mode 100644 index 00000000..6bf7f873 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go @@ -0,0 +1,83 @@ +/* + * + * Copyright 2024 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 gracefulswitch + +import ( + "encoding/json" + "fmt" + + "google.golang.org/grpc/balancer" + "google.golang.org/grpc/serviceconfig" +) + +type lbConfig struct { + serviceconfig.LoadBalancingConfig + + childBuilder balancer.Builder + childConfig serviceconfig.LoadBalancingConfig +} + +func ChildName(l serviceconfig.LoadBalancingConfig) string { + return l.(*lbConfig).childBuilder.Name() +} + +// ParseConfig parses a child config list and returns a LB config for the +// gracefulswitch Balancer. +// +// cfg is expected to be a json.RawMessage containing a JSON array of LB policy +// names + configs as the format of the "loadBalancingConfig" field in +// ServiceConfig. It returns a type that should be passed to +// UpdateClientConnState in the BalancerConfig field. +func ParseConfig(cfg json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { + var lbCfg []map[string]json.RawMessage + if err := json.Unmarshal(cfg, &lbCfg); err != nil { + return nil, err + } + for i, e := range lbCfg { + if len(e) != 1 { + return nil, fmt.Errorf("expected a JSON struct with one entry; received entry %v at index %d", e, i) + } + + var name string + var jsonCfg json.RawMessage + for name, jsonCfg = range e { + } + + builder := balancer.Get(name) + if builder == nil { + // Skip unregistered balancer names. + continue + } + + parser, ok := builder.(balancer.ConfigParser) + if !ok { + // This is a valid child with no config. + return &lbConfig{childBuilder: builder}, nil + } + + cfg, err := parser.ParseConfig(jsonCfg) + if err != nil { + return nil, fmt.Errorf("error parsing config for policy %q: %v", name, err) + } + + return &lbConfig{childBuilder: builder, childConfig: cfg}, nil + } + + return nil, fmt.Errorf("no supported policies found in config: %v", string(cfg)) +} diff --git a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go index 08666f62..45d5e50e 100644 --- a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go +++ b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go @@ -94,14 +94,23 @@ func (gsb *Balancer) balancerCurrentOrPending(bw *balancerWrapper) bool { // process is not complete when this method returns. This method must be called // synchronously alongside the rest of the balancer.Balancer methods this // Graceful Switch Balancer implements. +// +// Deprecated: use ParseConfig and pass a parsed config to UpdateClientConnState +// to cause the Balancer to automatically change to the new child when necessary. func (gsb *Balancer) SwitchTo(builder balancer.Builder) error { + _, err := gsb.switchTo(builder) + return err +} + +func (gsb *Balancer) switchTo(builder balancer.Builder) (*balancerWrapper, error) { gsb.mu.Lock() if gsb.closed { gsb.mu.Unlock() - return errBalancerClosed + return nil, errBalancerClosed } bw := &balancerWrapper{ - gsb: gsb, + builder: builder, + gsb: gsb, lastState: balancer.State{ ConnectivityState: connectivity.Connecting, Picker: base.NewErrPicker(balancer.ErrNoSubConnAvailable), @@ -129,7 +138,7 @@ func (gsb *Balancer) SwitchTo(builder balancer.Builder) error { gsb.balancerCurrent = nil } gsb.mu.Unlock() - return balancer.ErrBadResolverState + return nil, balancer.ErrBadResolverState } // This write doesn't need to take gsb.mu because this field never gets read @@ -138,7 +147,7 @@ func (gsb *Balancer) SwitchTo(builder balancer.Builder) error { // bw.Balancer field will never be forwarded to until this SwitchTo() // function returns. bw.Balancer = newBalancer - return nil + return bw, nil } // Returns nil if the graceful switch balancer is closed. @@ -152,12 +161,33 @@ func (gsb *Balancer) latestBalancer() *balancerWrapper { } // UpdateClientConnState forwards the update to the latest balancer created. +// +// If the state's BalancerConfig is the config returned by a call to +// gracefulswitch.ParseConfig, then this function will automatically SwitchTo +// the balancer indicated by the config before forwarding its config to it, if +// necessary. func (gsb *Balancer) UpdateClientConnState(state balancer.ClientConnState) error { // The resolver data is only relevant to the most recent LB Policy. balToUpdate := gsb.latestBalancer() + + gsbCfg, ok := state.BalancerConfig.(*lbConfig) + if ok { + // Switch to the child in the config unless it is already active. + if balToUpdate == nil || gsbCfg.childBuilder.Name() != balToUpdate.builder.Name() { + var err error + balToUpdate, err = gsb.switchTo(gsbCfg.childBuilder) + if err != nil { + return fmt.Errorf("could not switch to new child balancer: %w", err) + } + } + // Unwrap the child balancer's config. + state.BalancerConfig = gsbCfg.childConfig + } + if balToUpdate == nil { return errBalancerClosed } + // Perform this call without gsb.mu to prevent deadlocks if the child calls // back into the channel. The latest balancer can never be closed during a // call from the channel, even without gsb.mu held. @@ -169,6 +199,10 @@ func (gsb *Balancer) ResolverError(err error) { // The resolver data is only relevant to the most recent LB Policy. balToUpdate := gsb.latestBalancer() if balToUpdate == nil { + gsb.cc.UpdateState(balancer.State{ + ConnectivityState: connectivity.TransientFailure, + Picker: base.NewErrPicker(err), + }) return } // Perform this call without gsb.mu to prevent deadlocks if the child calls @@ -200,8 +234,8 @@ func (gsb *Balancer) ExitIdle() { } } -// UpdateSubConnState forwards the update to the appropriate child. -func (gsb *Balancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { +// updateSubConnState forwards the update to the appropriate child. +func (gsb *Balancer) updateSubConnState(sc balancer.SubConn, state balancer.SubConnState, cb func(balancer.SubConnState)) { gsb.currentMu.Lock() defer gsb.currentMu.Unlock() gsb.mu.Lock() @@ -214,13 +248,26 @@ func (gsb *Balancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubC } else if gsb.balancerPending != nil && gsb.balancerPending.subconns[sc] { balToUpdate = gsb.balancerPending } - gsb.mu.Unlock() if balToUpdate == nil { // SubConn belonged to a stale lb policy that has not yet fully closed, // or the balancer was already closed. + gsb.mu.Unlock() return } - balToUpdate.UpdateSubConnState(sc, state) + if state.ConnectivityState == connectivity.Shutdown { + delete(balToUpdate.subconns, sc) + } + gsb.mu.Unlock() + if cb != nil { + cb(state) + } else { + balToUpdate.UpdateSubConnState(sc, state) + } +} + +// UpdateSubConnState forwards the update to the appropriate child. +func (gsb *Balancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { + gsb.updateSubConnState(sc, state, nil) } // Close closes any active child balancers. @@ -242,33 +289,23 @@ func (gsb *Balancer) Close() { // // It implements the balancer.ClientConn interface and is passed down in that // capacity to the wrapped balancer. It maintains a set of subConns created by -// the wrapped balancer and calls from the latter to create/update/remove +// the wrapped balancer and calls from the latter to create/update/shutdown // SubConns update this set before being forwarded to the parent ClientConn. // State updates from the wrapped balancer can result in invocation of the // graceful switch logic. type balancerWrapper struct { balancer.Balancer - gsb *Balancer + gsb *Balancer + builder balancer.Builder lastState balancer.State subconns map[balancer.SubConn]bool // subconns created by this balancer } -func (bw *balancerWrapper) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { - if state.ConnectivityState == connectivity.Shutdown { - bw.gsb.mu.Lock() - delete(bw.subconns, sc) - bw.gsb.mu.Unlock() - } - // There is no need to protect this read with a mutex, as the write to the - // Balancer field happens in SwitchTo, which completes before this can be - // called. - bw.Balancer.UpdateSubConnState(sc, state) -} - -// Close closes the underlying LB policy and removes the subconns it created. bw -// must not be referenced via balancerCurrent or balancerPending in gsb when -// called. gsb.mu must not be held. Does not panic with a nil receiver. +// Close closes the underlying LB policy and shuts down the subconns it +// created. bw must not be referenced via balancerCurrent or balancerPending in +// gsb when called. gsb.mu must not be held. Does not panic with a nil +// receiver. func (bw *balancerWrapper) Close() { // before Close is called. if bw == nil { @@ -281,7 +318,7 @@ func (bw *balancerWrapper) Close() { bw.Balancer.Close() bw.gsb.mu.Lock() for sc := range bw.subconns { - bw.gsb.cc.RemoveSubConn(sc) + sc.Shutdown() } bw.gsb.mu.Unlock() } @@ -335,13 +372,16 @@ func (bw *balancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.Ne } bw.gsb.mu.Unlock() + var sc balancer.SubConn + oldListener := opts.StateListener + opts.StateListener = func(state balancer.SubConnState) { bw.gsb.updateSubConnState(sc, state, oldListener) } sc, err := bw.gsb.cc.NewSubConn(addrs, opts) if err != nil { return nil, err } bw.gsb.mu.Lock() if !bw.gsb.balancerCurrentOrPending(bw) { // balancer was closed during this call - bw.gsb.cc.RemoveSubConn(sc) + sc.Shutdown() bw.gsb.mu.Unlock() return nil, fmt.Errorf("%T at address %p that called NewSubConn is deleted", bw, bw) } @@ -360,13 +400,9 @@ func (bw *balancerWrapper) ResolveNow(opts resolver.ResolveNowOptions) { } func (bw *balancerWrapper) RemoveSubConn(sc balancer.SubConn) { - bw.gsb.mu.Lock() - if !bw.gsb.balancerCurrentOrPending(bw) { - bw.gsb.mu.Unlock() - return - } - bw.gsb.mu.Unlock() - bw.gsb.cc.RemoveSubConn(sc) + // Note: existing third party balancers may call this, so it must remain + // until RemoveSubConn is fully removed. + sc.Shutdown() } func (bw *balancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) { diff --git a/vendor/google.golang.org/grpc/internal/balancerload/load.go b/vendor/google.golang.org/grpc/internal/balancerload/load.go index 3a905d96..94a08d68 100644 --- a/vendor/google.golang.org/grpc/internal/balancerload/load.go +++ b/vendor/google.golang.org/grpc/internal/balancerload/load.go @@ -25,7 +25,7 @@ import ( // Parser converts loads from metadata into a concrete type. type Parser interface { // Parse parses loads from metadata. - Parse(md metadata.MD) interface{} + Parse(md metadata.MD) any } var parser Parser @@ -38,7 +38,7 @@ func SetParser(lr Parser) { } // Parse calls parser.Read(). -func Parse(md metadata.MD) interface{} { +func Parse(md metadata.MD) any { if parser == nil { return nil } diff --git a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go index 6c3f6322..e8456a77 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go @@ -25,11 +25,12 @@ import ( "sync/atomic" "time" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" binlogpb "google.golang.org/grpc/binarylog/grpc_binarylog_v1" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/timestamppb" ) type callIDGenerator struct { @@ -88,7 +89,7 @@ func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger { // in TruncatingMethodLogger as possible. func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *binlogpb.GrpcLogEntry { m := c.toProto() - timestamp, _ := ptypes.TimestampProto(time.Now()) + timestamp := timestamppb.Now() m.Timestamp = timestamp m.CallId = ml.callID m.SequenceIdWithinCall = ml.idWithinCallGen.next() @@ -178,7 +179,7 @@ func (c *ClientHeader) toProto() *binlogpb.GrpcLogEntry { Authority: c.Authority, } if c.Timeout > 0 { - clientHeader.Timeout = ptypes.DurationProto(c.Timeout) + clientHeader.Timeout = durationpb.New(c.Timeout) } ret := &binlogpb.GrpcLogEntry{ Type: binlogpb.GrpcLogEntry_EVENT_TYPE_CLIENT_HEADER, @@ -230,7 +231,7 @@ type ClientMessage struct { OnClientSide bool // Message can be a proto.Message or []byte. Other messages formats are not // supported. - Message interface{} + Message any } func (c *ClientMessage) toProto() *binlogpb.GrpcLogEntry { @@ -270,7 +271,7 @@ type ServerMessage struct { OnClientSide bool // Message can be a proto.Message or []byte. Other messages formats are not // supported. - Message interface{} + Message any } func (c *ServerMessage) toProto() *binlogpb.GrpcLogEntry { diff --git a/vendor/google.golang.org/grpc/internal/binarylog/sink.go b/vendor/google.golang.org/grpc/internal/binarylog/sink.go index 264de387..9ea598b1 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/sink.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/sink.go @@ -25,8 +25,8 @@ import ( "sync" "time" - "github.com/golang/protobuf/proto" binlogpb "google.golang.org/grpc/binarylog/grpc_binarylog_v1" + "google.golang.org/protobuf/proto" ) var ( diff --git a/vendor/google.golang.org/grpc/internal/buffer/unbounded.go b/vendor/google.golang.org/grpc/internal/buffer/unbounded.go index 81c2f5fd..11f91668 100644 --- a/vendor/google.golang.org/grpc/internal/buffer/unbounded.go +++ b/vendor/google.golang.org/grpc/internal/buffer/unbounded.go @@ -18,7 +18,10 @@ // Package buffer provides an implementation of an unbounded buffer. package buffer -import "sync" +import ( + "errors" + "sync" +) // Unbounded is an implementation of an unbounded buffer which does not use // extra goroutines. This is typically used for passing updates from one entity @@ -28,49 +31,50 @@ import "sync" // the underlying mutex used for synchronization. // // Unbounded supports values of any type to be stored in it by using a channel -// of `interface{}`. 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 +// 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 interface{} + c chan any closed bool + closing bool mu sync.Mutex - backlog []interface{} + backlog []any } // NewUnbounded returns a new instance of Unbounded. func NewUnbounded() *Unbounded { - return &Unbounded{c: make(chan interface{}, 1)} + return &Unbounded{c: make(chan any, 1)} } +var errBufferClosed = errors.New("Put called on closed buffer.Unbounded") + // Put adds t to the unbounded buffer. -func (b *Unbounded) Put(t interface{}) { +func (b *Unbounded) Put(t any) error { b.mu.Lock() defer b.mu.Unlock() - if b.closed { - return + if b.closing { + return errBufferClosed } if len(b.backlog) == 0 { select { case b.c <- t: - return + return nil default: } } b.backlog = append(b.backlog, t) + return nil } -// Load sends the earliest buffered data, if any, onto the read channel -// returned by Get(). Users are expected to call this every time they read a +// 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() { b.mu.Lock() defer b.mu.Unlock() - if b.closed { - return - } if len(b.backlog) > 0 { select { case b.c <- b.backlog[0]: @@ -78,6 +82,8 @@ func (b *Unbounded) Load() { b.backlog = b.backlog[1:] default: } + } else if b.closing && !b.closed { + close(b.c) } } @@ -88,18 +94,23 @@ func (b *Unbounded) Load() { // send the next buffered value onto the channel if there is any. // // If the unbounded buffer is closed, the read channel returned by this method -// is closed. -func (b *Unbounded) Get() <-chan interface{} { +// is closed after all data is drained. +func (b *Unbounded) Get() <-chan any { return b.c } -// Close closes the unbounded buffer. +// 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() { b.mu.Lock() defer b.mu.Unlock() - if b.closed { + if b.closing { return } - b.closed = true - close(b.c) + b.closing = true + if len(b.backlog) == 0 { + b.closed = true + close(b.c) + } } diff --git a/vendor/google.golang.org/grpc/internal/channelz/channel.go b/vendor/google.golang.org/grpc/internal/channelz/channel.go new file mode 100644 index 00000000..d7e9e1d5 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/channel.go @@ -0,0 +1,255 @@ +/* + * + * Copyright 2024 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 channelz + +import ( + "fmt" + "sync/atomic" + + "google.golang.org/grpc/connectivity" +) + +// Channel represents a channel within channelz, which includes metrics and +// internal channelz data, such as channelz id, child list, etc. +type Channel struct { + Entity + // ID is the channelz id of this channel. + ID int64 + // RefName is the human readable reference string of this channel. + RefName string + + closeCalled bool + nestedChans map[int64]string + subChans map[int64]string + Parent *Channel + trace *ChannelTrace + // traceRefCount is the number of trace events that reference this channel. + // Non-zero traceRefCount means the trace of this channel cannot be deleted. + traceRefCount int32 + + ChannelMetrics ChannelMetrics +} + +// Implemented to make Channel implement the Identifier interface used for +// nesting. +func (c *Channel) channelzIdentifier() {} + +func (c *Channel) String() string { + if c.Parent == nil { + return fmt.Sprintf("Channel #%d", c.ID) + } + return fmt.Sprintf("%s Channel #%d", c.Parent, c.ID) +} + +func (c *Channel) id() int64 { + return c.ID +} + +func (c *Channel) SubChans() map[int64]string { + db.mu.RLock() + defer db.mu.RUnlock() + return copyMap(c.subChans) +} + +func (c *Channel) NestedChans() map[int64]string { + db.mu.RLock() + defer db.mu.RUnlock() + return copyMap(c.nestedChans) +} + +func (c *Channel) Trace() *ChannelTrace { + db.mu.RLock() + defer db.mu.RUnlock() + return c.trace.copy() +} + +type ChannelMetrics struct { + // The current connectivity state of the channel. + State atomic.Pointer[connectivity.State] + // The target this channel originally tried to connect to. May be absent + Target atomic.Pointer[string] + // The number of calls started on the channel. + CallsStarted atomic.Int64 + // The number of calls that have completed with an OK status. + CallsSucceeded atomic.Int64 + // The number of calls that have a completed with a non-OK status. + CallsFailed atomic.Int64 + // The last time a call was started on the channel. + LastCallStartedTimestamp atomic.Int64 +} + +// CopyFrom copies the metrics in o to c. For testing only. +func (c *ChannelMetrics) CopyFrom(o *ChannelMetrics) { + c.State.Store(o.State.Load()) + c.Target.Store(o.Target.Load()) + c.CallsStarted.Store(o.CallsStarted.Load()) + c.CallsSucceeded.Store(o.CallsSucceeded.Load()) + c.CallsFailed.Store(o.CallsFailed.Load()) + c.LastCallStartedTimestamp.Store(o.LastCallStartedTimestamp.Load()) +} + +// Equal returns true iff the metrics of c are the same as the metrics of o. +// For testing only. +func (c *ChannelMetrics) Equal(o any) bool { + oc, ok := o.(*ChannelMetrics) + if !ok { + return false + } + if (c.State.Load() == nil) != (oc.State.Load() == nil) { + return false + } + if c.State.Load() != nil && *c.State.Load() != *oc.State.Load() { + return false + } + if (c.Target.Load() == nil) != (oc.Target.Load() == nil) { + return false + } + if c.Target.Load() != nil && *c.Target.Load() != *oc.Target.Load() { + return false + } + return c.CallsStarted.Load() == oc.CallsStarted.Load() && + c.CallsFailed.Load() == oc.CallsFailed.Load() && + c.CallsSucceeded.Load() == oc.CallsSucceeded.Load() && + c.LastCallStartedTimestamp.Load() == oc.LastCallStartedTimestamp.Load() +} + +func strFromPointer(s *string) string { + if s == nil { + return "" + } + return *s +} + +func (c *ChannelMetrics) String() string { + return fmt.Sprintf("State: %v, Target: %s, CallsStarted: %v, CallsSucceeded: %v, CallsFailed: %v, LastCallStartedTimestamp: %v", + c.State.Load(), strFromPointer(c.Target.Load()), c.CallsStarted.Load(), c.CallsSucceeded.Load(), c.CallsFailed.Load(), c.LastCallStartedTimestamp.Load(), + ) +} + +func NewChannelMetricForTesting(state connectivity.State, target string, started, succeeded, failed, timestamp int64) *ChannelMetrics { + c := &ChannelMetrics{} + c.State.Store(&state) + c.Target.Store(&target) + c.CallsStarted.Store(started) + c.CallsSucceeded.Store(succeeded) + c.CallsFailed.Store(failed) + c.LastCallStartedTimestamp.Store(timestamp) + return c +} + +func (c *Channel) addChild(id int64, e entry) { + switch v := e.(type) { + case *SubChannel: + c.subChans[id] = v.RefName + case *Channel: + c.nestedChans[id] = v.RefName + default: + logger.Errorf("cannot add a child (id = %d) of type %T to a channel", id, e) + } +} + +func (c *Channel) deleteChild(id int64) { + delete(c.subChans, id) + delete(c.nestedChans, id) + c.deleteSelfIfReady() +} + +func (c *Channel) triggerDelete() { + c.closeCalled = true + c.deleteSelfIfReady() +} + +func (c *Channel) getParentID() int64 { + if c.Parent == nil { + return -1 + } + return c.Parent.ID +} + +// deleteSelfFromTree tries to delete the channel from the channelz entry relation tree, which means +// deleting the channel reference from its parent's child list. +// +// In order for a channel to be deleted from the tree, it must meet the criteria that, removal of the +// corresponding grpc object has been invoked, and the channel does not have any children left. +// +// The returned boolean value indicates whether the channel has been successfully deleted from tree. +func (c *Channel) deleteSelfFromTree() (deleted bool) { + if !c.closeCalled || len(c.subChans)+len(c.nestedChans) != 0 { + return false + } + // not top channel + if c.Parent != nil { + c.Parent.deleteChild(c.ID) + } + return true +} + +// deleteSelfFromMap checks whether it is valid to delete the channel from the map, which means +// deleting the channel from channelz's tracking entirely. Users can no longer use id to query the +// channel, and its memory will be garbage collected. +// +// The trace reference count of the channel must be 0 in order to be deleted from the map. This is +// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, +// the trace of the referenced entity must not be deleted. In order to release the resource allocated +// by grpc, the reference to the grpc object is reset to a dummy object. +// +// deleteSelfFromMap must be called after deleteSelfFromTree returns true. +// +// It returns a bool to indicate whether the channel can be safely deleted from map. +func (c *Channel) deleteSelfFromMap() (delete bool) { + return c.getTraceRefCount() == 0 +} + +// deleteSelfIfReady tries to delete the channel itself from the channelz database. +// The delete process includes two steps: +// 1. delete the channel from the entry relation tree, i.e. delete the channel reference from its +// parent's child list. +// 2. delete the channel from the map, i.e. delete the channel entirely from channelz. Lookup by id +// will return entry not found error. +func (c *Channel) deleteSelfIfReady() { + if !c.deleteSelfFromTree() { + return + } + if !c.deleteSelfFromMap() { + return + } + db.deleteEntry(c.ID) + c.trace.clear() +} + +func (c *Channel) getChannelTrace() *ChannelTrace { + return c.trace +} + +func (c *Channel) incrTraceRefCount() { + atomic.AddInt32(&c.traceRefCount, 1) +} + +func (c *Channel) decrTraceRefCount() { + atomic.AddInt32(&c.traceRefCount, -1) +} + +func (c *Channel) getTraceRefCount() int { + i := atomic.LoadInt32(&c.traceRefCount) + return int(i) +} + +func (c *Channel) getRefName() string { + return c.RefName +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/channelmap.go b/vendor/google.golang.org/grpc/internal/channelz/channelmap.go new file mode 100644 index 00000000..dfe18b08 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/channelmap.go @@ -0,0 +1,402 @@ +/* + * + * Copyright 2018 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 channelz + +import ( + "fmt" + "sort" + "sync" + "time" +) + +// entry represents a node in the channelz database. +type entry interface { + // addChild adds a child e, whose channelz id is id to child list + addChild(id int64, e entry) + // deleteChild deletes a child with channelz id to be id from child list + deleteChild(id int64) + // triggerDelete tries to delete self from channelz database. However, if + // child list is not empty, then deletion from the database is on hold until + // the last child is deleted from database. + triggerDelete() + // deleteSelfIfReady check whether triggerDelete() has been called before, + // and whether child list is now empty. If both conditions are met, then + // delete self from database. + deleteSelfIfReady() + // getParentID returns parent ID of the entry. 0 value parent ID means no parent. + getParentID() int64 + Entity +} + +// channelMap is the storage data structure for channelz. +// +// Methods of channelMap can be divided in two two categories with respect to +// locking. +// +// 1. Methods acquire the global lock. +// 2. Methods that can only be called when global lock is held. +// +// A second type of method need always to be called inside a first type of method. +type channelMap struct { + mu sync.RWMutex + topLevelChannels map[int64]struct{} + channels map[int64]*Channel + subChannels map[int64]*SubChannel + sockets map[int64]*Socket + servers map[int64]*Server +} + +func newChannelMap() *channelMap { + return &channelMap{ + topLevelChannels: make(map[int64]struct{}), + channels: make(map[int64]*Channel), + subChannels: make(map[int64]*SubChannel), + sockets: make(map[int64]*Socket), + servers: make(map[int64]*Server), + } +} + +func (c *channelMap) addServer(id int64, s *Server) { + c.mu.Lock() + defer c.mu.Unlock() + s.cm = c + c.servers[id] = s +} + +func (c *channelMap) addChannel(id int64, cn *Channel, isTopChannel bool, pid int64) { + c.mu.Lock() + defer c.mu.Unlock() + cn.trace.cm = c + c.channels[id] = cn + if isTopChannel { + c.topLevelChannels[id] = struct{}{} + } else if p := c.channels[pid]; p != nil { + p.addChild(id, cn) + } else { + logger.Infof("channel %d references invalid parent ID %d", id, pid) + } +} + +func (c *channelMap) addSubChannel(id int64, sc *SubChannel, pid int64) { + c.mu.Lock() + defer c.mu.Unlock() + sc.trace.cm = c + c.subChannels[id] = sc + if p := c.channels[pid]; p != nil { + p.addChild(id, sc) + } else { + logger.Infof("subchannel %d references invalid parent ID %d", id, pid) + } +} + +func (c *channelMap) addSocket(s *Socket) { + c.mu.Lock() + defer c.mu.Unlock() + s.cm = c + c.sockets[s.ID] = s + if s.Parent == nil { + logger.Infof("normal socket %d has no parent", s.ID) + } + s.Parent.(entry).addChild(s.ID, s) +} + +// removeEntry triggers the removal of an entry, which may not indeed delete the +// entry, if it has to wait on the deletion of its children and until no other +// entity's channel trace references it. It may lead to a chain of entry +// deletion. For example, deleting the last socket of a gracefully shutting down +// server will lead to the server being also deleted. +func (c *channelMap) removeEntry(id int64) { + c.mu.Lock() + defer c.mu.Unlock() + c.findEntry(id).triggerDelete() +} + +// tracedChannel represents tracing operations which are present on both +// channels and subChannels. +type tracedChannel interface { + getChannelTrace() *ChannelTrace + incrTraceRefCount() + decrTraceRefCount() + getRefName() string +} + +// c.mu must be held by the caller +func (c *channelMap) decrTraceRefCount(id int64) { + e := c.findEntry(id) + if v, ok := e.(tracedChannel); ok { + v.decrTraceRefCount() + e.deleteSelfIfReady() + } +} + +// c.mu must be held by the caller. +func (c *channelMap) findEntry(id int64) entry { + if v, ok := c.channels[id]; ok { + return v + } + if v, ok := c.subChannels[id]; ok { + return v + } + if v, ok := c.servers[id]; ok { + return v + } + if v, ok := c.sockets[id]; ok { + return v + } + return &dummyEntry{idNotFound: id} +} + +// c.mu must be held by the caller +// +// deleteEntry deletes an entry from the channelMap. Before calling this method, +// caller must check this entry is ready to be deleted, i.e removeEntry() has +// been called on it, and no children still exist. +func (c *channelMap) deleteEntry(id int64) entry { + if v, ok := c.sockets[id]; ok { + delete(c.sockets, id) + return v + } + if v, ok := c.subChannels[id]; ok { + delete(c.subChannels, id) + return v + } + if v, ok := c.channels[id]; ok { + delete(c.channels, id) + delete(c.topLevelChannels, id) + return v + } + if v, ok := c.servers[id]; ok { + delete(c.servers, id) + return v + } + return &dummyEntry{idNotFound: id} +} + +func (c *channelMap) traceEvent(id int64, desc *TraceEvent) { + c.mu.Lock() + defer c.mu.Unlock() + child := c.findEntry(id) + childTC, ok := child.(tracedChannel) + if !ok { + return + } + childTC.getChannelTrace().append(&traceEvent{Desc: desc.Desc, Severity: desc.Severity, Timestamp: time.Now()}) + if desc.Parent != nil { + parent := c.findEntry(child.getParentID()) + var chanType RefChannelType + switch child.(type) { + case *Channel: + chanType = RefChannel + case *SubChannel: + chanType = RefSubChannel + } + if parentTC, ok := parent.(tracedChannel); ok { + parentTC.getChannelTrace().append(&traceEvent{ + Desc: desc.Parent.Desc, + Severity: desc.Parent.Severity, + Timestamp: time.Now(), + RefID: id, + RefName: childTC.getRefName(), + RefType: chanType, + }) + childTC.incrTraceRefCount() + } + } +} + +type int64Slice []int64 + +func (s int64Slice) Len() int { return len(s) } +func (s int64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s int64Slice) Less(i, j int) bool { return s[i] < s[j] } + +func copyMap(m map[int64]string) map[int64]string { + n := make(map[int64]string) + for k, v := range m { + n[k] = v + } + return n +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func (c *channelMap) getTopChannels(id int64, maxResults int) ([]*Channel, bool) { + if maxResults <= 0 { + maxResults = EntriesPerPage + } + c.mu.RLock() + defer c.mu.RUnlock() + l := int64(len(c.topLevelChannels)) + ids := make([]int64, 0, l) + + for k := range c.topLevelChannels { + ids = append(ids, k) + } + sort.Sort(int64Slice(ids)) + idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) + end := true + var t []*Channel + for _, v := range ids[idx:] { + if len(t) == maxResults { + end = false + break + } + if cn, ok := c.channels[v]; ok { + t = append(t, cn) + } + } + return t, end +} + +func (c *channelMap) getServers(id int64, maxResults int) ([]*Server, bool) { + if maxResults <= 0 { + maxResults = EntriesPerPage + } + c.mu.RLock() + defer c.mu.RUnlock() + ids := make([]int64, 0, len(c.servers)) + for k := range c.servers { + ids = append(ids, k) + } + sort.Sort(int64Slice(ids)) + idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) + end := true + var s []*Server + for _, v := range ids[idx:] { + if len(s) == maxResults { + end = false + break + } + if svr, ok := c.servers[v]; ok { + s = append(s, svr) + } + } + return s, end +} + +func (c *channelMap) getServerSockets(id int64, startID int64, maxResults int) ([]*Socket, bool) { + if maxResults <= 0 { + maxResults = EntriesPerPage + } + c.mu.RLock() + defer c.mu.RUnlock() + svr, ok := c.servers[id] + if !ok { + // server with id doesn't exist. + return nil, true + } + svrskts := svr.sockets + ids := make([]int64, 0, len(svrskts)) + sks := make([]*Socket, 0, min(len(svrskts), maxResults)) + for k := range svrskts { + ids = append(ids, k) + } + sort.Sort(int64Slice(ids)) + idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= startID }) + end := true + for _, v := range ids[idx:] { + if len(sks) == maxResults { + end = false + break + } + if ns, ok := c.sockets[v]; ok { + sks = append(sks, ns) + } + } + return sks, end +} + +func (c *channelMap) getChannel(id int64) *Channel { + c.mu.RLock() + defer c.mu.RUnlock() + return c.channels[id] +} + +func (c *channelMap) getSubChannel(id int64) *SubChannel { + c.mu.RLock() + defer c.mu.RUnlock() + return c.subChannels[id] +} + +func (c *channelMap) getSocket(id int64) *Socket { + c.mu.RLock() + defer c.mu.RUnlock() + return c.sockets[id] +} + +func (c *channelMap) getServer(id int64) *Server { + c.mu.RLock() + defer c.mu.RUnlock() + return c.servers[id] +} + +type dummyEntry struct { + // dummyEntry is a fake entry to handle entry not found case. + idNotFound int64 + Entity +} + +func (d *dummyEntry) String() string { + return fmt.Sprintf("non-existent entity #%d", d.idNotFound) +} + +func (d *dummyEntry) ID() int64 { return d.idNotFound } + +func (d *dummyEntry) addChild(id int64, e entry) { + // Note: It is possible for a normal program to reach here under race + // condition. For example, there could be a race between ClientConn.Close() + // info being propagated to addrConn and http2Client. ClientConn.Close() + // cancel the context and result in http2Client to error. The error info is + // then caught by transport monitor and before addrConn.tearDown() is called + // in side ClientConn.Close(). Therefore, the addrConn will create a new + // transport. And when registering the new transport in channelz, its parent + // addrConn could have already been torn down and deleted from channelz + // tracking, and thus reach the code here. + logger.Infof("attempt to add child of type %T with id %d to a parent (id=%d) that doesn't currently exist", e, id, d.idNotFound) +} + +func (d *dummyEntry) deleteChild(id int64) { + // It is possible for a normal program to reach here under race condition. + // Refer to the example described in addChild(). + logger.Infof("attempt to delete child with id %d from a parent (id=%d) that doesn't currently exist", id, d.idNotFound) +} + +func (d *dummyEntry) triggerDelete() { + logger.Warningf("attempt to delete an entry (id=%d) that doesn't currently exist", d.idNotFound) +} + +func (*dummyEntry) deleteSelfIfReady() { + // code should not reach here. deleteSelfIfReady is always called on an existing entry. +} + +func (*dummyEntry) getParentID() int64 { + return 0 +} + +// Entity is implemented by all channelz types. +type Entity interface { + isEntity() + fmt.Stringer + id() int64 +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/funcs.go b/vendor/google.golang.org/grpc/internal/channelz/funcs.go index 777cbcd7..03e24e15 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/funcs.go +++ b/vendor/google.golang.org/grpc/internal/channelz/funcs.go @@ -16,132 +16,54 @@ * */ -// Package channelz defines APIs for enabling channelz service, entry +// Package channelz defines internal APIs for enabling channelz service, entry // registration/deletion, and accessing channelz data. It also defines channelz // metric struct formats. -// -// All APIs in this package are experimental. package channelz import ( - "context" - "errors" - "fmt" - "sort" - "sync" "sync/atomic" "time" - "google.golang.org/grpc/grpclog" -) - -const ( - defaultMaxTraceEntry int32 = 30 + "google.golang.org/grpc/internal" ) var ( - db dbWrapper - idGen idGenerator - // EntryPerPage defines the number of channelz entries to be shown on a web page. - EntryPerPage = int64(50) - curState int32 - maxTraceEntry = defaultMaxTraceEntry + // IDGen is the global channelz entity ID generator. It should not be used + // outside this package except by tests. + IDGen IDGenerator + + db *channelMap = newChannelMap() + // EntriesPerPage defines the number of channelz entries to be shown on a web page. + EntriesPerPage = 50 + curState int32 ) // TurnOn turns on channelz data collection. func TurnOn() { - if !IsOn() { - db.set(newChannelMap()) - idGen.reset() - atomic.StoreInt32(&curState, 1) + atomic.StoreInt32(&curState, 1) +} + +func init() { + internal.ChannelzTurnOffForTesting = func() { + atomic.StoreInt32(&curState, 0) } } // IsOn returns whether channelz data collection is on. func IsOn() bool { - return atomic.CompareAndSwapInt32(&curState, 1, 1) -} - -// SetMaxTraceEntry sets maximum number of trace entry per entity (i.e. channel/subchannel). -// Setting it to 0 will disable channel tracing. -func SetMaxTraceEntry(i int32) { - atomic.StoreInt32(&maxTraceEntry, i) -} - -// ResetMaxTraceEntryToDefault resets the maximum number of trace entry per entity to default. -func ResetMaxTraceEntryToDefault() { - atomic.StoreInt32(&maxTraceEntry, defaultMaxTraceEntry) -} - -func getMaxTraceEntry() int { - i := atomic.LoadInt32(&maxTraceEntry) - return int(i) -} - -// dbWarpper wraps around a reference to internal channelz data storage, and -// provide synchronized functionality to set and get the reference. -type dbWrapper struct { - mu sync.RWMutex - DB *channelMap -} - -func (d *dbWrapper) set(db *channelMap) { - d.mu.Lock() - d.DB = db - d.mu.Unlock() -} - -func (d *dbWrapper) get() *channelMap { - d.mu.RLock() - defer d.mu.RUnlock() - return d.DB -} - -// NewChannelzStorageForTesting initializes channelz data storage and id -// generator for testing purposes. -// -// Returns a cleanup function to be invoked by the test, which waits for up to -// 10s for all channelz state to be reset by the grpc goroutines when those -// entities get closed. This cleanup function helps with ensuring that tests -// don't mess up each other. -func NewChannelzStorageForTesting() (cleanup func() error) { - db.set(newChannelMap()) - idGen.reset() - - return func() error { - cm := db.get() - if cm == nil { - return nil - } - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - ticker := time.NewTicker(10 * time.Millisecond) - defer ticker.Stop() - for { - cm.mu.RLock() - topLevelChannels, servers, channels, subChannels, listenSockets, normalSockets := len(cm.topLevelChannels), len(cm.servers), len(cm.channels), len(cm.subChannels), len(cm.listenSockets), len(cm.normalSockets) - cm.mu.RUnlock() - - if err := ctx.Err(); err != nil { - return fmt.Errorf("after 10s the channelz map has not been cleaned up yet, topchannels: %d, servers: %d, channels: %d, subchannels: %d, listen sockets: %d, normal sockets: %d", topLevelChannels, servers, channels, subChannels, listenSockets, normalSockets) - } - if topLevelChannels == 0 && servers == 0 && channels == 0 && subChannels == 0 && listenSockets == 0 && normalSockets == 0 { - return nil - } - <-ticker.C - } - } + return atomic.LoadInt32(&curState) == 1 } // GetTopChannels returns a slice of top channel's ChannelMetric, along with a // boolean indicating whether there's more top channels to be queried for. // -// The arg id specifies that only top channel with id at or above it will be included -// in the result. The returned slice is up to a length of the arg maxResults or -// EntryPerPage if maxResults is zero, and is sorted in ascending id order. -func GetTopChannels(id int64, maxResults int64) ([]*ChannelMetric, bool) { - return db.get().GetTopChannels(id, maxResults) +// The arg id specifies that only top channel with id at or above it will be +// included in the result. The returned slice is up to a length of the arg +// maxResults or EntriesPerPage if maxResults is zero, and is sorted in ascending +// id order. +func GetTopChannels(id int64, maxResults int) ([]*Channel, bool) { + return db.getTopChannels(id, maxResults) } // GetServers returns a slice of server's ServerMetric, along with a @@ -149,73 +71,69 @@ func GetTopChannels(id int64, maxResults int64) ([]*ChannelMetric, bool) { // // The arg id specifies that only server with id at or above it will be included // in the result. The returned slice is up to a length of the arg maxResults or -// EntryPerPage if maxResults is zero, and is sorted in ascending id order. -func GetServers(id int64, maxResults int64) ([]*ServerMetric, bool) { - return db.get().GetServers(id, maxResults) +// EntriesPerPage if maxResults is zero, and is sorted in ascending id order. +func GetServers(id int64, maxResults int) ([]*Server, bool) { + return db.getServers(id, maxResults) } // GetServerSockets returns a slice of server's (identified by id) normal socket's -// SocketMetric, along with a boolean indicating whether there's more sockets to +// SocketMetrics, along with a boolean indicating whether there's more sockets to // be queried for. // // The arg startID specifies that only sockets with id at or above it will be // included in the result. The returned slice is up to a length of the arg maxResults -// or EntryPerPage if maxResults is zero, and is sorted in ascending id order. -func GetServerSockets(id int64, startID int64, maxResults int64) ([]*SocketMetric, bool) { - return db.get().GetServerSockets(id, startID, maxResults) +// or EntriesPerPage if maxResults is zero, and is sorted in ascending id order. +func GetServerSockets(id int64, startID int64, maxResults int) ([]*Socket, bool) { + return db.getServerSockets(id, startID, maxResults) } -// GetChannel returns the ChannelMetric for the channel (identified by id). -func GetChannel(id int64) *ChannelMetric { - return db.get().GetChannel(id) +// GetChannel returns the Channel for the channel (identified by id). +func GetChannel(id int64) *Channel { + return db.getChannel(id) } -// GetSubChannel returns the SubChannelMetric for the subchannel (identified by id). -func GetSubChannel(id int64) *SubChannelMetric { - return db.get().GetSubChannel(id) +// GetSubChannel returns the SubChannel for the subchannel (identified by id). +func GetSubChannel(id int64) *SubChannel { + return db.getSubChannel(id) } -// GetSocket returns the SocketInternalMetric for the socket (identified by id). -func GetSocket(id int64) *SocketMetric { - return db.get().GetSocket(id) +// GetSocket returns the Socket for the socket (identified by id). +func GetSocket(id int64) *Socket { + return db.getSocket(id) } // GetServer returns the ServerMetric for the server (identified by id). -func GetServer(id int64) *ServerMetric { - return db.get().GetServer(id) +func GetServer(id int64) *Server { + return db.getServer(id) } // RegisterChannel registers the given channel c in the channelz database with -// ref as its reference name, and adds it to the child list of its parent -// (identified by pid). pid == nil means no parent. +// target as its target and reference name, and adds it to the child list of its +// parent. parent == nil means no parent. // // Returns a unique channelz identifier assigned to this channel. // // If channelz is not turned ON, the channelz database is not mutated. -func RegisterChannel(c Channel, pid *Identifier, ref string) *Identifier { - id := idGen.genID() - var parent int64 - isTopChannel := true - if pid != nil { - isTopChannel = false - parent = pid.Int() - } +func RegisterChannel(parent *Channel, target string) *Channel { + id := IDGen.genID() if !IsOn() { - return newIdentifer(RefChannel, id, pid) + return &Channel{ID: id} } - cn := &channel{ - refName: ref, - c: c, - subChans: make(map[int64]string), + isTopChannel := parent == nil + + cn := &Channel{ + ID: id, + RefName: target, nestedChans: make(map[int64]string), - id: id, - pid: parent, - trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())}, + subChans: make(map[int64]string), + Parent: parent, + trace: &ChannelTrace{CreationTime: time.Now(), Events: make([]*traceEvent, 0, getMaxTraceEntry())}, } - db.get().addChannel(id, cn, isTopChannel, parent) - return newIdentifer(RefChannel, id, pid) + cn.ChannelMetrics.Target.Store(&target) + db.addChannel(id, cn, isTopChannel, cn.getParentID()) + return cn } // RegisterSubChannel registers the given subChannel c in the channelz database @@ -225,565 +143,88 @@ func RegisterChannel(c Channel, pid *Identifier, ref string) *Identifier { // Returns a unique channelz identifier assigned to this subChannel. // // If channelz is not turned ON, the channelz database is not mutated. -func RegisterSubChannel(c Channel, pid *Identifier, ref string) (*Identifier, error) { - if pid == nil { - return nil, errors.New("a SubChannel's parent id cannot be nil") +func RegisterSubChannel(parent *Channel, ref string) *SubChannel { + id := IDGen.genID() + sc := &SubChannel{ + ID: id, + RefName: ref, + parent: parent, } - id := idGen.genID() + if !IsOn() { - return newIdentifer(RefSubChannel, id, pid), nil + return sc } - sc := &subChannel{ - refName: ref, - c: c, - sockets: make(map[int64]string), - id: id, - pid: pid.Int(), - trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())}, - } - db.get().addSubChannel(id, sc, pid.Int()) - return newIdentifer(RefSubChannel, id, pid), nil + sc.sockets = make(map[int64]string) + sc.trace = &ChannelTrace{CreationTime: time.Now(), Events: make([]*traceEvent, 0, getMaxTraceEntry())} + db.addSubChannel(id, sc, parent.ID) + return sc } // RegisterServer registers the given server s in channelz database. It returns // the unique channelz tracking id assigned to this server. // // If channelz is not turned ON, the channelz database is not mutated. -func RegisterServer(s Server, ref string) *Identifier { - id := idGen.genID() +func RegisterServer(ref string) *Server { + id := IDGen.genID() if !IsOn() { - return newIdentifer(RefServer, id, nil) + return &Server{ID: id} } - svr := &server{ - refName: ref, - s: s, + svr := &Server{ + RefName: ref, sockets: make(map[int64]string), listenSockets: make(map[int64]string), - id: id, + ID: id, } - db.get().addServer(id, svr) - return newIdentifer(RefServer, id, nil) + db.addServer(id, svr) + return svr } -// RegisterListenSocket registers the given listen socket s in channelz database -// with ref as its reference name, and add it to the child list of its parent -// (identified by pid). It returns the unique channelz tracking id assigned to -// this listen socket. -// -// If channelz is not turned ON, the channelz database is not mutated. -func RegisterListenSocket(s Socket, pid *Identifier, ref string) (*Identifier, error) { - if pid == nil { - return nil, errors.New("a ListenSocket's parent id cannot be 0") - } - id := idGen.genID() - if !IsOn() { - return newIdentifer(RefListenSocket, id, pid), nil - } - - ls := &listenSocket{refName: ref, s: s, id: id, pid: pid.Int()} - db.get().addListenSocket(id, ls, pid.Int()) - return newIdentifer(RefListenSocket, id, pid), nil -} - -// RegisterNormalSocket registers the given normal socket s in channelz database +// RegisterSocket registers the given normal socket s in channelz database // with ref as its reference name, and adds it to the child list of its parent -// (identified by pid). It returns the unique channelz tracking id assigned to -// this normal socket. +// (identified by skt.Parent, which must be set). It returns the unique channelz +// tracking id assigned to this normal socket. // // If channelz is not turned ON, the channelz database is not mutated. -func RegisterNormalSocket(s Socket, pid *Identifier, ref string) (*Identifier, error) { - if pid == nil { - return nil, errors.New("a NormalSocket's parent id cannot be 0") - } - id := idGen.genID() - if !IsOn() { - return newIdentifer(RefNormalSocket, id, pid), nil +func RegisterSocket(skt *Socket) *Socket { + skt.ID = IDGen.genID() + if IsOn() { + db.addSocket(skt) } - - ns := &normalSocket{refName: ref, s: s, id: id, pid: pid.Int()} - db.get().addNormalSocket(id, ns, pid.Int()) - return newIdentifer(RefNormalSocket, id, pid), nil + return skt } // RemoveEntry removes an entry with unique channelz tracking id to be id from // channelz database. // // If channelz is not turned ON, this function is a no-op. -func RemoveEntry(id *Identifier) { +func RemoveEntry(id int64) { if !IsOn() { return } - db.get().removeEntry(id.Int()) + db.removeEntry(id) } -// TraceEventDesc is what the caller of AddTraceEvent should provide to describe -// the event to be added to the channel trace. -// -// The Parent field is optional. It is used for an event that will be recorded -// in the entity's parent trace. -type TraceEventDesc struct { - Desc string - Severity Severity - Parent *TraceEventDesc -} - -// AddTraceEvent adds trace related to the entity with specified id, using the -// provided TraceEventDesc. -// -// If channelz is not turned ON, this will simply log the event descriptions. -func AddTraceEvent(l grpclog.DepthLoggerV2, id *Identifier, depth int, desc *TraceEventDesc) { - // Log only the trace description associated with the bottom most entity. - switch desc.Severity { - case CtUnknown, CtInfo: - l.InfoDepth(depth+1, withParens(id)+desc.Desc) - case CtWarning: - l.WarningDepth(depth+1, withParens(id)+desc.Desc) - case CtError: - l.ErrorDepth(depth+1, withParens(id)+desc.Desc) - } - - if getMaxTraceEntry() == 0 { - return - } - if IsOn() { - db.get().traceEvent(id.Int(), desc) - } -} - -// channelMap is the storage data structure for channelz. -// Methods of channelMap can be divided in two two categories with respect to locking. -// 1. Methods acquire the global lock. -// 2. Methods that can only be called when global lock is held. -// A second type of method need always to be called inside a first type of method. -type channelMap struct { - mu sync.RWMutex - topLevelChannels map[int64]struct{} - servers map[int64]*server - channels map[int64]*channel - subChannels map[int64]*subChannel - listenSockets map[int64]*listenSocket - normalSockets map[int64]*normalSocket -} - -func newChannelMap() *channelMap { - return &channelMap{ - topLevelChannels: make(map[int64]struct{}), - channels: make(map[int64]*channel), - listenSockets: make(map[int64]*listenSocket), - normalSockets: make(map[int64]*normalSocket), - servers: make(map[int64]*server), - subChannels: make(map[int64]*subChannel), - } -} - -func (c *channelMap) addServer(id int64, s *server) { - c.mu.Lock() - s.cm = c - c.servers[id] = s - c.mu.Unlock() -} - -func (c *channelMap) addChannel(id int64, cn *channel, isTopChannel bool, pid int64) { - c.mu.Lock() - cn.cm = c - cn.trace.cm = c - c.channels[id] = cn - if isTopChannel { - c.topLevelChannels[id] = struct{}{} - } else { - c.findEntry(pid).addChild(id, cn) - } - c.mu.Unlock() -} - -func (c *channelMap) addSubChannel(id int64, sc *subChannel, pid int64) { - c.mu.Lock() - sc.cm = c - sc.trace.cm = c - c.subChannels[id] = sc - c.findEntry(pid).addChild(id, sc) - c.mu.Unlock() -} - -func (c *channelMap) addListenSocket(id int64, ls *listenSocket, pid int64) { - c.mu.Lock() - ls.cm = c - c.listenSockets[id] = ls - c.findEntry(pid).addChild(id, ls) - c.mu.Unlock() -} - -func (c *channelMap) addNormalSocket(id int64, ns *normalSocket, pid int64) { - c.mu.Lock() - ns.cm = c - c.normalSockets[id] = ns - c.findEntry(pid).addChild(id, ns) - c.mu.Unlock() -} - -// removeEntry triggers the removal of an entry, which may not indeed delete the entry, if it has to -// wait on the deletion of its children and until no other entity's channel trace references it. -// It may lead to a chain of entry deletion. For example, deleting the last socket of a gracefully -// shutting down server will lead to the server being also deleted. -func (c *channelMap) removeEntry(id int64) { - c.mu.Lock() - c.findEntry(id).triggerDelete() - c.mu.Unlock() -} - -// c.mu must be held by the caller -func (c *channelMap) decrTraceRefCount(id int64) { - e := c.findEntry(id) - if v, ok := e.(tracedChannel); ok { - v.decrTraceRefCount() - e.deleteSelfIfReady() - } -} - -// c.mu must be held by the caller. -func (c *channelMap) findEntry(id int64) entry { - var v entry - var ok bool - if v, ok = c.channels[id]; ok { - return v - } - if v, ok = c.subChannels[id]; ok { - return v - } - if v, ok = c.servers[id]; ok { - return v - } - if v, ok = c.listenSockets[id]; ok { - return v - } - if v, ok = c.normalSockets[id]; ok { - return v - } - return &dummyEntry{idNotFound: id} -} - -// c.mu must be held by the caller -// deleteEntry simply deletes an entry from the channelMap. Before calling this -// method, caller must check this entry is ready to be deleted, i.e removeEntry() -// has been called on it, and no children still exist. -// Conditionals are ordered by the expected frequency of deletion of each entity -// type, in order to optimize performance. -func (c *channelMap) deleteEntry(id int64) { - var ok bool - if _, ok = c.normalSockets[id]; ok { - delete(c.normalSockets, id) - return - } - if _, ok = c.subChannels[id]; ok { - delete(c.subChannels, id) - return - } - if _, ok = c.channels[id]; ok { - delete(c.channels, id) - delete(c.topLevelChannels, id) - return - } - if _, ok = c.listenSockets[id]; ok { - delete(c.listenSockets, id) - return - } - if _, ok = c.servers[id]; ok { - delete(c.servers, id) - return - } -} - -func (c *channelMap) traceEvent(id int64, desc *TraceEventDesc) { - c.mu.Lock() - child := c.findEntry(id) - childTC, ok := child.(tracedChannel) - if !ok { - c.mu.Unlock() - return - } - childTC.getChannelTrace().append(&TraceEvent{Desc: desc.Desc, Severity: desc.Severity, Timestamp: time.Now()}) - if desc.Parent != nil { - parent := c.findEntry(child.getParentID()) - var chanType RefChannelType - switch child.(type) { - case *channel: - chanType = RefChannel - case *subChannel: - chanType = RefSubChannel - } - if parentTC, ok := parent.(tracedChannel); ok { - parentTC.getChannelTrace().append(&TraceEvent{ - Desc: desc.Parent.Desc, - Severity: desc.Parent.Severity, - Timestamp: time.Now(), - RefID: id, - RefName: childTC.getRefName(), - RefType: chanType, - }) - childTC.incrTraceRefCount() - } - } - c.mu.Unlock() -} - -type int64Slice []int64 - -func (s int64Slice) Len() int { return len(s) } -func (s int64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s int64Slice) Less(i, j int) bool { return s[i] < s[j] } - -func copyMap(m map[int64]string) map[int64]string { - n := make(map[int64]string) - for k, v := range m { - n[k] = v - } - return n -} - -func min(a, b int64) int64 { - if a < b { - return a - } - return b -} - -func (c *channelMap) GetTopChannels(id int64, maxResults int64) ([]*ChannelMetric, bool) { - if maxResults <= 0 { - maxResults = EntryPerPage - } - c.mu.RLock() - l := int64(len(c.topLevelChannels)) - ids := make([]int64, 0, l) - cns := make([]*channel, 0, min(l, maxResults)) - - for k := range c.topLevelChannels { - ids = append(ids, k) - } - sort.Sort(int64Slice(ids)) - idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) - count := int64(0) - var end bool - var t []*ChannelMetric - for i, v := range ids[idx:] { - if count == maxResults { - break - } - if cn, ok := c.channels[v]; ok { - cns = append(cns, cn) - t = append(t, &ChannelMetric{ - NestedChans: copyMap(cn.nestedChans), - SubChans: copyMap(cn.subChans), - }) - count++ - } - if i == len(ids[idx:])-1 { - end = true - break - } - } - c.mu.RUnlock() - if count == 0 { - end = true - } - - for i, cn := range cns { - t[i].ChannelData = cn.c.ChannelzMetric() - t[i].ID = cn.id - t[i].RefName = cn.refName - t[i].Trace = cn.trace.dumpData() - } - return t, end -} - -func (c *channelMap) GetServers(id, maxResults int64) ([]*ServerMetric, bool) { - if maxResults <= 0 { - maxResults = EntryPerPage - } - c.mu.RLock() - l := int64(len(c.servers)) - ids := make([]int64, 0, l) - ss := make([]*server, 0, min(l, maxResults)) - for k := range c.servers { - ids = append(ids, k) - } - sort.Sort(int64Slice(ids)) - idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) - count := int64(0) - var end bool - var s []*ServerMetric - for i, v := range ids[idx:] { - if count == maxResults { - break - } - if svr, ok := c.servers[v]; ok { - ss = append(ss, svr) - s = append(s, &ServerMetric{ - ListenSockets: copyMap(svr.listenSockets), - }) - count++ - } - if i == len(ids[idx:])-1 { - end = true - break - } - } - c.mu.RUnlock() - if count == 0 { - end = true - } - - for i, svr := range ss { - s[i].ServerData = svr.s.ChannelzMetric() - s[i].ID = svr.id - s[i].RefName = svr.refName - } - return s, end -} - -func (c *channelMap) GetServerSockets(id int64, startID int64, maxResults int64) ([]*SocketMetric, bool) { - if maxResults <= 0 { - maxResults = EntryPerPage - } - var svr *server - var ok bool - c.mu.RLock() - if svr, ok = c.servers[id]; !ok { - // server with id doesn't exist. - c.mu.RUnlock() - return nil, true - } - svrskts := svr.sockets - l := int64(len(svrskts)) - ids := make([]int64, 0, l) - sks := make([]*normalSocket, 0, min(l, maxResults)) - for k := range svrskts { - ids = append(ids, k) - } - sort.Sort(int64Slice(ids)) - idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= startID }) - count := int64(0) - var end bool - for i, v := range ids[idx:] { - if count == maxResults { - break - } - if ns, ok := c.normalSockets[v]; ok { - sks = append(sks, ns) - count++ - } - if i == len(ids[idx:])-1 { - end = true - break - } - } - c.mu.RUnlock() - if count == 0 { - end = true - } - s := make([]*SocketMetric, 0, len(sks)) - for _, ns := range sks { - sm := &SocketMetric{} - sm.SocketData = ns.s.ChannelzMetric() - sm.ID = ns.id - sm.RefName = ns.refName - s = append(s, sm) - } - return s, end -} - -func (c *channelMap) GetChannel(id int64) *ChannelMetric { - cm := &ChannelMetric{} - var cn *channel - var ok bool - c.mu.RLock() - if cn, ok = c.channels[id]; !ok { - // channel with id doesn't exist. - c.mu.RUnlock() - return nil - } - cm.NestedChans = copyMap(cn.nestedChans) - cm.SubChans = copyMap(cn.subChans) - // cn.c can be set to &dummyChannel{} when deleteSelfFromMap is called. Save a copy of cn.c when - // holding the lock to prevent potential data race. - chanCopy := cn.c - c.mu.RUnlock() - cm.ChannelData = chanCopy.ChannelzMetric() - cm.ID = cn.id - cm.RefName = cn.refName - cm.Trace = cn.trace.dumpData() - return cm -} - -func (c *channelMap) GetSubChannel(id int64) *SubChannelMetric { - cm := &SubChannelMetric{} - var sc *subChannel - var ok bool - c.mu.RLock() - if sc, ok = c.subChannels[id]; !ok { - // subchannel with id doesn't exist. - c.mu.RUnlock() - return nil - } - cm.Sockets = copyMap(sc.sockets) - // sc.c can be set to &dummyChannel{} when deleteSelfFromMap is called. Save a copy of sc.c when - // holding the lock to prevent potential data race. - chanCopy := sc.c - c.mu.RUnlock() - cm.ChannelData = chanCopy.ChannelzMetric() - cm.ID = sc.id - cm.RefName = sc.refName - cm.Trace = sc.trace.dumpData() - return cm -} - -func (c *channelMap) GetSocket(id int64) *SocketMetric { - sm := &SocketMetric{} - c.mu.RLock() - if ls, ok := c.listenSockets[id]; ok { - c.mu.RUnlock() - sm.SocketData = ls.s.ChannelzMetric() - sm.ID = ls.id - sm.RefName = ls.refName - return sm - } - if ns, ok := c.normalSockets[id]; ok { - c.mu.RUnlock() - sm.SocketData = ns.s.ChannelzMetric() - sm.ID = ns.id - sm.RefName = ns.refName - return sm - } - c.mu.RUnlock() - return nil -} - -func (c *channelMap) GetServer(id int64) *ServerMetric { - sm := &ServerMetric{} - var svr *server - var ok bool - c.mu.RLock() - if svr, ok = c.servers[id]; !ok { - c.mu.RUnlock() - return nil - } - sm.ListenSockets = copyMap(svr.listenSockets) - c.mu.RUnlock() - sm.ID = svr.id - sm.RefName = svr.refName - sm.ServerData = svr.s.ChannelzMetric() - return sm -} - -type idGenerator struct { +// IDGenerator is an incrementing atomic that tracks IDs for channelz entities. +type IDGenerator struct { id int64 } -func (i *idGenerator) reset() { +// Reset resets the generated ID back to zero. Should only be used at +// initialization or by tests sensitive to the ID number. +func (i *IDGenerator) Reset() { atomic.StoreInt64(&i.id, 0) } -func (i *idGenerator) genID() int64 { +func (i *IDGenerator) genID() int64 { return atomic.AddInt64(&i.id, 1) } + +// Identifier is an opaque channelz identifier used to expose channelz symbols +// outside of grpc. Currently only implemented by Channel since no other +// types require exposure outside grpc. +type Identifier interface { + Entity + channelzIdentifier() +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/id.go b/vendor/google.golang.org/grpc/internal/channelz/id.go deleted file mode 100644 index c9a27acd..00000000 --- a/vendor/google.golang.org/grpc/internal/channelz/id.go +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Copyright 2022 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 channelz - -import "fmt" - -// Identifier is an opaque identifier which uniquely identifies an entity in the -// channelz database. -type Identifier struct { - typ RefChannelType - id int64 - str string - pid *Identifier -} - -// Type returns the entity type corresponding to id. -func (id *Identifier) Type() RefChannelType { - return id.typ -} - -// Int returns the integer identifier corresponding to id. -func (id *Identifier) Int() int64 { - return id.id -} - -// String returns a string representation of the entity corresponding to id. -// -// This includes some information about the parent as well. Examples: -// Top-level channel: [Channel #channel-number] -// Nested channel: [Channel #parent-channel-number Channel #channel-number] -// Sub channel: [Channel #parent-channel SubChannel #subchannel-number] -func (id *Identifier) String() string { - return id.str -} - -// Equal returns true if other is the same as id. -func (id *Identifier) Equal(other *Identifier) bool { - if (id != nil) != (other != nil) { - return false - } - if id == nil && other == nil { - return true - } - return id.typ == other.typ && id.id == other.id && id.pid == other.pid -} - -// NewIdentifierForTesting returns a new opaque identifier to be used only for -// testing purposes. -func NewIdentifierForTesting(typ RefChannelType, id int64, pid *Identifier) *Identifier { - return newIdentifer(typ, id, pid) -} - -func newIdentifer(typ RefChannelType, id int64, pid *Identifier) *Identifier { - str := fmt.Sprintf("%s #%d", typ, id) - if pid != nil { - str = fmt.Sprintf("%s %s", pid, str) - } - return &Identifier{typ: typ, id: id, str: str, pid: pid} -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/logging.go b/vendor/google.golang.org/grpc/internal/channelz/logging.go index 8e13a3d2..ee4d7212 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/logging.go +++ b/vendor/google.golang.org/grpc/internal/channelz/logging.go @@ -26,53 +26,49 @@ import ( var logger = grpclog.Component("channelz") -func withParens(id *Identifier) string { - return "[" + id.String() + "] " -} - // Info logs and adds a trace event if channelz is on. -func Info(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Info(l grpclog.DepthLoggerV2, e Entity, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprint(args...), Severity: CtInfo, }) } // Infof logs and adds a trace event if channelz is on. -func Infof(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...interface{}) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Infof(l grpclog.DepthLoggerV2, e Entity, format string, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprintf(format, args...), Severity: CtInfo, }) } // Warning logs and adds a trace event if channelz is on. -func Warning(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Warning(l grpclog.DepthLoggerV2, e Entity, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprint(args...), Severity: CtWarning, }) } // Warningf logs and adds a trace event if channelz is on. -func Warningf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...interface{}) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Warningf(l grpclog.DepthLoggerV2, e Entity, format string, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprintf(format, args...), Severity: CtWarning, }) } // Error logs and adds a trace event if channelz is on. -func Error(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Error(l grpclog.DepthLoggerV2, e Entity, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprint(args...), Severity: CtError, }) } // Errorf logs and adds a trace event if channelz is on. -func Errorf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...interface{}) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Errorf(l grpclog.DepthLoggerV2, e Entity, format string, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprintf(format, args...), Severity: CtError, }) diff --git a/vendor/google.golang.org/grpc/internal/channelz/server.go b/vendor/google.golang.org/grpc/internal/channelz/server.go new file mode 100644 index 00000000..cdfc49d6 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/server.go @@ -0,0 +1,119 @@ +/* + * + * Copyright 2024 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 channelz + +import ( + "fmt" + "sync/atomic" +) + +// Server is the channelz representation of a server. +type Server struct { + Entity + ID int64 + RefName string + + ServerMetrics ServerMetrics + + closeCalled bool + sockets map[int64]string + listenSockets map[int64]string + cm *channelMap +} + +// ServerMetrics defines a struct containing metrics for servers. +type ServerMetrics struct { + // The number of incoming calls started on the server. + CallsStarted atomic.Int64 + // The number of incoming calls that have completed with an OK status. + CallsSucceeded atomic.Int64 + // The number of incoming calls that have a completed with a non-OK status. + CallsFailed atomic.Int64 + // The last time a call was started on the server. + LastCallStartedTimestamp atomic.Int64 +} + +// NewServerMetricsForTesting returns an initialized ServerMetrics. +func NewServerMetricsForTesting(started, succeeded, failed, timestamp int64) *ServerMetrics { + sm := &ServerMetrics{} + sm.CallsStarted.Store(started) + sm.CallsSucceeded.Store(succeeded) + sm.CallsFailed.Store(failed) + sm.LastCallStartedTimestamp.Store(timestamp) + return sm +} + +func (sm *ServerMetrics) CopyFrom(o *ServerMetrics) { + sm.CallsStarted.Store(o.CallsStarted.Load()) + sm.CallsSucceeded.Store(o.CallsSucceeded.Load()) + sm.CallsFailed.Store(o.CallsFailed.Load()) + sm.LastCallStartedTimestamp.Store(o.LastCallStartedTimestamp.Load()) +} + +// ListenSockets returns the listening sockets for s. +func (s *Server) ListenSockets() map[int64]string { + db.mu.RLock() + defer db.mu.RUnlock() + return copyMap(s.listenSockets) +} + +// String returns a printable description of s. +func (s *Server) String() string { + return fmt.Sprintf("Server #%d", s.ID) +} + +func (s *Server) id() int64 { + return s.ID +} + +func (s *Server) addChild(id int64, e entry) { + switch v := e.(type) { + case *Socket: + switch v.SocketType { + case SocketTypeNormal: + s.sockets[id] = v.RefName + case SocketTypeListen: + s.listenSockets[id] = v.RefName + } + default: + logger.Errorf("cannot add a child (id = %d) of type %T to a server", id, e) + } +} + +func (s *Server) deleteChild(id int64) { + delete(s.sockets, id) + delete(s.listenSockets, id) + s.deleteSelfIfReady() +} + +func (s *Server) triggerDelete() { + s.closeCalled = true + s.deleteSelfIfReady() +} + +func (s *Server) deleteSelfIfReady() { + if !s.closeCalled || len(s.sockets)+len(s.listenSockets) != 0 { + return + } + s.cm.deleteEntry(s.ID) +} + +func (s *Server) getParentID() int64 { + return 0 +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/socket.go b/vendor/google.golang.org/grpc/internal/channelz/socket.go new file mode 100644 index 00000000..fa64834b --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/socket.go @@ -0,0 +1,130 @@ +/* + * + * Copyright 2024 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 channelz + +import ( + "fmt" + "net" + "sync/atomic" + + "google.golang.org/grpc/credentials" +) + +// SocketMetrics defines the struct that the implementor of Socket interface +// should return from ChannelzMetric(). +type SocketMetrics struct { + // The number of streams that have been started. + StreamsStarted atomic.Int64 + // The number of streams that have ended successfully: + // On client side, receiving frame with eos bit set. + // On server side, sending frame with eos bit set. + StreamsSucceeded atomic.Int64 + // The number of streams that have ended unsuccessfully: + // On client side, termination without receiving frame with eos bit set. + // On server side, termination without sending frame with eos bit set. + StreamsFailed atomic.Int64 + // The number of messages successfully sent on this socket. + MessagesSent atomic.Int64 + MessagesReceived atomic.Int64 + // The number of keep alives sent. This is typically implemented with HTTP/2 + // ping messages. + KeepAlivesSent atomic.Int64 + // The last time a stream was created by this endpoint. Usually unset for + // servers. + LastLocalStreamCreatedTimestamp atomic.Int64 + // The last time a stream was created by the remote endpoint. Usually unset + // for clients. + LastRemoteStreamCreatedTimestamp atomic.Int64 + // The last time a message was sent by this endpoint. + LastMessageSentTimestamp atomic.Int64 + // The last time a message was received by this endpoint. + LastMessageReceivedTimestamp atomic.Int64 +} + +// EphemeralSocketMetrics are metrics that change rapidly and are tracked +// outside of channelz. +type EphemeralSocketMetrics struct { + // The amount of window, granted to the local endpoint by the remote endpoint. + // This may be slightly out of date due to network latency. This does NOT + // include stream level or TCP level flow control info. + LocalFlowControlWindow int64 + // The amount of window, granted to the remote endpoint by the local endpoint. + // This may be slightly out of date due to network latency. This does NOT + // include stream level or TCP level flow control info. + RemoteFlowControlWindow int64 +} + +type SocketType string + +const ( + SocketTypeNormal = "NormalSocket" + SocketTypeListen = "ListenSocket" +) + +type Socket struct { + Entity + SocketType SocketType + ID int64 + Parent Entity + cm *channelMap + SocketMetrics SocketMetrics + EphemeralMetrics func() *EphemeralSocketMetrics + + RefName string + // The locally bound address. Immutable. + LocalAddr net.Addr + // The remote bound address. May be absent. Immutable. + RemoteAddr net.Addr + // Optional, represents the name of the remote endpoint, if different than + // the original target name. Immutable. + RemoteName string + // Immutable. + SocketOptions *SocketOptionData + // Immutable. + Security credentials.ChannelzSecurityValue +} + +func (ls *Socket) String() string { + return fmt.Sprintf("%s %s #%d", ls.Parent, ls.SocketType, ls.ID) +} + +func (ls *Socket) id() int64 { + return ls.ID +} + +func (ls *Socket) addChild(id int64, e entry) { + logger.Errorf("cannot add a child (id = %d) of type %T to a listen socket", id, e) +} + +func (ls *Socket) deleteChild(id int64) { + logger.Errorf("cannot delete a child (id = %d) from a listen socket", id) +} + +func (ls *Socket) triggerDelete() { + ls.cm.deleteEntry(ls.ID) + ls.Parent.(entry).deleteChild(ls.ID) +} + +func (ls *Socket) deleteSelfIfReady() { + logger.Errorf("cannot call deleteSelfIfReady on a listen socket") +} + +func (ls *Socket) getParentID() int64 { + return ls.Parent.id() +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/subchannel.go b/vendor/google.golang.org/grpc/internal/channelz/subchannel.go new file mode 100644 index 00000000..3b88e4cb --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/subchannel.go @@ -0,0 +1,151 @@ +/* + * + * Copyright 2024 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 channelz + +import ( + "fmt" + "sync/atomic" +) + +// SubChannel is the channelz representation of a subchannel. +type SubChannel struct { + Entity + // ID is the channelz id of this subchannel. + ID int64 + // RefName is the human readable reference string of this subchannel. + RefName string + closeCalled bool + sockets map[int64]string + parent *Channel + trace *ChannelTrace + traceRefCount int32 + + ChannelMetrics ChannelMetrics +} + +func (sc *SubChannel) String() string { + return fmt.Sprintf("%s SubChannel #%d", sc.parent, sc.ID) +} + +func (sc *SubChannel) id() int64 { + return sc.ID +} + +func (sc *SubChannel) Sockets() map[int64]string { + db.mu.RLock() + defer db.mu.RUnlock() + return copyMap(sc.sockets) +} + +func (sc *SubChannel) Trace() *ChannelTrace { + db.mu.RLock() + defer db.mu.RUnlock() + return sc.trace.copy() +} + +func (sc *SubChannel) addChild(id int64, e entry) { + if v, ok := e.(*Socket); ok && v.SocketType == SocketTypeNormal { + sc.sockets[id] = v.RefName + } else { + logger.Errorf("cannot add a child (id = %d) of type %T to a subChannel", id, e) + } +} + +func (sc *SubChannel) deleteChild(id int64) { + delete(sc.sockets, id) + sc.deleteSelfIfReady() +} + +func (sc *SubChannel) triggerDelete() { + sc.closeCalled = true + sc.deleteSelfIfReady() +} + +func (sc *SubChannel) getParentID() int64 { + return sc.parent.ID +} + +// deleteSelfFromTree tries to delete the subchannel from the channelz entry relation tree, which +// means deleting the subchannel reference from its parent's child list. +// +// In order for a subchannel to be deleted from the tree, it must meet the criteria that, removal of +// the corresponding grpc object has been invoked, and the subchannel does not have any children left. +// +// The returned boolean value indicates whether the channel has been successfully deleted from tree. +func (sc *SubChannel) deleteSelfFromTree() (deleted bool) { + if !sc.closeCalled || len(sc.sockets) != 0 { + return false + } + sc.parent.deleteChild(sc.ID) + return true +} + +// deleteSelfFromMap checks whether it is valid to delete the subchannel from the map, which means +// deleting the subchannel from channelz's tracking entirely. Users can no longer use id to query +// the subchannel, and its memory will be garbage collected. +// +// The trace reference count of the subchannel must be 0 in order to be deleted from the map. This is +// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, +// the trace of the referenced entity must not be deleted. In order to release the resource allocated +// by grpc, the reference to the grpc object is reset to a dummy object. +// +// deleteSelfFromMap must be called after deleteSelfFromTree returns true. +// +// It returns a bool to indicate whether the channel can be safely deleted from map. +func (sc *SubChannel) deleteSelfFromMap() (delete bool) { + return sc.getTraceRefCount() == 0 +} + +// deleteSelfIfReady tries to delete the subchannel itself from the channelz database. +// The delete process includes two steps: +// 1. delete the subchannel from the entry relation tree, i.e. delete the subchannel reference from +// its parent's child list. +// 2. delete the subchannel from the map, i.e. delete the subchannel entirely from channelz. Lookup +// by id will return entry not found error. +func (sc *SubChannel) deleteSelfIfReady() { + if !sc.deleteSelfFromTree() { + return + } + if !sc.deleteSelfFromMap() { + return + } + db.deleteEntry(sc.ID) + sc.trace.clear() +} + +func (sc *SubChannel) getChannelTrace() *ChannelTrace { + return sc.trace +} + +func (sc *SubChannel) incrTraceRefCount() { + atomic.AddInt32(&sc.traceRefCount, 1) +} + +func (sc *SubChannel) decrTraceRefCount() { + atomic.AddInt32(&sc.traceRefCount, -1) +} + +func (sc *SubChannel) getTraceRefCount() int { + i := atomic.LoadInt32(&sc.traceRefCount) + return int(i) +} + +func (sc *SubChannel) getRefName() string { + return sc.RefName +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/types_linux.go b/vendor/google.golang.org/grpc/internal/channelz/syscall_linux.go similarity index 83% rename from vendor/google.golang.org/grpc/internal/channelz/types_linux.go rename to vendor/google.golang.org/grpc/internal/channelz/syscall_linux.go index 1b1c4cce..5ac73ff8 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/types_linux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/syscall_linux.go @@ -49,3 +49,17 @@ func (s *SocketOptionData) Getsockopt(fd uintptr) { s.TCPInfo = v } } + +// GetSocketOption gets the socket option info of the conn. +func GetSocketOption(socket any) *SocketOptionData { + c, ok := socket.(syscall.Conn) + if !ok { + return nil + } + data := &SocketOptionData{} + if rawConn, err := c.SyscallConn(); err == nil { + rawConn.Control(data.Getsockopt) + return data + } + return nil +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go b/vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go similarity index 90% rename from vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go rename to vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go index 8b06eed1..d1ed8df6 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* * @@ -41,3 +40,8 @@ func (s *SocketOptionData) Getsockopt(fd uintptr) { logger.Warning("Channelz: socket options are not supported on non-linux environments") }) } + +// GetSocketOption gets the socket option info of the conn. +func GetSocketOption(c any) *SocketOptionData { + return nil +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/trace.go b/vendor/google.golang.org/grpc/internal/channelz/trace.go new file mode 100644 index 00000000..36b86740 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/trace.go @@ -0,0 +1,204 @@ +/* + * + * Copyright 2018 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 channelz + +import ( + "fmt" + "sync" + "sync/atomic" + "time" + + "google.golang.org/grpc/grpclog" +) + +const ( + defaultMaxTraceEntry int32 = 30 +) + +var maxTraceEntry = defaultMaxTraceEntry + +// SetMaxTraceEntry sets maximum number of trace entries per entity (i.e. +// channel/subchannel). Setting it to 0 will disable channel tracing. +func SetMaxTraceEntry(i int32) { + atomic.StoreInt32(&maxTraceEntry, i) +} + +// ResetMaxTraceEntryToDefault resets the maximum number of trace entries per +// entity to default. +func ResetMaxTraceEntryToDefault() { + atomic.StoreInt32(&maxTraceEntry, defaultMaxTraceEntry) +} + +func getMaxTraceEntry() int { + i := atomic.LoadInt32(&maxTraceEntry) + return int(i) +} + +// traceEvent is an internal representation of a single trace event +type traceEvent struct { + // Desc is a simple description of the trace event. + Desc string + // Severity states the severity of this trace event. + Severity Severity + // Timestamp is the event time. + Timestamp time.Time + // RefID is the id of the entity that gets referenced in the event. RefID is 0 if no other entity is + // involved in this event. + // e.g. SubChannel (id: 4[]) Created. --> RefID = 4, RefName = "" (inside []) + RefID int64 + // RefName is the reference name for the entity that gets referenced in the event. + RefName string + // RefType indicates the referenced entity type, i.e Channel or SubChannel. + RefType RefChannelType +} + +// TraceEvent is what the caller of AddTraceEvent should provide to describe the +// event to be added to the channel trace. +// +// The Parent field is optional. It is used for an event that will be recorded +// in the entity's parent trace. +type TraceEvent struct { + Desc string + Severity Severity + Parent *TraceEvent +} + +type ChannelTrace struct { + cm *channelMap + clearCalled bool + CreationTime time.Time + EventNum int64 + mu sync.Mutex + Events []*traceEvent +} + +func (c *ChannelTrace) copy() *ChannelTrace { + return &ChannelTrace{ + CreationTime: c.CreationTime, + EventNum: c.EventNum, + Events: append(([]*traceEvent)(nil), c.Events...), + } +} + +func (c *ChannelTrace) append(e *traceEvent) { + c.mu.Lock() + if len(c.Events) == getMaxTraceEntry() { + del := c.Events[0] + c.Events = c.Events[1:] + if del.RefID != 0 { + // start recursive cleanup in a goroutine to not block the call originated from grpc. + go func() { + // need to acquire c.cm.mu lock to call the unlocked attemptCleanup func. + c.cm.mu.Lock() + c.cm.decrTraceRefCount(del.RefID) + c.cm.mu.Unlock() + }() + } + } + e.Timestamp = time.Now() + c.Events = append(c.Events, e) + c.EventNum++ + c.mu.Unlock() +} + +func (c *ChannelTrace) clear() { + if c.clearCalled { + return + } + c.clearCalled = true + c.mu.Lock() + for _, e := range c.Events { + if e.RefID != 0 { + // caller should have already held the c.cm.mu lock. + c.cm.decrTraceRefCount(e.RefID) + } + } + c.mu.Unlock() +} + +// Severity is the severity level of a trace event. +// The canonical enumeration of all valid values is here: +// https://github.com/grpc/grpc-proto/blob/9b13d199cc0d4703c7ea26c9c330ba695866eb23/grpc/channelz/v1/channelz.proto#L126. +type Severity int + +const ( + // CtUnknown indicates unknown severity of a trace event. + CtUnknown Severity = iota + // CtInfo indicates info level severity of a trace event. + CtInfo + // CtWarning indicates warning level severity of a trace event. + CtWarning + // CtError indicates error level severity of a trace event. + CtError +) + +// RefChannelType is the type of the entity being referenced in a trace event. +type RefChannelType int + +const ( + // RefUnknown indicates an unknown entity type, the zero value for this type. + RefUnknown RefChannelType = iota + // RefChannel indicates the referenced entity is a Channel. + RefChannel + // RefSubChannel indicates the referenced entity is a SubChannel. + RefSubChannel + // RefServer indicates the referenced entity is a Server. + RefServer + // RefListenSocket indicates the referenced entity is a ListenSocket. + RefListenSocket + // RefNormalSocket indicates the referenced entity is a NormalSocket. + RefNormalSocket +) + +var refChannelTypeToString = map[RefChannelType]string{ + RefUnknown: "Unknown", + RefChannel: "Channel", + RefSubChannel: "SubChannel", + RefServer: "Server", + RefListenSocket: "ListenSocket", + RefNormalSocket: "NormalSocket", +} + +func (r RefChannelType) String() string { + return refChannelTypeToString[r] +} + +// AddTraceEvent adds trace related to the entity with specified id, using the +// provided TraceEventDesc. +// +// If channelz is not turned ON, this will simply log the event descriptions. +func AddTraceEvent(l grpclog.DepthLoggerV2, e Entity, depth int, desc *TraceEvent) { + // Log only the trace description associated with the bottom most entity. + d := fmt.Sprintf("[%s]%s", e, desc.Desc) + switch desc.Severity { + case CtUnknown, CtInfo: + l.InfoDepth(depth+1, d) + case CtWarning: + l.WarningDepth(depth+1, d) + case CtError: + l.ErrorDepth(depth+1, d) + } + + if getMaxTraceEntry() == 0 { + return + } + if IsOn() { + db.traceEvent(e.id(), desc) + } +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/types.go b/vendor/google.golang.org/grpc/internal/channelz/types.go deleted file mode 100644 index 7b2f350e..00000000 --- a/vendor/google.golang.org/grpc/internal/channelz/types.go +++ /dev/null @@ -1,722 +0,0 @@ -/* - * - * Copyright 2018 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 channelz - -import ( - "net" - "sync" - "sync/atomic" - "time" - - "google.golang.org/grpc/connectivity" - "google.golang.org/grpc/credentials" -) - -// entry represents a node in the channelz database. -type entry interface { - // addChild adds a child e, whose channelz id is id to child list - addChild(id int64, e entry) - // deleteChild deletes a child with channelz id to be id from child list - deleteChild(id int64) - // triggerDelete tries to delete self from channelz database. However, if child - // list is not empty, then deletion from the database is on hold until the last - // child is deleted from database. - triggerDelete() - // deleteSelfIfReady check whether triggerDelete() has been called before, and whether child - // list is now empty. If both conditions are met, then delete self from database. - deleteSelfIfReady() - // getParentID returns parent ID of the entry. 0 value parent ID means no parent. - getParentID() int64 -} - -// dummyEntry is a fake entry to handle entry not found case. -type dummyEntry struct { - idNotFound int64 -} - -func (d *dummyEntry) addChild(id int64, e entry) { - // Note: It is possible for a normal program to reach here under race condition. - // For example, there could be a race between ClientConn.Close() info being propagated - // to addrConn and http2Client. ClientConn.Close() cancel the context and result - // in http2Client to error. The error info is then caught by transport monitor - // and before addrConn.tearDown() is called in side ClientConn.Close(). Therefore, - // the addrConn will create a new transport. And when registering the new transport in - // channelz, its parent addrConn could have already been torn down and deleted - // from channelz tracking, and thus reach the code here. - logger.Infof("attempt to add child of type %T with id %d to a parent (id=%d) that doesn't currently exist", e, id, d.idNotFound) -} - -func (d *dummyEntry) deleteChild(id int64) { - // It is possible for a normal program to reach here under race condition. - // Refer to the example described in addChild(). - logger.Infof("attempt to delete child with id %d from a parent (id=%d) that doesn't currently exist", id, d.idNotFound) -} - -func (d *dummyEntry) triggerDelete() { - logger.Warningf("attempt to delete an entry (id=%d) that doesn't currently exist", d.idNotFound) -} - -func (*dummyEntry) deleteSelfIfReady() { - // code should not reach here. deleteSelfIfReady is always called on an existing entry. -} - -func (*dummyEntry) getParentID() int64 { - return 0 -} - -// ChannelMetric defines the info channelz provides for a specific Channel, which -// includes ChannelInternalMetric and channelz-specific data, such as channelz id, -// child list, etc. -type ChannelMetric struct { - // ID is the channelz id of this channel. - ID int64 - // RefName is the human readable reference string of this channel. - RefName string - // ChannelData contains channel internal metric reported by the channel through - // ChannelzMetric(). - ChannelData *ChannelInternalMetric - // NestedChans tracks the nested channel type children of this channel in the format of - // a map from nested channel channelz id to corresponding reference string. - NestedChans map[int64]string - // SubChans tracks the subchannel type children of this channel in the format of a - // map from subchannel channelz id to corresponding reference string. - SubChans map[int64]string - // Sockets tracks the socket type children of this channel in the format of a map - // from socket channelz id to corresponding reference string. - // Note current grpc implementation doesn't allow channel having sockets directly, - // therefore, this is field is unused. - Sockets map[int64]string - // Trace contains the most recent traced events. - Trace *ChannelTrace -} - -// SubChannelMetric defines the info channelz provides for a specific SubChannel, -// which includes ChannelInternalMetric and channelz-specific data, such as -// channelz id, child list, etc. -type SubChannelMetric struct { - // ID is the channelz id of this subchannel. - ID int64 - // RefName is the human readable reference string of this subchannel. - RefName string - // ChannelData contains subchannel internal metric reported by the subchannel - // through ChannelzMetric(). - ChannelData *ChannelInternalMetric - // NestedChans tracks the nested channel type children of this subchannel in the format of - // a map from nested channel channelz id to corresponding reference string. - // Note current grpc implementation doesn't allow subchannel to have nested channels - // as children, therefore, this field is unused. - NestedChans map[int64]string - // SubChans tracks the subchannel type children of this subchannel in the format of a - // map from subchannel channelz id to corresponding reference string. - // Note current grpc implementation doesn't allow subchannel to have subchannels - // as children, therefore, this field is unused. - SubChans map[int64]string - // Sockets tracks the socket type children of this subchannel in the format of a map - // from socket channelz id to corresponding reference string. - Sockets map[int64]string - // Trace contains the most recent traced events. - Trace *ChannelTrace -} - -// ChannelInternalMetric defines the struct that the implementor of Channel interface -// should return from ChannelzMetric(). -type ChannelInternalMetric struct { - // current connectivity state of the channel. - State connectivity.State - // The target this channel originally tried to connect to. May be absent - Target string - // The number of calls started on the channel. - CallsStarted int64 - // The number of calls that have completed with an OK status. - CallsSucceeded int64 - // The number of calls that have a completed with a non-OK status. - CallsFailed int64 - // The last time a call was started on the channel. - LastCallStartedTimestamp time.Time -} - -// ChannelTrace stores traced events on a channel/subchannel and related info. -type ChannelTrace struct { - // EventNum is the number of events that ever got traced (i.e. including those that have been deleted) - EventNum int64 - // CreationTime is the creation time of the trace. - CreationTime time.Time - // Events stores the most recent trace events (up to $maxTraceEntry, newer event will overwrite the - // oldest one) - Events []*TraceEvent -} - -// TraceEvent represent a single trace event -type TraceEvent struct { - // Desc is a simple description of the trace event. - Desc string - // Severity states the severity of this trace event. - Severity Severity - // Timestamp is the event time. - Timestamp time.Time - // RefID is the id of the entity that gets referenced in the event. RefID is 0 if no other entity is - // involved in this event. - // e.g. SubChannel (id: 4[]) Created. --> RefID = 4, RefName = "" (inside []) - RefID int64 - // RefName is the reference name for the entity that gets referenced in the event. - RefName string - // RefType indicates the referenced entity type, i.e Channel or SubChannel. - RefType RefChannelType -} - -// Channel is the interface that should be satisfied in order to be tracked by -// channelz as Channel or SubChannel. -type Channel interface { - ChannelzMetric() *ChannelInternalMetric -} - -type dummyChannel struct{} - -func (d *dummyChannel) ChannelzMetric() *ChannelInternalMetric { - return &ChannelInternalMetric{} -} - -type channel struct { - refName string - c Channel - closeCalled bool - nestedChans map[int64]string - subChans map[int64]string - id int64 - pid int64 - cm *channelMap - trace *channelTrace - // traceRefCount is the number of trace events that reference this channel. - // Non-zero traceRefCount means the trace of this channel cannot be deleted. - traceRefCount int32 -} - -func (c *channel) addChild(id int64, e entry) { - switch v := e.(type) { - case *subChannel: - c.subChans[id] = v.refName - case *channel: - c.nestedChans[id] = v.refName - default: - logger.Errorf("cannot add a child (id = %d) of type %T to a channel", id, e) - } -} - -func (c *channel) deleteChild(id int64) { - delete(c.subChans, id) - delete(c.nestedChans, id) - c.deleteSelfIfReady() -} - -func (c *channel) triggerDelete() { - c.closeCalled = true - c.deleteSelfIfReady() -} - -func (c *channel) getParentID() int64 { - return c.pid -} - -// deleteSelfFromTree tries to delete the channel from the channelz entry relation tree, which means -// deleting the channel reference from its parent's child list. -// -// In order for a channel to be deleted from the tree, it must meet the criteria that, removal of the -// corresponding grpc object has been invoked, and the channel does not have any children left. -// -// The returned boolean value indicates whether the channel has been successfully deleted from tree. -func (c *channel) deleteSelfFromTree() (deleted bool) { - if !c.closeCalled || len(c.subChans)+len(c.nestedChans) != 0 { - return false - } - // not top channel - if c.pid != 0 { - c.cm.findEntry(c.pid).deleteChild(c.id) - } - return true -} - -// deleteSelfFromMap checks whether it is valid to delete the channel from the map, which means -// deleting the channel from channelz's tracking entirely. Users can no longer use id to query the -// channel, and its memory will be garbage collected. -// -// The trace reference count of the channel must be 0 in order to be deleted from the map. This is -// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, -// the trace of the referenced entity must not be deleted. In order to release the resource allocated -// by grpc, the reference to the grpc object is reset to a dummy object. -// -// deleteSelfFromMap must be called after deleteSelfFromTree returns true. -// -// It returns a bool to indicate whether the channel can be safely deleted from map. -func (c *channel) deleteSelfFromMap() (delete bool) { - if c.getTraceRefCount() != 0 { - c.c = &dummyChannel{} - return false - } - return true -} - -// deleteSelfIfReady tries to delete the channel itself from the channelz database. -// The delete process includes two steps: -// 1. delete the channel from the entry relation tree, i.e. delete the channel reference from its -// parent's child list. -// 2. delete the channel from the map, i.e. delete the channel entirely from channelz. Lookup by id -// will return entry not found error. -func (c *channel) deleteSelfIfReady() { - if !c.deleteSelfFromTree() { - return - } - if !c.deleteSelfFromMap() { - return - } - c.cm.deleteEntry(c.id) - c.trace.clear() -} - -func (c *channel) getChannelTrace() *channelTrace { - return c.trace -} - -func (c *channel) incrTraceRefCount() { - atomic.AddInt32(&c.traceRefCount, 1) -} - -func (c *channel) decrTraceRefCount() { - atomic.AddInt32(&c.traceRefCount, -1) -} - -func (c *channel) getTraceRefCount() int { - i := atomic.LoadInt32(&c.traceRefCount) - return int(i) -} - -func (c *channel) getRefName() string { - return c.refName -} - -type subChannel struct { - refName string - c Channel - closeCalled bool - sockets map[int64]string - id int64 - pid int64 - cm *channelMap - trace *channelTrace - traceRefCount int32 -} - -func (sc *subChannel) addChild(id int64, e entry) { - if v, ok := e.(*normalSocket); ok { - sc.sockets[id] = v.refName - } else { - logger.Errorf("cannot add a child (id = %d) of type %T to a subChannel", id, e) - } -} - -func (sc *subChannel) deleteChild(id int64) { - delete(sc.sockets, id) - sc.deleteSelfIfReady() -} - -func (sc *subChannel) triggerDelete() { - sc.closeCalled = true - sc.deleteSelfIfReady() -} - -func (sc *subChannel) getParentID() int64 { - return sc.pid -} - -// deleteSelfFromTree tries to delete the subchannel from the channelz entry relation tree, which -// means deleting the subchannel reference from its parent's child list. -// -// In order for a subchannel to be deleted from the tree, it must meet the criteria that, removal of -// the corresponding grpc object has been invoked, and the subchannel does not have any children left. -// -// The returned boolean value indicates whether the channel has been successfully deleted from tree. -func (sc *subChannel) deleteSelfFromTree() (deleted bool) { - if !sc.closeCalled || len(sc.sockets) != 0 { - return false - } - sc.cm.findEntry(sc.pid).deleteChild(sc.id) - return true -} - -// deleteSelfFromMap checks whether it is valid to delete the subchannel from the map, which means -// deleting the subchannel from channelz's tracking entirely. Users can no longer use id to query -// the subchannel, and its memory will be garbage collected. -// -// The trace reference count of the subchannel must be 0 in order to be deleted from the map. This is -// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, -// the trace of the referenced entity must not be deleted. In order to release the resource allocated -// by grpc, the reference to the grpc object is reset to a dummy object. -// -// deleteSelfFromMap must be called after deleteSelfFromTree returns true. -// -// It returns a bool to indicate whether the channel can be safely deleted from map. -func (sc *subChannel) deleteSelfFromMap() (delete bool) { - if sc.getTraceRefCount() != 0 { - // free the grpc struct (i.e. addrConn) - sc.c = &dummyChannel{} - return false - } - return true -} - -// deleteSelfIfReady tries to delete the subchannel itself from the channelz database. -// The delete process includes two steps: -// 1. delete the subchannel from the entry relation tree, i.e. delete the subchannel reference from -// its parent's child list. -// 2. delete the subchannel from the map, i.e. delete the subchannel entirely from channelz. Lookup -// by id will return entry not found error. -func (sc *subChannel) deleteSelfIfReady() { - if !sc.deleteSelfFromTree() { - return - } - if !sc.deleteSelfFromMap() { - return - } - sc.cm.deleteEntry(sc.id) - sc.trace.clear() -} - -func (sc *subChannel) getChannelTrace() *channelTrace { - return sc.trace -} - -func (sc *subChannel) incrTraceRefCount() { - atomic.AddInt32(&sc.traceRefCount, 1) -} - -func (sc *subChannel) decrTraceRefCount() { - atomic.AddInt32(&sc.traceRefCount, -1) -} - -func (sc *subChannel) getTraceRefCount() int { - i := atomic.LoadInt32(&sc.traceRefCount) - return int(i) -} - -func (sc *subChannel) getRefName() string { - return sc.refName -} - -// SocketMetric defines the info channelz provides for a specific Socket, which -// includes SocketInternalMetric and channelz-specific data, such as channelz id, etc. -type SocketMetric struct { - // ID is the channelz id of this socket. - ID int64 - // RefName is the human readable reference string of this socket. - RefName string - // SocketData contains socket internal metric reported by the socket through - // ChannelzMetric(). - SocketData *SocketInternalMetric -} - -// SocketInternalMetric defines the struct that the implementor of Socket interface -// should return from ChannelzMetric(). -type SocketInternalMetric struct { - // The number of streams that have been started. - StreamsStarted int64 - // The number of streams that have ended successfully: - // On client side, receiving frame with eos bit set. - // On server side, sending frame with eos bit set. - StreamsSucceeded int64 - // The number of streams that have ended unsuccessfully: - // On client side, termination without receiving frame with eos bit set. - // On server side, termination without sending frame with eos bit set. - StreamsFailed int64 - // The number of messages successfully sent on this socket. - MessagesSent int64 - MessagesReceived int64 - // The number of keep alives sent. This is typically implemented with HTTP/2 - // ping messages. - KeepAlivesSent int64 - // The last time a stream was created by this endpoint. Usually unset for - // servers. - LastLocalStreamCreatedTimestamp time.Time - // The last time a stream was created by the remote endpoint. Usually unset - // for clients. - LastRemoteStreamCreatedTimestamp time.Time - // The last time a message was sent by this endpoint. - LastMessageSentTimestamp time.Time - // The last time a message was received by this endpoint. - LastMessageReceivedTimestamp time.Time - // The amount of window, granted to the local endpoint by the remote endpoint. - // This may be slightly out of date due to network latency. This does NOT - // include stream level or TCP level flow control info. - LocalFlowControlWindow int64 - // The amount of window, granted to the remote endpoint by the local endpoint. - // This may be slightly out of date due to network latency. This does NOT - // include stream level or TCP level flow control info. - RemoteFlowControlWindow int64 - // The locally bound address. - LocalAddr net.Addr - // The remote bound address. May be absent. - RemoteAddr net.Addr - // Optional, represents the name of the remote endpoint, if different than - // the original target name. - RemoteName string - SocketOptions *SocketOptionData - Security credentials.ChannelzSecurityValue -} - -// Socket is the interface that should be satisfied in order to be tracked by -// channelz as Socket. -type Socket interface { - ChannelzMetric() *SocketInternalMetric -} - -type listenSocket struct { - refName string - s Socket - id int64 - pid int64 - cm *channelMap -} - -func (ls *listenSocket) addChild(id int64, e entry) { - logger.Errorf("cannot add a child (id = %d) of type %T to a listen socket", id, e) -} - -func (ls *listenSocket) deleteChild(id int64) { - logger.Errorf("cannot delete a child (id = %d) from a listen socket", id) -} - -func (ls *listenSocket) triggerDelete() { - ls.cm.deleteEntry(ls.id) - ls.cm.findEntry(ls.pid).deleteChild(ls.id) -} - -func (ls *listenSocket) deleteSelfIfReady() { - logger.Errorf("cannot call deleteSelfIfReady on a listen socket") -} - -func (ls *listenSocket) getParentID() int64 { - return ls.pid -} - -type normalSocket struct { - refName string - s Socket - id int64 - pid int64 - cm *channelMap -} - -func (ns *normalSocket) addChild(id int64, e entry) { - logger.Errorf("cannot add a child (id = %d) of type %T to a normal socket", id, e) -} - -func (ns *normalSocket) deleteChild(id int64) { - logger.Errorf("cannot delete a child (id = %d) from a normal socket", id) -} - -func (ns *normalSocket) triggerDelete() { - ns.cm.deleteEntry(ns.id) - ns.cm.findEntry(ns.pid).deleteChild(ns.id) -} - -func (ns *normalSocket) deleteSelfIfReady() { - logger.Errorf("cannot call deleteSelfIfReady on a normal socket") -} - -func (ns *normalSocket) getParentID() int64 { - return ns.pid -} - -// ServerMetric defines the info channelz provides for a specific Server, which -// includes ServerInternalMetric and channelz-specific data, such as channelz id, -// child list, etc. -type ServerMetric struct { - // ID is the channelz id of this server. - ID int64 - // RefName is the human readable reference string of this server. - RefName string - // ServerData contains server internal metric reported by the server through - // ChannelzMetric(). - ServerData *ServerInternalMetric - // ListenSockets tracks the listener socket type children of this server in the - // format of a map from socket channelz id to corresponding reference string. - ListenSockets map[int64]string -} - -// ServerInternalMetric defines the struct that the implementor of Server interface -// should return from ChannelzMetric(). -type ServerInternalMetric struct { - // The number of incoming calls started on the server. - CallsStarted int64 - // The number of incoming calls that have completed with an OK status. - CallsSucceeded int64 - // The number of incoming calls that have a completed with a non-OK status. - CallsFailed int64 - // The last time a call was started on the server. - LastCallStartedTimestamp time.Time -} - -// Server is the interface to be satisfied in order to be tracked by channelz as -// Server. -type Server interface { - ChannelzMetric() *ServerInternalMetric -} - -type server struct { - refName string - s Server - closeCalled bool - sockets map[int64]string - listenSockets map[int64]string - id int64 - cm *channelMap -} - -func (s *server) addChild(id int64, e entry) { - switch v := e.(type) { - case *normalSocket: - s.sockets[id] = v.refName - case *listenSocket: - s.listenSockets[id] = v.refName - default: - logger.Errorf("cannot add a child (id = %d) of type %T to a server", id, e) - } -} - -func (s *server) deleteChild(id int64) { - delete(s.sockets, id) - delete(s.listenSockets, id) - s.deleteSelfIfReady() -} - -func (s *server) triggerDelete() { - s.closeCalled = true - s.deleteSelfIfReady() -} - -func (s *server) deleteSelfIfReady() { - if !s.closeCalled || len(s.sockets)+len(s.listenSockets) != 0 { - return - } - s.cm.deleteEntry(s.id) -} - -func (s *server) getParentID() int64 { - return 0 -} - -type tracedChannel interface { - getChannelTrace() *channelTrace - incrTraceRefCount() - decrTraceRefCount() - getRefName() string -} - -type channelTrace struct { - cm *channelMap - createdTime time.Time - eventCount int64 - mu sync.Mutex - events []*TraceEvent -} - -func (c *channelTrace) append(e *TraceEvent) { - c.mu.Lock() - if len(c.events) == getMaxTraceEntry() { - del := c.events[0] - c.events = c.events[1:] - if del.RefID != 0 { - // start recursive cleanup in a goroutine to not block the call originated from grpc. - go func() { - // need to acquire c.cm.mu lock to call the unlocked attemptCleanup func. - c.cm.mu.Lock() - c.cm.decrTraceRefCount(del.RefID) - c.cm.mu.Unlock() - }() - } - } - e.Timestamp = time.Now() - c.events = append(c.events, e) - c.eventCount++ - c.mu.Unlock() -} - -func (c *channelTrace) clear() { - c.mu.Lock() - for _, e := range c.events { - if e.RefID != 0 { - // caller should have already held the c.cm.mu lock. - c.cm.decrTraceRefCount(e.RefID) - } - } - c.mu.Unlock() -} - -// Severity is the severity level of a trace event. -// The canonical enumeration of all valid values is here: -// https://github.com/grpc/grpc-proto/blob/9b13d199cc0d4703c7ea26c9c330ba695866eb23/grpc/channelz/v1/channelz.proto#L126. -type Severity int - -const ( - // CtUnknown indicates unknown severity of a trace event. - CtUnknown Severity = iota - // CtInfo indicates info level severity of a trace event. - CtInfo - // CtWarning indicates warning level severity of a trace event. - CtWarning - // CtError indicates error level severity of a trace event. - CtError -) - -// RefChannelType is the type of the entity being referenced in a trace event. -type RefChannelType int - -const ( - // RefUnknown indicates an unknown entity type, the zero value for this type. - RefUnknown RefChannelType = iota - // RefChannel indicates the referenced entity is a Channel. - RefChannel - // RefSubChannel indicates the referenced entity is a SubChannel. - RefSubChannel - // RefServer indicates the referenced entity is a Server. - RefServer - // RefListenSocket indicates the referenced entity is a ListenSocket. - RefListenSocket - // RefNormalSocket indicates the referenced entity is a NormalSocket. - RefNormalSocket -) - -var refChannelTypeToString = map[RefChannelType]string{ - RefUnknown: "Unknown", - RefChannel: "Channel", - RefSubChannel: "SubChannel", - RefServer: "Server", - RefListenSocket: "ListenSocket", - RefNormalSocket: "NormalSocket", -} - -func (r RefChannelType) String() string { - return refChannelTypeToString[r] -} - -func (c *channelTrace) dumpData() *ChannelTrace { - c.mu.Lock() - ct := &ChannelTrace{EventNum: c.eventCount, CreationTime: c.createdTime} - ct.Events = c.events[:len(c.events)] - c.mu.Unlock() - return ct -} diff --git a/vendor/google.golang.org/grpc/internal/credentials/credentials.go b/vendor/google.golang.org/grpc/internal/credentials/credentials.go index 32c9b590..9deee7f6 100644 --- a/vendor/google.golang.org/grpc/internal/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/internal/credentials/credentials.go @@ -25,12 +25,12 @@ import ( type requestInfoKey struct{} // NewRequestInfoContext creates a context with ri. -func NewRequestInfoContext(ctx context.Context, ri interface{}) context.Context { +func NewRequestInfoContext(ctx context.Context, ri any) context.Context { return context.WithValue(ctx, requestInfoKey{}, ri) } // RequestInfoFromContext extracts the RequestInfo from ctx. -func RequestInfoFromContext(ctx context.Context) interface{} { +func RequestInfoFromContext(ctx context.Context) any { return ctx.Value(requestInfoKey{}) } @@ -39,11 +39,11 @@ func RequestInfoFromContext(ctx context.Context) interface{} { type clientHandshakeInfoKey struct{} // ClientHandshakeInfoFromContext extracts the ClientHandshakeInfo from ctx. -func ClientHandshakeInfoFromContext(ctx context.Context) interface{} { +func ClientHandshakeInfoFromContext(ctx context.Context) any { return ctx.Value(clientHandshakeInfoKey{}) } // NewClientHandshakeInfoContext creates a context with chi. -func NewClientHandshakeInfoContext(ctx context.Context, chi interface{}) context.Context { +func NewClientHandshakeInfoContext(ctx context.Context, chi any) context.Context { return context.WithValue(ctx, clientHandshakeInfoKey{}, chi) } diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 80fd5c7d..685a3cb4 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -36,10 +36,13 @@ var ( // "GRPC_RING_HASH_CAP". This does not override the default bounds // checking which NACKs configs specifying ring sizes > 8*1024*1024 (~8M). RingHashCap = uint64FromEnv("GRPC_RING_HASH_CAP", 4096, 1, 8*1024*1024) - // PickFirstLBConfig is set if we should support configuration of the - // pick_first LB policy, which can be enabled by setting the environment - // variable "GRPC_EXPERIMENTAL_PICKFIRST_LB_CONFIG" to "true". - PickFirstLBConfig = boolFromEnv("GRPC_EXPERIMENTAL_PICKFIRST_LB_CONFIG", false) + // LeastRequestLB is set if we should support the least_request_experimental + // LB policy, which can be enabled by setting the environment variable + // "GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST" to "true". + LeastRequestLB = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST", false) + // ALTSMaxConcurrentHandshakes is the maximum number of concurrent ALTS + // handshakes that can be performed. + ALTSMaxConcurrentHandshakes = uint64FromEnv("GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES", 100, 1, 100) ) func boolFromEnv(envVar string, def bool) bool { diff --git a/vendor/google.golang.org/grpc/internal/envconfig/xds.go b/vendor/google.golang.org/grpc/internal/envconfig/xds.go index 02b4b6a1..29f234ac 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/xds.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/xds.go @@ -50,46 +50,7 @@ var ( // // When both bootstrap FileName and FileContent are set, FileName is used. XDSBootstrapFileContent = os.Getenv(XDSBootstrapFileContentEnv) - // XDSRingHash indicates whether ring hash support is enabled, which can be - // disabled by setting the environment variable - // "GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH" to "false". - XDSRingHash = boolFromEnv("GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH", true) - // XDSClientSideSecurity is used to control processing of security - // configuration on the client-side. - // - // Note that there is no env var protection for the server-side because we - // have a brand new API on the server-side and users explicitly need to use - // the new API to get security integration on the server. - XDSClientSideSecurity = boolFromEnv("GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT", true) - // XDSAggregateAndDNS indicates whether processing of aggregated cluster and - // DNS cluster is enabled, which can be disabled by setting the environment - // variable "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER" - // to "false". - XDSAggregateAndDNS = boolFromEnv("GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER", true) - - // XDSRBAC indicates whether xDS configured RBAC HTTP Filter is enabled, - // which can be disabled by setting the environment variable - // "GRPC_XDS_EXPERIMENTAL_RBAC" to "false". - XDSRBAC = boolFromEnv("GRPC_XDS_EXPERIMENTAL_RBAC", true) - // XDSOutlierDetection indicates whether outlier detection support is - // enabled, which can be disabled by setting the environment variable - // "GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION" to "false". - XDSOutlierDetection = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION", true) - // XDSFederation indicates whether federation support is enabled, which can - // be enabled by setting the environment variable - // "GRPC_EXPERIMENTAL_XDS_FEDERATION" to "true". - XDSFederation = boolFromEnv("GRPC_EXPERIMENTAL_XDS_FEDERATION", true) - - // XDSRLS indicates whether processing of Cluster Specifier plugins and - // support for the RLS CLuster Specifier is enabled, which can be disabled by - // setting the environment variable "GRPC_EXPERIMENTAL_XDS_RLS_LB" to - // "false". - XDSRLS = boolFromEnv("GRPC_EXPERIMENTAL_XDS_RLS_LB", true) // C2PResolverTestOnlyTrafficDirectorURI is the TD URI for testing. C2PResolverTestOnlyTrafficDirectorURI = os.Getenv("GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI") - // XDSCustomLBPolicy indicates whether Custom LB Policies are enabled, which - // can be disabled by setting the environment variable - // "GRPC_EXPERIMENTAL_XDS_CUSTOM_LB_CONFIG" to "false". - XDSCustomLBPolicy = boolFromEnv("GRPC_EXPERIMENTAL_XDS_CUSTOM_LB_CONFIG", true) ) diff --git a/vendor/google.golang.org/grpc/internal/experimental.go b/vendor/google.golang.org/grpc/internal/experimental.go new file mode 100644 index 00000000..7f7044e1 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/experimental.go @@ -0,0 +1,28 @@ +/* + * Copyright 2023 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 internal + +var ( + // WithRecvBufferPool is implemented by the grpc package and returns a dial + // option to configure a shared buffer pool for a grpc.ClientConn. + WithRecvBufferPool any // func (grpc.SharedBufferPool) grpc.DialOption + + // RecvBufferPool is implemented by the grpc package and returns a server + // option to configure a shared buffer pool for a grpc.Server. + RecvBufferPool any // func (grpc.SharedBufferPool) grpc.ServerOption +) diff --git a/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go b/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go index b68e26a3..bfc45102 100644 --- a/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go +++ b/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go @@ -30,7 +30,7 @@ var Logger LoggerV2 var DepthLogger DepthLoggerV2 // InfoDepth logs to the INFO log at the specified depth. -func InfoDepth(depth int, args ...interface{}) { +func InfoDepth(depth int, args ...any) { if DepthLogger != nil { DepthLogger.InfoDepth(depth, args...) } else { @@ -39,7 +39,7 @@ func InfoDepth(depth int, args ...interface{}) { } // WarningDepth logs to the WARNING log at the specified depth. -func WarningDepth(depth int, args ...interface{}) { +func WarningDepth(depth int, args ...any) { if DepthLogger != nil { DepthLogger.WarningDepth(depth, args...) } else { @@ -48,7 +48,7 @@ func WarningDepth(depth int, args ...interface{}) { } // ErrorDepth logs to the ERROR log at the specified depth. -func ErrorDepth(depth int, args ...interface{}) { +func ErrorDepth(depth int, args ...any) { if DepthLogger != nil { DepthLogger.ErrorDepth(depth, args...) } else { @@ -57,7 +57,7 @@ func ErrorDepth(depth int, args ...interface{}) { } // FatalDepth logs to the FATAL log at the specified depth. -func FatalDepth(depth int, args ...interface{}) { +func FatalDepth(depth int, args ...any) { if DepthLogger != nil { DepthLogger.FatalDepth(depth, args...) } else { @@ -71,35 +71,35 @@ func FatalDepth(depth int, args ...interface{}) { // is defined here to avoid a circular dependency. type LoggerV2 interface { // Info logs to INFO log. Arguments are handled in the manner of fmt.Print. - Info(args ...interface{}) + Info(args ...any) // Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println. - Infoln(args ...interface{}) + Infoln(args ...any) // Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf. - Infof(format string, args ...interface{}) + Infof(format string, args ...any) // Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print. - Warning(args ...interface{}) + Warning(args ...any) // Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println. - Warningln(args ...interface{}) + Warningln(args ...any) // Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf. - Warningf(format string, args ...interface{}) + Warningf(format string, args ...any) // Error logs to ERROR log. Arguments are handled in the manner of fmt.Print. - Error(args ...interface{}) + Error(args ...any) // Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println. - Errorln(args ...interface{}) + Errorln(args ...any) // Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. - Errorf(format string, args ...interface{}) + Errorf(format string, args ...any) // Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatal(args ...interface{}) + Fatal(args ...any) // Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatalln(args ...interface{}) + Fatalln(args ...any) // Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatalf(format string, args ...interface{}) + Fatalf(format string, args ...any) // V reports whether verbosity level l is at least the requested verbose level. V(l int) bool } @@ -116,11 +116,11 @@ type LoggerV2 interface { // later release. type DepthLoggerV2 interface { // InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Println. - InfoDepth(depth int, args ...interface{}) + InfoDepth(depth int, args ...any) // WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Println. - WarningDepth(depth int, args ...interface{}) + WarningDepth(depth int, args ...any) // ErrorDepth logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Println. - ErrorDepth(depth int, args ...interface{}) + ErrorDepth(depth int, args ...any) // FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Println. - FatalDepth(depth int, args ...interface{}) + FatalDepth(depth int, args ...any) } diff --git a/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go b/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go index 02224b42..faa998de 100644 --- a/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go +++ b/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go @@ -31,7 +31,7 @@ type PrefixLogger struct { } // Infof does info logging. -func (pl *PrefixLogger) Infof(format string, args ...interface{}) { +func (pl *PrefixLogger) Infof(format string, args ...any) { if pl != nil { // Handle nil, so the tests can pass in a nil logger. format = pl.prefix + format @@ -42,7 +42,7 @@ func (pl *PrefixLogger) Infof(format string, args ...interface{}) { } // Warningf does warning logging. -func (pl *PrefixLogger) Warningf(format string, args ...interface{}) { +func (pl *PrefixLogger) Warningf(format string, args ...any) { if pl != nil { format = pl.prefix + format pl.logger.WarningDepth(1, fmt.Sprintf(format, args...)) @@ -52,7 +52,7 @@ func (pl *PrefixLogger) Warningf(format string, args ...interface{}) { } // Errorf does error logging. -func (pl *PrefixLogger) Errorf(format string, args ...interface{}) { +func (pl *PrefixLogger) Errorf(format string, args ...any) { if pl != nil { format = pl.prefix + format pl.logger.ErrorDepth(1, fmt.Sprintf(format, args...)) @@ -62,7 +62,7 @@ func (pl *PrefixLogger) Errorf(format string, args ...interface{}) { } // Debugf does info logging at verbose level 2. -func (pl *PrefixLogger) Debugf(format string, args ...interface{}) { +func (pl *PrefixLogger) Debugf(format string, args ...any) { // TODO(6044): Refactor interfaces LoggerV2 and DepthLogger, and maybe // rewrite PrefixLogger a little to ensure that we don't use the global // `Logger` here, and instead use the `logger` field. diff --git a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go index d08e3e90..0126d6b5 100644 --- a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go +++ b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go @@ -1,3 +1,8 @@ +//go:build !go1.21 + +// TODO: when this file is deleted (after Go 1.20 support is dropped), delete +// all of grpcrand and call the rand package directly. + /* * * Copyright 2018 gRPC authors. @@ -80,6 +85,13 @@ func Uint32() uint32 { return r.Uint32() } +// ExpFloat64 implements rand.ExpFloat64 on the grpcrand global source. +func ExpFloat64() float64 { + mu.Lock() + defer mu.Unlock() + return r.ExpFloat64() +} + // Shuffle implements rand.Shuffle on the grpcrand global source. var Shuffle = func(n int, f func(int, int)) { mu.Lock() diff --git a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go new file mode 100644 index 00000000..c37299af --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go @@ -0,0 +1,73 @@ +//go:build go1.21 + +/* + * + * Copyright 2024 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 grpcrand implements math/rand functions in a concurrent-safe way +// with a global random source, independent of math/rand's global source. +package grpcrand + +import "math/rand" + +// This implementation will be used for Go version 1.21 or newer. +// For older versions, the original implementation with mutex will be used. + +// Int implements rand.Int on the grpcrand global source. +func Int() int { + return rand.Int() +} + +// Int63n implements rand.Int63n on the grpcrand global source. +func Int63n(n int64) int64 { + return rand.Int63n(n) +} + +// Intn implements rand.Intn on the grpcrand global source. +func Intn(n int) int { + return rand.Intn(n) +} + +// Int31n implements rand.Int31n on the grpcrand global source. +func Int31n(n int32) int32 { + return rand.Int31n(n) +} + +// Float64 implements rand.Float64 on the grpcrand global source. +func Float64() float64 { + return rand.Float64() +} + +// Uint64 implements rand.Uint64 on the grpcrand global source. +func Uint64() uint64 { + return rand.Uint64() +} + +// Uint32 implements rand.Uint32 on the grpcrand global source. +func Uint32() uint32 { + return rand.Uint32() +} + +// ExpFloat64 implements rand.ExpFloat64 on the grpcrand global source. +func ExpFloat64() float64 { + return rand.ExpFloat64() +} + +// Shuffle implements rand.Shuffle on the grpcrand global source. +var Shuffle = func(n int, f func(int, int)) { + rand.Shuffle(n, f) +} 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 37b8d411..f7f40a16 100644 --- a/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go +++ b/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go @@ -20,7 +20,6 @@ package grpcsync import ( "context" - "sync" "google.golang.org/grpc/internal/buffer" ) @@ -32,14 +31,12 @@ import ( // // This type is safe for concurrent access. type CallbackSerializer struct { - // Done is closed once the serializer is shut down completely, i.e all + // done is closed once the serializer is shut down completely, i.e all // scheduled callbacks are executed and the serializer has deallocated all // its resources. - Done chan struct{} + done chan struct{} callbacks *buffer.Unbounded - closedMu sync.Mutex - closed bool } // NewCallbackSerializer returns a new CallbackSerializer instance. The provided @@ -48,12 +45,12 @@ type CallbackSerializer struct { // callbacks will be added once this context is canceled, and any pending un-run // callbacks will be executed before the serializer is shut down. func NewCallbackSerializer(ctx context.Context) *CallbackSerializer { - t := &CallbackSerializer{ - Done: make(chan struct{}), + cs := &CallbackSerializer{ + done: make(chan struct{}), callbacks: buffer.NewUnbounded(), } - go t.run(ctx) - return t + go cs.run(ctx) + return cs } // Schedule adds a callback to be scheduled after existing callbacks are run. @@ -64,56 +61,40 @@ func NewCallbackSerializer(ctx context.Context) *CallbackSerializer { // Return value indicates if the callback was successfully added to the list of // callbacks to be executed by the serializer. It is not possible to add // callbacks once the context passed to NewCallbackSerializer is cancelled. -func (t *CallbackSerializer) Schedule(f func(ctx context.Context)) bool { - t.closedMu.Lock() - defer t.closedMu.Unlock() - - if t.closed { - return false - } - t.callbacks.Put(f) - return true +func (cs *CallbackSerializer) Schedule(f func(ctx context.Context)) bool { + return cs.callbacks.Put(f) == nil } -func (t *CallbackSerializer) run(ctx context.Context) { - var backlog []func(context.Context) +func (cs *CallbackSerializer) run(ctx context.Context) { + defer close(cs.done) - defer close(t.Done) + // TODO: when Go 1.21 is the oldest supported version, this loop and Close + // can be replaced with: + // + // context.AfterFunc(ctx, cs.callbacks.Close) for ctx.Err() == nil { select { case <-ctx.Done(): // Do nothing here. Next iteration of the for loop will not happen, // since ctx.Err() would be non-nil. - case callback, ok := <-t.callbacks.Get(): - if !ok { - return - } - t.callbacks.Load() - callback.(func(ctx context.Context))(ctx) + case cb := <-cs.callbacks.Get(): + cs.callbacks.Load() + cb.(func(context.Context))(ctx) } } - // Fetch pending callbacks if any, and execute them before returning from - // this method and closing t.Done. - t.closedMu.Lock() - t.closed = true - backlog = t.fetchPendingCallbacks() - t.callbacks.Close() - t.closedMu.Unlock() - for _, b := range backlog { - b(ctx) + // Close the buffer to prevent new callbacks from being added. + cs.callbacks.Close() + + // Run all pending callbacks. + for cb := range cs.callbacks.Get() { + cs.callbacks.Load() + cb.(func(context.Context))(ctx) } } -func (t *CallbackSerializer) fetchPendingCallbacks() []func(context.Context) { - var backlog []func(context.Context) - for { - select { - case b := <-t.callbacks.Get(): - backlog = append(backlog, b.(func(context.Context))) - t.callbacks.Load() - default: - return backlog - } - } +// Done returns a channel that is closed after the context passed to +// NewCallbackSerializer is canceled and all callbacks have been executed. +func (cs *CallbackSerializer) Done() <-chan struct{} { + return cs.done } diff --git a/vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go b/vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go new file mode 100644 index 00000000..aef8cec1 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go @@ -0,0 +1,121 @@ +/* + * + * Copyright 2023 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 ( + "context" + "sync" +) + +// Subscriber represents an entity that is subscribed to messages published on +// a PubSub. It wraps the callback to be invoked by the PubSub when a new +// message is published. +type Subscriber interface { + // OnMessage is invoked when a new message is published. Implementations + // must not block in this method. + OnMessage(msg any) +} + +// PubSub is a simple one-to-many publish-subscribe system that supports +// messages of arbitrary type. It guarantees that messages are delivered in +// the same order in which they were published. +// +// Publisher invokes the Publish() method to publish new messages, while +// subscribers interested in receiving these messages register a callback +// via the Subscribe() method. +// +// Once a PubSub is stopped, no more messages can be published, but any pending +// published messages will be delivered to the subscribers. Done may be used +// to determine when all published messages have been delivered. +type PubSub struct { + cs *CallbackSerializer + + // Access to the below fields are guarded by this mutex. + mu sync.Mutex + msg any + subscribers map[Subscriber]bool +} + +// NewPubSub returns a new PubSub instance. Users should cancel the +// provided context to shutdown the PubSub. +func NewPubSub(ctx context.Context) *PubSub { + return &PubSub{ + cs: NewCallbackSerializer(ctx), + subscribers: map[Subscriber]bool{}, + } +} + +// Subscribe registers the provided Subscriber to the PubSub. +// +// If the PubSub contains a previously published message, the Subscriber's +// OnMessage() callback will be invoked asynchronously with the existing +// message to begin with, and subsequently for every newly published message. +// +// The caller is responsible for invoking the returned cancel function to +// unsubscribe itself from the PubSub. +func (ps *PubSub) Subscribe(sub Subscriber) (cancel func()) { + ps.mu.Lock() + defer ps.mu.Unlock() + + ps.subscribers[sub] = true + + if ps.msg != nil { + msg := ps.msg + ps.cs.Schedule(func(context.Context) { + ps.mu.Lock() + defer ps.mu.Unlock() + if !ps.subscribers[sub] { + return + } + sub.OnMessage(msg) + }) + } + + return func() { + ps.mu.Lock() + defer ps.mu.Unlock() + delete(ps.subscribers, sub) + } +} + +// Publish publishes the provided message to the PubSub, and invokes +// callbacks registered by subscribers asynchronously. +func (ps *PubSub) Publish(msg any) { + ps.mu.Lock() + defer ps.mu.Unlock() + + ps.msg = msg + for sub := range ps.subscribers { + s := sub + ps.cs.Schedule(func(context.Context) { + ps.mu.Lock() + defer ps.mu.Unlock() + if !ps.subscribers[s] { + return + } + s.OnMessage(msg) + }) + } +} + +// Done returns a channel that is closed after the context passed to NewPubSub +// is canceled and all updates have been sent to subscribers. +func (ps *PubSub) Done() <-chan struct{} { + return ps.cs.Done() +} diff --git a/vendor/google.golang.org/grpc/internal/idle/idle.go b/vendor/google.golang.org/grpc/internal/idle/idle.go new file mode 100644 index 00000000..fe49cb74 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/idle/idle.go @@ -0,0 +1,278 @@ +/* + * + * Copyright 2023 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 idle contains a component for managing idleness (entering and exiting) +// based on RPC activity. +package idle + +import ( + "fmt" + "math" + "sync" + "sync/atomic" + "time" +) + +// For overriding in unit tests. +var timeAfterFunc = func(d time.Duration, f func()) *time.Timer { + return time.AfterFunc(d, f) +} + +// Enforcer is the functionality provided by grpc.ClientConn to enter +// and exit from idle mode. +type Enforcer interface { + ExitIdleMode() error + EnterIdleMode() +} + +// Manager implements idleness detection and calls the configured Enforcer to +// enter/exit idle mode when appropriate. Must be created by NewManager. +type Manager struct { + // State accessed atomically. + lastCallEndTime int64 // Unix timestamp in nanos; time when the most recent RPC completed. + activeCallsCount int32 // Count of active RPCs; -math.MaxInt32 means channel is idle or is trying to get there. + activeSinceLastTimerCheck int32 // Boolean; True if there was an RPC since the last timer callback. + closed int32 // Boolean; True when the manager is closed. + + // Can be accessed without atomics or mutex since these are set at creation + // time and read-only after that. + enforcer Enforcer // Functionality provided by grpc.ClientConn. + timeout time.Duration + + // idleMu is used to guarantee mutual exclusion in two scenarios: + // - Opposing intentions: + // - a: Idle timeout has fired and handleIdleTimeout() is trying to put + // the channel in idle mode because the channel has been inactive. + // - b: At the same time an RPC is made on the channel, and OnCallBegin() + // is trying to prevent the channel from going idle. + // - Competing intentions: + // - The channel is in idle mode and there are multiple RPCs starting at + // the same time, all trying to move the channel out of idle. Only one + // of them should succeed in doing so, while the other RPCs should + // piggyback on the first one and be successfully handled. + idleMu sync.RWMutex + actuallyIdle bool + timer *time.Timer +} + +// NewManager creates a new idleness manager implementation for the +// given idle timeout. It begins in idle mode. +func NewManager(enforcer Enforcer, timeout time.Duration) *Manager { + return &Manager{ + enforcer: enforcer, + timeout: timeout, + actuallyIdle: true, + activeCallsCount: -math.MaxInt32, + } +} + +// resetIdleTimerLocked resets the idle timer to the given duration. Called +// when exiting idle mode or when the timer fires and we need to reset it. +func (m *Manager) resetIdleTimerLocked(d time.Duration) { + if m.isClosed() || m.timeout == 0 || m.actuallyIdle { + return + } + + // It is safe to ignore the return value from Reset() because this method is + // only ever called from the timer callback or when exiting idle mode. + if m.timer != nil { + m.timer.Stop() + } + m.timer = timeAfterFunc(d, m.handleIdleTimeout) +} + +func (m *Manager) resetIdleTimer(d time.Duration) { + m.idleMu.Lock() + defer m.idleMu.Unlock() + m.resetIdleTimerLocked(d) +} + +// handleIdleTimeout is the timer callback that is invoked upon expiry of the +// configured idle timeout. The channel is considered inactive if there are no +// ongoing calls and no RPC activity since the last time the timer fired. +func (m *Manager) handleIdleTimeout() { + if m.isClosed() { + return + } + + if atomic.LoadInt32(&m.activeCallsCount) > 0 { + m.resetIdleTimer(m.timeout) + return + } + + // There has been activity on the channel since we last got here. Reset the + // timer and return. + if atomic.LoadInt32(&m.activeSinceLastTimerCheck) == 1 { + // Set the timer to fire after a duration of idle timeout, calculated + // from the time the most recent RPC completed. + atomic.StoreInt32(&m.activeSinceLastTimerCheck, 0) + m.resetIdleTimer(time.Duration(atomic.LoadInt64(&m.lastCallEndTime)-time.Now().UnixNano()) + m.timeout) + return + } + + // Now that we've checked that there has been no activity, attempt to enter + // idle mode, which is very likely to succeed. + if m.tryEnterIdleMode() { + // Successfully entered idle mode. No timer needed until we exit idle. + return + } + + // Failed to enter idle mode due to a concurrent RPC that kept the channel + // active, or because of an error from the channel. Undo the attempt to + // enter idle, and reset the timer to try again later. + m.resetIdleTimer(m.timeout) +} + +// tryEnterIdleMode instructs the channel to enter idle mode. But before +// that, it performs a last minute check to ensure that no new RPC has come in, +// making the channel active. +// +// Return value indicates whether or not the channel moved to idle mode. +// +// Holds idleMu which ensures mutual exclusion with exitIdleMode. +func (m *Manager) tryEnterIdleMode() bool { + // Setting the activeCallsCount to -math.MaxInt32 indicates to OnCallBegin() + // that the channel is either in idle mode or is trying to get there. + if !atomic.CompareAndSwapInt32(&m.activeCallsCount, 0, -math.MaxInt32) { + // This CAS operation can fail if an RPC started after we checked for + // activity in the timer handler, or one was ongoing from before the + // last time the timer fired, or if a test is attempting to enter idle + // mode without checking. In all cases, abort going into idle mode. + return false + } + // N.B. if we fail to enter idle mode after this, we must re-add + // math.MaxInt32 to m.activeCallsCount. + + m.idleMu.Lock() + defer m.idleMu.Unlock() + + if atomic.LoadInt32(&m.activeCallsCount) != -math.MaxInt32 { + // We raced and lost to a new RPC. Very rare, but stop entering idle. + atomic.AddInt32(&m.activeCallsCount, math.MaxInt32) + return false + } + if atomic.LoadInt32(&m.activeSinceLastTimerCheck) == 1 { + // A very short RPC could have come in (and also finished) after we + // checked for calls count and activity in handleIdleTimeout(), but + // before the CAS operation. So, we need to check for activity again. + atomic.AddInt32(&m.activeCallsCount, math.MaxInt32) + return false + } + + // No new RPCs have come in since we set the active calls count value to + // -math.MaxInt32. And since we have the lock, it is safe to enter idle mode + // unconditionally now. + m.enforcer.EnterIdleMode() + m.actuallyIdle = true + return true +} + +func (m *Manager) EnterIdleModeForTesting() { + m.tryEnterIdleMode() +} + +// OnCallBegin is invoked at the start of every RPC. +func (m *Manager) OnCallBegin() error { + if m.isClosed() { + return nil + } + + if atomic.AddInt32(&m.activeCallsCount, 1) > 0 { + // Channel is not idle now. Set the activity bit and allow the call. + atomic.StoreInt32(&m.activeSinceLastTimerCheck, 1) + return nil + } + + // Channel is either in idle mode or is in the process of moving to idle + // mode. Attempt to exit idle mode to allow this RPC. + if err := m.ExitIdleMode(); err != nil { + // Undo the increment to calls count, and return an error causing the + // RPC to fail. + atomic.AddInt32(&m.activeCallsCount, -1) + return err + } + + atomic.StoreInt32(&m.activeSinceLastTimerCheck, 1) + return nil +} + +// ExitIdleMode instructs m to call the enforcer's ExitIdleMode and update m's +// internal state. +func (m *Manager) ExitIdleMode() error { + // Holds idleMu which ensures mutual exclusion with tryEnterIdleMode. + m.idleMu.Lock() + defer m.idleMu.Unlock() + + if m.isClosed() || !m.actuallyIdle { + // This can happen in three scenarios: + // - handleIdleTimeout() set the calls count to -math.MaxInt32 and called + // tryEnterIdleMode(). But before the latter could grab the lock, an RPC + // came in and OnCallBegin() noticed that the calls count is negative. + // - Channel is in idle mode, and multiple new RPCs come in at the same + // time, all of them notice a negative calls count in OnCallBegin and get + // here. The first one to get the lock would got the channel to exit idle. + // - Channel is not in idle mode, and the user calls Connect which calls + // m.ExitIdleMode. + // + // In any case, there is nothing to do here. + return nil + } + + if err := m.enforcer.ExitIdleMode(); err != nil { + return fmt.Errorf("failed to exit idle mode: %w", err) + } + + // Undo the idle entry process. This also respects any new RPC attempts. + atomic.AddInt32(&m.activeCallsCount, math.MaxInt32) + m.actuallyIdle = false + + // Start a new timer to fire after the configured idle timeout. + m.resetIdleTimerLocked(m.timeout) + return nil +} + +// OnCallEnd is invoked at the end of every RPC. +func (m *Manager) OnCallEnd() { + if m.isClosed() { + return + } + + // Record the time at which the most recent call finished. + atomic.StoreInt64(&m.lastCallEndTime, time.Now().UnixNano()) + + // Decrement the active calls count. This count can temporarily go negative + // when the timer callback is in the process of moving the channel to idle + // mode, but one or more RPCs come in and complete before the timer callback + // can get done with the process of moving to idle mode. + atomic.AddInt32(&m.activeCallsCount, -1) +} + +func (m *Manager) isClosed() bool { + return atomic.LoadInt32(&m.closed) == 1 +} + +func (m *Manager) Close() { + atomic.StoreInt32(&m.closed, 1) + + m.idleMu.Lock() + if m.timer != nil { + m.timer.Stop() + m.timer = nil + } + m.idleMu.Unlock() +} diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go index 42ff39c8..48d24bdb 100644 --- a/vendor/google.golang.org/grpc/internal/internal.go +++ b/vendor/google.golang.org/grpc/internal/internal.go @@ -30,7 +30,7 @@ import ( var ( // WithHealthCheckFunc is set by dialoptions.go - WithHealthCheckFunc interface{} // func (HealthChecker) DialOption + WithHealthCheckFunc any // func (HealthChecker) DialOption // HealthCheckFunc is used to provide client-side LB channel health checking HealthCheckFunc HealthChecker // BalancerUnregister is exported by package balancer to unregister a balancer. @@ -38,8 +38,12 @@ var ( // KeepaliveMinPingTime is the minimum ping interval. This must be 10s by // default, but tests may wish to set it lower for convenience. KeepaliveMinPingTime = 10 * time.Second + // KeepaliveMinServerPingTime is the minimum ping interval for servers. + // This must be 1s by default, but tests may wish to set it lower for + // convenience. + KeepaliveMinServerPingTime = time.Second // ParseServiceConfig parses a JSON representation of the service config. - ParseServiceConfig interface{} // func(string) *serviceconfig.ParseResult + ParseServiceConfig any // func(string) *serviceconfig.ParseResult // EqualServiceConfigForTesting is for testing service config generation and // parsing. Both a and b should be returned by ParseServiceConfig. // This function compares the config without rawJSON stripped, in case the @@ -49,33 +53,33 @@ var ( // given name. This is set by package certprovider for use from xDS // bootstrap code while parsing certificate provider configs in the // bootstrap file. - GetCertificateProviderBuilder interface{} // func(string) certprovider.Builder + GetCertificateProviderBuilder any // func(string) certprovider.Builder // GetXDSHandshakeInfoForTesting returns a pointer to the xds.HandshakeInfo // stored in the passed in attributes. This is set by // credentials/xds/xds.go. - GetXDSHandshakeInfoForTesting interface{} // func (*attributes.Attributes) *xds.HandshakeInfo + GetXDSHandshakeInfoForTesting any // func (*attributes.Attributes) *unsafe.Pointer // GetServerCredentials returns the transport credentials configured on a // gRPC server. An xDS-enabled server needs to know what type of credentials // is configured on the underlying gRPC server. This is set by server.go. - GetServerCredentials interface{} // func (*grpc.Server) credentials.TransportCredentials + GetServerCredentials any // func (*grpc.Server) credentials.TransportCredentials // CanonicalString returns the canonical string of the code defined here: // https://github.com/grpc/grpc/blob/master/doc/statuscodes.md. // // This is used in the 1.0 release of gcp/observability, and thus must not be // deleted or changed. - CanonicalString interface{} // func (codes.Code) string - // DrainServerTransports initiates a graceful close of existing connections - // on a gRPC server accepted on the provided listener address. An - // xDS-enabled server invokes this method on a grpc.Server when a particular - // listener moves to "not-serving" mode. - DrainServerTransports interface{} // func(*grpc.Server, string) + CanonicalString any // func (codes.Code) string + // IsRegisteredMethod returns whether the passed in method is registered as + // a method on the server. + IsRegisteredMethod any // func(*grpc.Server, string) bool + // ServerFromContext returns the server from the context. + ServerFromContext any // func(context.Context) *grpc.Server // AddGlobalServerOptions adds an array of ServerOption that will be // effective globally for newly created servers. The priority will be: 1. // user-provided; 2. this method; 3. default values. // // This is used in the 1.0 release of gcp/observability, and thus must not be // deleted or changed. - AddGlobalServerOptions interface{} // func(opt ...ServerOption) + AddGlobalServerOptions any // func(opt ...ServerOption) // ClearGlobalServerOptions clears the array of extra ServerOption. This // method is useful in testing and benchmarking. // @@ -88,14 +92,14 @@ var ( // // This is used in the 1.0 release of gcp/observability, and thus must not be // deleted or changed. - AddGlobalDialOptions interface{} // func(opt ...DialOption) + AddGlobalDialOptions any // func(opt ...DialOption) // DisableGlobalDialOptions returns a DialOption that prevents the // ClientConn from applying the global DialOptions (set via // AddGlobalDialOptions). // // This is used in the 1.0 release of gcp/observability, and thus must not be // deleted or changed. - DisableGlobalDialOptions interface{} // func() grpc.DialOption + DisableGlobalDialOptions any // func() grpc.DialOption // ClearGlobalDialOptions clears the array of extra DialOption. This // method is useful in testing and benchmarking. // @@ -104,23 +108,26 @@ var ( ClearGlobalDialOptions func() // JoinDialOptions combines the dial options passed as arguments into a // single dial option. - JoinDialOptions interface{} // func(...grpc.DialOption) grpc.DialOption + JoinDialOptions any // func(...grpc.DialOption) grpc.DialOption // JoinServerOptions combines the server options passed as arguments into a // single server option. - JoinServerOptions interface{} // func(...grpc.ServerOption) grpc.ServerOption + JoinServerOptions any // func(...grpc.ServerOption) grpc.ServerOption // WithBinaryLogger returns a DialOption that specifies the binary logger // for a ClientConn. // // This is used in the 1.0 release of gcp/observability, and thus must not be // deleted or changed. - WithBinaryLogger interface{} // func(binarylog.Logger) grpc.DialOption + WithBinaryLogger any // func(binarylog.Logger) grpc.DialOption // BinaryLogger returns a ServerOption that can set the binary logger for a // server. // // This is used in the 1.0 release of gcp/observability, and thus must not be // deleted or changed. - BinaryLogger interface{} // func(binarylog.Logger) grpc.ServerOption + BinaryLogger any // func(binarylog.Logger) grpc.ServerOption + + // SubscribeToConnectivityStateChanges adds a grpcsync.Subscriber to a provided grpc.ClientConn + SubscribeToConnectivityStateChanges any // func(*grpc.ClientConn, grpcsync.Subscriber) // NewXDSResolverWithConfigForTesting creates a new xds resolver builder using // the provided xds bootstrap config instead of the global configuration from @@ -131,7 +138,7 @@ var ( // // This function should ONLY be used for testing and may not work with some // other features, including the CSDS service. - NewXDSResolverWithConfigForTesting interface{} // func([]byte) (resolver.Builder, error) + NewXDSResolverWithConfigForTesting any // func([]byte) (resolver.Builder, error) // RegisterRLSClusterSpecifierPluginForTesting registers the RLS Cluster // Specifier Plugin for testing purposes, regardless of the XDSRLS environment @@ -163,7 +170,36 @@ var ( UnregisterRBACHTTPFilterForTesting func() // ORCAAllowAnyMinReportingInterval is for examples/orca use ONLY. - ORCAAllowAnyMinReportingInterval interface{} // func(so *orca.ServiceOptions) + ORCAAllowAnyMinReportingInterval any // func(so *orca.ServiceOptions) + + // GRPCResolverSchemeExtraMetadata determines when gRPC will add extra + // metadata to RPCs. + GRPCResolverSchemeExtraMetadata string = "xds" + + // EnterIdleModeForTesting gets the ClientConn to enter IDLE mode. + EnterIdleModeForTesting any // func(*grpc.ClientConn) + + // ExitIdleModeForTesting gets the ClientConn to exit IDLE mode. + ExitIdleModeForTesting any // func(*grpc.ClientConn) error + + ChannelzTurnOffForTesting func() + + // TriggerXDSResourceNameNotFoundForTesting triggers the resource-not-found + // error for a given resource type and name. This is usually triggered when + // the associated watch timer fires. For testing purposes, having this + // function makes events more predictable than relying on timer events. + TriggerXDSResourceNameNotFoundForTesting any // func(func(xdsresource.Type, string), string, string) error + + // TriggerXDSResourceNameNotFoundClient invokes the testing xDS Client + // singleton to invoke resource not found for a resource type name and + // resource name. + TriggerXDSResourceNameNotFoundClient any // func(string, string) error + + // FromOutgoingContextRaw returns the un-merged, intermediary contents of metadata.rawMD. + FromOutgoingContextRaw any // func(context.Context) (metadata.MD, [][]string, bool) + + // UserSetDefaultScheme is set to true if the user has overridden the default resolver scheme. + UserSetDefaultScheme bool = false ) // HealthChecker defines the signature of the client-side LB channel health checking function. @@ -174,7 +210,7 @@ var ( // // The health checking protocol is defined at: // https://github.com/grpc/grpc/blob/master/doc/health-checking.md -type HealthChecker func(ctx context.Context, newStream func(string) (interface{}, error), setConnectivityState func(connectivity.State, error), serviceName string) error +type HealthChecker func(ctx context.Context, newStream func(string) (any, error), setConnectivityState func(connectivity.State, error), serviceName string) error const ( // CredsBundleModeFallback switches GoogleDefaultCreds to fallback mode. diff --git a/vendor/google.golang.org/grpc/internal/metadata/metadata.go b/vendor/google.golang.org/grpc/internal/metadata/metadata.go index c82e608e..900bfb71 100644 --- a/vendor/google.golang.org/grpc/internal/metadata/metadata.go +++ b/vendor/google.golang.org/grpc/internal/metadata/metadata.go @@ -35,7 +35,7 @@ const mdKey = mdKeyType("grpc.internal.address.metadata") type mdValue metadata.MD -func (m mdValue) Equal(o interface{}) bool { +func (m mdValue) Equal(o any) bool { om, ok := o.(mdValue) if !ok { return false diff --git a/vendor/google.golang.org/grpc/internal/pretty/pretty.go b/vendor/google.golang.org/grpc/internal/pretty/pretty.go index 0177af4b..dbee7a60 100644 --- a/vendor/google.golang.org/grpc/internal/pretty/pretty.go +++ b/vendor/google.golang.org/grpc/internal/pretty/pretty.go @@ -24,10 +24,8 @@ import ( "encoding/json" "fmt" - "github.com/golang/protobuf/jsonpb" - protov1 "github.com/golang/protobuf/proto" "google.golang.org/protobuf/encoding/protojson" - protov2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/protoadapt" ) const jsonIndent = " " @@ -35,22 +33,15 @@ const jsonIndent = " " // ToJSON marshals the input into a json string. // // If marshal fails, it falls back to fmt.Sprintf("%+v"). -func ToJSON(e interface{}) string { - switch ee := e.(type) { - case protov1.Message: - mm := jsonpb.Marshaler{Indent: jsonIndent} - ret, err := mm.MarshalToString(ee) - if err != nil { - // This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2 - // messages are not imported, and this will fail because the message - // is not found. - return fmt.Sprintf("%+v", ee) - } - return ret - case protov2.Message: +func ToJSON(e any) string { + if ee, ok := e.(protoadapt.MessageV1); ok { + e = protoadapt.MessageV2Of(ee) + } + + if ee, ok := e.(protoadapt.MessageV2); ok { mm := protojson.MarshalOptions{ - Multiline: true, Indent: jsonIndent, + Multiline: true, } ret, err := mm.Marshal(ee) if err != nil { @@ -60,13 +51,13 @@ func ToJSON(e interface{}) string { return fmt.Sprintf("%+v", ee) } return string(ret) - default: - ret, err := json.MarshalIndent(ee, "", jsonIndent) - if err != nil { - return fmt.Sprintf("%+v", ee) - } - return string(ret) } + + ret, err := json.MarshalIndent(e, "", jsonIndent) + if err != nil { + return fmt.Sprintf("%+v", e) + } + return string(ret) } // FormatJSON formats the input json bytes with indentation. 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 c7a18a94..f0603871 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go +++ b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go @@ -92,7 +92,7 @@ type ClientStream interface { // calling RecvMsg on the same stream at the same time, but it is not safe // to call SendMsg on the same stream in different goroutines. It is also // not safe to call CloseSend concurrently with SendMsg. - SendMsg(m interface{}) error + SendMsg(m any) error // RecvMsg blocks until it receives a message into m or the stream is // done. It returns io.EOF when the stream completes successfully. On // any other error, the stream is aborted and the error contains the RPC @@ -101,7 +101,7 @@ type ClientStream interface { // It is safe to have a goroutine calling SendMsg and another goroutine // calling RecvMsg on the same stream at the same time, but it is not // safe to call RecvMsg on the same stream in different goroutines. - RecvMsg(m interface{}) error + RecvMsg(m any) error } // ClientInterceptor is an interceptor for gRPC client streams. diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go index 09a667f3..abab35e2 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go @@ -23,7 +23,6 @@ package dns import ( "context" "encoding/json" - "errors" "fmt" "net" "os" @@ -37,6 +36,7 @@ import ( "google.golang.org/grpc/internal/backoff" "google.golang.org/grpc/internal/envconfig" "google.golang.org/grpc/internal/grpcrand" + "google.golang.org/grpc/internal/resolver/dns/internal" "google.golang.org/grpc/resolver" "google.golang.org/grpc/serviceconfig" ) @@ -45,55 +45,46 @@ import ( // addresses from SRV records. Must not be changed after init time. var EnableSRVLookups = false -var logger = grpclog.Component("dns") +// ResolvingTimeout specifies the maximum duration for a DNS resolution request. +// If the timeout expires before a response is received, the request will be canceled. +// +// It is recommended to set this value at application startup. Avoid modifying this variable +// after initialization as it's not thread-safe for concurrent modification. +var ResolvingTimeout = 30 * time.Second -// Globals to stub out in tests. TODO: Perhaps these two can be combined into a -// single variable for testing the resolver? -var ( - newTimer = time.NewTimer - newTimerDNSResRate = time.NewTimer -) +var logger = grpclog.Component("dns") func init() { resolver.Register(NewBuilder()) + internal.TimeAfterFunc = time.After + internal.NewNetResolver = newNetResolver + internal.AddressDialer = addressDialer } const ( defaultPort = "443" defaultDNSSvrPort = "53" golang = "GO" - // txtPrefix is the prefix string to be prepended to the host name for txt record lookup. + // txtPrefix is the prefix string to be prepended to the host name for txt + // record lookup. txtPrefix = "_grpc_config." // In DNS, service config is encoded in a TXT record via the mechanism // described in RFC-1464 using the attribute name grpc_config. txtAttribute = "grpc_config=" ) -var ( - errMissingAddr = errors.New("dns resolver: missing address") - - // Addresses ending with a colon that is supposed to be the separator - // between host and port is not allowed. E.g. "::" is a valid address as - // it is an IPv6 address (host only) and "[::]:" is invalid as it ends with - // a colon as the host and port separator - errEndsWithColon = errors.New("dns resolver: missing port after port-separator colon") -) - -var ( - defaultResolver netResolver = net.DefaultResolver - // To prevent excessive re-resolution, we enforce a rate limit on DNS - // resolution requests. - minDNSResRate = 30 * time.Second -) - -var customAuthorityDialler = func(authority string) func(ctx context.Context, network, address string) (net.Conn, error) { - return func(ctx context.Context, network, address string) (net.Conn, error) { +var addressDialer = func(address string) func(context.Context, string, string) (net.Conn, error) { + return func(ctx context.Context, network, _ string) (net.Conn, error) { var dialer net.Dialer - return dialer.DialContext(ctx, network, authority) + return dialer.DialContext(ctx, network, address) } } -var customAuthorityResolver = func(authority string) (netResolver, error) { +var newNetResolver = func(authority string) (internal.NetResolver, error) { + if authority == "" { + return net.DefaultResolver, nil + } + host, port, err := parseTarget(authority, defaultDNSSvrPort) if err != nil { return nil, err @@ -103,7 +94,7 @@ var customAuthorityResolver = func(authority string) (netResolver, error) { return &net.Resolver{ PreferGo: true, - Dial: customAuthorityDialler(authorityWithPort), + Dial: internal.AddressDialer(authorityWithPort), }, nil } @@ -114,7 +105,8 @@ func NewBuilder() resolver.Builder { type dnsBuilder struct{} -// Build creates and starts a DNS resolver that watches the name resolution of the target. +// Build creates and starts a DNS resolver that watches the name resolution of +// the target. func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) { host, port, err := parseTarget(target.Endpoint(), defaultPort) if err != nil { @@ -140,13 +132,9 @@ func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts disableServiceConfig: opts.DisableServiceConfig, } - if target.URL.Host == "" { - d.resolver = defaultResolver - } else { - d.resolver, err = customAuthorityResolver(target.URL.Host) - if err != nil { - return nil, err - } + d.resolver, err = internal.NewNetResolver(target.URL.Host) + if err != nil { + return nil, err } d.wg.Add(1) @@ -159,12 +147,6 @@ func (b *dnsBuilder) Scheme() string { return "dns" } -type netResolver interface { - LookupHost(ctx context.Context, host string) (addrs []string, err error) - LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*net.SRV, err error) - LookupTXT(ctx context.Context, name string) (txts []string, err error) -} - // deadResolver is a resolver that does nothing. type deadResolver struct{} @@ -176,23 +158,26 @@ func (deadResolver) Close() {} type dnsResolver struct { host string port string - resolver netResolver + resolver internal.NetResolver ctx context.Context cancel context.CancelFunc cc resolver.ClientConn - // rn channel is used by ResolveNow() to force an immediate resolution of the target. + // rn channel is used by ResolveNow() to force an immediate resolution of the + // target. rn chan struct{} - // wg is used to enforce Close() to return after the watcher() goroutine has finished. - // Otherwise, data race will be possible. [Race Example] in dns_resolver_test we - // replace the real lookup functions with mocked ones to facilitate testing. - // If Close() doesn't wait for watcher() goroutine finishes, race detector sometimes - // will warns lookup (READ the lookup function pointers) inside watcher() goroutine - // has data race with replaceNetFunc (WRITE the lookup function pointers). + // wg is used to enforce Close() to return after the watcher() goroutine has + // finished. Otherwise, data race will be possible. [Race Example] in + // dns_resolver_test we replace the real lookup functions with mocked ones to + // facilitate testing. If Close() doesn't wait for watcher() goroutine + // finishes, race detector sometimes will warns lookup (READ the lookup + // function pointers) inside watcher() goroutine has data race with + // replaceNetFunc (WRITE the lookup function pointers). wg sync.WaitGroup disableServiceConfig bool } -// ResolveNow invoke an immediate resolution of the target that this dnsResolver watches. +// ResolveNow invoke an immediate resolution of the target that this +// dnsResolver watches. func (d *dnsResolver) ResolveNow(resolver.ResolveNowOptions) { select { case d.rn <- struct{}{}: @@ -218,44 +203,43 @@ func (d *dnsResolver) watcher() { err = d.cc.UpdateState(*state) } - var timer *time.Timer + var waitTime time.Duration if err == nil { - // Success resolving, wait for the next ResolveNow. However, also wait 30 seconds at the very least - // to prevent constantly re-resolving. + // Success resolving, wait for the next ResolveNow. However, also wait 30 + // seconds at the very least to prevent constantly re-resolving. backoffIndex = 1 - timer = newTimerDNSResRate(minDNSResRate) + waitTime = internal.MinResolutionRate select { case <-d.ctx.Done(): - timer.Stop() return case <-d.rn: } } else { - // Poll on an error found in DNS Resolver or an error received from ClientConn. - timer = newTimer(backoff.DefaultExponential.Backoff(backoffIndex)) + // Poll on an error found in DNS Resolver or an error received from + // ClientConn. + waitTime = backoff.DefaultExponential.Backoff(backoffIndex) backoffIndex++ } select { case <-d.ctx.Done(): - timer.Stop() return - case <-timer.C: + case <-internal.TimeAfterFunc(waitTime): } } } -func (d *dnsResolver) lookupSRV() ([]resolver.Address, error) { +func (d *dnsResolver) lookupSRV(ctx context.Context) ([]resolver.Address, error) { if !EnableSRVLookups { return nil, nil } var newAddrs []resolver.Address - _, srvs, err := d.resolver.LookupSRV(d.ctx, "grpclb", "tcp", d.host) + _, srvs, err := d.resolver.LookupSRV(ctx, "grpclb", "tcp", d.host) if err != nil { err = handleDNSError(err, "SRV") // may become nil return nil, err } for _, s := range srvs { - lbAddrs, err := d.resolver.LookupHost(d.ctx, s.Target) + lbAddrs, err := d.resolver.LookupHost(ctx, s.Target) if err != nil { err = handleDNSError(err, "A") // may become nil if err == nil { @@ -278,7 +262,8 @@ func (d *dnsResolver) lookupSRV() ([]resolver.Address, error) { } func handleDNSError(err error, lookupType string) error { - if dnsErr, ok := err.(*net.DNSError); ok && !dnsErr.IsTimeout && !dnsErr.IsTemporary { + dnsErr, ok := err.(*net.DNSError) + if ok && !dnsErr.IsTimeout && !dnsErr.IsTemporary { // Timeouts and temporary errors should be communicated to gRPC to // attempt another DNS query (with backoff). Other errors should be // suppressed (they may represent the absence of a TXT record). @@ -291,8 +276,8 @@ func handleDNSError(err error, lookupType string) error { return err } -func (d *dnsResolver) lookupTXT() *serviceconfig.ParseResult { - ss, err := d.resolver.LookupTXT(d.ctx, txtPrefix+d.host) +func (d *dnsResolver) lookupTXT(ctx context.Context) *serviceconfig.ParseResult { + ss, err := d.resolver.LookupTXT(ctx, txtPrefix+d.host) if err != nil { if envconfig.TXTErrIgnore { return nil @@ -307,18 +292,20 @@ func (d *dnsResolver) lookupTXT() *serviceconfig.ParseResult { res += s } - // TXT record must have "grpc_config=" attribute in order to be used as service config. + // TXT record must have "grpc_config=" attribute in order to be used as + // service config. if !strings.HasPrefix(res, txtAttribute) { logger.Warningf("dns: TXT record %v missing %v attribute", res, txtAttribute) - // This is not an error; it is the equivalent of not having a service config. + // This is not an error; it is the equivalent of not having a service + // config. return nil } sc := canaryingSC(strings.TrimPrefix(res, txtAttribute)) return d.cc.ParseServiceConfig(sc) } -func (d *dnsResolver) lookupHost() ([]resolver.Address, error) { - addrs, err := d.resolver.LookupHost(d.ctx, d.host) +func (d *dnsResolver) lookupHost(ctx context.Context) ([]resolver.Address, error) { + addrs, err := d.resolver.LookupHost(ctx, d.host) if err != nil { err = handleDNSError(err, "A") return nil, err @@ -336,8 +323,10 @@ func (d *dnsResolver) lookupHost() ([]resolver.Address, error) { } func (d *dnsResolver) lookup() (*resolver.State, error) { - srv, srvErr := d.lookupSRV() - addrs, hostErr := d.lookupHost() + ctx, cancel := context.WithTimeout(d.ctx, ResolvingTimeout) + defer cancel() + srv, srvErr := d.lookupSRV(ctx) + addrs, hostErr := d.lookupHost(ctx) if hostErr != nil && (srvErr != nil || len(srv) == 0) { return nil, hostErr } @@ -347,14 +336,15 @@ func (d *dnsResolver) lookup() (*resolver.State, error) { state = grpclbstate.Set(state, &grpclbstate.State{BalancerAddresses: srv}) } if !d.disableServiceConfig { - state.ServiceConfig = d.lookupTXT() + state.ServiceConfig = d.lookupTXT(ctx) } return &state, nil } -// formatIP returns ok = false if addr is not a valid textual representation of an IP address. -// If addr is an IPv4 address, return the addr and ok = true. -// If addr is an IPv6 address, return the addr enclosed in square brackets and ok = true. +// formatIP returns ok = false if addr is not a valid textual representation of +// an IP address. If addr is an IPv4 address, return the addr and ok = true. +// If addr is an IPv6 address, return the addr enclosed in square brackets and +// ok = true. func formatIP(addr string) (addrIP string, ok bool) { ip := net.ParseIP(addr) if ip == nil { @@ -366,10 +356,10 @@ func formatIP(addr string) (addrIP string, ok bool) { return "[" + addr + "]", true } -// parseTarget takes the user input target string and default port, returns formatted host and port info. -// If target doesn't specify a port, set the port to be the defaultPort. -// If target is in IPv6 format and host-name is enclosed in square brackets, brackets -// are stripped when setting the host. +// parseTarget takes the user input target string and default port, returns +// formatted host and port info. If target doesn't specify a port, set the port +// to be the defaultPort. If target is in IPv6 format and host-name is enclosed +// in square brackets, brackets are stripped when setting the host. // examples: // target: "www.google.com" defaultPort: "443" returns host: "www.google.com", port: "443" // target: "ipv4-host:80" defaultPort: "443" returns host: "ipv4-host", port: "80" @@ -377,7 +367,7 @@ func formatIP(addr string) (addrIP string, ok bool) { // target: ":80" defaultPort: "443" returns host: "localhost", port: "80" func parseTarget(target, defaultPort string) (host, port string, err error) { if target == "" { - return "", "", errMissingAddr + return "", "", internal.ErrMissingAddr } if ip := net.ParseIP(target); ip != nil { // target is an IPv4 or IPv6(without brackets) address @@ -385,12 +375,14 @@ func parseTarget(target, defaultPort string) (host, port string, err error) { } if host, port, err = net.SplitHostPort(target); err == nil { if port == "" { - // If the port field is empty (target ends with colon), e.g. "[::1]:", this is an error. - return "", "", errEndsWithColon + // If the port field is empty (target ends with colon), e.g. "[::1]:", + // this is an error. + return "", "", internal.ErrEndsWithColon } // target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port if host == "" { - // Keep consistent with net.Dial(): If the host is empty, as in ":80", the local system is assumed. + // Keep consistent with net.Dial(): If the host is empty, as in ":80", + // the local system is assumed. host = "localhost" } return host, port, nil diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go b/vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go new file mode 100644 index 00000000..c7fc557d --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go @@ -0,0 +1,70 @@ +/* + * + * Copyright 2023 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 internal contains functionality internal to the dns resolver package. +package internal + +import ( + "context" + "errors" + "net" + "time" +) + +// NetResolver groups the methods on net.Resolver that are used by the DNS +// resolver implementation. This allows the default net.Resolver instance to be +// overidden from tests. +type NetResolver interface { + LookupHost(ctx context.Context, host string) (addrs []string, err error) + LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*net.SRV, err error) + LookupTXT(ctx context.Context, name string) (txts []string, err error) +} + +var ( + // ErrMissingAddr is the error returned when building a DNS resolver when + // the provided target name is empty. + ErrMissingAddr = errors.New("dns resolver: missing address") + + // ErrEndsWithColon is the error returned when building a DNS resolver when + // the provided target name ends with a colon that is supposed to be the + // separator between host and port. E.g. "::" is a valid address as it is + // an IPv6 address (host only) and "[::]:" is invalid as it ends with a + // colon as the host and port separator + ErrEndsWithColon = errors.New("dns resolver: missing port after port-separator colon") +) + +// The following vars are overridden from tests. +var ( + // MinResolutionRate is the minimum rate at which re-resolutions are + // allowed. This helps to prevent excessive re-resolution. + MinResolutionRate = 30 * time.Second + + // TimeAfterFunc is used by the DNS resolver to wait for the given duration + // to elapse. In non-test code, this is implemented by time.After. In test + // code, this can be used to control the amount of time the resolver is + // blocked waiting for the duration to elapse. + TimeAfterFunc func(time.Duration) <-chan time.Time + + // NewNetResolver returns the net.Resolver instance for the given target. + NewNetResolver func(string) (NetResolver, error) + + // AddressDialer is the dialer used to dial the DNS server. It accepts the + // Host portion of the URL corresponding to the user's dial target and + // returns a dial function. + AddressDialer func(address string) func(context.Context, string, string) (net.Conn, error) +) diff --git a/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go b/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go index 16091168..27cd81af 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go +++ b/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go @@ -61,6 +61,10 @@ func (b *builder) Scheme() string { return b.scheme } +func (b *builder) OverrideAuthority(resolver.Target) string { + return "localhost" +} + type nopResolver struct { } diff --git a/vendor/google.golang.org/grpc/internal/status/status.go b/vendor/google.golang.org/grpc/internal/status/status.go index b0ead4f5..c7dbc820 100644 --- a/vendor/google.golang.org/grpc/internal/status/status.go +++ b/vendor/google.golang.org/grpc/internal/status/status.go @@ -31,10 +31,11 @@ import ( "errors" "fmt" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" spb "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc/codes" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/protoadapt" + "google.golang.org/protobuf/types/known/anypb" ) // Status represents an RPC status code, message, and details. It is immutable @@ -43,13 +44,41 @@ type Status struct { s *spb.Status } +// NewWithProto returns a new status including details from statusProto. This +// is meant to be used by the gRPC library only. +func NewWithProto(code codes.Code, message string, statusProto []string) *Status { + if len(statusProto) != 1 { + // No grpc-status-details bin header, or multiple; just ignore. + return &Status{s: &spb.Status{Code: int32(code), Message: message}} + } + st := &spb.Status{} + if err := proto.Unmarshal([]byte(statusProto[0]), st); err != nil { + // Probably not a google.rpc.Status proto; do not provide details. + return &Status{s: &spb.Status{Code: int32(code), Message: message}} + } + if st.Code == int32(code) { + // The codes match between the grpc-status header and the + // grpc-status-details-bin header; use the full details proto. + return &Status{s: st} + } + return &Status{ + s: &spb.Status{ + Code: int32(codes.Internal), + Message: fmt.Sprintf( + "grpc-status-details-bin mismatch: grpc-status=%v, grpc-message=%q, grpc-status-details-bin=%+v", + code, message, st, + ), + }, + } +} + // New returns a Status representing c and msg. func New(c codes.Code, msg string) *Status { return &Status{s: &spb.Status{Code: int32(c), Message: msg}} } // Newf returns New(c, fmt.Sprintf(format, a...)). -func Newf(c codes.Code, format string, a ...interface{}) *Status { +func Newf(c codes.Code, format string, a ...any) *Status { return New(c, fmt.Sprintf(format, a...)) } @@ -64,7 +93,7 @@ func Err(c codes.Code, msg string) error { } // Errorf returns Error(c, fmt.Sprintf(format, a...)). -func Errorf(c codes.Code, format string, a ...interface{}) error { +func Errorf(c codes.Code, format string, a ...any) error { return Err(c, fmt.Sprintf(format, a...)) } @@ -102,14 +131,14 @@ func (s *Status) Err() error { // WithDetails returns a new status with the provided details messages appended to the status. // If any errors are encountered, it returns nil and the first error encountered. -func (s *Status) WithDetails(details ...proto.Message) (*Status, error) { +func (s *Status) WithDetails(details ...protoadapt.MessageV1) (*Status, error) { if s.Code() == codes.OK { return nil, errors.New("no error details for status with code OK") } // s.Code() != OK implies that s.Proto() != nil. p := s.Proto() for _, detail := range details { - any, err := ptypes.MarshalAny(detail) + any, err := anypb.New(protoadapt.MessageV2Of(detail)) if err != nil { return nil, err } @@ -120,18 +149,18 @@ func (s *Status) WithDetails(details ...proto.Message) (*Status, error) { // Details returns a slice of details messages attached to the status. // If a detail cannot be decoded, the error is returned in place of the detail. -func (s *Status) Details() []interface{} { +func (s *Status) Details() []any { if s == nil || s.s == nil { return nil } - details := make([]interface{}, 0, len(s.s.Details)) + details := make([]any, 0, len(s.s.Details)) for _, any := range s.s.Details { - detail := &ptypes.DynamicAny{} - if err := ptypes.UnmarshalAny(any, detail); err != nil { + detail, err := any.UnmarshalNew() + if err != nil { details = append(details, err) continue } - details = append(details, detail.Message) + details = append(details, detail) } return details } diff --git a/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go b/vendor/google.golang.org/grpc/internal/tcp_keepalive_others.go similarity index 69% rename from vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go rename to vendor/google.golang.org/grpc/internal/tcp_keepalive_others.go index 837ddc40..4f347edd 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/tcp_keepalive_others.go @@ -1,9 +1,7 @@ -//go:build !linux -// +build !linux +//go:build !unix && !windows /* - * - * Copyright 2018 gRPC authors. + * Copyright 2023 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +17,13 @@ * */ -package channelz +package internal + +import ( + "net" +) -// GetSocketOption gets the socket option info of the conn. -func GetSocketOption(c interface{}) *SocketOptionData { - return nil +// NetDialerWithTCPKeepalive returns a vanilla net.Dialer on non-unix platforms. +func NetDialerWithTCPKeepalive() *net.Dialer { + return &net.Dialer{} } diff --git a/vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go b/vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go new file mode 100644 index 00000000..078137b7 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go @@ -0,0 +1,54 @@ +//go:build unix + +/* + * Copyright 2023 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 internal + +import ( + "net" + "syscall" + "time" + + "golang.org/x/sys/unix" +) + +// NetDialerWithTCPKeepalive returns a net.Dialer that enables TCP keepalives on +// the underlying connection with OS default values for keepalive parameters. +// +// TODO: Once https://github.com/golang/go/issues/62254 lands, and the +// appropriate Go version becomes less than our least supported Go version, we +// should look into using the new API to make things more straightforward. +func NetDialerWithTCPKeepalive() *net.Dialer { + return &net.Dialer{ + // Setting a negative value here prevents the Go stdlib from overriding + // the values of TCP keepalive time and interval. It also prevents the + // Go stdlib from enabling TCP keepalives by default. + KeepAlive: time.Duration(-1), + // This method is called after the underlying network socket is created, + // but before dialing the socket (or calling its connect() method). The + // combination of unconditionally enabling TCP keepalives here, and + // disabling the overriding of TCP keepalive parameters by setting the + // KeepAlive field to a negative value above, results in OS defaults for + // the TCP keealive interval and time parameters. + Control: func(_, _ string, c syscall.RawConn) error { + return c.Control(func(fd uintptr) { + unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1) + }) + }, + } +} diff --git a/vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go b/vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go new file mode 100644 index 00000000..fd7d43a8 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go @@ -0,0 +1,54 @@ +//go:build windows + +/* + * Copyright 2023 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 internal + +import ( + "net" + "syscall" + "time" + + "golang.org/x/sys/windows" +) + +// NetDialerWithTCPKeepalive returns a net.Dialer that enables TCP keepalives on +// the underlying connection with OS default values for keepalive parameters. +// +// TODO: Once https://github.com/golang/go/issues/62254 lands, and the +// appropriate Go version becomes less than our least supported Go version, we +// should look into using the new API to make things more straightforward. +func NetDialerWithTCPKeepalive() *net.Dialer { + return &net.Dialer{ + // Setting a negative value here prevents the Go stdlib from overriding + // the values of TCP keepalive time and interval. It also prevents the + // Go stdlib from enabling TCP keepalives by default. + KeepAlive: time.Duration(-1), + // This method is called after the underlying network socket is created, + // but before dialing the socket (or calling its connect() method). The + // combination of unconditionally enabling TCP keepalives here, and + // disabling the overriding of TCP keepalive parameters by setting the + // KeepAlive field to a negative value above, results in OS defaults for + // the TCP keealive interval and time parameters. + Control: func(_, _ string, c syscall.RawConn) error { + return c.Control(func(fd uintptr) { + windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_KEEPALIVE, 1) + }) + }, + } +} diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index be5a9c81..83c38298 100644 --- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -40,7 +40,7 @@ var updateHeaderTblSize = func(e *hpack.Encoder, v uint32) { } type itemNode struct { - it interface{} + it any next *itemNode } @@ -49,7 +49,7 @@ type itemList struct { tail *itemNode } -func (il *itemList) enqueue(i interface{}) { +func (il *itemList) enqueue(i any) { n := &itemNode{it: i} if il.tail == nil { il.head, il.tail = n, n @@ -61,11 +61,11 @@ func (il *itemList) enqueue(i interface{}) { // peek returns the first item in the list without removing it from the // list. -func (il *itemList) peek() interface{} { +func (il *itemList) peek() any { return il.head.it } -func (il *itemList) dequeue() interface{} { +func (il *itemList) dequeue() any { if il.head == nil { return nil } @@ -336,7 +336,7 @@ func (c *controlBuffer) put(it cbItem) error { return err } -func (c *controlBuffer) executeAndPut(f func(it interface{}) bool, it cbItem) (bool, error) { +func (c *controlBuffer) executeAndPut(f func(it any) bool, it cbItem) (bool, error) { var wakeUp bool c.mu.Lock() if c.err != nil { @@ -373,7 +373,7 @@ func (c *controlBuffer) executeAndPut(f func(it interface{}) bool, it cbItem) (b } // Note argument f should never be nil. -func (c *controlBuffer) execute(f func(it interface{}) bool, it interface{}) (bool, error) { +func (c *controlBuffer) execute(f func(it any) bool, it any) (bool, error) { c.mu.Lock() if c.err != nil { c.mu.Unlock() @@ -387,7 +387,7 @@ func (c *controlBuffer) execute(f func(it interface{}) bool, it interface{}) (bo return true, nil } -func (c *controlBuffer) get(block bool) (interface{}, error) { +func (c *controlBuffer) get(block bool) (any, error) { for { c.mu.Lock() if c.err != nil { @@ -535,8 +535,8 @@ const minBatchSize = 1000 // size is too low to give stream goroutines a chance to fill it up. // // Upon exiting, if the error causing the exit is not an I/O error, run() -// flushes and closes the underlying connection. Otherwise, the connection is -// left open to allow the I/O error to be encountered by the reader instead. +// flushes the underlying connection. The connection is always left open to +// allow different closing behavior on the client and server. func (l *loopyWriter) run() (err error) { defer func() { if l.logger.V(logLevel) { @@ -544,7 +544,6 @@ func (l *loopyWriter) run() (err error) { } if !isIOError(err) { l.framer.writer.Flush() - l.conn.Close() } l.cbuf.finish() }() @@ -830,7 +829,7 @@ func (l *loopyWriter) goAwayHandler(g *goAway) error { return nil } -func (l *loopyWriter) handle(i interface{}) error { +func (l *loopyWriter) handle(i any) error { switch i := i.(type) { case *incomingWindowUpdate: l.incomingWindowUpdateHandler(i) diff --git a/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go index 98f80e3f..4a3ddce2 100644 --- a/vendor/google.golang.org/grpc/internal/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go @@ -35,7 +35,6 @@ import ( "sync" "time" - "github.com/golang/protobuf/proto" "golang.org/x/net/http2" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -45,20 +44,17 @@ import ( "google.golang.org/grpc/peer" "google.golang.org/grpc/stats" "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" ) // NewServerHandlerTransport returns a ServerTransport handling gRPC from // inside an http.Handler, or writes an HTTP error to w and returns an error. // It requires that the http Server supports HTTP/2. func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []stats.Handler) (ServerTransport, error) { - if r.ProtoMajor != 2 { - msg := "gRPC requires HTTP/2" - http.Error(w, msg, http.StatusBadRequest) - return nil, errors.New(msg) - } - if r.Method != "POST" { + if r.Method != http.MethodPost { + w.Header().Set("Allow", http.MethodPost) msg := fmt.Sprintf("invalid gRPC request method %q", r.Method) - http.Error(w, msg, http.StatusBadRequest) + http.Error(w, msg, http.StatusMethodNotAllowed) return nil, errors.New(msg) } contentType := r.Header.Get("Content-Type") @@ -69,17 +65,36 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []s http.Error(w, msg, http.StatusUnsupportedMediaType) return nil, errors.New(msg) } + if r.ProtoMajor != 2 { + msg := "gRPC requires HTTP/2" + http.Error(w, msg, http.StatusHTTPVersionNotSupported) + return nil, errors.New(msg) + } if _, ok := w.(http.Flusher); !ok { msg := "gRPC requires a ResponseWriter supporting http.Flusher" http.Error(w, msg, http.StatusInternalServerError) return nil, errors.New(msg) } + var localAddr net.Addr + if la := r.Context().Value(http.LocalAddrContextKey); la != nil { + localAddr, _ = la.(net.Addr) + } + var authInfo credentials.AuthInfo + if r.TLS != nil { + authInfo = credentials.TLSInfo{State: *r.TLS, CommonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.PrivacyAndIntegrity}} + } + p := peer.Peer{ + Addr: strAddr(r.RemoteAddr), + LocalAddr: localAddr, + AuthInfo: authInfo, + } st := &serverHandlerTransport{ rw: w, req: r, closedCh: make(chan struct{}), writes: make(chan func()), + peer: p, contentType: contentType, contentSubtype: contentSubtype, stats: stats, @@ -134,6 +149,8 @@ type serverHandlerTransport struct { headerMD metadata.MD + peer peer.Peer + closeOnce sync.Once closedCh chan struct{} // closed on Close @@ -165,7 +182,13 @@ func (ht *serverHandlerTransport) Close(err error) { }) } -func (ht *serverHandlerTransport) RemoteAddr() net.Addr { return strAddr(ht.req.RemoteAddr) } +func (ht *serverHandlerTransport) Peer() *peer.Peer { + return &peer.Peer{ + Addr: ht.peer.Addr, + LocalAddr: ht.peer.LocalAddr, + AuthInfo: ht.peer.AuthInfo, + } +} // strAddr is a net.Addr backed by either a TCP "ip:port" string, or // the empty string if unknown. @@ -220,18 +243,20 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) erro h.Set("Grpc-Message", encodeGrpcMessage(m)) } + s.hdrMu.Lock() if p := st.Proto(); p != nil && len(p.Details) > 0 { + delete(s.trailer, grpcStatusDetailsBinHeader) stBytes, err := proto.Marshal(p) if err != nil { // TODO: return error instead, when callers are able to handle it. panic(err) } - h.Set("Grpc-Status-Details-Bin", encodeBinHeader(stBytes)) + h.Set(grpcStatusDetailsBinHeader, encodeBinHeader(stBytes)) } - if md := s.Trailer(); len(md) > 0 { - for k, vv := range md { + if len(s.trailer) > 0 { + for k, vv := range s.trailer { // Clients don't tolerate reading restricted headers after some non restricted ones were sent. if isReservedHeader(k) { continue @@ -243,6 +268,7 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) erro } } } + s.hdrMu.Unlock() }) if err == nil { // transport has not been closed @@ -287,7 +313,7 @@ func (ht *serverHandlerTransport) writeCommonHeaders(s *Stream) { } // writeCustomHeaders sets custom headers set on the stream via SetHeader -// on the first write call (Write, WriteHeader, or WriteStatus). +// on the first write call (Write, WriteHeader, or WriteStatus) func (ht *serverHandlerTransport) writeCustomHeaders(s *Stream) { h := ht.rw.Header() @@ -344,10 +370,8 @@ func (ht *serverHandlerTransport) WriteHeader(s *Stream, md metadata.MD) error { return err } -func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), traceCtx func(context.Context, string) context.Context) { +func (ht *serverHandlerTransport) HandleStreams(ctx context.Context, startStream func(*Stream)) { // With this transport type there will be exactly 1 stream: this HTTP request. - - ctx := ht.req.Context() var cancel context.CancelFunc if ht.timeoutSet { ctx, cancel = context.WithTimeout(ctx, ht.timeout) @@ -367,34 +391,19 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace ht.Close(errors.New("request is done processing")) }() + ctx = metadata.NewIncomingContext(ctx, ht.headerMD) req := ht.req - s := &Stream{ - id: 0, // irrelevant - requestRead: func(int) {}, - cancel: cancel, - buf: newRecvBuffer(), - st: ht, - method: req.URL.Path, - recvCompress: req.Header.Get("grpc-encoding"), - contentSubtype: ht.contentSubtype, - } - pr := &peer.Peer{ - Addr: ht.RemoteAddr(), - } - if req.TLS != nil { - pr.AuthInfo = credentials.TLSInfo{State: *req.TLS, CommonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.PrivacyAndIntegrity}} - } - ctx = metadata.NewIncomingContext(ctx, ht.headerMD) - s.ctx = peer.NewContext(ctx, pr) - for _, sh := range ht.stats { - s.ctx = sh.TagRPC(s.ctx, &stats.RPCTagInfo{FullMethodName: s.method}) - inHeader := &stats.InHeader{ - FullMethod: s.method, - RemoteAddr: ht.RemoteAddr(), - Compression: s.recvCompress, - } - sh.HandleRPC(s.ctx, inHeader) + id: 0, // irrelevant + ctx: ctx, + requestRead: func(int) {}, + cancel: cancel, + buf: newRecvBuffer(), + st: ht, + method: req.URL.Path, + recvCompress: req.Header.Get("grpc-encoding"), + contentSubtype: ht.contentSubtype, + headerWireLength: 0, // won't have access to header wire length until golang/go#18997. } s.trReader = &transportReader{ reader: &recvBufferReader{ctx: s.ctx, ctxDone: s.ctx.Done(), recv: s.buf, freeBuffer: func(*bytes.Buffer) {}}, 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 326bf084..deba0c4d 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -36,6 +36,7 @@ import ( "golang.org/x/net/http2/hpack" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/channelz" icredentials "google.golang.org/grpc/internal/credentials" "google.golang.org/grpc/internal/grpclog" @@ -43,7 +44,7 @@ import ( "google.golang.org/grpc/internal/grpcutil" imetadata "google.golang.org/grpc/internal/metadata" istatus "google.golang.org/grpc/internal/status" - "google.golang.org/grpc/internal/syscall" + isyscall "google.golang.org/grpc/internal/syscall" "google.golang.org/grpc/internal/transport/networktype" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" @@ -58,6 +59,8 @@ import ( // atomically. var clientConnectionCounter uint64 +var metadataFromOutgoingContextRaw = internal.FromOutgoingContextRaw.(func(context.Context) (metadata.MD, [][]string, bool)) + // http2Client implements the ClientTransport interface with HTTP2. type http2Client struct { lastRead int64 // Keep this field 64-bit aligned. Accessed atomically. @@ -137,9 +140,7 @@ type http2Client struct { // variable. kpDormant bool - // Fields below are for channelz metric collection. - channelzID *channelz.Identifier - czData *channelzData + channelz *channelz.Socket onClose func(GoAwayReason) @@ -176,7 +177,7 @@ func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error if networkType == "tcp" && useProxy { return proxyDial(ctx, address, grpcUA) } - return (&net.Dialer{}).DialContext(ctx, networkType, address) + return internal.NetDialerWithTCPKeepalive().DialContext(ctx, networkType, address) } func isTemporary(err error) bool { @@ -262,7 +263,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts } keepaliveEnabled := false if kp.Time != infinity { - if err = syscall.SetTCPUserTimeout(conn, kp.Timeout); err != nil { + if err = isyscall.SetTCPUserTimeout(conn, kp.Timeout); err != nil { return nil, connectionErrorf(false, err, "transport: failed to set TCP_USER_TIMEOUT: %v", err) } keepaliveEnabled = true @@ -316,6 +317,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts if opts.MaxHeaderListSize != nil { maxHeaderListSize = *opts.MaxHeaderListSize } + t := &http2Client{ ctx: ctx, ctxDone: ctx.Done(), // Cache Done chan. @@ -330,7 +332,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts readerDone: make(chan struct{}), writerDone: make(chan struct{}), goAway: make(chan struct{}), - framer: newFramer(conn, writeBufSize, readBufSize, maxHeaderListSize), + framer: newFramer(conn, writeBufSize, readBufSize, opts.SharedWriteBuffer, maxHeaderListSize), fc: &trInFlow{limit: uint32(icwz)}, scheme: scheme, activeStreams: make(map[uint32]*Stream), @@ -343,11 +345,25 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts maxConcurrentStreams: defaultMaxStreamsClient, streamQuota: defaultMaxStreamsClient, streamsQuotaAvailable: make(chan struct{}, 1), - czData: new(channelzData), keepaliveEnabled: keepaliveEnabled, bufferPool: newBufferPool(), onClose: onClose, } + var czSecurity credentials.ChannelzSecurityValue + if au, ok := authInfo.(credentials.ChannelzSecurityInfo); ok { + czSecurity = au.GetSecurityValue() + } + t.channelz = channelz.RegisterSocket( + &channelz.Socket{ + SocketType: channelz.SocketTypeNormal, + Parent: opts.ChannelzParent, + SocketMetrics: channelz.SocketMetrics{}, + EphemeralMetrics: t.socketMetrics, + LocalAddr: t.localAddr, + RemoteAddr: t.remoteAddr, + SocketOptions: channelz.GetSocketOption(t.conn), + Security: czSecurity, + }) t.logger = prefixLoggerForClientTransport(t) // Add peer information to the http2client context. t.ctx = peer.NewContext(t.ctx, t.getPeer()) @@ -378,10 +394,6 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts } sh.HandleConn(t.ctx, connBegin) } - t.channelzID, err = channelz.RegisterNormalSocket(t, opts.ChannelzParentID, fmt.Sprintf("%s -> %s", t.localAddr, t.remoteAddr)) - if err != nil { - return nil, err - } if t.keepaliveEnabled { t.kpDormancyCond = sync.NewCond(&t.mu) go t.keepalive() @@ -448,7 +460,13 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts } go func() { t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger) - t.loopy.run() + if err := t.loopy.run(); !isIOError(err) { + // Immediately close the connection, as the loopy writer returns + // when there are no more active streams and we were draining (the + // server sent a GOAWAY). For I/O errors, the reader will hit it + // after draining any remaining incoming data. + t.conn.Close() + } close(t.writerDone) }() return t, nil @@ -493,8 +511,9 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { func (t *http2Client) getPeer() *peer.Peer { return &peer.Peer{ - Addr: t.remoteAddr, - AuthInfo: t.authInfo, // Can be nil + Addr: t.remoteAddr, + AuthInfo: t.authInfo, // Can be nil + LocalAddr: t.localAddr, } } @@ -566,7 +585,7 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-trace-bin", Value: encodeBinHeader(b)}) } - if md, added, ok := metadata.FromOutgoingContextRaw(ctx); ok { + if md, added, ok := metadataFromOutgoingContextRaw(ctx); ok { var k string for k, vv := range md { // HTTP doesn't allow you to set pseudoheaders after non pseudoheaders were set. @@ -746,8 +765,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, return ErrConnClosing } if channelz.IsOn() { - atomic.AddInt64(&t.czData.streamsStarted, 1) - atomic.StoreInt64(&t.czData.lastStreamCreatedTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.StreamsStarted.Add(1) + t.channelz.SocketMetrics.LastLocalStreamCreatedTimestamp.Store(time.Now().UnixNano()) } // If the keepalive goroutine has gone dormant, wake it up. if t.kpDormant { @@ -762,7 +781,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, firstTry := true var ch chan struct{} transportDrainRequired := false - checkForStreamQuota := func(it interface{}) bool { + checkForStreamQuota := func(it any) bool { if t.streamQuota <= 0 { // Can go negative if server decreases it. if firstTry { t.waitingStreams++ @@ -800,7 +819,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, return true } var hdrListSizeErr error - checkForHeaderListSize := func(it interface{}) bool { + checkForHeaderListSize := func(it any) bool { if t.maxSendHeaderListSize == nil { return true } @@ -815,7 +834,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, return true } for { - success, err := t.controlBuf.executeAndPut(func(it interface{}) bool { + success, err := t.controlBuf.executeAndPut(func(it any) bool { return checkForHeaderListSize(it) && checkForStreamQuota(it) }, hdr) if err != nil { @@ -918,16 +937,16 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. t.mu.Unlock() if channelz.IsOn() { if eosReceived { - atomic.AddInt64(&t.czData.streamsSucceeded, 1) + t.channelz.SocketMetrics.StreamsSucceeded.Add(1) } else { - atomic.AddInt64(&t.czData.streamsFailed, 1) + t.channelz.SocketMetrics.StreamsFailed.Add(1) } } }, rst: rst, rstCode: rstCode, } - addBackStreamQuota := func(interface{}) bool { + addBackStreamQuota := func(any) bool { t.streamQuota++ if t.streamQuota > 0 && t.waitingStreams > 0 { select { @@ -975,7 +994,7 @@ func (t *http2Client) Close(err error) { t.controlBuf.finish() t.cancel() t.conn.Close() - channelz.RemoveEntry(t.channelzID) + channelz.RemoveEntry(t.channelz.ID) // Append info about previous goaways if there were any, since this may be important // for understanding the root cause for this connection to be closed. _, goAwayDebugMessage := t.GetGoAwayReason() @@ -1080,7 +1099,7 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) { // for the transport and the stream based on the current bdp // estimation. func (t *http2Client) updateFlowControl(n uint32) { - updateIWS := func(interface{}) bool { + updateIWS := func(any) bool { t.initialWindowSize = int32(n) t.mu.Lock() for _, s := range t.activeStreams { @@ -1233,7 +1252,7 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame, isFirst bool) { } updateFuncs = append(updateFuncs, updateStreamQuota) } - t.controlBuf.executeAndPut(func(interface{}) bool { + t.controlBuf.executeAndPut(func(any) bool { for _, f := range updateFuncs { f() } @@ -1321,10 +1340,8 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { for streamID, stream := range t.activeStreams { if streamID > id && streamID <= upperLimit { // The stream was unprocessed by the server. - if streamID > id && streamID <= upperLimit { - atomic.StoreUint32(&stream.unprocessed, 1) - streamsToClose = append(streamsToClose, stream) - } + atomic.StoreUint32(&stream.unprocessed, 1) + streamsToClose = append(streamsToClose, stream) } } t.mu.Unlock() @@ -1399,7 +1416,6 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { mdata = make(map[string][]string) contentTypeErr = "malformed header: missing HTTP content-type" grpcMessage string - statusGen *status.Status recvCompress string httpStatusCode *int httpStatusErr string @@ -1434,12 +1450,6 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { rawStatusCode = codes.Code(uint32(code)) case "grpc-message": grpcMessage = decodeGrpcMessage(hf.Value) - case "grpc-status-details-bin": - var err error - statusGen, err = decodeGRPCStatusDetails(hf.Value) - if err != nil { - headerError = fmt.Sprintf("transport: malformed grpc-status-details-bin: %v", err) - } case ":status": if hf.Value == "200" { httpStatusErr = "" @@ -1505,14 +1515,15 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { return } - isHeader := false - - // If headerChan hasn't been closed yet - if atomic.CompareAndSwapUint32(&s.headerChanClosed, 0, 1) { - s.headerValid = true - if !endStream { - // HEADERS frame block carries a Response-Headers. - isHeader = true + // For headers, set them in s.header and close headerChan. For trailers or + // trailers-only, closeStream will set the trailers and close headerChan as + // needed. + if !endStream { + // If headerChan hasn't been closed yet (expected, given we checked it + // above, but something else could have potentially closed the whole + // stream). + if atomic.CompareAndSwapUint32(&s.headerChanClosed, 0, 1) { + s.headerValid = true // These values can be set without any synchronization because // stream goroutine will read it only after seeing a closed // headerChan which we'll close after setting this. @@ -1520,15 +1531,12 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { if len(mdata) > 0 { s.header = mdata } - } else { - // HEADERS frame block carries a Trailers-Only. - s.noHeaders = true + close(s.headerChan) } - close(s.headerChan) } for _, sh := range t.statsHandlers { - if isHeader { + if !endStream { inHeader := &stats.InHeader{ Client: true, WireLength: int(frame.Header().Length), @@ -1550,13 +1558,12 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { return } - if statusGen == nil { - statusGen = status.New(rawStatusCode, grpcMessage) - } + status := istatus.NewWithProto(rawStatusCode, grpcMessage, mdata[grpcStatusDetailsBinHeader]) - // if client received END_STREAM from server while stream was still active, send RST_STREAM - rst := s.getState() == streamActive - t.closeStream(s, io.EOF, rst, http2.ErrCodeNo, statusGen, mdata, true) + // If client received END_STREAM from server while stream was still active, + // send RST_STREAM. + rstStream := s.getState() == streamActive + t.closeStream(s, io.EOF, rstStream, http2.ErrCodeNo, status, mdata, true) } // readServerPreface reads and handles the initial settings frame from the @@ -1710,7 +1717,7 @@ func (t *http2Client) keepalive() { // keepalive timer expired. In both cases, we need to send a ping. if !outstandingPing { if channelz.IsOn() { - atomic.AddInt64(&t.czData.kpCount, 1) + t.channelz.SocketMetrics.KeepAlivesSent.Add(1) } t.controlBuf.put(p) timeoutLeft = t.kp.Timeout @@ -1740,40 +1747,23 @@ func (t *http2Client) GoAway() <-chan struct{} { return t.goAway } -func (t *http2Client) ChannelzMetric() *channelz.SocketInternalMetric { - s := channelz.SocketInternalMetric{ - StreamsStarted: atomic.LoadInt64(&t.czData.streamsStarted), - StreamsSucceeded: atomic.LoadInt64(&t.czData.streamsSucceeded), - StreamsFailed: atomic.LoadInt64(&t.czData.streamsFailed), - MessagesSent: atomic.LoadInt64(&t.czData.msgSent), - MessagesReceived: atomic.LoadInt64(&t.czData.msgRecv), - KeepAlivesSent: atomic.LoadInt64(&t.czData.kpCount), - LastLocalStreamCreatedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastStreamCreatedTime)), - LastMessageSentTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgSentTime)), - LastMessageReceivedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgRecvTime)), - LocalFlowControlWindow: int64(t.fc.getSize()), - SocketOptions: channelz.GetSocketOption(t.conn), - LocalAddr: t.localAddr, - RemoteAddr: t.remoteAddr, - // RemoteName : - } - if au, ok := t.authInfo.(credentials.ChannelzSecurityInfo); ok { - s.Security = au.GetSecurityValue() - } - s.RemoteFlowControlWindow = t.getOutFlowWindow() - return &s +func (t *http2Client) socketMetrics() *channelz.EphemeralSocketMetrics { + return &channelz.EphemeralSocketMetrics{ + LocalFlowControlWindow: int64(t.fc.getSize()), + RemoteFlowControlWindow: t.getOutFlowWindow(), + } } func (t *http2Client) RemoteAddr() net.Addr { return t.remoteAddr } func (t *http2Client) IncrMsgSent() { - atomic.AddInt64(&t.czData.msgSent, 1) - atomic.StoreInt64(&t.czData.lastMsgSentTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.MessagesSent.Add(1) + t.channelz.SocketMetrics.LastMessageSentTimestamp.Store(time.Now().UnixNano()) } func (t *http2Client) IncrMsgRecv() { - atomic.AddInt64(&t.czData.msgRecv, 1) - atomic.StoreInt64(&t.czData.lastMsgRecvTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.MessagesReceived.Add(1) + t.channelz.SocketMetrics.LastMessageReceivedTimestamp.Store(time.Now().UnixNano()) } func (t *http2Client) getOutFlowWindow() int64 { 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 ec4eef21..d582e047 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -32,13 +32,13 @@ import ( "sync/atomic" "time" - "github.com/golang/protobuf/proto" "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpcutil" "google.golang.org/grpc/internal/pretty" "google.golang.org/grpc/internal/syscall" + "google.golang.org/protobuf/proto" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -68,18 +68,15 @@ var serverConnectionCounter uint64 // http2Server implements the ServerTransport interface with HTTP2. type http2Server struct { - lastRead int64 // Keep this field 64-bit aligned. Accessed atomically. - ctx context.Context - done chan struct{} - conn net.Conn - loopy *loopyWriter - readerDone chan struct{} // sync point to enable testing. - writerDone chan struct{} // sync point to enable testing. - remoteAddr net.Addr - localAddr net.Addr - authInfo credentials.AuthInfo // auth info about the connection - inTapHandle tap.ServerInHandle - framer *framer + lastRead int64 // Keep this field 64-bit aligned. Accessed atomically. + done chan struct{} + conn net.Conn + loopy *loopyWriter + readerDone chan struct{} // sync point to enable testing. + loopyWriterDone chan struct{} + peer peer.Peer + inTapHandle tap.ServerInHandle + framer *framer // The max number of concurrent streams. maxStreams uint32 // controlBuf delivers all the control related tasks (e.g., window @@ -121,8 +118,7 @@ type http2Server struct { idle time.Time // Fields below are for channelz metric collection. - channelzID *channelz.Identifier - czData *channelzData + channelz *channelz.Socket bufferPool *bufferPool connectionID uint64 @@ -165,7 +161,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, if config.MaxHeaderListSize != nil { maxHeaderListSize = *config.MaxHeaderListSize } - framer := newFramer(conn, writeBufSize, readBufSize, maxHeaderListSize) + framer := newFramer(conn, writeBufSize, readBufSize, config.SharedWriteBuffer, maxHeaderListSize) // Send initial settings as connection preface to client. isettings := []http2.Setting{{ ID: http2.SettingMaxFrameSize, @@ -233,7 +229,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, kp.Timeout = defaultServerKeepaliveTimeout } if kp.Time != infinity { - if err = syscall.SetTCPUserTimeout(conn, kp.Timeout); err != nil { + if err = syscall.SetTCPUserTimeout(rawConn, kp.Timeout); err != nil { return nil, connectionErrorf(false, err, "transport: failed to set TCP_USER_TIMEOUT: %v", err) } } @@ -243,16 +239,18 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, } done := make(chan struct{}) + peer := peer.Peer{ + Addr: conn.RemoteAddr(), + LocalAddr: conn.LocalAddr(), + AuthInfo: authInfo, + } t := &http2Server{ - ctx: setConnection(context.Background(), rawConn), done: done, conn: conn, - remoteAddr: conn.RemoteAddr(), - localAddr: conn.LocalAddr(), - authInfo: authInfo, + peer: peer, framer: framer, readerDone: make(chan struct{}), - writerDone: make(chan struct{}), + loopyWriterDone: make(chan struct{}), maxStreams: config.MaxStreams, inTapHandle: config.InTapHandle, fc: &trInFlow{limit: uint32(icwz)}, @@ -263,12 +261,25 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, idle: time.Now(), kep: kep, initialWindowSize: iwz, - czData: new(channelzData), bufferPool: newBufferPool(), } + var czSecurity credentials.ChannelzSecurityValue + if au, ok := authInfo.(credentials.ChannelzSecurityInfo); ok { + czSecurity = au.GetSecurityValue() + } + t.channelz = channelz.RegisterSocket( + &channelz.Socket{ + SocketType: channelz.SocketTypeNormal, + Parent: config.ChannelzParent, + SocketMetrics: channelz.SocketMetrics{}, + EphemeralMetrics: t.socketMetrics, + LocalAddr: t.peer.LocalAddr, + RemoteAddr: t.peer.Addr, + SocketOptions: channelz.GetSocketOption(t.conn), + Security: czSecurity, + }, + ) t.logger = prefixLoggerForServerTransport(t) - // Add peer information to the http2server context. - t.ctx = peer.NewContext(t.ctx, t.getPeer()) t.controlBuf = newControlBuffer(t.done) if dynamicWindow { @@ -277,18 +288,6 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, updateFlowControl: t.updateFlowControl, } } - for _, sh := range t.stats { - t.ctx = sh.TagConn(t.ctx, &stats.ConnTagInfo{ - RemoteAddr: t.remoteAddr, - LocalAddr: t.localAddr, - }) - connBegin := &stats.ConnBegin{} - sh.HandleConn(t.ctx, connBegin) - } - t.channelzID, err = channelz.RegisterNormalSocket(t, config.ChannelzParentID, fmt.Sprintf("%s -> %s", t.remoteAddr, t.localAddr)) - if err != nil { - return nil, err - } t.connectionID = atomic.AddUint64(&serverConnectionCounter, 1) t.framer.writer.Flush() @@ -333,8 +332,26 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, go func() { t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger) t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler - t.loopy.run() - close(t.writerDone) + err := t.loopy.run() + close(t.loopyWriterDone) + if !isIOError(err) { + // Close the connection if a non-I/O error occurs (for I/O errors + // the reader will also encounter the error and close). Wait 1 + // second before closing the connection, or when the reader is done + // (i.e. the client already closed the connection or a connection + // error occurred). This avoids the potential problem where there + // is unread data on the receive side of the connection, which, if + // closed, would lead to a TCP RST instead of FIN, and the client + // encountering errors. For more info: + // https://github.com/grpc/grpc-go/issues/5358 + timer := time.NewTimer(time.Second) + defer timer.Stop() + select { + case <-t.readerDone: + case <-timer.C: + } + t.conn.Close() + } }() go t.keepalive() return t, nil @@ -342,7 +359,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, // operateHeaders takes action on the decoded headers. Returns an error if fatal // error encountered and transport needs to close, otherwise returns nil. -func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) error { +func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeadersFrame, handle func(*Stream)) error { // Acquire max stream ID lock for entire duration t.maxStreamMu.Lock() defer t.maxStreamMu.Unlock() @@ -369,10 +386,11 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( buf := newRecvBuffer() s := &Stream{ - id: streamID, - st: t, - buf: buf, - fc: &inFlow{limit: uint32(t.initialWindowSize)}, + id: streamID, + st: t, + buf: buf, + fc: &inFlow{limit: uint32(t.initialWindowSize)}, + headerWireLength: int(frame.Header().Length), } var ( // if false, content-type was missing or invalid @@ -511,9 +529,9 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( s.state = streamReadDone } if timeoutSet { - s.ctx, s.cancel = context.WithTimeout(t.ctx, timeout) + s.ctx, s.cancel = context.WithTimeout(ctx, timeout) } else { - s.ctx, s.cancel = context.WithCancel(t.ctx) + s.ctx, s.cancel = context.WithCancel(ctx) } // Attach the received metadata to the context. @@ -561,7 +579,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( } if t.inTapHandle != nil { var err error - if s.ctx, err = t.inTapHandle(s.ctx, &tap.Info{FullMethodName: s.method}); err != nil { + if s.ctx, err = t.inTapHandle(s.ctx, &tap.Info{FullMethodName: s.method, Header: mdata}); err != nil { t.mu.Unlock() if t.logger.V(logLevel) { t.logger.Infof("Aborting the stream early due to InTapHandle failure: %v", err) @@ -586,25 +604,12 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( } t.mu.Unlock() if channelz.IsOn() { - atomic.AddInt64(&t.czData.streamsStarted, 1) - atomic.StoreInt64(&t.czData.lastStreamCreatedTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.StreamsStarted.Add(1) + t.channelz.SocketMetrics.LastRemoteStreamCreatedTimestamp.Store(time.Now().UnixNano()) } s.requestRead = func(n int) { t.adjustWindow(s, uint32(n)) } - s.ctx = traceCtx(s.ctx, s.method) - for _, sh := range t.stats { - s.ctx = sh.TagRPC(s.ctx, &stats.RPCTagInfo{FullMethodName: s.method}) - inHeader := &stats.InHeader{ - FullMethod: s.method, - RemoteAddr: t.remoteAddr, - LocalAddr: t.localAddr, - Compression: s.recvCompress, - WireLength: int(frame.Header().Length), - Header: mdata.Copy(), - } - sh.HandleRPC(s.ctx, inHeader) - } s.ctxDone = s.ctx.Done() s.wq = newWriteQuota(defaultWriteQuota, s.ctxDone) s.trReader = &transportReader{ @@ -630,8 +635,11 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( // HandleStreams receives incoming streams using the given handler. This is // typically run in a separate goroutine. // traceCtx attaches trace to ctx and returns the new context. -func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.Context, string) context.Context) { - defer close(t.readerDone) +func (t *http2Server) HandleStreams(ctx context.Context, handle func(*Stream)) { + defer func() { + close(t.readerDone) + <-t.loopyWriterDone + }() for { t.controlBuf.throttle() frame, err := t.framer.fr.ReadFrame() @@ -656,18 +664,20 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context. } continue } - if err == io.EOF || err == io.ErrUnexpectedEOF { - t.Close(err) - return - } t.Close(err) return } switch frame := frame.(type) { case *http2.MetaHeadersFrame: - if err := t.operateHeaders(frame, handle, traceCtx); err != nil { - t.Close(err) - break + if err := t.operateHeaders(ctx, frame, handle); err != nil { + // Any error processing client headers, e.g. invalid stream ID, + // is considered a protocol violation. + t.controlBuf.put(&goAway{ + code: http2.ErrCodeProtocol, + debugData: []byte(err.Error()), + closeConn: err, + }) + continue } case *http2.DataFrame: t.handleData(frame) @@ -850,7 +860,7 @@ func (t *http2Server) handleSettings(f *http2.SettingsFrame) { } return nil }) - t.controlBuf.executeAndPut(func(interface{}) bool { + t.controlBuf.executeAndPut(func(any) bool { for _, f := range updateFuncs { f() } @@ -934,7 +944,7 @@ func appendHeaderFieldsFromMD(headerFields []hpack.HeaderField, md metadata.MD) return headerFields } -func (t *http2Server) checkForHeaderListSize(it interface{}) bool { +func (t *http2Server) checkForHeaderListSize(it any) bool { if t.maxSendHeaderListSize == nil { return true } @@ -980,7 +990,12 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { } } if err := t.writeHeaderLocked(s); err != nil { - return status.Convert(err).Err() + switch e := err.(type) { + case ConnectionError: + return status.Error(codes.Unavailable, e.Desc) + default: + return status.Convert(err).Err() + } } return nil } @@ -1053,12 +1068,15 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-message", Value: encodeGrpcMessage(st.Message())}) if p := st.Proto(); p != nil && len(p.Details) > 0 { + // Do not use the user's grpc-status-details-bin (if present) if we are + // even attempting to set our own. + delete(s.trailer, grpcStatusDetailsBinHeader) stBytes, err := proto.Marshal(p) if err != nil { // TODO: return error instead, when callers are able to handle it. t.logger.Errorf("Failed to marshal rpc status: %s, error: %v", pretty.ToJSON(p), err) } else { - headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)}) + headerFields = append(headerFields, hpack.HeaderField{Name: grpcStatusDetailsBinHeader, Value: encodeBinHeader(stBytes)}) } } @@ -1195,7 +1213,7 @@ func (t *http2Server) keepalive() { } if !outstandingPing { if channelz.IsOn() { - atomic.AddInt64(&t.czData.kpCount, 1) + t.channelz.SocketMetrics.KeepAlivesSent.Add(1) } t.controlBuf.put(p) kpTimeoutLeft = t.kp.Timeout @@ -1235,15 +1253,11 @@ func (t *http2Server) Close(err error) { if err := t.conn.Close(); err != nil && t.logger.V(logLevel) { t.logger.Infof("Error closing underlying net.Conn during Close: %v", err) } - channelz.RemoveEntry(t.channelzID) + channelz.RemoveEntry(t.channelz.ID) // Cancel all active streams. for _, s := range streams { s.cancel() } - for _, sh := range t.stats { - connEnd := &stats.ConnEnd{} - sh.HandleConn(t.ctx, connEnd) - } } // deleteStream deletes the stream s from transport's active streams. @@ -1260,9 +1274,9 @@ func (t *http2Server) deleteStream(s *Stream, eosReceived bool) { if channelz.IsOn() { if eosReceived { - atomic.AddInt64(&t.czData.streamsSucceeded, 1) + t.channelz.SocketMetrics.StreamsSucceeded.Add(1) } else { - atomic.AddInt64(&t.czData.streamsFailed, 1) + t.channelz.SocketMetrics.StreamsFailed.Add(1) } } } @@ -1309,10 +1323,6 @@ func (t *http2Server) closeStream(s *Stream, rst bool, rstCode http2.ErrCode, eo }) } -func (t *http2Server) RemoteAddr() net.Addr { - return t.remoteAddr -} - func (t *http2Server) Drain(debugData string) { t.mu.Lock() defer t.mu.Unlock() @@ -1349,6 +1359,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { if err := t.framer.fr.WriteGoAway(sid, g.code, g.debugData); err != nil { return false, err } + t.framer.writer.Flush() if retErr != nil { return false, retErr } @@ -1369,7 +1380,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { return false, err } go func() { - timer := time.NewTimer(time.Minute) + timer := time.NewTimer(5 * time.Second) defer timer.Stop() select { case <-t.drainEvent.Done(): @@ -1382,38 +1393,21 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { return false, nil } -func (t *http2Server) ChannelzMetric() *channelz.SocketInternalMetric { - s := channelz.SocketInternalMetric{ - StreamsStarted: atomic.LoadInt64(&t.czData.streamsStarted), - StreamsSucceeded: atomic.LoadInt64(&t.czData.streamsSucceeded), - StreamsFailed: atomic.LoadInt64(&t.czData.streamsFailed), - MessagesSent: atomic.LoadInt64(&t.czData.msgSent), - MessagesReceived: atomic.LoadInt64(&t.czData.msgRecv), - KeepAlivesSent: atomic.LoadInt64(&t.czData.kpCount), - LastRemoteStreamCreatedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastStreamCreatedTime)), - LastMessageSentTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgSentTime)), - LastMessageReceivedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgRecvTime)), - LocalFlowControlWindow: int64(t.fc.getSize()), - SocketOptions: channelz.GetSocketOption(t.conn), - LocalAddr: t.localAddr, - RemoteAddr: t.remoteAddr, - // RemoteName : - } - if au, ok := t.authInfo.(credentials.ChannelzSecurityInfo); ok { - s.Security = au.GetSecurityValue() - } - s.RemoteFlowControlWindow = t.getOutFlowWindow() - return &s +func (t *http2Server) socketMetrics() *channelz.EphemeralSocketMetrics { + return &channelz.EphemeralSocketMetrics{ + LocalFlowControlWindow: int64(t.fc.getSize()), + RemoteFlowControlWindow: t.getOutFlowWindow(), + } } func (t *http2Server) IncrMsgSent() { - atomic.AddInt64(&t.czData.msgSent, 1) - atomic.StoreInt64(&t.czData.lastMsgSentTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.MessagesSent.Add(1) + t.channelz.SocketMetrics.LastMessageSentTimestamp.Add(1) } func (t *http2Server) IncrMsgRecv() { - atomic.AddInt64(&t.czData.msgRecv, 1) - atomic.StoreInt64(&t.czData.lastMsgRecvTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.MessagesReceived.Add(1) + t.channelz.SocketMetrics.LastMessageReceivedTimestamp.Add(1) } func (t *http2Server) getOutFlowWindow() int64 { @@ -1431,10 +1425,12 @@ func (t *http2Server) getOutFlowWindow() int64 { } } -func (t *http2Server) getPeer() *peer.Peer { +// Peer returns the peer of the transport. +func (t *http2Server) Peer() *peer.Peer { return &peer.Peer{ - Addr: t.remoteAddr, - AuthInfo: t.authInfo, // Can be nil + Addr: t.peer.Addr, + LocalAddr: t.peer.LocalAddr, + AuthInfo: t.peer.AuthInfo, // Can be nil } } @@ -1459,6 +1455,6 @@ func GetConnection(ctx context.Context) net.Conn { // SetConnection adds the connection to the context to be able to get // information about the destination ip and port for an incoming RPC. This also // allows any unary or streaming interceptors to see the connection. -func setConnection(ctx context.Context, conn net.Conn) context.Context { +func SetConnection(ctx context.Context, conn net.Conn) context.Context { return context.WithValue(ctx, connectionKey{}, conn) } 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 19cbb18f..39cef3bd 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http_util.go +++ b/vendor/google.golang.org/grpc/internal/transport/http_util.go @@ -30,15 +30,13 @@ import ( "net/url" "strconv" "strings" + "sync" "time" "unicode/utf8" - "github.com/golang/protobuf/proto" "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" - spb "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) const ( @@ -87,6 +85,8 @@ var ( } ) +var grpcStatusDetailsBinHeader = "grpc-status-details-bin" + // isReservedHeader checks whether hdr belongs to HTTP2 headers // reserved by gRPC protocol. Any other headers are classified as the // user-specified metadata. @@ -102,7 +102,6 @@ func isReservedHeader(hdr string) bool { "grpc-message", "grpc-status", "grpc-timeout", - "grpc-status-details-bin", // Intentionally exclude grpc-previous-rpc-attempts and // grpc-retry-pushback-ms, which are "reserved", but their API // intentionally works via metadata. @@ -153,18 +152,6 @@ func decodeMetadataHeader(k, v string) (string, error) { return v, nil } -func decodeGRPCStatusDetails(rawDetails string) (*status.Status, error) { - v, err := decodeBinHeader(rawDetails) - if err != nil { - return nil, err - } - st := &spb.Status{} - if err = proto.Unmarshal(v, st); err != nil { - return nil, err - } - return status.FromProto(st), nil -} - type timeoutUnit uint8 const ( @@ -309,6 +296,7 @@ func decodeGrpcMessageUnchecked(msg string) string { } type bufWriter struct { + pool *sync.Pool buf []byte offset int batchSize int @@ -316,12 +304,17 @@ type bufWriter struct { err error } -func newBufWriter(conn net.Conn, batchSize int) *bufWriter { - return &bufWriter{ - buf: make([]byte, batchSize*2), +func newBufWriter(conn net.Conn, batchSize int, pool *sync.Pool) *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) } + return w } func (w *bufWriter) Write(b []byte) (n int, err error) { @@ -332,19 +325,34 @@ func (w *bufWriter) Write(b []byte) (n int, err error) { n, err = w.conn.Write(b) return n, toIOError(err) } + if w.buf == nil { + b := w.pool.Get().(*[]byte) + w.buf = *b + } for len(b) > 0 { nn := copy(w.buf[w.offset:], b) b = b[nn:] w.offset += nn n += nn if w.offset >= w.batchSize { - err = w.Flush() + err = w.flushKeepBuffer() } } return n, err } 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 + } + return err +} + +func (w *bufWriter) flushKeepBuffer() error { if w.err != nil { return w.err } @@ -381,7 +389,10 @@ type framer struct { fr *http2.Framer } -func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, maxHeaderListSize uint32) *framer { +var writeBufferPoolMap map[int]*sync.Pool = make(map[int]*sync.Pool) +var writeBufferMutex sync.Mutex + +func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, sharedWriteBuffer bool, maxHeaderListSize uint32) *framer { if writeBufferSize < 0 { writeBufferSize = 0 } @@ -389,7 +400,11 @@ func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, maxHeaderList if readBufferSize > 0 { r = bufio.NewReaderSize(r, readBufferSize) } - w := newBufWriter(conn, writeBufferSize) + var pool *sync.Pool + if sharedWriteBuffer { + pool = getWriteBufferPool(writeBufferSize) + } + w := newBufWriter(conn, writeBufferSize, pool) f := &framer{ writer: w, fr: http2.NewFramer(w, r), @@ -403,6 +418,23 @@ func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, maxHeaderList return f } +func getWriteBufferPool(size int) *sync.Pool { + writeBufferMutex.Lock() + defer writeBufferMutex.Unlock() + pool, ok := writeBufferPoolMap[size] + if ok { + return pool + } + pool = &sync.Pool{ + New: func() any { + b := make([]byte, size) + return &b + }, + } + writeBufferPoolMap[size] = pool + return pool +} + // parseDialTarget returns the network and address to pass to dialer. func parseDialTarget(target string) (string, string) { net := "tcp" diff --git a/vendor/google.golang.org/grpc/internal/transport/proxy.go b/vendor/google.golang.org/grpc/internal/transport/proxy.go index 41596198..24fa1032 100644 --- a/vendor/google.golang.org/grpc/internal/transport/proxy.go +++ b/vendor/google.golang.org/grpc/internal/transport/proxy.go @@ -28,6 +28,8 @@ import ( "net/http" "net/http/httputil" "net/url" + + "google.golang.org/grpc/internal" ) const proxyAuthHeaderKey = "Proxy-Authorization" @@ -112,7 +114,7 @@ func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, backendAddr stri // proxyDial dials, connecting to a proxy first if necessary. Checks if a proxy // is necessary, dials, does the HTTP CONNECT handshake, and returns the // connection. -func proxyDial(ctx context.Context, addr string, grpcUA string) (conn net.Conn, err error) { +func proxyDial(ctx context.Context, addr string, grpcUA string) (net.Conn, error) { newAddr := addr proxyURL, err := mapAddress(addr) if err != nil { @@ -122,15 +124,15 @@ func proxyDial(ctx context.Context, addr string, grpcUA string) (conn net.Conn, newAddr = proxyURL.Host } - conn, err = (&net.Dialer{}).DialContext(ctx, "tcp", newAddr) + conn, err := internal.NetDialerWithTCPKeepalive().DialContext(ctx, "tcp", newAddr) if err != nil { - return + return nil, err } - if proxyURL != nil { + if proxyURL == nil { // proxy is disabled if proxyURL is nil. - conn, err = doHTTPConnectHandshake(ctx, conn, addr, proxyURL, grpcUA) + return conn, err } - return + return doHTTPConnectHandshake(ctx, conn, addr, proxyURL, grpcUA) } func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error { diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index aa1c8965..0d2a6e47 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -28,6 +28,7 @@ import ( "fmt" "io" "net" + "strings" "sync" "sync/atomic" "time" @@ -37,16 +38,13 @@ import ( "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" "google.golang.org/grpc/resolver" "google.golang.org/grpc/stats" "google.golang.org/grpc/status" "google.golang.org/grpc/tap" ) -// ErrNoHeaders is used as a signal that a trailers only response was received, -// and is not a real error. -var ErrNoHeaders = errors.New("stream has no headers") - const logLevel = 2 type bufferPool struct { @@ -56,7 +54,7 @@ type bufferPool struct { func newBufferPool() *bufferPool { return &bufferPool{ pool: sync.Pool{ - New: func() interface{} { + New: func() any { return new(bytes.Buffer) }, }, @@ -269,7 +267,8 @@ type Stream struct { // headerValid indicates whether a valid header was received. Only // meaningful after headerChan is closed (always call waitOnHeader() before // reading its value). Not valid on server side. - headerValid bool + headerValid bool + headerWireLength int // Only set on server side. // hdrMu protects header and trailer metadata on the server-side. hdrMu sync.Mutex @@ -364,8 +363,12 @@ func (s *Stream) SendCompress() string { // ClientAdvertisedCompressors returns the compressor names advertised by the // client via grpc-accept-encoding header. -func (s *Stream) ClientAdvertisedCompressors() string { - return s.clientAdvertisedCompressors +func (s *Stream) ClientAdvertisedCompressors() []string { + values := strings.Split(s.clientAdvertisedCompressors, ",") + for i, v := range values { + values[i] = strings.TrimSpace(v) + } + return values } // Done returns a channel which is closed when it receives the final status @@ -390,14 +393,10 @@ func (s *Stream) Header() (metadata.MD, error) { } s.waitOnHeader() - if !s.headerValid { + if !s.headerValid || s.noHeaders { return nil, s.status.Err() } - if s.noHeaders { - return nil, ErrNoHeaders - } - return s.header.Copy(), nil } @@ -433,6 +432,12 @@ func (s *Stream) Context() context.Context { return s.ctx } +// SetContext sets the context of the stream. This will be deleted once the +// stats handler callouts all move to gRPC layer. +func (s *Stream) SetContext(ctx context.Context) { + s.ctx = ctx +} + // Method returns the method for the stream. func (s *Stream) Method() string { return s.method @@ -445,6 +450,12 @@ func (s *Stream) Status() *status.Status { return s.status } +// HeaderWireLength returns the size of the headers of the stream as received +// from the wire. Valid only on the server. +func (s *Stream) HeaderWireLength() int { + return s.headerWireLength +} + // SetHeader sets the header metadata. This can be called multiple times. // Server side only. // This should not be called in parallel to other data writes. @@ -559,7 +570,8 @@ type ServerConfig struct { InitialConnWindowSize int32 WriteBufferSize int ReadBufferSize int - ChannelzParentID *channelz.Identifier + SharedWriteBuffer bool + ChannelzParent *channelz.Server MaxHeaderListSize *uint32 HeaderTableSize *uint32 } @@ -592,8 +604,10 @@ type ConnectOptions struct { WriteBufferSize int // ReadBufferSize sets the size of read buffer, which in turn determines how much data can be read at most for one read syscall. ReadBufferSize int - // ChannelzParentID sets the addrConn id which initiate the creation of this client transport. - ChannelzParentID *channelz.Identifier + // SharedWriteBuffer indicates whether connections should reuse write buffer + SharedWriteBuffer bool + // ChannelzParent sets the addrConn id which initiated the creation of this client transport. + ChannelzParent *channelz.SubChannel // MaxHeaderListSize sets the max (uncompressed) size of header list that is prepared to be received. MaxHeaderListSize *uint32 // UseProxy specifies if a proxy should be used. @@ -703,7 +717,7 @@ type ClientTransport interface { // Write methods for a given Stream will be called serially. type ServerTransport interface { // HandleStreams receives incoming streams using the given handler. - HandleStreams(func(*Stream), func(context.Context, string) context.Context) + HandleStreams(context.Context, func(*Stream)) // WriteHeader sends the header metadata for the given stream. // WriteHeader may not be called on all streams. @@ -722,8 +736,8 @@ type ServerTransport interface { // handlers will be terminated asynchronously. Close(err error) - // RemoteAddr returns the remote network address. - RemoteAddr() net.Addr + // Peer returns the peer of the server transport. + Peer() *peer.Peer // Drain notifies the client this ServerTransport stops accepting new RPCs. Drain(debugData string) @@ -736,7 +750,7 @@ type ServerTransport interface { } // connectionErrorf creates an ConnectionError with the specified error description. -func connectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError { +func connectionErrorf(temp bool, e error, format string, a ...any) ConnectionError { return ConnectionError{ Desc: fmt.Sprintf(format, a...), temp: temp, @@ -806,30 +820,6 @@ const ( GoAwayTooManyPings GoAwayReason = 2 ) -// channelzData is used to store channelz related data for http2Client and http2Server. -// These fields cannot be embedded in the original structs (e.g. http2Client), since to do atomic -// operation on int64 variable on 32-bit machine, user is responsible to enforce memory alignment. -// Here, by grouping those int64 fields inside a struct, we are enforcing the alignment. -type channelzData struct { - kpCount int64 - // The number of streams that have started, including already finished ones. - streamsStarted int64 - // Client side: The number of streams that have ended successfully by receiving - // EoS bit set frame from server. - // Server side: The number of streams that have ended successfully by sending - // frame with EoS bit set. - streamsSucceeded int64 - streamsFailed int64 - // lastStreamCreatedTime stores the timestamp that the last stream gets created. It is of int64 type - // instead of time.Time since it's more costly to atomically update time.Time variable than int64 - // variable. The same goes for lastMsgSentTime and lastMsgRecvTime. - lastStreamCreatedTime int64 - msgSent int64 - msgRecv int64 - lastMsgSentTime int64 - lastMsgRecvTime int64 -} - // ContextErr converts the error from context package into a status error. func ContextErr(err error) error { switch err { diff --git a/vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go b/vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go deleted file mode 100644 index e8b49277..00000000 --- a/vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021 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 internal - -import ( - "google.golang.org/grpc/attributes" - "google.golang.org/grpc/resolver" -) - -// handshakeClusterNameKey is the type used as the key to store cluster name in -// the Attributes field of resolver.Address. -type handshakeClusterNameKey struct{} - -// SetXDSHandshakeClusterName returns a copy of addr in which the Attributes field -// is updated with the cluster name. -func SetXDSHandshakeClusterName(addr resolver.Address, clusterName string) resolver.Address { - addr.Attributes = addr.Attributes.WithValue(handshakeClusterNameKey{}, clusterName) - return addr -} - -// GetXDSHandshakeClusterName returns cluster name stored in attr. -func GetXDSHandshakeClusterName(attr *attributes.Attributes) (string, bool) { - v := attr.Value(handshakeClusterNameKey{}) - name, ok := v.(string) - return name, ok -} diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go index a2cdcaf1..1e9485fd 100644 --- a/vendor/google.golang.org/grpc/metadata/metadata.go +++ b/vendor/google.golang.org/grpc/metadata/metadata.go @@ -25,8 +25,14 @@ import ( "context" "fmt" "strings" + + "google.golang.org/grpc/internal" ) +func init() { + internal.FromOutgoingContextRaw = fromOutgoingContextRaw +} + // DecodeKeyValue returns k, v, nil. // // Deprecated: use k and v directly instead. @@ -153,14 +159,16 @@ func Join(mds ...MD) MD { type mdIncomingKey struct{} type mdOutgoingKey struct{} -// NewIncomingContext creates a new context with incoming md attached. +// NewIncomingContext creates a new context with incoming md attached. md must +// not be modified after calling this function. func NewIncomingContext(ctx context.Context, md MD) context.Context { return context.WithValue(ctx, mdIncomingKey{}, md) } // NewOutgoingContext creates a new context with outgoing md attached. If used // in conjunction with AppendToOutgoingContext, NewOutgoingContext will -// overwrite any previously-appended metadata. +// overwrite any previously-appended metadata. md must not be modified after +// calling this function. func NewOutgoingContext(ctx context.Context, md MD) context.Context { return context.WithValue(ctx, mdOutgoingKey{}, rawMD{md: md}) } @@ -203,7 +211,8 @@ func FromIncomingContext(ctx context.Context) (MD, bool) { } // ValueFromIncomingContext returns the metadata value corresponding to the metadata -// key from the incoming metadata if it exists. Key must be lower-case. +// key from the incoming metadata if it exists. Keys are matched in a case insensitive +// manner. // // # Experimental // @@ -219,33 +228,29 @@ func ValueFromIncomingContext(ctx context.Context, key string) []string { return copyOf(v) } for k, v := range md { - // We need to manually convert all keys to lower case, because MD is a - // map, and there's no guarantee that the MD attached to the context is - // created using our helper functions. - if strings.ToLower(k) == key { + // Case insenitive comparison: MD is a map, and there's no guarantee + // that the MD attached to the context is created using our helper + // functions. + if strings.EqualFold(k, key) { return copyOf(v) } } return nil } -// the returned slice must not be modified in place func copyOf(v []string) []string { vals := make([]string, len(v)) copy(vals, v) return vals } -// FromOutgoingContextRaw returns the un-merged, intermediary contents of rawMD. +// fromOutgoingContextRaw returns the un-merged, intermediary contents of rawMD. // // Remember to perform strings.ToLower on the keys, for both the returned MD (MD // is a map, there's no guarantee it's created using our helper functions) and // the extra kv pairs (AppendToOutgoingContext doesn't turn them into // lowercase). -// -// This is intended for gRPC-internal use ONLY. Users should use -// FromOutgoingContext instead. -func FromOutgoingContextRaw(ctx context.Context) (MD, [][]string, bool) { +func fromOutgoingContextRaw(ctx context.Context) (MD, [][]string, bool) { raw, ok := ctx.Value(mdOutgoingKey{}).(rawMD) if !ok { return nil, nil, false diff --git a/vendor/google.golang.org/grpc/peer/peer.go b/vendor/google.golang.org/grpc/peer/peer.go index e01d219f..a821ff9b 100644 --- a/vendor/google.golang.org/grpc/peer/peer.go +++ b/vendor/google.golang.org/grpc/peer/peer.go @@ -32,6 +32,8 @@ import ( type Peer struct { // Addr is the peer address. Addr net.Addr + // LocalAddr is the local address. + LocalAddr net.Addr // AuthInfo is the authentication information of the transport. // It is nil if there is no transport security being used. AuthInfo credentials.AuthInfo diff --git a/vendor/google.golang.org/grpc/picker_wrapper.go b/vendor/google.golang.org/grpc/picker_wrapper.go index 02f97595..bf56faa7 100644 --- a/vendor/google.golang.org/grpc/picker_wrapper.go +++ b/vendor/google.golang.org/grpc/picker_wrapper.go @@ -28,31 +28,31 @@ import ( "google.golang.org/grpc/internal/channelz" istatus "google.golang.org/grpc/internal/status" "google.golang.org/grpc/internal/transport" + "google.golang.org/grpc/stats" "google.golang.org/grpc/status" ) // pickerWrapper is a wrapper of balancer.Picker. It blocks on certain pick // actions and unblock when there's a picker update. type pickerWrapper struct { - mu sync.Mutex - done bool - idle bool - blockingCh chan struct{} - picker balancer.Picker + mu sync.Mutex + done bool + blockingCh chan struct{} + picker balancer.Picker + statsHandlers []stats.Handler // to record blocking picker calls } -func newPickerWrapper() *pickerWrapper { - return &pickerWrapper{blockingCh: make(chan struct{})} +func newPickerWrapper(statsHandlers []stats.Handler) *pickerWrapper { + return &pickerWrapper{ + blockingCh: make(chan struct{}), + statsHandlers: statsHandlers, + } } // updatePicker is called by UpdateBalancerState. It unblocks all blocked pick. func (pw *pickerWrapper) updatePicker(p balancer.Picker) { pw.mu.Lock() - if pw.done || pw.idle { - // There is a small window where a picker update from the LB policy can - // race with the channel going to idle mode. If the picker is idle here, - // it is because the channel asked it to do so, and therefore it is sage - // to ignore the update from the LB policy. + if pw.done { pw.mu.Unlock() return } @@ -95,6 +95,7 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. var ch chan struct{} var lastPickErr error + for { pw.mu.Lock() if pw.done { @@ -129,6 +130,20 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. continue } + // If the channel is set, it means that the pick call had to wait for a + // new picker at some point. Either it's the first iteration and this + // function received the first picker, or a picker errored with + // ErrNoSubConnAvailable or errored with failfast set to false, which + // will trigger a continue to the next iteration. In the first case this + // conditional will hit if this call had to block (the channel is set). + // In the second case, the only way it will get to this conditional is + // if there is a new picker. + if ch != nil { + for _, sh := range pw.statsHandlers { + sh.HandleRPC(ctx, &stats.PickerUpdated{}) + } + } + ch = pw.blockingCh p := pw.picker pw.mu.Unlock() @@ -190,23 +205,15 @@ func (pw *pickerWrapper) close() { close(pw.blockingCh) } -func (pw *pickerWrapper) enterIdleMode() { - pw.mu.Lock() - defer pw.mu.Unlock() - if pw.done { - return - } - pw.idle = true -} - -func (pw *pickerWrapper) exitIdleMode() { +// reset clears the pickerWrapper and prepares it for being used again when idle +// mode is exited. +func (pw *pickerWrapper) reset() { pw.mu.Lock() defer pw.mu.Unlock() if pw.done { return } pw.blockingCh = make(chan struct{}) - pw.idle = false } // dropError is a wrapper error that indicates the LB policy wishes to drop the diff --git a/vendor/google.golang.org/grpc/pickfirst.go b/vendor/google.golang.org/grpc/pickfirst.go index abe266b0..e3ea42ba 100644 --- a/vendor/google.golang.org/grpc/pickfirst.go +++ b/vendor/google.golang.org/grpc/pickfirst.go @@ -25,25 +25,28 @@ import ( "google.golang.org/grpc/balancer" "google.golang.org/grpc/connectivity" - "google.golang.org/grpc/internal/envconfig" + internalgrpclog "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpcrand" + "google.golang.org/grpc/internal/pretty" + "google.golang.org/grpc/resolver" "google.golang.org/grpc/serviceconfig" ) -// PickFirstBalancerName is the name of the pick_first balancer. -const PickFirstBalancerName = "pick_first" - -func newPickfirstBuilder() balancer.Builder { - return &pickfirstBuilder{} -} +const ( + // PickFirstBalancerName is the name of the pick_first balancer. + PickFirstBalancerName = "pick_first" + logPrefix = "[pick-first-lb %p] " +) type pickfirstBuilder struct{} -func (*pickfirstBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { - return &pickfirstBalancer{cc: cc} +func (pickfirstBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { + b := &pickfirstBalancer{cc: cc} + b.logger = internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf(logPrefix, b)) + return b } -func (*pickfirstBuilder) Name() string { +func (pickfirstBuilder) Name() string { return PickFirstBalancerName } @@ -56,24 +59,24 @@ type pfConfig struct { ShuffleAddressList bool `json:"shuffleAddressList"` } -func (*pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { - cfg := &pfConfig{} - if err := json.Unmarshal(js, cfg); err != nil { +func (pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { + var cfg pfConfig + if err := json.Unmarshal(js, &cfg); err != nil { return nil, fmt.Errorf("pickfirst: unable to unmarshal LB policy config: %s, error: %v", string(js), err) } return cfg, nil } type pickfirstBalancer struct { + logger *internalgrpclog.PrefixLogger state connectivity.State cc balancer.ClientConn subConn balancer.SubConn - cfg *pfConfig } func (b *pickfirstBalancer) ResolverError(err error) { - if logger.V(2) { - logger.Infof("pickfirstBalancer: ResolverError called with error: %v", err) + if b.logger.V(2) { + b.logger.Infof("Received error from the name resolver: %v", err) } if b.subConn == nil { b.state = connectivity.TransientFailure @@ -96,35 +99,44 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState // The resolver reported an empty address list. Treat it like an error by // calling b.ResolverError. if b.subConn != nil { - // Remove the old subConn. All addresses were removed, so it is no longer - // valid. - b.cc.RemoveSubConn(b.subConn) + // Shut down the old subConn. All addresses were removed, so it is + // no longer valid. + b.subConn.Shutdown() b.subConn = nil } b.ResolverError(errors.New("produced zero addresses")) return balancer.ErrBadResolverState } - if state.BalancerConfig != nil { - cfg, ok := state.BalancerConfig.(*pfConfig) - if !ok { - return fmt.Errorf("pickfirstBalancer: received nil or illegal BalancerConfig (type %T): %v", state.BalancerConfig, state.BalancerConfig) - } - b.cfg = cfg + // We don't have to guard this block with the env var because ParseConfig + // already does so. + cfg, ok := state.BalancerConfig.(pfConfig) + if state.BalancerConfig != nil && !ok { + return fmt.Errorf("pickfirst: received illegal BalancerConfig (type %T): %v", state.BalancerConfig, state.BalancerConfig) } - - if envconfig.PickFirstLBConfig && b.cfg != nil && b.cfg.ShuffleAddressList { + if cfg.ShuffleAddressList { + addrs = append([]resolver.Address{}, addrs...) grpcrand.Shuffle(len(addrs), func(i, j int) { addrs[i], addrs[j] = addrs[j], addrs[i] }) } + + if b.logger.V(2) { + b.logger.Infof("Received new config %s, resolver state %s", pretty.ToJSON(cfg), pretty.ToJSON(state.ResolverState)) + } + if b.subConn != nil { b.cc.UpdateAddresses(b.subConn, addrs) return nil } - subConn, err := b.cc.NewSubConn(addrs, balancer.NewSubConnOptions{}) + var subConn balancer.SubConn + subConn, err := b.cc.NewSubConn(addrs, balancer.NewSubConnOptions{ + StateListener: func(state balancer.SubConnState) { + b.updateSubConnState(subConn, state) + }, + }) if err != nil { - if logger.V(2) { - logger.Errorf("pickfirstBalancer: failed to NewSubConn: %v", err) + if b.logger.V(2) { + b.logger.Infof("Failed to create new SubConn: %v", err) } b.state = connectivity.TransientFailure b.cc.UpdateState(balancer.State{ @@ -143,13 +155,19 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState return nil } +// UpdateSubConnState is unused as a StateListener is always registered when +// creating SubConns. func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubConn, state balancer.SubConnState) { - if logger.V(2) { - logger.Infof("pickfirstBalancer: UpdateSubConnState: %p, %v", subConn, state) + b.logger.Errorf("UpdateSubConnState(%v, %+v) called unexpectedly", subConn, state) +} + +func (b *pickfirstBalancer) updateSubConnState(subConn balancer.SubConn, state balancer.SubConnState) { + if b.logger.V(2) { + b.logger.Infof("Received SubConn state update: %p, %+v", subConn, state) } if b.subConn != subConn { - if logger.V(2) { - logger.Infof("pickfirstBalancer: ignored state change because subConn is not recognized") + if b.logger.V(2) { + b.logger.Infof("Ignored state change because subConn is not recognized") } return } @@ -221,7 +239,3 @@ func (i *idlePicker) Pick(balancer.PickInfo) (balancer.PickResult, error) { i.subConn.Connect() return balancer.PickResult{}, balancer.ErrNoSubConnAvailable } - -func init() { - balancer.Register(newPickfirstBuilder()) -} diff --git a/vendor/google.golang.org/grpc/preloader.go b/vendor/google.golang.org/grpc/preloader.go index cd455478..73bd6336 100644 --- a/vendor/google.golang.org/grpc/preloader.go +++ b/vendor/google.golang.org/grpc/preloader.go @@ -37,7 +37,7 @@ type PreparedMsg struct { } // Encode marshalls and compresses the message using the codec and compressor for the stream. -func (p *PreparedMsg) Encode(s Stream, msg interface{}) error { +func (p *PreparedMsg) Encode(s Stream, msg any) error { ctx := s.Context() rpcInfo, ok := rpcInfoFromContext(ctx) if !ok { diff --git a/vendor/google.golang.org/grpc/reflection/README.md b/vendor/google.golang.org/grpc/reflection/README.md index 04b6371a..9ace83cc 100644 --- a/vendor/google.golang.org/grpc/reflection/README.md +++ b/vendor/google.golang.org/grpc/reflection/README.md @@ -2,7 +2,7 @@ Package reflection implements server reflection service. -The service implemented is defined in: https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto. +The service implemented is defined in: https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1/reflection.proto. To register server reflection on a gRPC server: ```go diff --git a/vendor/google.golang.org/grpc/reflection/adapt.go b/vendor/google.golang.org/grpc/reflection/adapt.go new file mode 100644 index 00000000..33b907a3 --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/adapt.go @@ -0,0 +1,187 @@ +/* + * + * Copyright 2023 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 reflection + +import ( + v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1" + v1reflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1" + v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" + v1alphareflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" +) + +// asV1Alpha returns an implementation of the v1alpha version of the reflection +// interface that delegates all calls to the given v1 version. +func asV1Alpha(svr v1reflectiongrpc.ServerReflectionServer) v1alphareflectiongrpc.ServerReflectionServer { + return v1AlphaServerImpl{svr: svr} +} + +type v1AlphaServerImpl struct { + svr v1reflectiongrpc.ServerReflectionServer +} + +func (s v1AlphaServerImpl) ServerReflectionInfo(stream v1alphareflectiongrpc.ServerReflection_ServerReflectionInfoServer) error { + return s.svr.ServerReflectionInfo(v1AlphaServerStreamAdapter{stream}) +} + +type v1AlphaServerStreamAdapter struct { + v1alphareflectiongrpc.ServerReflection_ServerReflectionInfoServer +} + +func (s v1AlphaServerStreamAdapter) Send(response *v1reflectionpb.ServerReflectionResponse) error { + return s.ServerReflection_ServerReflectionInfoServer.Send(v1ToV1AlphaResponse(response)) +} + +func (s v1AlphaServerStreamAdapter) Recv() (*v1reflectionpb.ServerReflectionRequest, error) { + resp, err := s.ServerReflection_ServerReflectionInfoServer.Recv() + if err != nil { + return nil, err + } + return v1AlphaToV1Request(resp), nil +} + +func v1ToV1AlphaResponse(v1 *v1reflectionpb.ServerReflectionResponse) *v1alphareflectionpb.ServerReflectionResponse { + var v1alpha v1alphareflectionpb.ServerReflectionResponse + v1alpha.ValidHost = v1.ValidHost + if v1.OriginalRequest != nil { + v1alpha.OriginalRequest = v1ToV1AlphaRequest(v1.OriginalRequest) + } + switch mr := v1.MessageResponse.(type) { + case *v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse: + if mr != nil { + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1alphareflectionpb.FileDescriptorResponse{ + FileDescriptorProto: mr.FileDescriptorResponse.GetFileDescriptorProto(), + }, + } + } + case *v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse: + if mr != nil { + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse{ + AllExtensionNumbersResponse: &v1alphareflectionpb.ExtensionNumberResponse{ + BaseTypeName: mr.AllExtensionNumbersResponse.GetBaseTypeName(), + ExtensionNumber: mr.AllExtensionNumbersResponse.GetExtensionNumber(), + }, + } + } + case *v1reflectionpb.ServerReflectionResponse_ListServicesResponse: + if mr != nil { + svcs := make([]*v1alphareflectionpb.ServiceResponse, len(mr.ListServicesResponse.GetService())) + for i, svc := range mr.ListServicesResponse.GetService() { + svcs[i] = &v1alphareflectionpb.ServiceResponse{ + Name: svc.GetName(), + } + } + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_ListServicesResponse{ + ListServicesResponse: &v1alphareflectionpb.ListServiceResponse{ + Service: svcs, + }, + } + } + case *v1reflectionpb.ServerReflectionResponse_ErrorResponse: + if mr != nil { + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1alphareflectionpb.ErrorResponse{ + ErrorCode: mr.ErrorResponse.GetErrorCode(), + ErrorMessage: mr.ErrorResponse.GetErrorMessage(), + }, + } + } + default: + // no value set + } + return &v1alpha +} + +func v1AlphaToV1Request(v1alpha *v1alphareflectionpb.ServerReflectionRequest) *v1reflectionpb.ServerReflectionRequest { + var v1 v1reflectionpb.ServerReflectionRequest + v1.Host = v1alpha.Host + switch mr := v1alpha.MessageRequest.(type) { + case *v1alphareflectionpb.ServerReflectionRequest_FileByFilename: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileByFilename{ + FileByFilename: mr.FileByFilename, + } + case *v1alphareflectionpb.ServerReflectionRequest_FileContainingSymbol: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileContainingSymbol{ + FileContainingSymbol: mr.FileContainingSymbol, + } + case *v1alphareflectionpb.ServerReflectionRequest_FileContainingExtension: + if mr.FileContainingExtension != nil { + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileContainingExtension{ + FileContainingExtension: &v1reflectionpb.ExtensionRequest{ + ContainingType: mr.FileContainingExtension.GetContainingType(), + ExtensionNumber: mr.FileContainingExtension.GetExtensionNumber(), + }, + } + } + case *v1alphareflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType{ + AllExtensionNumbersOfType: mr.AllExtensionNumbersOfType, + } + case *v1alphareflectionpb.ServerReflectionRequest_ListServices: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_ListServices{ + ListServices: mr.ListServices, + } + default: + // no value set + } + return &v1 +} + +func v1ToV1AlphaRequest(v1 *v1reflectionpb.ServerReflectionRequest) *v1alphareflectionpb.ServerReflectionRequest { + var v1alpha v1alphareflectionpb.ServerReflectionRequest + v1alpha.Host = v1.Host + switch mr := v1.MessageRequest.(type) { + case *v1reflectionpb.ServerReflectionRequest_FileByFilename: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileByFilename{ + FileByFilename: mr.FileByFilename, + } + } + case *v1reflectionpb.ServerReflectionRequest_FileContainingSymbol: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileContainingSymbol{ + FileContainingSymbol: mr.FileContainingSymbol, + } + } + case *v1reflectionpb.ServerReflectionRequest_FileContainingExtension: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileContainingExtension{ + FileContainingExtension: &v1alphareflectionpb.ExtensionRequest{ + ContainingType: mr.FileContainingExtension.GetContainingType(), + ExtensionNumber: mr.FileContainingExtension.GetExtensionNumber(), + }, + } + } + case *v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType{ + AllExtensionNumbersOfType: mr.AllExtensionNumbersOfType, + } + } + case *v1reflectionpb.ServerReflectionRequest_ListServices: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_ListServices{ + ListServices: mr.ListServices, + } + } + default: + // no value set + } + return &v1alpha +} diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go new file mode 100644 index 00000000..8953c9d8 --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go @@ -0,0 +1,953 @@ +// Copyright 2016 The 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. + +// Service exported by server reflection. A more complete description of how +// server reflection works can be found at +// https://github.com/grpc/grpc/blob/master/doc/server-reflection.md +// +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.32.0 +// protoc v4.25.2 +// source: grpc/reflection/v1/reflection.proto + +package grpc_reflection_v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The message sent by the client when calling ServerReflectionInfo method. +type ServerReflectionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` + // To use reflection service, the client should set one of the following + // fields in message_request. The server distinguishes requests by their + // defined field and then handles them using corresponding methods. + // + // Types that are assignable to MessageRequest: + // + // *ServerReflectionRequest_FileByFilename + // *ServerReflectionRequest_FileContainingSymbol + // *ServerReflectionRequest_FileContainingExtension + // *ServerReflectionRequest_AllExtensionNumbersOfType + // *ServerReflectionRequest_ListServices + MessageRequest isServerReflectionRequest_MessageRequest `protobuf_oneof:"message_request"` +} + +func (x *ServerReflectionRequest) Reset() { + *x = ServerReflectionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerReflectionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerReflectionRequest) ProtoMessage() {} + +func (x *ServerReflectionRequest) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerReflectionRequest.ProtoReflect.Descriptor instead. +func (*ServerReflectionRequest) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{0} +} + +func (x *ServerReflectionRequest) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (m *ServerReflectionRequest) GetMessageRequest() isServerReflectionRequest_MessageRequest { + if m != nil { + return m.MessageRequest + } + return nil +} + +func (x *ServerReflectionRequest) GetFileByFilename() string { + if x, ok := x.GetMessageRequest().(*ServerReflectionRequest_FileByFilename); ok { + return x.FileByFilename + } + return "" +} + +func (x *ServerReflectionRequest) GetFileContainingSymbol() string { + if x, ok := x.GetMessageRequest().(*ServerReflectionRequest_FileContainingSymbol); ok { + return x.FileContainingSymbol + } + return "" +} + +func (x *ServerReflectionRequest) GetFileContainingExtension() *ExtensionRequest { + if x, ok := x.GetMessageRequest().(*ServerReflectionRequest_FileContainingExtension); ok { + return x.FileContainingExtension + } + return nil +} + +func (x *ServerReflectionRequest) GetAllExtensionNumbersOfType() string { + if x, ok := x.GetMessageRequest().(*ServerReflectionRequest_AllExtensionNumbersOfType); ok { + return x.AllExtensionNumbersOfType + } + return "" +} + +func (x *ServerReflectionRequest) GetListServices() string { + if x, ok := x.GetMessageRequest().(*ServerReflectionRequest_ListServices); ok { + return x.ListServices + } + return "" +} + +type isServerReflectionRequest_MessageRequest interface { + isServerReflectionRequest_MessageRequest() +} + +type ServerReflectionRequest_FileByFilename struct { + // Find a proto file by the file name. + FileByFilename string `protobuf:"bytes,3,opt,name=file_by_filename,json=fileByFilename,proto3,oneof"` +} + +type ServerReflectionRequest_FileContainingSymbol struct { + // Find the proto file that declares the given fully-qualified symbol name. + // This field should be a fully-qualified symbol name + // (e.g. .[.] or .). + FileContainingSymbol string `protobuf:"bytes,4,opt,name=file_containing_symbol,json=fileContainingSymbol,proto3,oneof"` +} + +type ServerReflectionRequest_FileContainingExtension struct { + // Find the proto file which defines an extension extending the given + // message type with the given field number. + FileContainingExtension *ExtensionRequest `protobuf:"bytes,5,opt,name=file_containing_extension,json=fileContainingExtension,proto3,oneof"` +} + +type ServerReflectionRequest_AllExtensionNumbersOfType struct { + // Finds the tag numbers used by all known extensions of the given message + // type, and appends them to ExtensionNumberResponse in an undefined order. + // Its corresponding method is best-effort: it's not guaranteed that the + // reflection service will implement this method, and it's not guaranteed + // that this method will provide all extensions. Returns + // StatusCode::UNIMPLEMENTED if it's not implemented. + // This field should be a fully-qualified type name. The format is + // . + AllExtensionNumbersOfType string `protobuf:"bytes,6,opt,name=all_extension_numbers_of_type,json=allExtensionNumbersOfType,proto3,oneof"` +} + +type ServerReflectionRequest_ListServices struct { + // List the full names of registered services. The content will not be + // checked. + ListServices string `protobuf:"bytes,7,opt,name=list_services,json=listServices,proto3,oneof"` +} + +func (*ServerReflectionRequest_FileByFilename) isServerReflectionRequest_MessageRequest() {} + +func (*ServerReflectionRequest_FileContainingSymbol) isServerReflectionRequest_MessageRequest() {} + +func (*ServerReflectionRequest_FileContainingExtension) isServerReflectionRequest_MessageRequest() {} + +func (*ServerReflectionRequest_AllExtensionNumbersOfType) isServerReflectionRequest_MessageRequest() { +} + +func (*ServerReflectionRequest_ListServices) isServerReflectionRequest_MessageRequest() {} + +// The type name and extension number sent by the client when requesting +// file_containing_extension. +type ExtensionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Fully-qualified type name. The format should be . + ContainingType string `protobuf:"bytes,1,opt,name=containing_type,json=containingType,proto3" json:"containing_type,omitempty"` + ExtensionNumber int32 `protobuf:"varint,2,opt,name=extension_number,json=extensionNumber,proto3" json:"extension_number,omitempty"` +} + +func (x *ExtensionRequest) Reset() { + *x = ExtensionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExtensionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtensionRequest) ProtoMessage() {} + +func (x *ExtensionRequest) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtensionRequest.ProtoReflect.Descriptor instead. +func (*ExtensionRequest) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{1} +} + +func (x *ExtensionRequest) GetContainingType() string { + if x != nil { + return x.ContainingType + } + return "" +} + +func (x *ExtensionRequest) GetExtensionNumber() int32 { + if x != nil { + return x.ExtensionNumber + } + return 0 +} + +// The message sent by the server to answer ServerReflectionInfo method. +type ServerReflectionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ValidHost string `protobuf:"bytes,1,opt,name=valid_host,json=validHost,proto3" json:"valid_host,omitempty"` + OriginalRequest *ServerReflectionRequest `protobuf:"bytes,2,opt,name=original_request,json=originalRequest,proto3" json:"original_request,omitempty"` + // The server sets one of the following fields according to the message_request + // in the request. + // + // Types that are assignable to MessageResponse: + // + // *ServerReflectionResponse_FileDescriptorResponse + // *ServerReflectionResponse_AllExtensionNumbersResponse + // *ServerReflectionResponse_ListServicesResponse + // *ServerReflectionResponse_ErrorResponse + MessageResponse isServerReflectionResponse_MessageResponse `protobuf_oneof:"message_response"` +} + +func (x *ServerReflectionResponse) Reset() { + *x = ServerReflectionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerReflectionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerReflectionResponse) ProtoMessage() {} + +func (x *ServerReflectionResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerReflectionResponse.ProtoReflect.Descriptor instead. +func (*ServerReflectionResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{2} +} + +func (x *ServerReflectionResponse) GetValidHost() string { + if x != nil { + return x.ValidHost + } + return "" +} + +func (x *ServerReflectionResponse) GetOriginalRequest() *ServerReflectionRequest { + if x != nil { + return x.OriginalRequest + } + return nil +} + +func (m *ServerReflectionResponse) GetMessageResponse() isServerReflectionResponse_MessageResponse { + if m != nil { + return m.MessageResponse + } + return nil +} + +func (x *ServerReflectionResponse) GetFileDescriptorResponse() *FileDescriptorResponse { + if x, ok := x.GetMessageResponse().(*ServerReflectionResponse_FileDescriptorResponse); ok { + return x.FileDescriptorResponse + } + return nil +} + +func (x *ServerReflectionResponse) GetAllExtensionNumbersResponse() *ExtensionNumberResponse { + if x, ok := x.GetMessageResponse().(*ServerReflectionResponse_AllExtensionNumbersResponse); ok { + return x.AllExtensionNumbersResponse + } + return nil +} + +func (x *ServerReflectionResponse) GetListServicesResponse() *ListServiceResponse { + if x, ok := x.GetMessageResponse().(*ServerReflectionResponse_ListServicesResponse); ok { + return x.ListServicesResponse + } + return nil +} + +func (x *ServerReflectionResponse) GetErrorResponse() *ErrorResponse { + if x, ok := x.GetMessageResponse().(*ServerReflectionResponse_ErrorResponse); ok { + return x.ErrorResponse + } + return nil +} + +type isServerReflectionResponse_MessageResponse interface { + isServerReflectionResponse_MessageResponse() +} + +type ServerReflectionResponse_FileDescriptorResponse struct { + // This message is used to answer file_by_filename, file_containing_symbol, + // file_containing_extension requests with transitive dependencies. + // As the repeated label is not allowed in oneof fields, we use a + // FileDescriptorResponse message to encapsulate the repeated fields. + // The reflection service is allowed to avoid sending FileDescriptorProtos + // that were previously sent in response to earlier requests in the stream. + FileDescriptorResponse *FileDescriptorResponse `protobuf:"bytes,4,opt,name=file_descriptor_response,json=fileDescriptorResponse,proto3,oneof"` +} + +type ServerReflectionResponse_AllExtensionNumbersResponse struct { + // This message is used to answer all_extension_numbers_of_type requests. + AllExtensionNumbersResponse *ExtensionNumberResponse `protobuf:"bytes,5,opt,name=all_extension_numbers_response,json=allExtensionNumbersResponse,proto3,oneof"` +} + +type ServerReflectionResponse_ListServicesResponse struct { + // This message is used to answer list_services requests. + ListServicesResponse *ListServiceResponse `protobuf:"bytes,6,opt,name=list_services_response,json=listServicesResponse,proto3,oneof"` +} + +type ServerReflectionResponse_ErrorResponse struct { + // This message is used when an error occurs. + ErrorResponse *ErrorResponse `protobuf:"bytes,7,opt,name=error_response,json=errorResponse,proto3,oneof"` +} + +func (*ServerReflectionResponse_FileDescriptorResponse) isServerReflectionResponse_MessageResponse() { +} + +func (*ServerReflectionResponse_AllExtensionNumbersResponse) isServerReflectionResponse_MessageResponse() { +} + +func (*ServerReflectionResponse_ListServicesResponse) isServerReflectionResponse_MessageResponse() {} + +func (*ServerReflectionResponse_ErrorResponse) isServerReflectionResponse_MessageResponse() {} + +// Serialized FileDescriptorProto messages sent by the server answering +// a file_by_filename, file_containing_symbol, or file_containing_extension +// request. +type FileDescriptorResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Serialized FileDescriptorProto messages. We avoid taking a dependency on + // descriptor.proto, which uses proto2 only features, by making them opaque + // bytes instead. + FileDescriptorProto [][]byte `protobuf:"bytes,1,rep,name=file_descriptor_proto,json=fileDescriptorProto,proto3" json:"file_descriptor_proto,omitempty"` +} + +func (x *FileDescriptorResponse) Reset() { + *x = FileDescriptorResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileDescriptorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileDescriptorResponse) ProtoMessage() {} + +func (x *FileDescriptorResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileDescriptorResponse.ProtoReflect.Descriptor instead. +func (*FileDescriptorResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{3} +} + +func (x *FileDescriptorResponse) GetFileDescriptorProto() [][]byte { + if x != nil { + return x.FileDescriptorProto + } + return nil +} + +// A list of extension numbers sent by the server answering +// all_extension_numbers_of_type request. +type ExtensionNumberResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Full name of the base type, including the package name. The format + // is . + BaseTypeName string `protobuf:"bytes,1,opt,name=base_type_name,json=baseTypeName,proto3" json:"base_type_name,omitempty"` + ExtensionNumber []int32 `protobuf:"varint,2,rep,packed,name=extension_number,json=extensionNumber,proto3" json:"extension_number,omitempty"` +} + +func (x *ExtensionNumberResponse) Reset() { + *x = ExtensionNumberResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExtensionNumberResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtensionNumberResponse) ProtoMessage() {} + +func (x *ExtensionNumberResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtensionNumberResponse.ProtoReflect.Descriptor instead. +func (*ExtensionNumberResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{4} +} + +func (x *ExtensionNumberResponse) GetBaseTypeName() string { + if x != nil { + return x.BaseTypeName + } + return "" +} + +func (x *ExtensionNumberResponse) GetExtensionNumber() []int32 { + if x != nil { + return x.ExtensionNumber + } + return nil +} + +// A list of ServiceResponse sent by the server answering list_services request. +type ListServiceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The information of each service may be expanded in the future, so we use + // ServiceResponse message to encapsulate it. + Service []*ServiceResponse `protobuf:"bytes,1,rep,name=service,proto3" json:"service,omitempty"` +} + +func (x *ListServiceResponse) Reset() { + *x = ListServiceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListServiceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListServiceResponse) ProtoMessage() {} + +func (x *ListServiceResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListServiceResponse.ProtoReflect.Descriptor instead. +func (*ListServiceResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{5} +} + +func (x *ListServiceResponse) GetService() []*ServiceResponse { + if x != nil { + return x.Service + } + return nil +} + +// The information of a single service used by ListServiceResponse to answer +// list_services request. +type ServiceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Full name of a registered service, including its package name. The format + // is . + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *ServiceResponse) Reset() { + *x = ServiceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServiceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceResponse) ProtoMessage() {} + +func (x *ServiceResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServiceResponse.ProtoReflect.Descriptor instead. +func (*ServiceResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{6} +} + +func (x *ServiceResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// The error code and error message sent by the server when an error occurs. +type ErrorResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // This field uses the error codes defined in grpc::StatusCode. + ErrorCode int32 `protobuf:"varint,1,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"` + ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` +} + +func (x *ErrorResponse) Reset() { + *x = ErrorResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ErrorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ErrorResponse) ProtoMessage() {} + +func (x *ErrorResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ErrorResponse.ProtoReflect.Descriptor instead. +func (*ErrorResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{7} +} + +func (x *ErrorResponse) GetErrorCode() int32 { + if x != nil { + return x.ErrorCode + } + return 0 +} + +func (x *ErrorResponse) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +var File_grpc_reflection_v1_reflection_proto protoreflect.FileDescriptor + +var file_grpc_reflection_v1_reflection_proto_rawDesc = []byte{ + 0x0a, 0x23, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x72, 0x65, 0x66, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x22, 0xf3, 0x02, 0x0a, 0x17, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x66, 0x69, 0x6c, + 0x65, 0x5f, 0x62, 0x79, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x79, 0x46, 0x69, 0x6c, + 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x16, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x14, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x62, 0x0a, + 0x19, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, + 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x24, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x17, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x42, 0x0a, 0x1d, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x19, 0x61, 0x6c, 0x6c, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x4f, + 0x66, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0d, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, + 0x6c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x42, 0x11, 0x0a, 0x0f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x66, 0x0a, 0x10, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0xae, 0x04, 0x0a, 0x18, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x68, 0x6f, + 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x48, + 0x6f, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x10, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0f, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x66, 0x0a, 0x18, 0x66, + 0x69, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x16, 0x66, 0x69, 0x6c, + 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x1e, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x5f, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x1b, 0x61, 0x6c, 0x6c, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x16, 0x6c, 0x69, 0x73, 0x74, 0x5f, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x72, + 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x48, 0x00, 0x52, 0x14, 0x6c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0e, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x12, 0x0a, 0x10, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4c, 0x0a, 0x16, 0x46, 0x69, 0x6c, 0x65, + 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x13, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, + 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6a, 0x0a, 0x17, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x61, 0x73, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x05, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x22, 0x54, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x07, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, + 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x25, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x53, 0x0a, 0x0d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x32, 0x89, 0x01, 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, + 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x75, 0x0a, 0x14, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x2b, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x66, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, + 0x42, 0x66, 0x0a, 0x15, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x72, 0x65, 0x66, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x15, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x34, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, + 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x65, 0x66, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x72, 0x65, 0x66, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_grpc_reflection_v1_reflection_proto_rawDescOnce sync.Once + file_grpc_reflection_v1_reflection_proto_rawDescData = file_grpc_reflection_v1_reflection_proto_rawDesc +) + +func file_grpc_reflection_v1_reflection_proto_rawDescGZIP() []byte { + file_grpc_reflection_v1_reflection_proto_rawDescOnce.Do(func() { + file_grpc_reflection_v1_reflection_proto_rawDescData = protoimpl.X.CompressGZIP(file_grpc_reflection_v1_reflection_proto_rawDescData) + }) + return file_grpc_reflection_v1_reflection_proto_rawDescData +} + +var file_grpc_reflection_v1_reflection_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_grpc_reflection_v1_reflection_proto_goTypes = []interface{}{ + (*ServerReflectionRequest)(nil), // 0: grpc.reflection.v1.ServerReflectionRequest + (*ExtensionRequest)(nil), // 1: grpc.reflection.v1.ExtensionRequest + (*ServerReflectionResponse)(nil), // 2: grpc.reflection.v1.ServerReflectionResponse + (*FileDescriptorResponse)(nil), // 3: grpc.reflection.v1.FileDescriptorResponse + (*ExtensionNumberResponse)(nil), // 4: grpc.reflection.v1.ExtensionNumberResponse + (*ListServiceResponse)(nil), // 5: grpc.reflection.v1.ListServiceResponse + (*ServiceResponse)(nil), // 6: grpc.reflection.v1.ServiceResponse + (*ErrorResponse)(nil), // 7: grpc.reflection.v1.ErrorResponse +} +var file_grpc_reflection_v1_reflection_proto_depIdxs = []int32{ + 1, // 0: grpc.reflection.v1.ServerReflectionRequest.file_containing_extension:type_name -> grpc.reflection.v1.ExtensionRequest + 0, // 1: grpc.reflection.v1.ServerReflectionResponse.original_request:type_name -> grpc.reflection.v1.ServerReflectionRequest + 3, // 2: grpc.reflection.v1.ServerReflectionResponse.file_descriptor_response:type_name -> grpc.reflection.v1.FileDescriptorResponse + 4, // 3: grpc.reflection.v1.ServerReflectionResponse.all_extension_numbers_response:type_name -> grpc.reflection.v1.ExtensionNumberResponse + 5, // 4: grpc.reflection.v1.ServerReflectionResponse.list_services_response:type_name -> grpc.reflection.v1.ListServiceResponse + 7, // 5: grpc.reflection.v1.ServerReflectionResponse.error_response:type_name -> grpc.reflection.v1.ErrorResponse + 6, // 6: grpc.reflection.v1.ListServiceResponse.service:type_name -> grpc.reflection.v1.ServiceResponse + 0, // 7: grpc.reflection.v1.ServerReflection.ServerReflectionInfo:input_type -> grpc.reflection.v1.ServerReflectionRequest + 2, // 8: grpc.reflection.v1.ServerReflection.ServerReflectionInfo:output_type -> grpc.reflection.v1.ServerReflectionResponse + 8, // [8:9] is the sub-list for method output_type + 7, // [7:8] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_grpc_reflection_v1_reflection_proto_init() } +func file_grpc_reflection_v1_reflection_proto_init() { + if File_grpc_reflection_v1_reflection_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_grpc_reflection_v1_reflection_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerReflectionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_grpc_reflection_v1_reflection_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExtensionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_grpc_reflection_v1_reflection_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerReflectionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_grpc_reflection_v1_reflection_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileDescriptorResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_grpc_reflection_v1_reflection_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExtensionNumberResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_grpc_reflection_v1_reflection_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListServiceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_grpc_reflection_v1_reflection_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServiceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_grpc_reflection_v1_reflection_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ErrorResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_grpc_reflection_v1_reflection_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*ServerReflectionRequest_FileByFilename)(nil), + (*ServerReflectionRequest_FileContainingSymbol)(nil), + (*ServerReflectionRequest_FileContainingExtension)(nil), + (*ServerReflectionRequest_AllExtensionNumbersOfType)(nil), + (*ServerReflectionRequest_ListServices)(nil), + } + file_grpc_reflection_v1_reflection_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*ServerReflectionResponse_FileDescriptorResponse)(nil), + (*ServerReflectionResponse_AllExtensionNumbersResponse)(nil), + (*ServerReflectionResponse_ListServicesResponse)(nil), + (*ServerReflectionResponse_ErrorResponse)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_grpc_reflection_v1_reflection_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_grpc_reflection_v1_reflection_proto_goTypes, + DependencyIndexes: file_grpc_reflection_v1_reflection_proto_depIdxs, + MessageInfos: file_grpc_reflection_v1_reflection_proto_msgTypes, + }.Build() + File_grpc_reflection_v1_reflection_proto = out.File + file_grpc_reflection_v1_reflection_proto_rawDesc = nil + file_grpc_reflection_v1_reflection_proto_goTypes = nil + file_grpc_reflection_v1_reflection_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go new file mode 100644 index 00000000..d6cdd5b5 --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go @@ -0,0 +1,164 @@ +// Copyright 2016 The 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. + +// Service exported by server reflection. A more complete description of how +// server reflection works can be found at +// https://github.com/grpc/grpc/blob/master/doc/server-reflection.md +// +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.25.2 +// source: grpc/reflection/v1/reflection.proto + +package grpc_reflection_v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + ServerReflection_ServerReflectionInfo_FullMethodName = "/grpc.reflection.v1.ServerReflection/ServerReflectionInfo" +) + +// ServerReflectionClient is the client API for ServerReflection service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ServerReflectionClient interface { + // The reflection service is structured as a bidirectional stream, ensuring + // all related requests go to a single server. + ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (ServerReflection_ServerReflectionInfoClient, error) +} + +type serverReflectionClient struct { + cc grpc.ClientConnInterface +} + +func NewServerReflectionClient(cc grpc.ClientConnInterface) ServerReflectionClient { + return &serverReflectionClient{cc} +} + +func (c *serverReflectionClient) ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (ServerReflection_ServerReflectionInfoClient, error) { + stream, err := c.cc.NewStream(ctx, &ServerReflection_ServiceDesc.Streams[0], ServerReflection_ServerReflectionInfo_FullMethodName, opts...) + if err != nil { + return nil, err + } + x := &serverReflectionServerReflectionInfoClient{stream} + return x, nil +} + +type ServerReflection_ServerReflectionInfoClient interface { + Send(*ServerReflectionRequest) error + Recv() (*ServerReflectionResponse, error) + grpc.ClientStream +} + +type serverReflectionServerReflectionInfoClient struct { + grpc.ClientStream +} + +func (x *serverReflectionServerReflectionInfoClient) Send(m *ServerReflectionRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *serverReflectionServerReflectionInfoClient) Recv() (*ServerReflectionResponse, error) { + m := new(ServerReflectionResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// ServerReflectionServer is the server API for ServerReflection service. +// All implementations should embed UnimplementedServerReflectionServer +// for forward compatibility +type ServerReflectionServer interface { + // The reflection service is structured as a bidirectional stream, ensuring + // all related requests go to a single server. + ServerReflectionInfo(ServerReflection_ServerReflectionInfoServer) error +} + +// UnimplementedServerReflectionServer should be embedded to have forward compatible implementations. +type UnimplementedServerReflectionServer struct { +} + +func (UnimplementedServerReflectionServer) ServerReflectionInfo(ServerReflection_ServerReflectionInfoServer) error { + return status.Errorf(codes.Unimplemented, "method ServerReflectionInfo not implemented") +} + +// UnsafeServerReflectionServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ServerReflectionServer will +// result in compilation errors. +type UnsafeServerReflectionServer interface { + mustEmbedUnimplementedServerReflectionServer() +} + +func RegisterServerReflectionServer(s grpc.ServiceRegistrar, srv ServerReflectionServer) { + s.RegisterService(&ServerReflection_ServiceDesc, srv) +} + +func _ServerReflection_ServerReflectionInfo_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ServerReflectionServer).ServerReflectionInfo(&serverReflectionServerReflectionInfoServer{stream}) +} + +type ServerReflection_ServerReflectionInfoServer interface { + Send(*ServerReflectionResponse) error + Recv() (*ServerReflectionRequest, error) + grpc.ServerStream +} + +type serverReflectionServerReflectionInfoServer struct { + grpc.ServerStream +} + +func (x *serverReflectionServerReflectionInfoServer) Send(m *ServerReflectionResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *serverReflectionServerReflectionInfoServer) Recv() (*ServerReflectionRequest, error) { + m := new(ServerReflectionRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// ServerReflection_ServiceDesc is the grpc.ServiceDesc for ServerReflection service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ServerReflection_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.reflection.v1.ServerReflection", + HandlerType: (*ServerReflectionServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "ServerReflectionInfo", + Handler: _ServerReflection_ServerReflectionInfo_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "grpc/reflection/v1/reflection.proto", +} diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go index d54c0767..929733e7 100644 --- a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go @@ -18,8 +18,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v4.22.0 +// protoc-gen-go v1.32.0 +// protoc v4.25.2 // grpc/reflection/v1alpha/reflection.proto is a deprecated file. package grpc_reflection_v1alpha diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go index 367a029b..ef691406 100644 --- a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go @@ -19,7 +19,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v4.22.0 +// - protoc v4.25.2 // grpc/reflection/v1alpha/reflection.proto is a deprecated file. package grpc_reflection_v1alpha diff --git a/vendor/google.golang.org/grpc/reflection/serverreflection.go b/vendor/google.golang.org/grpc/reflection/serverreflection.go index e2f9ebfb..c3b40839 100644 --- a/vendor/google.golang.org/grpc/reflection/serverreflection.go +++ b/vendor/google.golang.org/grpc/reflection/serverreflection.go @@ -48,8 +48,9 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" - v1alphagrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" - v1alphapb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" + v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1" + v1reflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1" + v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" ) // GRPCServer is the interface provided by a gRPC server. It is implemented by @@ -63,9 +64,19 @@ type GRPCServer interface { var _ GRPCServer = (*grpc.Server)(nil) // Register registers the server reflection service on the given gRPC server. +// Both the v1 and v1alpha versions are registered. func Register(s GRPCServer) { - svr := NewServer(ServerOptions{Services: s}) - v1alphagrpc.RegisterServerReflectionServer(s, svr) + svr := NewServerV1(ServerOptions{Services: s}) + v1alphareflectiongrpc.RegisterServerReflectionServer(s, asV1Alpha(svr)) + v1reflectiongrpc.RegisterServerReflectionServer(s, svr) +} + +// RegisterV1 registers only the v1 version of the server reflection service +// on the given gRPC server. Many clients may only support v1alpha so most +// users should use Register instead, at least until clients have upgraded. +func RegisterV1(s GRPCServer) { + svr := NewServerV1(ServerOptions{Services: s}) + v1reflectiongrpc.RegisterServerReflectionServer(s, svr) } // ServiceInfoProvider is an interface used to retrieve metadata about the @@ -120,13 +131,27 @@ type ServerOptions struct { // NewServer returns a reflection server implementation using the given options. // This can be used to customize behavior of the reflection service. Most usages +// should prefer to use Register instead. For backwards compatibility reasons, +// this returns the v1alpha version of the reflection server. For a v1 version +// of the reflection server, see NewServerV1. +// +// # Experimental +// +// Notice: This function is EXPERIMENTAL and may be changed or removed in a +// later release. +func NewServer(opts ServerOptions) v1alphareflectiongrpc.ServerReflectionServer { + return asV1Alpha(NewServerV1(opts)) +} + +// NewServerV1 returns a reflection server implementation using the given options. +// This can be used to customize behavior of the reflection service. Most usages // should prefer to use Register instead. // // # Experimental // // Notice: This function is EXPERIMENTAL and may be changed or removed in a // later release. -func NewServer(opts ServerOptions) v1alphagrpc.ServerReflectionServer { +func NewServerV1(opts ServerOptions) v1reflectiongrpc.ServerReflectionServer { if opts.DescriptorResolver == nil { opts.DescriptorResolver = protoregistry.GlobalFiles } @@ -141,7 +166,7 @@ func NewServer(opts ServerOptions) v1alphagrpc.ServerReflectionServer { } type serverReflectionServer struct { - v1alphagrpc.UnimplementedServerReflectionServer + v1alphareflectiongrpc.UnimplementedServerReflectionServer s ServiceInfoProvider descResolver protodesc.Resolver extResolver ExtensionResolver @@ -151,11 +176,20 @@ type serverReflectionServer struct { // wire format ([]byte). The fileDescriptors will include fd and all the // transitive dependencies of fd with names not in sentFileDescriptors. func (s *serverReflectionServer) fileDescWithDependencies(fd protoreflect.FileDescriptor, sentFileDescriptors map[string]bool) ([][]byte, error) { + if fd.IsPlaceholder() { + // If the given root file is a placeholder, treat it + // as missing instead of serializing it. + return nil, protoregistry.NotFound + } var r [][]byte queue := []protoreflect.FileDescriptor{fd} for len(queue) > 0 { currentfd := queue[0] queue = queue[1:] + if currentfd.IsPlaceholder() { + // Skip any missing files in the dependency graph. + continue + } if sent := sentFileDescriptors[currentfd.Path()]; len(r) == 0 || !sent { sentFileDescriptors[currentfd.Path()] = true fdProto := protodesc.ToFileDescriptorProto(currentfd) @@ -215,11 +249,11 @@ func (s *serverReflectionServer) allExtensionNumbersForTypeName(name string) ([] } // listServices returns the names of services this server exposes. -func (s *serverReflectionServer) listServices() []*v1alphapb.ServiceResponse { +func (s *serverReflectionServer) listServices() []*v1reflectionpb.ServiceResponse { serviceInfo := s.s.GetServiceInfo() - resp := make([]*v1alphapb.ServiceResponse, 0, len(serviceInfo)) + resp := make([]*v1reflectionpb.ServiceResponse, 0, len(serviceInfo)) for svc := range serviceInfo { - resp = append(resp, &v1alphapb.ServiceResponse{Name: svc}) + resp = append(resp, &v1reflectionpb.ServiceResponse{Name: svc}) } sort.Slice(resp, func(i, j int) bool { return resp[i].Name < resp[j].Name @@ -228,7 +262,7 @@ func (s *serverReflectionServer) listServices() []*v1alphapb.ServiceResponse { } // ServerReflectionInfo is the reflection service handler. -func (s *serverReflectionServer) ServerReflectionInfo(stream v1alphagrpc.ServerReflection_ServerReflectionInfoServer) error { +func (s *serverReflectionServer) ServerReflectionInfo(stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoServer) error { sentFileDescriptors := make(map[string]bool) for { in, err := stream.Recv() @@ -239,79 +273,79 @@ func (s *serverReflectionServer) ServerReflectionInfo(stream v1alphagrpc.ServerR return err } - out := &v1alphapb.ServerReflectionResponse{ + out := &v1reflectionpb.ServerReflectionResponse{ ValidHost: in.Host, OriginalRequest: in, } switch req := in.MessageRequest.(type) { - case *v1alphapb.ServerReflectionRequest_FileByFilename: + case *v1reflectionpb.ServerReflectionRequest_FileByFilename: var b [][]byte fd, err := s.descResolver.FindFileByPath(req.FileByFilename) if err == nil { b, err = s.fileDescWithDependencies(fd, sentFileDescriptors) } if err != nil { - out.MessageResponse = &v1alphapb.ServerReflectionResponse_ErrorResponse{ - ErrorResponse: &v1alphapb.ErrorResponse{ + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ ErrorCode: int32(codes.NotFound), ErrorMessage: err.Error(), }, } } else { - out.MessageResponse = &v1alphapb.ServerReflectionResponse_FileDescriptorResponse{ - FileDescriptorResponse: &v1alphapb.FileDescriptorResponse{FileDescriptorProto: b}, + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, } } - case *v1alphapb.ServerReflectionRequest_FileContainingSymbol: + case *v1reflectionpb.ServerReflectionRequest_FileContainingSymbol: b, err := s.fileDescEncodingContainingSymbol(req.FileContainingSymbol, sentFileDescriptors) if err != nil { - out.MessageResponse = &v1alphapb.ServerReflectionResponse_ErrorResponse{ - ErrorResponse: &v1alphapb.ErrorResponse{ + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ ErrorCode: int32(codes.NotFound), ErrorMessage: err.Error(), }, } } else { - out.MessageResponse = &v1alphapb.ServerReflectionResponse_FileDescriptorResponse{ - FileDescriptorResponse: &v1alphapb.FileDescriptorResponse{FileDescriptorProto: b}, + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, } } - case *v1alphapb.ServerReflectionRequest_FileContainingExtension: + case *v1reflectionpb.ServerReflectionRequest_FileContainingExtension: typeName := req.FileContainingExtension.ContainingType extNum := req.FileContainingExtension.ExtensionNumber b, err := s.fileDescEncodingContainingExtension(typeName, extNum, sentFileDescriptors) if err != nil { - out.MessageResponse = &v1alphapb.ServerReflectionResponse_ErrorResponse{ - ErrorResponse: &v1alphapb.ErrorResponse{ + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ ErrorCode: int32(codes.NotFound), ErrorMessage: err.Error(), }, } } else { - out.MessageResponse = &v1alphapb.ServerReflectionResponse_FileDescriptorResponse{ - FileDescriptorResponse: &v1alphapb.FileDescriptorResponse{FileDescriptorProto: b}, + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, } } - case *v1alphapb.ServerReflectionRequest_AllExtensionNumbersOfType: + case *v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: extNums, err := s.allExtensionNumbersForTypeName(req.AllExtensionNumbersOfType) if err != nil { - out.MessageResponse = &v1alphapb.ServerReflectionResponse_ErrorResponse{ - ErrorResponse: &v1alphapb.ErrorResponse{ + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ ErrorCode: int32(codes.NotFound), ErrorMessage: err.Error(), }, } } else { - out.MessageResponse = &v1alphapb.ServerReflectionResponse_AllExtensionNumbersResponse{ - AllExtensionNumbersResponse: &v1alphapb.ExtensionNumberResponse{ + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse{ + AllExtensionNumbersResponse: &v1reflectionpb.ExtensionNumberResponse{ BaseTypeName: req.AllExtensionNumbersOfType, ExtensionNumber: extNums, }, } } - case *v1alphapb.ServerReflectionRequest_ListServices: - out.MessageResponse = &v1alphapb.ServerReflectionResponse_ListServicesResponse{ - ListServicesResponse: &v1alphapb.ListServiceResponse{ + case *v1reflectionpb.ServerReflectionRequest_ListServices: + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ListServicesResponse{ + ListServicesResponse: &v1reflectionpb.ListServiceResponse{ Service: s.listServices(), }, } diff --git a/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go new file mode 100644 index 00000000..b54a3a32 --- /dev/null +++ b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go @@ -0,0 +1,54 @@ +/* + * + * Copyright 2018 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 dns implements a dns resolver to be installed as the default resolver +// in grpc. +// +// Deprecated: this package is imported by grpc and should not need to be +// imported directly by users. +package dns + +import ( + "time" + + "google.golang.org/grpc/internal/resolver/dns" + "google.golang.org/grpc/resolver" +) + +// SetResolvingTimeout sets the maximum duration for DNS resolution requests. +// +// This function affects the global timeout used by all channels using the DNS +// name resolver scheme. +// +// It must be called only at application startup, before any gRPC calls are +// made. Modifying this value after initialization is not thread-safe. +// +// The default value is 30 seconds. Setting the timeout too low may result in +// premature timeouts during resolution, while setting it too high may lead to +// unnecessary delays in service discovery. Choose a value appropriate for your +// specific needs and network environment. +func SetResolvingTimeout(timeout time.Duration) { + dns.ResolvingTimeout = timeout +} + +// NewBuilder creates a dnsBuilder which is used to factory DNS resolvers. +// +// Deprecated: import grpc and use resolver.Get("dns") instead. +func NewBuilder() resolver.Builder { + return dns.NewBuilder() +} diff --git a/vendor/google.golang.org/grpc/resolver/map.go b/vendor/google.golang.org/grpc/resolver/map.go index efcb7f3e..ada5b9bb 100644 --- a/vendor/google.golang.org/grpc/resolver/map.go +++ b/vendor/google.golang.org/grpc/resolver/map.go @@ -20,7 +20,7 @@ package resolver type addressMapEntry struct { addr Address - value interface{} + value any } // AddressMap is a map of addresses to arbitrary values taking into account @@ -69,7 +69,7 @@ func (l addressMapEntryList) find(addr Address) int { } // Get returns the value for the address in the map, if present. -func (a *AddressMap) Get(addr Address) (value interface{}, ok bool) { +func (a *AddressMap) Get(addr Address) (value any, ok bool) { addrKey := toMapKey(&addr) entryList := a.m[addrKey] if entry := entryList.find(addr); entry != -1 { @@ -79,7 +79,7 @@ func (a *AddressMap) Get(addr Address) (value interface{}, ok bool) { } // Set updates or adds the value to the address in the map. -func (a *AddressMap) Set(addr Address, value interface{}) { +func (a *AddressMap) Set(addr Address, value any) { addrKey := toMapKey(&addr) entryList := a.m[addrKey] if entry := entryList.find(addr); entry != -1 { @@ -127,8 +127,8 @@ func (a *AddressMap) Keys() []Address { } // Values returns a slice of all current map values. -func (a *AddressMap) Values() []interface{} { - ret := make([]interface{}, 0, a.Len()) +func (a *AddressMap) Values() []any { + ret := make([]any, 0, a.Len()) for _, entryList := range a.m { for _, entry := range entryList { ret = append(ret, entry.value) @@ -136,3 +136,116 @@ func (a *AddressMap) Values() []interface{} { } return ret } + +type endpointNode struct { + addrs map[string]struct{} +} + +// Equal returns whether the unordered set of addrs are the same between the +// endpoint nodes. +func (en *endpointNode) Equal(en2 *endpointNode) bool { + if len(en.addrs) != len(en2.addrs) { + return false + } + for addr := range en.addrs { + if _, ok := en2.addrs[addr]; !ok { + return false + } + } + return true +} + +func toEndpointNode(endpoint Endpoint) endpointNode { + en := make(map[string]struct{}) + for _, addr := range endpoint.Addresses { + en[addr.Addr] = struct{}{} + } + return endpointNode{ + addrs: en, + } +} + +// EndpointMap is a map of endpoints to arbitrary values keyed on only the +// unordered set of address strings within an endpoint. This map is not thread +// safe, thus it is unsafe to access concurrently. Must be created via +// NewEndpointMap; do not construct directly. +type EndpointMap struct { + endpoints map[*endpointNode]any +} + +// NewEndpointMap creates a new EndpointMap. +func NewEndpointMap() *EndpointMap { + return &EndpointMap{ + endpoints: make(map[*endpointNode]any), + } +} + +// Get returns the value for the address in the map, if present. +func (em *EndpointMap) Get(e Endpoint) (value any, ok bool) { + en := toEndpointNode(e) + if endpoint := em.find(en); endpoint != nil { + return em.endpoints[endpoint], true + } + return nil, false +} + +// Set updates or adds the value to the address in the map. +func (em *EndpointMap) Set(e Endpoint, value any) { + en := toEndpointNode(e) + if endpoint := em.find(en); endpoint != nil { + em.endpoints[endpoint] = value + return + } + em.endpoints[&en] = value +} + +// Len returns the number of entries in the map. +func (em *EndpointMap) Len() int { + return len(em.endpoints) +} + +// Keys returns a slice of all current map keys, as endpoints specifying the +// addresses present in the endpoint keys, in which uniqueness is determined by +// the unordered set of addresses. Thus, endpoint information returned is not +// the full endpoint data (drops duplicated addresses and attributes) but can be +// used for EndpointMap accesses. +func (em *EndpointMap) Keys() []Endpoint { + ret := make([]Endpoint, 0, len(em.endpoints)) + for en := range em.endpoints { + var endpoint Endpoint + for addr := range en.addrs { + endpoint.Addresses = append(endpoint.Addresses, Address{Addr: addr}) + } + ret = append(ret, endpoint) + } + return ret +} + +// Values returns a slice of all current map values. +func (em *EndpointMap) Values() []any { + ret := make([]any, 0, len(em.endpoints)) + for _, val := range em.endpoints { + ret = append(ret, val) + } + return ret +} + +// find returns a pointer to the endpoint node in em if the endpoint node is +// already present. If not found, nil is returned. The comparisons are done on +// the unordered set of addresses within an endpoint. +func (em EndpointMap) find(e endpointNode) *endpointNode { + for endpoint := range em.endpoints { + if e.Equal(endpoint) { + return endpoint + } + } + return nil +} + +// Delete removes the specified endpoint from the map. +func (em *EndpointMap) Delete(e Endpoint) { + en := toEndpointNode(e) + if entry := em.find(en); entry != nil { + delete(em.endpoints, entry) + } +} diff --git a/vendor/google.golang.org/grpc/resolver/resolver.go b/vendor/google.golang.org/grpc/resolver/resolver.go index 353c10b6..20285451 100644 --- a/vendor/google.golang.org/grpc/resolver/resolver.go +++ b/vendor/google.golang.org/grpc/resolver/resolver.go @@ -29,6 +29,7 @@ import ( "google.golang.org/grpc/attributes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/internal" "google.golang.org/grpc/serviceconfig" ) @@ -63,39 +64,22 @@ func Get(scheme string) Builder { } // SetDefaultScheme sets the default scheme that will be used. The default -// default scheme is "passthrough". +// scheme is initially set to "passthrough". // // NOTE: this function must only be called during initialization time (i.e. in // an init() function), and is not thread-safe. The scheme set last overrides // previously set values. func SetDefaultScheme(scheme string) { defaultScheme = scheme + internal.UserSetDefaultScheme = true } -// GetDefaultScheme gets the default scheme that will be used. +// GetDefaultScheme gets the default scheme that will be used by grpc.Dial. If +// SetDefaultScheme is never called, the default scheme used by grpc.NewClient is "dns" instead. func GetDefaultScheme() string { return defaultScheme } -// AddressType indicates the address type returned by name resolution. -// -// Deprecated: use Attributes in Address instead. -type AddressType uint8 - -const ( - // Backend indicates the address is for a backend server. - // - // Deprecated: use Attributes in Address instead. - Backend AddressType = iota - // GRPCLB indicates the address is for a grpclb load balancer. - // - // Deprecated: to select the GRPCLB load balancing policy, use a service - // config with a corresponding loadBalancingConfig. To supply balancer - // addresses to the GRPCLB load balancing policy, set State.Attributes - // using balancer/grpclb/state.Set. - GRPCLB -) - // Address represents a server the client connects to. // // # Experimental @@ -111,9 +95,6 @@ type Address struct { // the address, instead of the hostname from the Dial target string. In most cases, // this should not be set. // - // If Type is GRPCLB, ServerName should be the name of the remote load - // balancer, not the name of the backend. - // // WARNING: ServerName must only be populated with trusted values. It // is insecure to populate it with data from untrusted inputs since untrusted // values could be used to bypass the authority checks performed by TLS. @@ -126,27 +107,29 @@ type Address struct { // BalancerAttributes contains arbitrary data about this address intended // for consumption by the LB policy. These attributes do not affect SubConn // creation, connection establishment, handshaking, etc. - BalancerAttributes *attributes.Attributes - - // Type is the type of this address. // - // Deprecated: use Attributes instead. - Type AddressType + // Deprecated: when an Address is inside an Endpoint, this field should not + // be used, and it will eventually be removed entirely. + BalancerAttributes *attributes.Attributes // Metadata is the information associated with Addr, which may be used // to make load balancing decision. // // Deprecated: use Attributes instead. - Metadata interface{} + Metadata any } // Equal returns whether a and o are identical. Metadata is compared directly, // not with any recursive introspection. +// +// This method compares all fields of the address. When used to tell apart +// addresses during subchannel creation or connection establishment, it might be +// more appropriate for the caller to implement custom equality logic. func (a Address) Equal(o Address) bool { return a.Addr == o.Addr && a.ServerName == o.ServerName && a.Attributes.Equal(o.Attributes) && a.BalancerAttributes.Equal(o.BalancerAttributes) && - a.Type == o.Type && a.Metadata == o.Metadata + a.Metadata == o.Metadata } // String returns JSON formatted string representation of the address. @@ -188,13 +171,42 @@ type BuildOptions struct { // field. In most cases though, it is not appropriate, and this field may // be ignored. Dialer func(context.Context, string) (net.Conn, error) + // Authority is the effective authority of the clientconn for which the + // resolver is built. + Authority string +} + +// An Endpoint is one network endpoint, or server, which may have multiple +// addresses with which it can be accessed. +type Endpoint struct { + // Addresses contains a list of addresses used to access this endpoint. + Addresses []Address + + // Attributes contains arbitrary data about this endpoint intended for + // consumption by the LB policy. + Attributes *attributes.Attributes } // State contains the current Resolver state relevant to the ClientConn. type State struct { // Addresses is the latest set of resolved addresses for the target. + // + // If a resolver sets Addresses but does not set Endpoints, one Endpoint + // will be created for each Address before the State is passed to the LB + // policy. The BalancerAttributes of each entry in Addresses will be set + // in Endpoints.Attributes, and be cleared in the Endpoint's Address's + // BalancerAttributes. + // + // Soon, Addresses will be deprecated and replaced fully by Endpoints. Addresses []Address + // Endpoints is the latest set of resolved endpoints for the target. + // + // If a resolver produces a State containing Endpoints but not Addresses, + // it must take care to ensure the LB policies it selects will support + // Endpoints. + Endpoints []Endpoint + // ServiceConfig contains the result from parsing the latest service // config. If it is nil, it indicates no service config is present or the // resolver does not provide service configs. @@ -234,11 +246,6 @@ type ClientConn interface { // // Deprecated: Use UpdateState instead. NewAddress(addresses []Address) - // NewServiceConfig is called by resolver to notify ClientConn a new - // service config. The service config should be provided as a json string. - // - // Deprecated: Use UpdateState instead. - NewServiceConfig(serviceConfig string) // ParseServiceConfig parses the provided service config and returns an // object that provides the parsed config. ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult @@ -254,20 +261,7 @@ type ClientConn interface { // target does not contain a scheme or if the parsed scheme is not registered // (i.e. no corresponding resolver available to resolve the endpoint), we will // apply the default scheme, and will attempt to reparse it. -// -// Examples: -// -// - "dns://some_authority/foo.bar" -// Target{Scheme: "dns", Authority: "some_authority", Endpoint: "foo.bar"} -// - "foo.bar" -// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "foo.bar"} -// - "unknown_scheme://authority/endpoint" -// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"} type Target struct { - // Deprecated: use URL.Scheme instead. - Scheme string - // Deprecated: use URL.Host instead. - Authority string // URL contains the parsed dial target with an optional default scheme added // to it if the original dial target contained no scheme or contained an // unregistered scheme. Any query params specified in the original dial @@ -293,6 +287,11 @@ func (t Target) Endpoint() string { return strings.TrimPrefix(endpoint, "/") } +// String returns the canonical string representation of Target. +func (t Target) String() string { + return t.URL.Scheme + "://" + t.URL.Host + "/" + t.Endpoint() +} + // Builder creates a resolver that will be used to watch name resolution updates. type Builder interface { // Build creates a new resolver for the given target. @@ -322,9 +321,12 @@ type Resolver interface { Close() } -// UnregisterForTesting removes the resolver builder with the given scheme from the -// resolver map. -// This function is for testing only. -func UnregisterForTesting(scheme string) { - delete(m, scheme) +// AuthorityOverrider is implemented by Builders that wish to override the +// default authority for the ClientConn. +// By default, the authority used is target.Endpoint(). +type AuthorityOverrider interface { + // OverrideAuthority returns the authority to use for a ClientConn with the + // given target. The implementation must generate it without blocking, + // typically in line, and must keep it unchanged. + OverrideAuthority(Target) string } diff --git a/vendor/google.golang.org/grpc/resolver_conn_wrapper.go b/vendor/google.golang.org/grpc/resolver_conn_wrapper.go deleted file mode 100644 index b408b368..00000000 --- a/vendor/google.golang.org/grpc/resolver_conn_wrapper.go +++ /dev/null @@ -1,239 +0,0 @@ -/* - * - * Copyright 2017 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 grpc - -import ( - "context" - "strings" - "sync" - - "google.golang.org/grpc/balancer" - "google.golang.org/grpc/internal/channelz" - "google.golang.org/grpc/internal/grpcsync" - "google.golang.org/grpc/internal/pretty" - "google.golang.org/grpc/resolver" - "google.golang.org/grpc/serviceconfig" -) - -// resolverStateUpdater wraps the single method used by ccResolverWrapper to -// report a state update from the actual resolver implementation. -type resolverStateUpdater interface { - updateResolverState(s resolver.State, err error) error -} - -// ccResolverWrapper is a wrapper on top of cc for resolvers. -// It implements resolver.ClientConn interface. -type ccResolverWrapper struct { - // The following fields are initialized when the wrapper is created and are - // read-only afterwards, and therefore can be accessed without a mutex. - cc resolverStateUpdater - channelzID *channelz.Identifier - ignoreServiceConfig bool - opts ccResolverWrapperOpts - serializer *grpcsync.CallbackSerializer // To serialize all incoming calls. - serializerCancel context.CancelFunc // To close the serializer, accessed only from close(). - - // All incoming (resolver --> gRPC) calls are guaranteed to execute in a - // mutually exclusive manner as they are scheduled on the serializer. - // Fields accessed *only* in these serializer callbacks, can therefore be - // accessed without a mutex. - curState resolver.State - - // mu guards access to the below fields. - mu sync.Mutex - closed bool - resolver resolver.Resolver // Accessed only from outgoing calls. -} - -// ccResolverWrapperOpts wraps the arguments to be passed when creating a new -// ccResolverWrapper. -type ccResolverWrapperOpts struct { - target resolver.Target // User specified dial target to resolve. - builder resolver.Builder // Resolver builder to use. - bOpts resolver.BuildOptions // Resolver build options to use. - channelzID *channelz.Identifier // Channelz identifier for the channel. -} - -// newCCResolverWrapper uses the resolver.Builder to build a Resolver and -// returns a ccResolverWrapper object which wraps the newly built resolver. -func newCCResolverWrapper(cc resolverStateUpdater, opts ccResolverWrapperOpts) (*ccResolverWrapper, error) { - ctx, cancel := context.WithCancel(context.Background()) - ccr := &ccResolverWrapper{ - cc: cc, - channelzID: opts.channelzID, - ignoreServiceConfig: opts.bOpts.DisableServiceConfig, - opts: opts, - serializer: grpcsync.NewCallbackSerializer(ctx), - serializerCancel: cancel, - } - - // Cannot hold the lock at build time because the resolver can send an - // update or error inline and these incoming calls grab the lock to schedule - // a callback in the serializer. - r, err := opts.builder.Build(opts.target, ccr, opts.bOpts) - if err != nil { - cancel() - return nil, err - } - - // Any error reported by the resolver at build time that leads to a - // re-resolution request from the balancer is dropped by grpc until we - // return from this function. So, we don't have to handle pending resolveNow - // requests here. - ccr.mu.Lock() - ccr.resolver = r - ccr.mu.Unlock() - - return ccr, nil -} - -func (ccr *ccResolverWrapper) resolveNow(o resolver.ResolveNowOptions) { - ccr.mu.Lock() - defer ccr.mu.Unlock() - - // ccr.resolver field is set only after the call to Build() returns. But in - // the process of building, the resolver may send an error update which when - // propagated to the balancer may result in a re-resolution request. - if ccr.closed || ccr.resolver == nil { - return - } - ccr.resolver.ResolveNow(o) -} - -func (ccr *ccResolverWrapper) close() { - ccr.mu.Lock() - if ccr.closed { - ccr.mu.Unlock() - return - } - - channelz.Info(logger, ccr.channelzID, "Closing the name resolver") - - // Close the serializer to ensure that no more calls from the resolver are - // handled, before actually closing the resolver. - ccr.serializerCancel() - ccr.closed = true - r := ccr.resolver - ccr.mu.Unlock() - - // Give enqueued callbacks a chance to finish. - <-ccr.serializer.Done - - // Spawn a goroutine to close the resolver (since it may block trying to - // cleanup all allocated resources) and return early. - go r.Close() -} - -// serializerScheduleLocked is a convenience method to schedule a function to be -// run on the serializer while holding ccr.mu. -func (ccr *ccResolverWrapper) serializerScheduleLocked(f func(context.Context)) { - ccr.mu.Lock() - ccr.serializer.Schedule(f) - ccr.mu.Unlock() -} - -// UpdateState is called by resolver implementations to report new state to gRPC -// which includes addresses and service config. -func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error { - errCh := make(chan error, 1) - ok := ccr.serializer.Schedule(func(context.Context) { - ccr.addChannelzTraceEvent(s) - ccr.curState = s - if err := ccr.cc.updateResolverState(ccr.curState, nil); err == balancer.ErrBadResolverState { - errCh <- balancer.ErrBadResolverState - return - } - errCh <- nil - }) - if !ok { - // The only time when Schedule() fail to add the callback to the - // serializer is when the serializer is closed, and this happens only - // when the resolver wrapper is closed. - return nil - } - return <-errCh -} - -// ReportError is called by resolver implementations to report errors -// encountered during name resolution to gRPC. -func (ccr *ccResolverWrapper) ReportError(err error) { - ccr.serializerScheduleLocked(func(_ context.Context) { - channelz.Warningf(logger, ccr.channelzID, "ccResolverWrapper: reporting error to cc: %v", err) - ccr.cc.updateResolverState(resolver.State{}, err) - }) -} - -// NewAddress is called by the resolver implementation to send addresses to -// gRPC. -func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) { - ccr.serializerScheduleLocked(func(_ context.Context) { - ccr.addChannelzTraceEvent(resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig}) - ccr.curState.Addresses = addrs - ccr.cc.updateResolverState(ccr.curState, nil) - }) -} - -// NewServiceConfig is called by the resolver implementation to send service -// configs to gRPC. -func (ccr *ccResolverWrapper) NewServiceConfig(sc string) { - ccr.serializerScheduleLocked(func(_ context.Context) { - channelz.Infof(logger, ccr.channelzID, "ccResolverWrapper: got new service config: %s", sc) - if ccr.ignoreServiceConfig { - channelz.Info(logger, ccr.channelzID, "Service config lookups disabled; ignoring config") - return - } - scpr := parseServiceConfig(sc) - if scpr.Err != nil { - channelz.Warningf(logger, ccr.channelzID, "ccResolverWrapper: error parsing service config: %v", scpr.Err) - return - } - ccr.addChannelzTraceEvent(resolver.State{Addresses: ccr.curState.Addresses, ServiceConfig: scpr}) - ccr.curState.ServiceConfig = scpr - ccr.cc.updateResolverState(ccr.curState, nil) - }) -} - -// ParseServiceConfig is called by resolver implementations to parse a JSON -// representation of the service config. -func (ccr *ccResolverWrapper) ParseServiceConfig(scJSON string) *serviceconfig.ParseResult { - return parseServiceConfig(scJSON) -} - -// addChannelzTraceEvent adds a channelz trace event containing the new -// state received from resolver implementations. -func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) { - var updates []string - var oldSC, newSC *ServiceConfig - var oldOK, newOK bool - if ccr.curState.ServiceConfig != nil { - oldSC, oldOK = ccr.curState.ServiceConfig.Config.(*ServiceConfig) - } - if s.ServiceConfig != nil { - newSC, newOK = s.ServiceConfig.Config.(*ServiceConfig) - } - if oldOK != newOK || (oldOK && newOK && oldSC.rawJSONString != newSC.rawJSONString) { - updates = append(updates, "service config updated") - } - if len(ccr.curState.Addresses) > 0 && len(s.Addresses) == 0 { - updates = append(updates, "resolver returned an empty address list") - } else if len(ccr.curState.Addresses) == 0 && len(s.Addresses) > 0 { - updates = append(updates, "resolver returned new addresses") - } - channelz.Infof(logger, ccr.channelzID, "Resolver state updated: %s (%v)", pretty.ToJSON(s), strings.Join(updates, "; ")) -} diff --git a/vendor/google.golang.org/grpc/resolver_wrapper.go b/vendor/google.golang.org/grpc/resolver_wrapper.go new file mode 100644 index 00000000..9dcc9780 --- /dev/null +++ b/vendor/google.golang.org/grpc/resolver_wrapper.go @@ -0,0 +1,198 @@ +/* + * + * Copyright 2017 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 grpc + +import ( + "context" + "strings" + "sync" + + "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/grpcsync" + "google.golang.org/grpc/internal/pretty" + "google.golang.org/grpc/resolver" + "google.golang.org/grpc/serviceconfig" +) + +// ccResolverWrapper is a wrapper on top of cc for resolvers. +// It implements resolver.ClientConn interface. +type ccResolverWrapper struct { + // The following fields are initialized when the wrapper is created and are + // read-only afterwards, and therefore can be accessed without a mutex. + cc *ClientConn + ignoreServiceConfig bool + serializer *grpcsync.CallbackSerializer + serializerCancel context.CancelFunc + + resolver resolver.Resolver // only accessed within the serializer + + // The following fields are protected by mu. Caller must take cc.mu before + // taking mu. + mu sync.Mutex + curState resolver.State + closed bool +} + +// newCCResolverWrapper initializes the ccResolverWrapper. It can only be used +// after calling start, which builds the resolver. +func newCCResolverWrapper(cc *ClientConn) *ccResolverWrapper { + ctx, cancel := context.WithCancel(cc.ctx) + return &ccResolverWrapper{ + cc: cc, + ignoreServiceConfig: cc.dopts.disableServiceConfig, + serializer: grpcsync.NewCallbackSerializer(ctx), + serializerCancel: cancel, + } +} + +// start builds the name resolver using the resolver.Builder in cc and returns +// any error encountered. It must always be the first operation performed on +// any newly created ccResolverWrapper, except that close may be called instead. +func (ccr *ccResolverWrapper) start() error { + errCh := make(chan error) + ccr.serializer.Schedule(func(ctx context.Context) { + if ctx.Err() != nil { + return + } + opts := resolver.BuildOptions{ + DisableServiceConfig: ccr.cc.dopts.disableServiceConfig, + DialCreds: ccr.cc.dopts.copts.TransportCredentials, + CredsBundle: ccr.cc.dopts.copts.CredsBundle, + Dialer: ccr.cc.dopts.copts.Dialer, + Authority: ccr.cc.authority, + } + var err error + ccr.resolver, err = ccr.cc.resolverBuilder.Build(ccr.cc.parsedTarget, ccr, opts) + errCh <- err + }) + return <-errCh +} + +func (ccr *ccResolverWrapper) resolveNow(o resolver.ResolveNowOptions) { + ccr.serializer.Schedule(func(ctx context.Context) { + if ctx.Err() != nil || ccr.resolver == nil { + return + } + ccr.resolver.ResolveNow(o) + }) +} + +// close initiates async shutdown of the wrapper. To determine the wrapper has +// finished shutting down, the channel should block on ccr.serializer.Done() +// without cc.mu held. +func (ccr *ccResolverWrapper) close() { + channelz.Info(logger, ccr.cc.channelz, "Closing the name resolver") + ccr.mu.Lock() + ccr.closed = true + ccr.mu.Unlock() + + ccr.serializer.Schedule(func(context.Context) { + if ccr.resolver == nil { + return + } + ccr.resolver.Close() + ccr.resolver = nil + }) + ccr.serializerCancel() +} + +// UpdateState is called by resolver implementations to report new state to gRPC +// which includes addresses and service config. +func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error { + ccr.cc.mu.Lock() + ccr.mu.Lock() + if ccr.closed { + ccr.mu.Unlock() + ccr.cc.mu.Unlock() + return nil + } + if s.Endpoints == nil { + s.Endpoints = make([]resolver.Endpoint, 0, len(s.Addresses)) + for _, a := range s.Addresses { + ep := resolver.Endpoint{Addresses: []resolver.Address{a}, Attributes: a.BalancerAttributes} + ep.Addresses[0].BalancerAttributes = nil + s.Endpoints = append(s.Endpoints, ep) + } + } + ccr.addChannelzTraceEvent(s) + ccr.curState = s + ccr.mu.Unlock() + return ccr.cc.updateResolverStateAndUnlock(s, nil) +} + +// ReportError is called by resolver implementations to report errors +// encountered during name resolution to gRPC. +func (ccr *ccResolverWrapper) ReportError(err error) { + ccr.cc.mu.Lock() + ccr.mu.Lock() + if ccr.closed { + ccr.mu.Unlock() + ccr.cc.mu.Unlock() + return + } + ccr.mu.Unlock() + channelz.Warningf(logger, ccr.cc.channelz, "ccResolverWrapper: reporting error to cc: %v", err) + ccr.cc.updateResolverStateAndUnlock(resolver.State{}, err) +} + +// NewAddress is called by the resolver implementation to send addresses to +// gRPC. +func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) { + ccr.cc.mu.Lock() + ccr.mu.Lock() + if ccr.closed { + ccr.mu.Unlock() + ccr.cc.mu.Unlock() + return + } + s := resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig} + ccr.addChannelzTraceEvent(s) + ccr.curState = s + ccr.mu.Unlock() + ccr.cc.updateResolverStateAndUnlock(s, nil) +} + +// ParseServiceConfig is called by resolver implementations to parse a JSON +// representation of the service config. +func (ccr *ccResolverWrapper) ParseServiceConfig(scJSON string) *serviceconfig.ParseResult { + return parseServiceConfig(scJSON) +} + +// addChannelzTraceEvent adds a channelz trace event containing the new +// state received from resolver implementations. +func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) { + var updates []string + var oldSC, newSC *ServiceConfig + var oldOK, newOK bool + if ccr.curState.ServiceConfig != nil { + oldSC, oldOK = ccr.curState.ServiceConfig.Config.(*ServiceConfig) + } + if s.ServiceConfig != nil { + newSC, newOK = s.ServiceConfig.Config.(*ServiceConfig) + } + if oldOK != newOK || (oldOK && newOK && oldSC.rawJSONString != newSC.rawJSONString) { + updates = append(updates, "service config updated") + } + if len(ccr.curState.Addresses) > 0 && len(s.Addresses) == 0 { + updates = append(updates, "resolver returned an empty address list") + } else if len(ccr.curState.Addresses) == 0 && len(s.Addresses) > 0 { + updates = append(updates, "resolver returned new addresses") + } + channelz.Infof(logger, ccr.cc.channelz, "Resolver state updated: %s (%v)", pretty.ToJSON(s), strings.Join(updates, "; ")) +} diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 2030736a..998e251d 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -75,7 +75,7 @@ func NewGZIPCompressorWithLevel(level int) (Compressor, error) { } return &gzipCompressor{ pool: sync.Pool{ - New: func() interface{} { + New: func() any { w, err := gzip.NewWriterLevel(io.Discard, level) if err != nil { panic(err) @@ -189,6 +189,20 @@ type EmptyCallOption struct{} func (EmptyCallOption) before(*callInfo) error { return nil } func (EmptyCallOption) after(*callInfo, *csAttempt) {} +// StaticMethod returns a CallOption which specifies that a call is being made +// to a method that is static, which means the method is known at compile time +// and doesn't change at runtime. This can be used as a signal to stats plugins +// that this method is safe to include as a key to a measurement. +func StaticMethod() CallOption { + return StaticMethodCallOption{} +} + +// StaticMethodCallOption is a CallOption that specifies that a call comes +// from a static method. +type StaticMethodCallOption struct { + EmptyCallOption +} + // Header returns a CallOptions that retrieves the header metadata // for a unary RPC. func Header(md *metadata.MD) CallOption { @@ -577,6 +591,9 @@ type parser struct { // The header of a gRPC message. Find more detail at // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md header [5]byte + + // recvBufferPool is the pool of shared receive buffers. + recvBufferPool SharedBufferPool } // recvMsg reads a complete gRPC message from the stream. @@ -610,9 +627,7 @@ func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byt if int(length) > maxReceiveMessageSize { return 0, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", length, maxReceiveMessageSize) } - // TODO(bradfitz,zhaoq): garbage. reuse buffer after proto decoding instead - // of making it for each message: - msg = make([]byte, int(length)) + msg = p.recvBufferPool.Get(int(length)) if _, err := p.r.Read(msg); err != nil { if err == io.EOF { err = io.ErrUnexpectedEOF @@ -625,7 +640,7 @@ func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byt // encode serializes msg and returns a buffer containing the message, or an // error if it is too large to be transmitted by grpc. If msg is nil, it // generates an empty message. -func encode(c baseCodec, msg interface{}) ([]byte, error) { +func encode(c baseCodec, msg any) ([]byte, error) { if msg == nil { // NOTE: typed nils will not be caught by this check return nil, nil } @@ -639,14 +654,18 @@ func encode(c baseCodec, msg interface{}) ([]byte, error) { return b, nil } -// compress returns the input bytes compressed by compressor or cp. If both -// compressors are nil, returns nil. +// compress returns the input bytes compressed by compressor or cp. +// If both compressors are nil, or if the message has zero length, returns nil, +// indicating no compression was done. // // TODO(dfawley): eliminate cp parameter by wrapping Compressor in an encoding.Compressor. func compress(in []byte, cp Compressor, compressor encoding.Compressor) ([]byte, error) { if compressor == nil && cp == nil { return nil, nil } + if len(in) == 0 { + return nil, nil + } wrapErr := func(err error) error { return status.Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error()) } @@ -692,7 +711,7 @@ func msgHeader(data, compData []byte) (hdr []byte, payload []byte) { return hdr, data } -func outPayload(client bool, msg interface{}, data, payload []byte, t time.Time) *stats.OutPayload { +func outPayload(client bool, msg any, data, payload []byte, t time.Time) *stats.OutPayload { return &stats.OutPayload{ Client: client, Payload: msg, @@ -725,17 +744,19 @@ type payloadInfo struct { uncompressedBytes []byte } -func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) ([]byte, error) { - pf, d, err := p.recvMsg(maxReceiveMessageSize) +// recvAndDecompress reads a message from the stream, decompressing it if necessary. +// +// Cancelling the returned cancel function releases the buffer back to the pool. So the caller should cancel as soon as +// the buffer is no longer needed. +func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor, +) (uncompressedBuf []byte, cancel func(), err error) { + pf, compressedBuf, err := p.recvMsg(maxReceiveMessageSize) if err != nil { - return nil, err - } - if payInfo != nil { - payInfo.compressedLength = len(d) + return nil, nil, err } if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil); st != nil { - return nil, st.Err() + return nil, nil, st.Err() } var size int @@ -743,21 +764,35 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei // To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor, // use this decompressor as the default. if dc != nil { - d, err = dc.Do(bytes.NewReader(d)) - size = len(d) + uncompressedBuf, err = dc.Do(bytes.NewReader(compressedBuf)) + size = len(uncompressedBuf) } else { - d, size, err = decompress(compressor, d, maxReceiveMessageSize) + uncompressedBuf, size, err = decompress(compressor, compressedBuf, maxReceiveMessageSize) } if err != nil { - return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err) + return nil, nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err) } if size > maxReceiveMessageSize { // TODO: Revisit the error code. Currently keep it consistent with java // implementation. - return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize) + return nil, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize) + } + } else { + uncompressedBuf = compressedBuf + } + + if payInfo != nil { + payInfo.compressedLength = len(compressedBuf) + payInfo.uncompressedBytes = uncompressedBuf + + cancel = func() {} + } else { + cancel = func() { + p.recvBufferPool.Put(&compressedBuf) } } - return d, nil + + return uncompressedBuf, cancel, nil } // Using compressor, decompress d, returning data and size. @@ -777,6 +812,9 @@ func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize // size is used as an estimate to size the buffer, but we // will read more data if available. // +MinRead so ReadFrom will not reallocate if size is correct. + // + // TODO: If we ensure that the buffer size is the same as the DecompressedSize, + // we can also utilize the recv buffer pool here. buf := bytes.NewBuffer(make([]byte, 0, size+bytes.MinRead)) bytesRead, err := buf.ReadFrom(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1)) return buf.Bytes(), int(bytesRead), err @@ -791,17 +829,16 @@ func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize // For the two compressor parameters, both should not be set, but if they are, // dc takes precedence over compressor. // TODO(dfawley): wrap the old compressor/decompressor using the new API? -func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m interface{}, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) error { - d, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor) +func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m any, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) error { + buf, cancel, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor) if err != nil { return err } - if err := c.Unmarshal(d, m); err != nil { + defer cancel() + + if err := c.Unmarshal(buf, m); err != nil { return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message: %v", err) } - if payInfo != nil { - payInfo.uncompressedBytes = d - } return nil } @@ -860,19 +897,22 @@ func ErrorDesc(err error) string { // Errorf returns nil if c is OK. // // Deprecated: use status.Errorf instead. -func Errorf(c codes.Code, format string, a ...interface{}) error { +func Errorf(c codes.Code, format string, a ...any) error { return status.Errorf(c, format, a...) } +var errContextCanceled = status.Error(codes.Canceled, context.Canceled.Error()) +var errContextDeadline = status.Error(codes.DeadlineExceeded, context.DeadlineExceeded.Error()) + // toRPCErr converts an error into an error from the status package. func toRPCErr(err error) error { switch err { case nil, io.EOF: return err case context.DeadlineExceeded: - return status.Error(codes.DeadlineExceeded, err.Error()) + return errContextDeadline case context.Canceled: - return status.Error(codes.Canceled, err.Error()) + return errContextCanceled case io.ErrUnexpectedEOF: return status.Error(codes.Internal, err.Error()) } @@ -922,19 +962,6 @@ func setCallInfoCodec(c *callInfo) error { return nil } -// channelzData is used to store channelz related data for ClientConn, addrConn and Server. -// These fields cannot be embedded in the original structs (e.g. ClientConn), since to do atomic -// operation on int64 variable on 32-bit machine, user is responsible to enforce memory alignment. -// Here, by grouping those int64 fields inside a struct, we are enforcing the alignment. -type channelzData struct { - callsStarted int64 - callsFailed int64 - callsSucceeded int64 - // lastCallStartedTime stores the timestamp that last call starts. It is of int64 type instead of - // time.Time since it's more costly to atomically update time.Time variable than int64 variable. - lastCallStartedTime int64 -} - // The SupportPackageIsVersion variables are referenced from generated protocol // buffer files to ensure compatibility with the gRPC version used. The latest // support package version is 7. @@ -948,6 +975,7 @@ const ( SupportPackageIsVersion5 = true SupportPackageIsVersion6 = true SupportPackageIsVersion7 = true + SupportPackageIsVersion8 = true ) const grpcUA = "grpc-go/" + Version diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index 8869cc90..fd4558da 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -33,8 +33,6 @@ import ( "sync/atomic" "time" - "golang.org/x/net/trace" - "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/encoding" @@ -70,9 +68,10 @@ func init() { internal.GetServerCredentials = func(srv *Server) credentials.TransportCredentials { return srv.opts.creds } - internal.DrainServerTransports = func(srv *Server, addr string) { - srv.drainServerTransports(addr) + internal.IsRegisteredMethod = func(srv *Server, method string) bool { + return srv.isRegisteredMethod(method) } + internal.ServerFromContext = serverFromContext internal.AddGlobalServerOptions = func(opt ...ServerOption) { globalServerOptions = append(globalServerOptions, opt...) } @@ -81,12 +80,13 @@ func init() { } internal.BinaryLogger = binaryLogger internal.JoinServerOptions = newJoinServerOption + internal.RecvBufferPool = recvBufferPool } var statusOK = status.New(codes.OK, "") var logger = grpclog.Component("core") -type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor UnaryServerInterceptor) (interface{}, error) +type methodHandler func(srv any, ctx context.Context, dec func(any) error, interceptor UnaryServerInterceptor) (any, error) // MethodDesc represents an RPC service's method specification. type MethodDesc struct { @@ -99,20 +99,20 @@ type ServiceDesc struct { ServiceName string // The pointer to the service interface. Used to check whether the user // provided implementation satisfies the interface requirements. - HandlerType interface{} + HandlerType any Methods []MethodDesc Streams []StreamDesc - Metadata interface{} + Metadata any } // 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 interface{} + serviceImpl any methods map[string]*MethodDesc streams map[string]*StreamDesc - mdata interface{} + mdata any } // Server is a gRPC server to serve RPC requests. @@ -129,17 +129,18 @@ type Server struct { drain bool cv *sync.Cond // signaled when connections close for GracefulStop services map[string]*serviceInfo // service name -> service info - events trace.EventLog + events traceEventLog quit *grpcsync.Event done *grpcsync.Event channelzRemoveOnce sync.Once - serveWG sync.WaitGroup // counts active Serve goroutines for GracefulStop + serveWG sync.WaitGroup // counts active Serve goroutines for Stop/GracefulStop + handlersWG sync.WaitGroup // counts active method handler goroutines - channelzID *channelz.Identifier - czData *channelzData + channelz *channelz.Server - serverWorkerChannel chan func() + serverWorkerChannel chan func() + serverWorkerChannelClose func() } type serverOptions struct { @@ -164,10 +165,13 @@ type serverOptions struct { initialConnWindowSize int32 writeBufferSize int readBufferSize int + sharedWriteBuffer bool connectionTimeout time.Duration maxHeaderListSize *uint32 headerTableSize *uint32 numServerWorkers uint32 + recvBufferPool SharedBufferPool + waitForHandlers bool } var defaultServerOptions = serverOptions{ @@ -177,6 +181,7 @@ var defaultServerOptions = serverOptions{ connectionTimeout: 120 * time.Second, writeBufferSize: defaultWriteBufSize, readBufferSize: defaultReadBufSize, + recvBufferPool: nopBufferPool{}, } var globalServerOptions []ServerOption @@ -228,12 +233,24 @@ func newJoinServerOption(opts ...ServerOption) ServerOption { return &joinServerOption{opts: opts} } +// SharedWriteBuffer allows reusing per-connection transport write buffer. +// If this option is set to true every connection will release the buffer after +// flushing the data on the wire. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func SharedWriteBuffer(val bool) ServerOption { + return newFuncServerOption(func(o *serverOptions) { + o.sharedWriteBuffer = val + }) +} + // WriteBufferSize determines how much data can be batched before doing a write -// on the wire. The corresponding memory allocation for this buffer will be -// twice the size to keep syscalls low. The default value for this buffer is -// 32KB. Zero or negative values will disable the write buffer such that each -// write will be on underlying connection. -// Note: A Send call may not directly translate to a write. +// on the wire. The default value for this buffer is 32KB. Zero or negative +// values will disable the write buffer such that each write will be on underlying +// connection. Note: A Send call may not directly translate to a write. func WriteBufferSize(s int) ServerOption { return newFuncServerOption(func(o *serverOptions) { o.writeBufferSize = s @@ -268,9 +285,9 @@ func InitialConnWindowSize(s int32) ServerOption { // KeepaliveParams returns a ServerOption that sets keepalive and max-age parameters for the server. func KeepaliveParams(kp keepalive.ServerParameters) ServerOption { - if kp.Time > 0 && kp.Time < time.Second { + if kp.Time > 0 && kp.Time < internal.KeepaliveMinServerPingTime { logger.Warning("Adjusting keepalive ping interval to minimum period of 1s") - kp.Time = time.Second + kp.Time = internal.KeepaliveMinServerPingTime } return newFuncServerOption(func(o *serverOptions) { @@ -550,6 +567,44 @@ func NumStreamWorkers(numServerWorkers uint32) ServerOption { }) } +// WaitForHandlers cause Stop to wait until all outstanding method handlers have +// exited before returning. If false, Stop will return as soon as all +// connections have closed, but method handlers may still be running. By +// default, Stop does not wait for method handlers to return. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func WaitForHandlers(w bool) ServerOption { + return newFuncServerOption(func(o *serverOptions) { + o.waitForHandlers = w + }) +} + +// RecvBufferPool returns a ServerOption that configures the server +// to use the provided shared buffer pool for parsing incoming messages. Depending +// on the application's workload, this could result in reduced memory allocation. +// +// If you are unsure about how to implement a memory pool but want to utilize one, +// begin with grpc.NewSharedBufferPool. +// +// Note: The shared buffer pool feature will not be active if any of the following +// options are used: StatsHandler, EnableTracing, or binary logging. In such +// cases, the shared buffer pool will be ignored. +// +// Deprecated: use experimental.WithRecvBufferPool instead. Will be deleted in +// v1.60.0 or later. +func RecvBufferPool(bufferPool SharedBufferPool) ServerOption { + return recvBufferPool(bufferPool) +} + +func recvBufferPool(bufferPool SharedBufferPool) ServerOption { + return newFuncServerOption(func(o *serverOptions) { + o.recvBufferPool = bufferPool + }) +} + // 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 @@ -578,15 +633,14 @@ func (s *Server) serverWorker() { // connections to reduce the time spent overall on runtime.morestack. func (s *Server) initServerWorkers() { s.serverWorkerChannel = make(chan func()) + s.serverWorkerChannelClose = grpcsync.OnceFunc(func() { + close(s.serverWorkerChannel) + }) for i := uint32(0); i < s.opts.numServerWorkers; i++ { go s.serverWorker() } } -func (s *Server) stopServerWorkers() { - close(s.serverWorkerChannel) -} - // NewServer creates a gRPC server which has no service registered and has not // started to accept requests yet. func NewServer(opt ...ServerOption) *Server { @@ -604,28 +658,27 @@ func NewServer(opt ...ServerOption) *Server { services: make(map[string]*serviceInfo), quit: grpcsync.NewEvent(), done: grpcsync.NewEvent(), - czData: new(channelzData), + channelz: channelz.RegisterServer(""), } chainUnaryServerInterceptors(s) chainStreamServerInterceptors(s) s.cv = sync.NewCond(&s.mu) if EnableTracing { _, file, line, _ := runtime.Caller(1) - s.events = trace.NewEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line)) + s.events = newTraceEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line)) } if s.opts.numServerWorkers > 0 { s.initServerWorkers() } - s.channelzID = channelz.RegisterServer(&channelzServer{s}, "") - channelz.Info(logger, s.channelzID, "Server created") + channelz.Info(logger, s.channelz, "Server created") return s } // printf records an event in s's event log, unless s has been stopped. // REQUIRES s.mu is held. -func (s *Server) printf(format string, a ...interface{}) { +func (s *Server) printf(format string, a ...any) { if s.events != nil { s.events.Printf(format, a...) } @@ -633,7 +686,7 @@ func (s *Server) printf(format string, a ...interface{}) { // errorf records an error in s's event log, unless s has been stopped. // REQUIRES s.mu is held. -func (s *Server) errorf(format string, a ...interface{}) { +func (s *Server) errorf(format string, a ...any) { if s.events != nil { s.events.Errorf(format, a...) } @@ -648,14 +701,14 @@ type ServiceRegistrar interface { // once the server has started serving. // desc describes the service and its methods and handlers. impl is the // service implementation which is passed to the method handlers. - RegisterService(desc *ServiceDesc, impl interface{}) + RegisterService(desc *ServiceDesc, impl any) } // RegisterService registers a service and its implementation to the gRPC // server. It is called from the IDL generated code. This must be called before // invoking Serve. If ss is non-nil (for legacy code), its type is checked to // ensure it implements sd.HandlerType. -func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) { +func (s *Server) RegisterService(sd *ServiceDesc, ss any) { if ss != nil { ht := reflect.TypeOf(sd.HandlerType).Elem() st := reflect.TypeOf(ss) @@ -666,7 +719,7 @@ func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) { s.register(sd, ss) } -func (s *Server) register(sd *ServiceDesc, ss interface{}) { +func (s *Server) register(sd *ServiceDesc, ss any) { s.mu.Lock() defer s.mu.Unlock() s.printf("RegisterService(%q)", sd.ServiceName) @@ -707,7 +760,7 @@ type MethodInfo struct { type ServiceInfo struct { Methods []MethodInfo // Metadata is the metadata specified in ServiceDesc when registering service. - Metadata interface{} + Metadata any } // GetServiceInfo returns a map from service names to ServiceInfo. @@ -745,20 +798,13 @@ var ErrServerStopped = errors.New("grpc: the server has been stopped") type listenSocket struct { net.Listener - channelzID *channelz.Identifier -} - -func (l *listenSocket) ChannelzMetric() *channelz.SocketInternalMetric { - return &channelz.SocketInternalMetric{ - SocketOptions: channelz.GetSocketOption(l.Listener), - LocalAddr: l.Listener.Addr(), - } + channelz *channelz.Socket } func (l *listenSocket) Close() error { err := l.Listener.Close() - channelz.RemoveEntry(l.channelzID) - channelz.Info(logger, l.channelzID, "ListenSocket deleted") + channelz.RemoveEntry(l.channelz.ID) + channelz.Info(logger, l.channelz, "ListenSocket deleted") return err } @@ -768,6 +814,18 @@ func (l *listenSocket) Close() error { // Serve returns when lis.Accept fails with fatal errors. lis will be closed when // this method returns. // Serve will return a non-nil error unless Stop or GracefulStop is called. +// +// Note: All supported releases of Go (as of December 2023) override the OS +// defaults for TCP keepalive time and interval to 15s. To enable TCP keepalive +// with OS defaults for keepalive time and interval, callers need to do the +// following two things: +// - pass a net.Listener created by calling the Listen method on a +// net.ListenConfig with the `KeepAlive` field set to a negative value. This +// will result in the Go standard library not overriding OS defaults for TCP +// keepalive interval and time. But this will also result in the Go standard +// library not enabling TCP keepalives by default. +// - override the Accept method on the passed in net.Listener and set the +// SO_KEEPALIVE socket option to enable TCP keepalives, with OS defaults. func (s *Server) Serve(lis net.Listener) error { s.mu.Lock() s.printf("serving") @@ -788,7 +846,16 @@ func (s *Server) Serve(lis net.Listener) error { } }() - ls := &listenSocket{Listener: lis} + ls := &listenSocket{ + Listener: lis, + channelz: channelz.RegisterSocket(&channelz.Socket{ + SocketType: channelz.SocketTypeListen, + Parent: s.channelz, + RefName: lis.Addr().String(), + LocalAddr: lis.Addr(), + SocketOptions: channelz.GetSocketOption(lis)}, + ), + } s.lis[ls] = true defer func() { @@ -800,14 +867,8 @@ func (s *Server) Serve(lis net.Listener) error { s.mu.Unlock() }() - var err error - ls.channelzID, err = channelz.RegisterListenSocket(ls, s.channelzID, lis.Addr().String()) - if err != nil { - s.mu.Unlock() - return err - } s.mu.Unlock() - channelz.Info(logger, ls.channelzID, "ListenSocket created") + channelz.Info(logger, ls.channelz, "ListenSocket created") var tempDelay time.Duration // how long to sleep on accept failure for { @@ -875,24 +936,21 @@ func (s *Server) handleRawConn(lisAddr string, rawConn net.Conn) { return } + if cc, ok := rawConn.(interface { + PassServerTransport(transport.ServerTransport) + }); ok { + cc.PassServerTransport(st) + } + if !s.addConn(lisAddr, st) { return } go func() { - s.serveStreams(st) + s.serveStreams(context.Background(), st, rawConn) s.removeConn(lisAddr, st) }() } -func (s *Server) drainServerTransports(addr string) { - s.mu.Lock() - conns := s.conns[addr] - for st := range conns { - st.Drain("") - } - s.mu.Unlock() -} - // newHTTP2Transport sets up a http/2 transport (using the // gRPC http2 server transport in transport/http2_server.go). func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { @@ -908,7 +966,8 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { InitialConnWindowSize: s.opts.initialConnWindowSize, WriteBufferSize: s.opts.writeBufferSize, ReadBufferSize: s.opts.readBufferSize, - ChannelzParentID: s.channelzID, + SharedWriteBuffer: s.opts.sharedWriteBuffer, + ChannelzParent: s.channelz, MaxHeaderListSize: s.opts.maxHeaderListSize, HeaderTableSize: s.opts.headerTableSize, } @@ -922,7 +981,7 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { if err != credentials.ErrConnDispatched { // Don't log on ErrConnDispatched and io.EOF to prevent log spam. if err != io.EOF { - channelz.Info(logger, s.channelzID, "grpc: Server.Serve failed to create ServerTransport: ", err) + channelz.Info(logger, s.channelz, "grpc: Server.Serve failed to create ServerTransport: ", err) } c.Close() } @@ -932,19 +991,32 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { return st } -func (s *Server) serveStreams(st transport.ServerTransport) { - defer st.Close(errors.New("finished serving streams for the server transport")) - var wg sync.WaitGroup +func (s *Server) serveStreams(ctx context.Context, st transport.ServerTransport, rawConn net.Conn) { + ctx = transport.SetConnection(ctx, rawConn) + ctx = peer.NewContext(ctx, st.Peer()) + for _, sh := range s.opts.statsHandlers { + ctx = sh.TagConn(ctx, &stats.ConnTagInfo{ + RemoteAddr: st.Peer().Addr, + LocalAddr: st.Peer().LocalAddr, + }) + sh.HandleConn(ctx, &stats.ConnBegin{}) + } - streamQuota := newHandlerQuota(s.opts.maxConcurrentStreams) - st.HandleStreams(func(stream *transport.Stream) { - wg.Add(1) + defer func() { + st.Close(errors.New("finished serving streams for the server transport")) + for _, sh := range s.opts.statsHandlers { + sh.HandleConn(ctx, &stats.ConnEnd{}) + } + }() + streamQuota := newHandlerQuota(s.opts.maxConcurrentStreams) + st.HandleStreams(ctx, func(stream *transport.Stream) { + s.handlersWG.Add(1) streamQuota.acquire() f := func() { defer streamQuota.release() - defer wg.Done() - s.handleStream(st, stream, s.traceInfo(st, stream)) + defer s.handlersWG.Done() + s.handleStream(st, stream) } if s.opts.numServerWorkers > 0 { @@ -956,14 +1028,7 @@ func (s *Server) serveStreams(st transport.ServerTransport) { } } go f() - }, func(ctx context.Context, method string) context.Context { - if !EnableTracing { - return ctx - } - tr := trace.New("grpc.Recv."+methodFamily(method), method) - return trace.NewContext(ctx, tr) }) - wg.Wait() } var _ http.Handler = (*Server)(nil) @@ -1007,31 +1072,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } defer s.removeConn(listenerAddressForServeHTTP, st) - s.serveStreams(st) -} - -// traceInfo returns a traceInfo and associates it with stream, if tracing is enabled. -// If tracing is not enabled, it returns nil. -func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Stream) (trInfo *traceInfo) { - if !EnableTracing { - return nil - } - tr, ok := trace.FromContext(stream.Context()) - if !ok { - return nil - } - - trInfo = &traceInfo{ - tr: tr, - firstLine: firstLine{ - client: false, - remoteAddr: st.RemoteAddr(), - }, - } - if dl, ok := stream.Context().Deadline(); ok { - trInfo.firstLine.deadline = time.Until(dl) - } - return trInfo + s.serveStreams(r.Context(), st, nil) } func (s *Server) addConn(addr string, st transport.ServerTransport) bool { @@ -1072,37 +1113,28 @@ func (s *Server) removeConn(addr string, st transport.ServerTransport) { } } -func (s *Server) channelzMetric() *channelz.ServerInternalMetric { - return &channelz.ServerInternalMetric{ - CallsStarted: atomic.LoadInt64(&s.czData.callsStarted), - CallsSucceeded: atomic.LoadInt64(&s.czData.callsSucceeded), - CallsFailed: atomic.LoadInt64(&s.czData.callsFailed), - LastCallStartedTimestamp: time.Unix(0, atomic.LoadInt64(&s.czData.lastCallStartedTime)), - } -} - func (s *Server) incrCallsStarted() { - atomic.AddInt64(&s.czData.callsStarted, 1) - atomic.StoreInt64(&s.czData.lastCallStartedTime, time.Now().UnixNano()) + s.channelz.ServerMetrics.CallsStarted.Add(1) + s.channelz.ServerMetrics.LastCallStartedTimestamp.Store(time.Now().UnixNano()) } func (s *Server) incrCallsSucceeded() { - atomic.AddInt64(&s.czData.callsSucceeded, 1) + s.channelz.ServerMetrics.CallsSucceeded.Add(1) } func (s *Server) incrCallsFailed() { - atomic.AddInt64(&s.czData.callsFailed, 1) + s.channelz.ServerMetrics.CallsFailed.Add(1) } -func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options, comp encoding.Compressor) error { +func (s *Server) sendResponse(ctx context.Context, t transport.ServerTransport, stream *transport.Stream, msg any, cp Compressor, opts *transport.Options, comp encoding.Compressor) error { data, err := encode(s.getCodec(stream.ContentSubtype()), msg) if err != nil { - channelz.Error(logger, s.channelzID, "grpc: server failed to encode response: ", err) + channelz.Error(logger, s.channelz, "grpc: server failed to encode response: ", err) return err } compData, err := compress(data, cp, comp) if err != nil { - channelz.Error(logger, s.channelzID, "grpc: server failed to compress response: ", err) + channelz.Error(logger, s.channelz, "grpc: server failed to compress response: ", err) return err } hdr, payload := msgHeader(data, compData) @@ -1113,7 +1145,7 @@ func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Str err = t.Write(stream, hdr, payload, opts) if err == nil { for _, sh := range s.opts.statsHandlers { - sh.HandleRPC(stream.Context(), outPayload(false, msg, data, payload, time.Now())) + sh.HandleRPC(ctx, outPayload(false, msg, data, payload, time.Now())) } } return err @@ -1141,7 +1173,7 @@ func chainUnaryServerInterceptors(s *Server) { } func chainUnaryInterceptors(interceptors []UnaryServerInterceptor) UnaryServerInterceptor { - return func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (interface{}, error) { + return func(ctx context.Context, req any, info *UnaryServerInfo, handler UnaryHandler) (any, error) { return interceptors[0](ctx, req, info, getChainUnaryHandler(interceptors, 0, info, handler)) } } @@ -1150,12 +1182,12 @@ func getChainUnaryHandler(interceptors []UnaryServerInterceptor, curr int, info if curr == len(interceptors)-1 { return finalHandler } - return func(ctx context.Context, req interface{}) (interface{}, error) { + return func(ctx context.Context, req any) (any, error) { return interceptors[curr+1](ctx, req, info, getChainUnaryHandler(interceptors, curr+1, info, finalHandler)) } } -func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.Stream, info *serviceInfo, md *MethodDesc, trInfo *traceInfo) (err error) { +func (s *Server) processUnaryRPC(ctx context.Context, t transport.ServerTransport, stream *transport.Stream, info *serviceInfo, md *MethodDesc, trInfo *traceInfo) (err error) { shs := s.opts.statsHandlers if len(shs) != 0 || trInfo != nil || channelz.IsOn() { if channelz.IsOn() { @@ -1169,7 +1201,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. IsClientStream: false, IsServerStream: false, } - sh.HandleRPC(stream.Context(), statsBegin) + sh.HandleRPC(ctx, statsBegin) } if trInfo != nil { trInfo.tr.LazyLog(&trInfo.firstLine, false) @@ -1187,7 +1219,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. defer func() { if trInfo != nil { if err != nil && err != io.EOF { - trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) trInfo.tr.SetError() } trInfo.tr.Finish() @@ -1201,7 +1233,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if err != nil && err != io.EOF { end.Error = toRPCErr(err) } - sh.HandleRPC(stream.Context(), end) + sh.HandleRPC(ctx, end) } if channelz.IsOn() { @@ -1223,7 +1255,6 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } } if len(binlogs) != 0 { - ctx := stream.Context() md, _ := metadata.FromIncomingContext(ctx) logEntry := &binarylog.ClientHeader{ Header: md, @@ -1294,22 +1325,25 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if len(shs) != 0 || len(binlogs) != 0 { payInfo = &payloadInfo{} } - d, err := recvAndDecompress(&parser{r: stream}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp) + + d, cancel, err := recvAndDecompress(&parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp) if err != nil { if e := t.WriteStatus(stream, status.Convert(err)); e != nil { - channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e) + channelz.Warningf(logger, s.channelz, "grpc: Server.processUnaryRPC failed to write status: %v", e) } return err } if channelz.IsOn() { t.IncrMsgRecv() } - df := func(v interface{}) error { + df := func(v any) error { + defer cancel() + if err := s.getCodec(stream.ContentSubtype()).Unmarshal(d, v); err != nil { return status.Errorf(codes.Internal, "grpc: error unmarshalling request: %v", err) } for _, sh := range shs { - sh.HandleRPC(stream.Context(), &stats.InPayload{ + sh.HandleRPC(ctx, &stats.InPayload{ RecvTime: time.Now(), Payload: v, Length: len(d), @@ -1323,7 +1357,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Message: d, } for _, binlog := range binlogs { - binlog.Log(stream.Context(), cm) + binlog.Log(ctx, cm) } } if trInfo != nil { @@ -1331,7 +1365,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } return nil } - ctx := NewContextWithServerTransportStream(stream.Context(), stream) + ctx = NewContextWithServerTransportStream(ctx, stream) reply, appErr := md.Handler(info.serviceImpl, ctx, df, s.opts.unaryInt) if appErr != nil { appStatus, ok := status.FromError(appErr) @@ -1346,7 +1380,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. trInfo.tr.SetError() } if e := t.WriteStatus(stream, appStatus); e != nil { - channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e) + 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 { @@ -1356,7 +1390,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Header: h, } for _, binlog := range binlogs { - binlog.Log(stream.Context(), sh) + binlog.Log(ctx, sh) } } st := &binarylog.ServerTrailer{ @@ -1364,7 +1398,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Err: appErr, } for _, binlog := range binlogs { - binlog.Log(stream.Context(), st) + binlog.Log(ctx, st) } } return appErr @@ -1379,14 +1413,14 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if stream.SendCompress() != sendCompressorName { comp = encoding.GetCompressor(stream.SendCompress()) } - if err := s.sendResponse(t, stream, reply, cp, opts, comp); err != nil { + if err := s.sendResponse(ctx, t, 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 := t.WriteStatus(stream, sts); e != nil { - channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e) + channelz.Warningf(logger, s.channelz, "grpc: Server.processUnaryRPC failed to write status: %v", e) } } else { switch st := err.(type) { @@ -1406,8 +1440,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Err: appErr, } for _, binlog := range binlogs { - binlog.Log(stream.Context(), sh) - binlog.Log(stream.Context(), st) + binlog.Log(ctx, sh) + binlog.Log(ctx, st) } } return err @@ -1421,8 +1455,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Message: reply, } for _, binlog := range binlogs { - binlog.Log(stream.Context(), sh) - binlog.Log(stream.Context(), sm) + binlog.Log(ctx, sh) + binlog.Log(ctx, sm) } } if channelz.IsOn() { @@ -1440,7 +1474,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Err: appErr, } for _, binlog := range binlogs { - binlog.Log(stream.Context(), st) + binlog.Log(ctx, st) } } return t.WriteStatus(stream, statusOK) @@ -1468,7 +1502,7 @@ func chainStreamServerInterceptors(s *Server) { } func chainStreamInterceptors(interceptors []StreamServerInterceptor) StreamServerInterceptor { - return func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error { + return func(srv any, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error { return interceptors[0](srv, ss, info, getChainStreamHandler(interceptors, 0, info, handler)) } } @@ -1477,12 +1511,12 @@ func getChainStreamHandler(interceptors []StreamServerInterceptor, curr int, inf if curr == len(interceptors)-1 { return finalHandler } - return func(srv interface{}, stream ServerStream) error { + return func(srv any, stream ServerStream) error { return interceptors[curr+1](srv, stream, info, getChainStreamHandler(interceptors, curr+1, info, finalHandler)) } } -func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, info *serviceInfo, sd *StreamDesc, trInfo *traceInfo) (err error) { +func (s *Server) processStreamingRPC(ctx context.Context, t transport.ServerTransport, stream *transport.Stream, info *serviceInfo, sd *StreamDesc, trInfo *traceInfo) (err error) { if channelz.IsOn() { s.incrCallsStarted() } @@ -1496,15 +1530,15 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp IsServerStream: sd.ServerStreams, } for _, sh := range shs { - sh.HandleRPC(stream.Context(), statsBegin) + sh.HandleRPC(ctx, statsBegin) } } - ctx := NewContextWithServerTransportStream(stream.Context(), stream) + ctx = NewContextWithServerTransportStream(ctx, stream) ss := &serverStream{ ctx: ctx, t: t, s: stream, - p: &parser{r: stream}, + p: &parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, codec: s.getCodec(stream.ContentSubtype()), maxReceiveMessageSize: s.opts.maxReceiveMessageSize, maxSendMessageSize: s.opts.maxSendMessageSize, @@ -1518,7 +1552,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp if trInfo != nil { ss.mu.Lock() if err != nil && err != io.EOF { - ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) ss.trInfo.tr.SetError() } ss.trInfo.tr.Finish() @@ -1535,7 +1569,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp end.Error = toRPCErr(err) } for _, sh := range shs { - sh.HandleRPC(stream.Context(), end) + sh.HandleRPC(ctx, end) } } @@ -1577,7 +1611,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp logEntry.PeerAddr = peer.Addr } for _, binlog := range ss.binlogs { - binlog.Log(stream.Context(), logEntry) + binlog.Log(ctx, logEntry) } } @@ -1621,7 +1655,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp trInfo.tr.LazyLog(&trInfo.firstLine, false) } var appErr error - var server interface{} + var server any if info != nil { server = info.serviceImpl } @@ -1655,7 +1689,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp Err: appErr, } for _, binlog := range ss.binlogs { - binlog.Log(stream.Context(), st) + binlog.Log(ctx, st) } } t.WriteStatus(ss.s, appStatus) @@ -1673,53 +1707,87 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp Err: appErr, } for _, binlog := range ss.binlogs { - binlog.Log(stream.Context(), st) + binlog.Log(ctx, st) } } return t.WriteStatus(ss.s, statusOK) } -func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream, trInfo *traceInfo) { +func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream) { + ctx := stream.Context() + ctx = contextWithServer(ctx, s) + var ti *traceInfo + if EnableTracing { + tr := newTrace("grpc.Recv."+methodFamily(stream.Method()), stream.Method()) + ctx = newTraceContext(ctx, tr) + ti = &traceInfo{ + tr: tr, + firstLine: firstLine{ + client: false, + remoteAddr: t.Peer().Addr, + }, + } + if dl, ok := ctx.Deadline(); ok { + ti.firstLine.deadline = time.Until(dl) + } + } + sm := stream.Method() if sm != "" && sm[0] == '/' { sm = sm[1:] } pos := strings.LastIndex(sm, "/") if pos == -1 { - if trInfo != nil { - trInfo.tr.LazyLog(&fmtStringer{"Malformed method name %q", []interface{}{sm}}, true) - trInfo.tr.SetError() + if ti != nil { + ti.tr.LazyLog(&fmtStringer{"Malformed method name %q", []any{sm}}, true) + ti.tr.SetError() } errDesc := fmt.Sprintf("malformed method name: %q", stream.Method()) if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil { - if trInfo != nil { - trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) - trInfo.tr.SetError() + if ti != nil { + ti.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) + ti.tr.SetError() } - channelz.Warningf(logger, s.channelzID, "grpc: Server.handleStream failed to write status: %v", err) + channelz.Warningf(logger, s.channelz, "grpc: Server.handleStream failed to write status: %v", err) } - if trInfo != nil { - trInfo.tr.Finish() + if ti != nil { + ti.tr.Finish() } return } service := sm[:pos] method := sm[pos+1:] + md, _ := metadata.FromIncomingContext(ctx) + for _, sh := range s.opts.statsHandlers { + ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: stream.Method()}) + sh.HandleRPC(ctx, &stats.InHeader{ + FullMethod: stream.Method(), + RemoteAddr: t.Peer().Addr, + LocalAddr: t.Peer().LocalAddr, + Compression: stream.RecvCompress(), + WireLength: stream.HeaderWireLength(), + Header: md, + }) + } + // To have calls in stream callouts work. Will delete once all stats handler + // calls come from the gRPC layer. + stream.SetContext(ctx) + srv, knownService := s.services[service] if knownService { if md, ok := srv.methods[method]; ok { - s.processUnaryRPC(t, stream, srv, md, trInfo) + s.processUnaryRPC(ctx, t, stream, srv, md, ti) return } if sd, ok := srv.streams[method]; ok { - s.processStreamingRPC(t, stream, srv, sd, trInfo) + s.processStreamingRPC(ctx, t, stream, srv, sd, ti) return } } // Unknown service, or known server unknown method. if unknownDesc := s.opts.unknownStreamDesc; unknownDesc != nil { - s.processStreamingRPC(t, stream, nil, unknownDesc, trInfo) + s.processStreamingRPC(ctx, t, stream, nil, unknownDesc, ti) return } var errDesc string @@ -1728,19 +1796,19 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str } else { errDesc = fmt.Sprintf("unknown method %v for service %v", method, service) } - if trInfo != nil { - trInfo.tr.LazyPrintf("%s", errDesc) - trInfo.tr.SetError() + if ti != nil { + ti.tr.LazyPrintf("%s", errDesc) + ti.tr.SetError() } if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil { - if trInfo != nil { - trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) - trInfo.tr.SetError() + if ti != nil { + ti.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) + ti.tr.SetError() } - channelz.Warningf(logger, s.channelzID, "grpc: Server.handleStream failed to write status: %v", err) + channelz.Warningf(logger, s.channelz, "grpc: Server.handleStream failed to write status: %v", err) } - if trInfo != nil { - trInfo.tr.Finish() + if ti != nil { + ti.tr.Finish() } } @@ -1795,62 +1863,71 @@ func ServerTransportStreamFromContext(ctx context.Context) ServerTransportStream // pending RPCs on the client side will get notified by connection // errors. func (s *Server) Stop() { - s.quit.Fire() + s.stop(false) +} - defer func() { - s.serveWG.Wait() - s.done.Fire() - }() +// GracefulStop stops the gRPC server gracefully. It stops the server from +// accepting new connections and RPCs and blocks until all the pending RPCs are +// finished. +func (s *Server) GracefulStop() { + s.stop(true) +} - s.channelzRemoveOnce.Do(func() { channelz.RemoveEntry(s.channelzID) }) +func (s *Server) stop(graceful bool) { + s.quit.Fire() + defer s.done.Fire() + s.channelzRemoveOnce.Do(func() { channelz.RemoveEntry(s.channelz.ID) }) s.mu.Lock() - listeners := s.lis - s.lis = nil - conns := s.conns - s.conns = nil - // interrupt GracefulStop if Stop and GracefulStop are called concurrently. - s.cv.Broadcast() + s.closeListenersLocked() + // Wait for serving threads to be ready to exit. Only then can we be sure no + // new conns will be created. s.mu.Unlock() + s.serveWG.Wait() - for lis := range listeners { - lis.Close() + s.mu.Lock() + defer s.mu.Unlock() + + if graceful { + s.drainAllServerTransportsLocked() + } else { + s.closeServerTransportsLocked() } - for _, cs := range conns { - for st := range cs { - st.Close(errors.New("Server.Stop called")) - } + + for len(s.conns) != 0 { + s.cv.Wait() } + s.conns = nil + if s.opts.numServerWorkers > 0 { - s.stopServerWorkers() + // Closing the channel (only once, via grpcsync.OnceFunc) after all the + // connections have been closed above ensures that there are no + // goroutines executing the callback passed to st.HandleStreams (where + // the channel is written to). + s.serverWorkerChannelClose() + } + + if graceful || s.opts.waitForHandlers { + s.handlersWG.Wait() } - s.mu.Lock() if s.events != nil { s.events.Finish() s.events = nil } - s.mu.Unlock() } -// GracefulStop stops the gRPC server gracefully. It stops the server from -// accepting new connections and RPCs and blocks until all the pending RPCs are -// finished. -func (s *Server) GracefulStop() { - s.quit.Fire() - defer s.done.Fire() - - s.channelzRemoveOnce.Do(func() { channelz.RemoveEntry(s.channelzID) }) - s.mu.Lock() - if s.conns == nil { - s.mu.Unlock() - return +// s.mu must be held by the caller. +func (s *Server) closeServerTransportsLocked() { + for _, conns := range s.conns { + for st := range conns { + st.Close(errors.New("Server.Stop called")) + } } +} - for lis := range s.lis { - lis.Close() - } - s.lis = nil +// s.mu must be held by the caller. +func (s *Server) drainAllServerTransportsLocked() { if !s.drain { for _, conns := range s.conns { for st := range conns { @@ -1859,22 +1936,14 @@ func (s *Server) GracefulStop() { } s.drain = true } +} - // Wait for serving threads to be ready to exit. Only then can we be sure no - // new conns will be created. - s.mu.Unlock() - s.serveWG.Wait() - s.mu.Lock() - - for len(s.conns) != 0 { - s.cv.Wait() - } - s.conns = nil - if s.events != nil { - s.events.Finish() - s.events = nil +// s.mu must be held by the caller. +func (s *Server) closeListenersLocked() { + for lis := range s.lis { + lis.Close() } - s.mu.Unlock() + s.lis = nil } // contentSubtype must be lowercase @@ -1888,11 +1957,50 @@ func (s *Server) getCodec(contentSubtype string) baseCodec { } codec := encoding.GetCodec(contentSubtype) if codec == nil { + logger.Warningf("Unsupported codec %q. Defaulting to %q for now. This will start to fail in future releases.", contentSubtype, proto.Name) return encoding.GetCodec(proto.Name) } return codec } +type serverKey struct{} + +// serverFromContext gets the Server from the context. +func serverFromContext(ctx context.Context) *Server { + s, _ := ctx.Value(serverKey{}).(*Server) + return s +} + +// contextWithServer sets the Server in the context. +func contextWithServer(ctx context.Context, server *Server) context.Context { + return context.WithValue(ctx, serverKey{}, server) +} + +// isRegisteredMethod returns whether the passed in method is registered as a +// method on the server. /service/method and service/method will match if the +// service and method are registered on the server. +func (s *Server) isRegisteredMethod(serviceMethod string) bool { + if serviceMethod != "" && serviceMethod[0] == '/' { + serviceMethod = serviceMethod[1:] + } + pos := strings.LastIndex(serviceMethod, "/") + if pos == -1 { // Invalid method name syntax. + return false + } + service := serviceMethod[:pos] + 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 + } + } + return false +} + // SetHeader sets the header metadata to be sent from the server to the client. // The context provided must be the context passed to the server's handler. // @@ -1994,7 +2102,7 @@ func ClientSupportedCompressors(ctx context.Context) ([]string, error) { return nil, fmt.Errorf("failed to fetch the stream from the given context %v", ctx) } - return strings.Split(stream.ClientAdvertisedCompressors(), ","), nil + return stream.ClientAdvertisedCompressors(), nil } // SetTrailer sets the trailer metadata that will be sent when an RPC returns. @@ -2024,17 +2132,9 @@ func Method(ctx context.Context) (string, bool) { return s.Method(), true } -type channelzServer struct { - s *Server -} - -func (c *channelzServer) ChannelzMetric() *channelz.ServerInternalMetric { - return c.s.channelzMetric() -} - // validateSendCompressor returns an error when given compressor name cannot be // handled by the server or the client based on the advertised compressors. -func validateSendCompressor(name, clientCompressors string) error { +func validateSendCompressor(name string, clientCompressors []string) error { if name == encoding.Identity { return nil } @@ -2043,7 +2143,7 @@ func validateSendCompressor(name, clientCompressors string) error { return fmt.Errorf("compressor not registered %q", name) } - for _, c := range strings.Split(clientCompressors, ",") { + for _, c := range clientCompressors { if c == name { return nil // found match } @@ -2054,12 +2154,12 @@ func validateSendCompressor(name, clientCompressors string) error { // atomicSemaphore implements a blocking, counting semaphore. acquire should be // called synchronously; release may be called asynchronously. type atomicSemaphore struct { - n int64 + n atomic.Int64 wait chan struct{} } func (q *atomicSemaphore) acquire() { - if atomic.AddInt64(&q.n, -1) < 0 { + if q.n.Add(-1) < 0 { // We ran out of quota. Block until a release happens. <-q.wait } @@ -2070,12 +2170,14 @@ func (q *atomicSemaphore) release() { // concurrent calls to acquire, but also note that with synchronous calls to // acquire, as our system does, n will never be less than -1. There are // fairness issues (queuing) to consider if this was to be generalized. - if atomic.AddInt64(&q.n, 1) <= 0 { + if q.n.Add(1) <= 0 { // An acquire was waiting on us. Unblock it. q.wait <- struct{}{} } } func newHandlerQuota(n uint32) *atomicSemaphore { - return &atomicSemaphore{n: int64(n), wait: make(chan struct{}, 1)} + a := &atomicSemaphore{wait: make(chan struct{}, 1)} + a.n.Store(int64(n)) + return a } diff --git a/vendor/google.golang.org/grpc/service_config.go b/vendor/google.golang.org/grpc/service_config.go index 0df11fc0..2b35c5d2 100644 --- a/vendor/google.golang.org/grpc/service_config.go +++ b/vendor/google.golang.org/grpc/service_config.go @@ -25,8 +25,10 @@ import ( "reflect" "time" + "google.golang.org/grpc/balancer" "google.golang.org/grpc/codes" "google.golang.org/grpc/internal" + "google.golang.org/grpc/internal/balancer/gracefulswitch" internalserviceconfig "google.golang.org/grpc/internal/serviceconfig" "google.golang.org/grpc/serviceconfig" ) @@ -41,11 +43,6 @@ const maxInt = int(^uint(0) >> 1) // https://github.com/grpc/grpc/blob/master/doc/service_config.md type MethodConfig = internalserviceconfig.MethodConfig -type lbConfig struct { - name string - cfg serviceconfig.LoadBalancingConfig -} - // ServiceConfig is provided by the service provider and contains parameters for how // clients that connect to the service should behave. // @@ -55,14 +52,9 @@ type lbConfig struct { type ServiceConfig struct { serviceconfig.Config - // LB is the load balancer the service providers recommends. This is - // deprecated; lbConfigs is preferred. If lbConfig and LB are both present, - // lbConfig will be used. - LB *string - // lbConfig is the service config's load balancing configuration. If // lbConfig and LB are both present, lbConfig will be used. - lbConfig *lbConfig + lbConfig serviceconfig.LoadBalancingConfig // Methods contains a map for the methods in this service. If there is an // exact match for a method (i.e. /service/method) in the map, use the @@ -164,7 +156,7 @@ type jsonMC struct { // TODO(lyuxuan): delete this struct after cleaning up old service config implementation. type jsonSC struct { LoadBalancingPolicy *string - LoadBalancingConfig *internalserviceconfig.BalancerConfig + LoadBalancingConfig *json.RawMessage MethodConfig *[]jsonMC RetryThrottling *retryThrottlingPolicy HealthCheckConfig *healthCheckConfig @@ -184,18 +176,33 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { return &serviceconfig.ParseResult{Err: err} } sc := ServiceConfig{ - LB: rsc.LoadBalancingPolicy, Methods: make(map[string]MethodConfig), retryThrottling: rsc.RetryThrottling, healthCheckConfig: rsc.HealthCheckConfig, rawJSONString: js, } - if c := rsc.LoadBalancingConfig; c != nil { - sc.lbConfig = &lbConfig{ - name: c.Name, - cfg: c.Config, + c := rsc.LoadBalancingConfig + if c == nil { + name := PickFirstBalancerName + if rsc.LoadBalancingPolicy != nil { + name = *rsc.LoadBalancingPolicy + } + if balancer.Get(name) == nil { + name = PickFirstBalancerName } + cfg := []map[string]any{{name: struct{}{}}} + strCfg, err := json.Marshal(cfg) + if err != nil { + return &serviceconfig.ParseResult{Err: fmt.Errorf("unexpected error marshaling simple LB config: %w", err)} + } + r := json.RawMessage(strCfg) + c = &r + } + cfg, err := gracefulswitch.ParseConfig(*c) + if err != nil { + return &serviceconfig.ParseResult{Err: err} } + sc.lbConfig = cfg if rsc.MethodConfig == nil { return &serviceconfig.ParseResult{Config: &sc} diff --git a/vendor/google.golang.org/grpc/shared_buffer_pool.go b/vendor/google.golang.org/grpc/shared_buffer_pool.go new file mode 100644 index 00000000..48a64cfe --- /dev/null +++ b/vendor/google.golang.org/grpc/shared_buffer_pool.go @@ -0,0 +1,154 @@ +/* + * + * Copyright 2023 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 grpc + +import "sync" + +// SharedBufferPool is a pool of buffers that can be shared, resulting in +// decreased memory allocation. Currently, in gRPC-go, it is only utilized +// for parsing incoming messages. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +type SharedBufferPool interface { + // Get returns a buffer with specified length from the pool. + // + // The returned byte slice may be not zero initialized. + Get(length int) []byte + + // Put returns a buffer to the pool. + Put(*[]byte) +} + +// NewSharedBufferPool creates a simple SharedBufferPool with buckets +// of different sizes to optimize memory usage. This prevents the pool from +// wasting large amounts of memory, even when handling messages of varying sizes. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func NewSharedBufferPool() SharedBufferPool { + return &simpleSharedBufferPool{ + pools: [poolArraySize]simpleSharedBufferChildPool{ + newBytesPool(level0PoolMaxSize), + newBytesPool(level1PoolMaxSize), + newBytesPool(level2PoolMaxSize), + newBytesPool(level3PoolMaxSize), + newBytesPool(level4PoolMaxSize), + newBytesPool(0), + }, + } +} + +// simpleSharedBufferPool is a simple implementation of SharedBufferPool. +type simpleSharedBufferPool struct { + pools [poolArraySize]simpleSharedBufferChildPool +} + +func (p *simpleSharedBufferPool) Get(size int) []byte { + return p.pools[p.poolIdx(size)].Get(size) +} + +func (p *simpleSharedBufferPool) Put(bs *[]byte) { + p.pools[p.poolIdx(cap(*bs))].Put(bs) +} + +func (p *simpleSharedBufferPool) poolIdx(size int) int { + switch { + case size <= level0PoolMaxSize: + return level0PoolIdx + case size <= level1PoolMaxSize: + return level1PoolIdx + case size <= level2PoolMaxSize: + return level2PoolIdx + case size <= level3PoolMaxSize: + return level3PoolIdx + case size <= level4PoolMaxSize: + return level4PoolIdx + default: + return levelMaxPoolIdx + } +} + +const ( + level0PoolMaxSize = 16 // 16 B + level1PoolMaxSize = level0PoolMaxSize * 16 // 256 B + level2PoolMaxSize = level1PoolMaxSize * 16 // 4 KB + level3PoolMaxSize = level2PoolMaxSize * 16 // 64 KB + level4PoolMaxSize = level3PoolMaxSize * 16 // 1 MB +) + +const ( + level0PoolIdx = iota + level1PoolIdx + level2PoolIdx + level3PoolIdx + level4PoolIdx + levelMaxPoolIdx + poolArraySize +) + +type simpleSharedBufferChildPool interface { + Get(size int) []byte + Put(any) +} + +type bufferPool struct { + sync.Pool + + defaultSize int +} + +func (p *bufferPool) Get(size int) []byte { + bs := p.Pool.Get().(*[]byte) + + if cap(*bs) < size { + p.Pool.Put(bs) + + return make([]byte, size) + } + + return (*bs)[:size] +} + +func newBytesPool(size int) simpleSharedBufferChildPool { + return &bufferPool{ + Pool: sync.Pool{ + New: func() any { + bs := make([]byte, size) + return &bs + }, + }, + defaultSize: size, + } +} + +// nopBufferPool is a buffer pool just makes new buffer without pooling. +type nopBufferPool struct { +} + +func (nopBufferPool) Get(length int) []byte { + return make([]byte, length) +} + +func (nopBufferPool) Put(*[]byte) { +} diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go index 7a552a9b..4ab70e2d 100644 --- a/vendor/google.golang.org/grpc/stats/stats.go +++ b/vendor/google.golang.org/grpc/stats/stats.go @@ -59,12 +59,22 @@ func (s *Begin) IsClient() bool { return s.Client } func (s *Begin) isRPCStats() {} +// PickerUpdated indicates that the LB policy provided a new picker while the +// RPC was waiting for one. +type PickerUpdated struct{} + +// IsClient indicates if the stats information is from client side. Only Client +// Side interfaces with a Picker, thus always returns true. +func (*PickerUpdated) IsClient() bool { return true } + +func (*PickerUpdated) isRPCStats() {} + // InPayload contains the information for an incoming payload. type InPayload struct { // Client is true if this InPayload is from client side. Client bool // Payload is the payload with original type. - Payload interface{} + Payload any // Data is the serialized message payload. Data []byte @@ -134,7 +144,7 @@ type OutPayload struct { // Client is true if this OutPayload is from client side. Client bool // Payload is the payload with original type. - Payload interface{} + Payload any // Data is the serialized message payload. Data []byte // Length is the size of the uncompressed payload data. Does not include any diff --git a/vendor/google.golang.org/grpc/status/status.go b/vendor/google.golang.org/grpc/status/status.go index bcf2e4d8..a93360ef 100644 --- a/vendor/google.golang.org/grpc/status/status.go +++ b/vendor/google.golang.org/grpc/status/status.go @@ -50,7 +50,7 @@ func New(c codes.Code, msg string) *Status { } // Newf returns New(c, fmt.Sprintf(format, a...)). -func Newf(c codes.Code, format string, a ...interface{}) *Status { +func Newf(c codes.Code, format string, a ...any) *Status { return New(c, fmt.Sprintf(format, a...)) } @@ -60,7 +60,7 @@ func Error(c codes.Code, msg string) error { } // Errorf returns Error(c, fmt.Sprintf(format, a...)). -func Errorf(c codes.Code, format string, a ...interface{}) error { +func Errorf(c codes.Code, format string, a ...any) error { return Error(c, fmt.Sprintf(format, a...)) } @@ -99,25 +99,27 @@ func FromError(err error) (s *Status, ok bool) { } type grpcstatus interface{ GRPCStatus() *Status } if gs, ok := err.(grpcstatus); ok { - if gs.GRPCStatus() == nil { + grpcStatus := gs.GRPCStatus() + if grpcStatus == nil { // Error has status nil, which maps to codes.OK. There // is no sensible behavior for this, so we turn it into // an error with codes.Unknown and discard the existing // status. return New(codes.Unknown, err.Error()), false } - return gs.GRPCStatus(), true + return grpcStatus, true } var gs grpcstatus if errors.As(err, &gs) { - if gs.GRPCStatus() == nil { + grpcStatus := gs.GRPCStatus() + if grpcStatus == nil { // Error wraps an error that has status nil, which maps // to codes.OK. There is no sensible behavior for this, // so we turn it into an error with codes.Unknown and // discard the existing status. return New(codes.Unknown, err.Error()), false } - p := gs.GRPCStatus().Proto() + p := grpcStatus.Proto() p.Message = err.Error() return status.FromProto(p), true } diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 10092685..d939ffc6 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -27,10 +27,10 @@ import ( "sync" "time" - "golang.org/x/net/trace" "google.golang.org/grpc/balancer" "google.golang.org/grpc/codes" "google.golang.org/grpc/encoding" + "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/balancerload" "google.golang.org/grpc/internal/binarylog" "google.golang.org/grpc/internal/channelz" @@ -47,6 +47,8 @@ import ( "google.golang.org/grpc/status" ) +var metadataFromOutgoingContextRaw = internal.FromOutgoingContextRaw.(func(context.Context) (metadata.MD, [][]string, bool)) + // StreamHandler defines the handler called by gRPC server to complete the // execution of a streaming RPC. // @@ -54,7 +56,7 @@ import ( // status package, or be one of the context errors. Otherwise, gRPC will use // codes.Unknown as the status code and err.Error() as the status message of the // RPC. -type StreamHandler func(srv interface{}, stream ServerStream) error +type StreamHandler func(srv any, stream ServerStream) error // StreamDesc represents a streaming RPC service's method specification. Used // on the server when registering services and on the client when initiating @@ -79,9 +81,9 @@ type Stream interface { // Deprecated: See ClientStream and ServerStream documentation instead. Context() context.Context // Deprecated: See ClientStream and ServerStream documentation instead. - SendMsg(m interface{}) error + SendMsg(m any) error // Deprecated: See ClientStream and ServerStream documentation instead. - RecvMsg(m interface{}) error + RecvMsg(m any) error } // ClientStream defines the client-side behavior of a streaming RPC. @@ -90,7 +92,9 @@ type Stream interface { // status package. type ClientStream interface { // Header returns the header metadata received from the server if there - // is any. It blocks if the metadata is not ready to read. + // is any. It blocks if the metadata is not ready to read. If the metadata + // is nil and the error is also nil, then the stream was terminated without + // headers, and the status can be discovered by calling RecvMsg. Header() (metadata.MD, error) // Trailer returns the trailer metadata from the server, if there is any. // It must only be called after stream.CloseAndRecv has returned, or @@ -126,7 +130,7 @@ type ClientStream interface { // // It is not safe to modify the message after calling SendMsg. Tracing // libraries and stats handlers may use the message lazily. - SendMsg(m interface{}) error + SendMsg(m any) error // RecvMsg blocks until it receives a message into m or the stream is // done. It returns io.EOF when the stream completes successfully. On // any other error, the stream is aborted and the error contains the RPC @@ -135,7 +139,7 @@ type ClientStream interface { // It is safe to have a goroutine calling SendMsg and another goroutine // calling RecvMsg on the same stream at the same time, but it is not // safe to call RecvMsg on the same stream in different goroutines. - RecvMsg(m interface{}) error + RecvMsg(m any) error } // NewStream creates a new Stream for the client side. This is typically @@ -155,11 +159,6 @@ type ClientStream interface { // If none of the above happen, a goroutine and a context will be leaked, and grpc // will not call the optionally-configured stats handler with a stats.End message. func (cc *ClientConn) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) { - if err := cc.idlenessMgr.onCallBegin(); err != nil { - return nil, err - } - defer cc.idlenessMgr.onCallEnd() - // allow interceptor to see all applicable call options, which means those // configured as defaults from dial option as well as per-call options opts = combine(cc.dopts.callOptions, opts) @@ -176,7 +175,17 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth } func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) { - if md, added, ok := metadata.FromOutgoingContextRaw(ctx); ok { + // Start tracking the RPC for idleness purposes. This is where a stream is + // created for both streaming and unary RPCs, and hence is a good place to + // track active RPC count. + if err := cc.idlenessMgr.OnCallBegin(); err != nil { + return nil, err + } + // Add a calloption, to decrement the active call count, that gets executed + // when the RPC completes. + opts = append([]CallOption{OnFinish(func(error) { cc.idlenessMgr.OnCallEnd() })}, opts...) + + if md, added, ok := metadataFromOutgoingContextRaw(ctx); ok { // validate md if err := imetadata.Validate(md); err != nil { return nil, status.Error(codes.Internal, err.Error()) @@ -421,7 +430,7 @@ func (cs *clientStream) newAttemptLocked(isTransparent bool) (*csAttempt, error) var trInfo *traceInfo if EnableTracing { trInfo = &traceInfo{ - tr: trace.New("grpc.Sent."+methodFamily(method), method), + tr: newTrace("grpc.Sent."+methodFamily(method), method), firstLine: firstLine{ client: true, }, @@ -430,10 +439,10 @@ func (cs *clientStream) newAttemptLocked(isTransparent bool) (*csAttempt, error) trInfo.firstLine.deadline = time.Until(deadline) } trInfo.tr.LazyLog(&trInfo.firstLine, false) - ctx = trace.NewContext(ctx, trInfo.tr) + ctx = newTraceContext(ctx, trInfo.tr) } - if cs.cc.parsedTarget.URL.Scheme == "xds" { + if cs.cc.parsedTarget.URL.Scheme == internal.GRPCResolverSchemeExtraMetadata { // Add extra metadata (metadata that will be added by transport) to context // so the balancer can see them. ctx = grpcutil.WithExtraMetadata(ctx, metadata.Pairs( @@ -507,7 +516,7 @@ func (a *csAttempt) newStream() error { return toRPCErr(nse.Err) } a.s = s - a.p = &parser{r: s} + a.p = &parser{r: s, recvBufferPool: a.cs.cc.dopts.recvBufferPool} return nil } @@ -646,13 +655,13 @@ func (a *csAttempt) shouldRetry(err error) (bool, error) { if len(sps) == 1 { var e error if pushback, e = strconv.Atoi(sps[0]); e != nil || pushback < 0 { - channelz.Infof(logger, cs.cc.channelzID, "Server retry pushback specified to abort (%q).", sps[0]) + channelz.Infof(logger, cs.cc.channelz, "Server retry pushback specified to abort (%q).", sps[0]) cs.retryThrottler.throttle() // This counts as a failure for throttling. return false, err } hasPushback = true } else if len(sps) > 1 { - channelz.Warningf(logger, cs.cc.channelzID, "Server retry pushback specified multiple values (%q); not retrying.", sps) + channelz.Warningf(logger, cs.cc.channelz, "Server retry pushback specified multiple values (%q); not retrying.", sps) cs.retryThrottler.throttle() // This counts as a failure for throttling. return false, err } @@ -788,23 +797,24 @@ func (cs *clientStream) withRetry(op func(a *csAttempt) error, onSuccess func()) func (cs *clientStream) Header() (metadata.MD, error) { var m metadata.MD - noHeader := false err := cs.withRetry(func(a *csAttempt) error { var err error m, err = a.s.Header() - if err == transport.ErrNoHeaders { - noHeader = true - return nil - } return toRPCErr(err) }, cs.commitAttemptLocked) + if m == nil && err == nil { + // The stream ended with success. Finish the clientStream. + err = io.EOF + } + if err != nil { cs.finish(err) - return nil, err + // Do not return the error. The user should get it by calling Recv(). + return nil, nil } - if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged && !noHeader { + if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged && m != nil { // Only log if binary log is on and header has not been logged, and // there is actually headers to log. logEntry := &binarylog.ServerHeader{ @@ -820,6 +830,7 @@ func (cs *clientStream) Header() (metadata.MD, error) { binlog.Log(cs.ctx, logEntry) } } + return m, nil } @@ -860,7 +871,7 @@ func (cs *clientStream) bufferForRetryLocked(sz int, op func(a *csAttempt) error cs.buffer = append(cs.buffer, op) } -func (cs *clientStream) SendMsg(m interface{}) (err error) { +func (cs *clientStream) SendMsg(m any) (err error) { defer func() { if err != nil && err != io.EOF { // Call finish on the client stream for errors generated by this SendMsg @@ -904,7 +915,7 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { return err } -func (cs *clientStream) RecvMsg(m interface{}) error { +func (cs *clientStream) RecvMsg(m any) error { if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged { // Call Header() to binary log header if it's not already logged. cs.Header() @@ -928,24 +939,6 @@ func (cs *clientStream) RecvMsg(m interface{}) error { if err != nil || !cs.desc.ServerStreams { // err != nil or non-server-streaming indicates end of stream. cs.finish(err) - - if len(cs.binlogs) != 0 { - // finish will not log Trailer. Log Trailer here. - logEntry := &binarylog.ServerTrailer{ - OnClientSide: true, - Trailer: cs.Trailer(), - Err: err, - } - if logEntry.Err == io.EOF { - logEntry.Err = nil - } - if peer, ok := peer.FromContext(cs.Context()); ok { - logEntry.PeerAddr = peer.Addr - } - for _, binlog := range cs.binlogs { - binlog.Log(cs.ctx, logEntry) - } - } } return err } @@ -1001,18 +994,30 @@ func (cs *clientStream) finish(err error) { } } } + cs.mu.Unlock() - // For binary logging. only log cancel in finish (could be caused by RPC ctx - // canceled or ClientConn closed). Trailer will be logged in RecvMsg. - // - // Only one of cancel or trailer needs to be logged. In the cases where - // users don't call RecvMsg, users must have already canceled the RPC. - if len(cs.binlogs) != 0 && status.Code(err) == codes.Canceled { - c := &binarylog.Cancel{ - OnClientSide: true, - } - for _, binlog := range cs.binlogs { - binlog.Log(cs.ctx, c) + // Only one of cancel or trailer needs to be logged. + if len(cs.binlogs) != 0 { + switch err { + case errContextCanceled, errContextDeadline, ErrClientConnClosing: + c := &binarylog.Cancel{ + OnClientSide: true, + } + for _, binlog := range cs.binlogs { + binlog.Log(cs.ctx, c) + } + default: + logEntry := &binarylog.ServerTrailer{ + OnClientSide: true, + Trailer: cs.Trailer(), + Err: err, + } + if peer, ok := peer.FromContext(cs.Context()); ok { + logEntry.PeerAddr = peer.Addr + } + for _, binlog := range cs.binlogs { + binlog.Log(cs.ctx, logEntry) + } } } if err == nil { @@ -1028,7 +1033,7 @@ func (cs *clientStream) finish(err error) { cs.cancel() } -func (a *csAttempt) sendMsg(m interface{}, hdr, payld, data []byte) error { +func (a *csAttempt) sendMsg(m any, hdr, payld, data []byte) error { cs := a.cs if a.trInfo != nil { a.mu.Lock() @@ -1055,7 +1060,7 @@ func (a *csAttempt) sendMsg(m interface{}, hdr, payld, data []byte) error { return nil } -func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) { +func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) { cs := a.cs if len(a.statsHandlers) != 0 && payInfo == nil { payInfo = &payloadInfo{} @@ -1270,7 +1275,7 @@ func newNonRetryClientStream(ctx context.Context, desc *StreamDesc, method strin return nil, err } as.s = s - as.p = &parser{r: s} + as.p = &parser{r: s, recvBufferPool: ac.dopts.recvBufferPool} ac.incrCallsStarted() if desc != unaryStreamDesc { // Listen on stream context to cleanup when the stream context is @@ -1348,7 +1353,7 @@ func (as *addrConnStream) Context() context.Context { return as.s.Context() } -func (as *addrConnStream) SendMsg(m interface{}) (err error) { +func (as *addrConnStream) SendMsg(m any) (err error) { defer func() { if err != nil && err != io.EOF { // Call finish on the client stream for errors generated by this SendMsg @@ -1393,7 +1398,7 @@ func (as *addrConnStream) SendMsg(m interface{}) (err error) { return nil } -func (as *addrConnStream) RecvMsg(m interface{}) (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. @@ -1512,7 +1517,7 @@ type ServerStream interface { // // It is not safe to modify the message after calling SendMsg. Tracing // libraries and stats handlers may use the message lazily. - SendMsg(m interface{}) error + SendMsg(m any) error // RecvMsg blocks until it receives a message into m or the stream is // done. It returns io.EOF when the client has performed a CloseSend. On // any non-EOF error, the stream is aborted and the error contains the @@ -1521,7 +1526,7 @@ type ServerStream interface { // It is safe to have a goroutine calling SendMsg and another goroutine // calling RecvMsg on the same stream at the same time, but it is not // safe to call RecvMsg on the same stream in different goroutines. - RecvMsg(m interface{}) error + RecvMsg(m any) error } // serverStream implements a server side Stream. @@ -1602,7 +1607,7 @@ func (ss *serverStream) SetTrailer(md metadata.MD) { ss.s.SetTrailer(md) } -func (ss *serverStream) SendMsg(m interface{}) (err error) { +func (ss *serverStream) SendMsg(m any) (err error) { defer func() { if ss.trInfo != nil { ss.mu.Lock() @@ -1610,7 +1615,7 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { if err == nil { ss.trInfo.tr.LazyLog(&payload{sent: true, msg: m}, true) } else { - ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) ss.trInfo.tr.SetError() } } @@ -1677,7 +1682,7 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { return nil } -func (ss *serverStream) RecvMsg(m interface{}) (err error) { +func (ss *serverStream) RecvMsg(m any) (err error) { defer func() { if ss.trInfo != nil { ss.mu.Lock() @@ -1685,7 +1690,7 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { if err == nil { ss.trInfo.tr.LazyLog(&payload{sent: false, msg: m}, true) } else if err != io.EOF { - ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) ss.trInfo.tr.SetError() } } @@ -1757,7 +1762,7 @@ func MethodFromServerStream(stream ServerStream) (string, bool) { // prepareMsg returns the hdr, payload and data // using the compressors passed or using the // passed preparedmsg -func prepareMsg(m interface{}, codec baseCodec, cp Compressor, comp encoding.Compressor) (hdr, payload, data []byte, err error) { +func prepareMsg(m any, codec baseCodec, cp Compressor, comp encoding.Compressor) (hdr, payload, data []byte, err error) { if preparedMsg, ok := m.(*PreparedMsg); ok { return preparedMsg.hdr, preparedMsg.payload, preparedMsg.encodedData, nil } diff --git a/vendor/google.golang.org/grpc/tap/tap.go b/vendor/google.golang.org/grpc/tap/tap.go index bfa5dfa4..07f01257 100644 --- a/vendor/google.golang.org/grpc/tap/tap.go +++ b/vendor/google.golang.org/grpc/tap/tap.go @@ -27,6 +27,8 @@ package tap import ( "context" + + "google.golang.org/grpc/metadata" ) // Info defines the relevant information needed by the handles. @@ -34,6 +36,10 @@ type Info struct { // FullMethodName is the string of grpc method (in the format of // /package.service/method). FullMethodName string + + // Header contains the header metadata received. + Header metadata.MD + // TODO: More to be added. } diff --git a/vendor/google.golang.org/grpc/trace.go b/vendor/google.golang.org/grpc/trace.go index 07a2d26b..10f4f798 100644 --- a/vendor/google.golang.org/grpc/trace.go +++ b/vendor/google.golang.org/grpc/trace.go @@ -26,8 +26,6 @@ import ( "strings" "sync" "time" - - "golang.org/x/net/trace" ) // EnableTracing controls whether to trace RPCs using the golang.org/x/net/trace package. @@ -44,9 +42,31 @@ func methodFamily(m string) string { return m } +// traceEventLog mirrors golang.org/x/net/trace.EventLog. +// +// It exists in order to avoid importing x/net/trace on grpcnotrace builds. +type traceEventLog interface { + Printf(format string, a ...any) + Errorf(format string, a ...any) + Finish() +} + +// traceLog mirrors golang.org/x/net/trace.Trace. +// +// It exists in order to avoid importing x/net/trace on grpcnotrace builds. +type traceLog interface { + LazyLog(x fmt.Stringer, sensitive bool) + LazyPrintf(format string, a ...any) + SetError() + SetRecycler(f func(any)) + SetTraceInfo(traceID, spanID uint64) + SetMaxEvents(m int) + Finish() +} + // traceInfo contains tracing information for an RPC. type traceInfo struct { - tr trace.Trace + tr traceLog firstLine firstLine } @@ -97,8 +117,8 @@ func truncate(x string, l int) string { // payload represents an RPC request or response payload. type payload struct { - sent bool // whether this is an outgoing payload - msg interface{} // e.g. a proto.Message + sent bool // whether this is an outgoing payload + msg any // e.g. a proto.Message // TODO(dsymonds): add stringifying info to codec, and limit how much we hold here? } @@ -111,7 +131,7 @@ func (p payload) String() string { type fmtStringer struct { format string - a []interface{} + a []any } func (f *fmtStringer) String() string { diff --git a/vendor/google.golang.org/grpc/trace_notrace.go b/vendor/google.golang.org/grpc/trace_notrace.go new file mode 100644 index 00000000..1da3a230 --- /dev/null +++ b/vendor/google.golang.org/grpc/trace_notrace.go @@ -0,0 +1,52 @@ +//go:build grpcnotrace + +/* + * + * Copyright 2024 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 grpc + +// grpcnotrace can be used to avoid importing golang.org/x/net/trace, which in +// turn enables binaries using gRPC-Go for dead code elimination, which can +// yield 10-15% improvements in binary size when tracing is not needed. + +import ( + "context" + "fmt" +) + +type notrace struct{} + +func (notrace) LazyLog(x fmt.Stringer, sensitive bool) {} +func (notrace) LazyPrintf(format string, a ...any) {} +func (notrace) SetError() {} +func (notrace) SetRecycler(f func(any)) {} +func (notrace) SetTraceInfo(traceID, spanID uint64) {} +func (notrace) SetMaxEvents(m int) {} +func (notrace) Finish() {} + +func newTrace(family, title string) traceLog { + return notrace{} +} + +func newTraceContext(ctx context.Context, tr traceLog) context.Context { + return ctx +} + +func newTraceEventLog(family, title string) traceEventLog { + return nil +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/util_linux.go b/vendor/google.golang.org/grpc/trace_withtrace.go similarity index 59% rename from vendor/google.golang.org/grpc/internal/channelz/util_linux.go rename to vendor/google.golang.org/grpc/trace_withtrace.go index 8d194e44..88d6e857 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/util_linux.go +++ b/vendor/google.golang.org/grpc/trace_withtrace.go @@ -1,6 +1,8 @@ +//go:build !grpcnotrace + /* * - * Copyright 2018 gRPC authors. + * Copyright 2024 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,22 +18,22 @@ * */ -package channelz +package grpc import ( - "syscall" + "context" + + t "golang.org/x/net/trace" ) -// GetSocketOption gets the socket option info of the conn. -func GetSocketOption(socket interface{}) *SocketOptionData { - c, ok := socket.(syscall.Conn) - if !ok { - return nil - } - data := &SocketOptionData{} - if rawConn, err := c.SyscallConn(); err == nil { - rawConn.Control(data.Getsockopt) - return data - } - return nil +func newTrace(family, title string) traceLog { + return t.New(family, title) +} + +func newTraceContext(ctx context.Context, tr traceLog) context.Context { + return t.NewContext(ctx, tr) +} + +func newTraceEventLog(family, title string) traceEventLog { + return t.NewEventLog(family, title) } diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 3cc75406..2556f758 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.56.3" +const Version = "1.63.2" diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh index a8e4732b..7e6b92e4 100644 --- a/vendor/google.golang.org/grpc/vet.sh +++ b/vendor/google.golang.org/grpc/vet.sh @@ -35,14 +35,13 @@ if [[ "$1" = "-install" ]]; then # Install the pinned versions as defined in module tools. pushd ./test/tools go install \ - golang.org/x/lint/golint \ golang.org/x/tools/cmd/goimports \ honnef.co/go/tools/cmd/staticcheck \ github.com/client9/misspell/cmd/misspell popd if [[ -z "${VET_SKIP_PROTO}" ]]; then if [[ "${GITHUB_ACTIONS}" = "true" ]]; then - PROTOBUF_VERSION=22.0 # a.k.a v4.22.0 in pb.go files. + PROTOBUF_VERSION=25.2 # a.k.a. v4.22.0 in pb.go files. PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip pushd /home/runner/go wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME} @@ -77,12 +76,23 @@ fi not grep 'func Test[^(]' *_test.go not grep 'func Test[^(]' test/*.go +# - Check for typos in test function names +git grep 'func (s) ' -- "*_test.go" | not grep -v 'func (s) Test' +git grep 'func [A-Z]' -- "*_test.go" | not grep -v 'func Test\|Benchmark\|Example' + # - Do not import x/net/context. not git grep -l 'x/net/context' -- "*.go" +# - Do not use time.After except in tests. It has the potential to leak the +# timer since there is no way to stop it early. +git grep -l 'time.After(' -- "*.go" | not grep -v '_test.go\|test_utils\|testutils' + # - Do not import math/rand for real library code. Use internal/grpcrand for # thread safety. -git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^stress\|grpcrand\|^benchmark\|wrr_test' +git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^interop/stress\|grpcrand\|^benchmark\|wrr_test' + +# - Do not use "interface{}"; use "any" instead. +git grep -l 'interface{}' -- "*.go" 2>&1 | not grep -v '\.pb\.go\|protoc-gen-go-grpc\|grpc_testing_not_regenerate' # - Do not call grpclog directly. Use grpclog.Component instead. git grep -l -e 'grpclog.I' --or -e 'grpclog.W' --or -e 'grpclog.E' --or -e 'grpclog.F' --or -e 'grpclog.V' -- "*.go" | not grep -v '^grpclog/component.go\|^internal/grpctest/tlogger_test.go' @@ -90,13 +100,15 @@ git grep -l -e 'grpclog.I' --or -e 'grpclog.W' --or -e 'grpclog.E' --or -e 'grpc # - Ensure all ptypes proto packages are renamed when importing. not git grep "\(import \|^\s*\)\"github.com/golang/protobuf/ptypes/" -- "*.go" +# - Ensure all usages of grpc_testing package are renamed when importing. +not git grep "\(import \|^\s*\)\"google.golang.org/grpc/interop/grpc_testing" -- "*.go" + # - Ensure all xds proto imports are renamed to *pb or *grpc. git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' ':(exclude)*.pb.go' | not grep -v 'pb "\|grpc "' misspell -error . -# - gofmt, goimports, golint (with exceptions for generated code), go vet, -# go mod tidy. +# - gofmt, goimports, go vet, go mod tidy. # Perform these checks on each module inside gRPC. for MOD_FILE in $(find . -name 'go.mod'); do MOD_DIR=$(dirname ${MOD_FILE}) @@ -104,105 +116,80 @@ for MOD_FILE in $(find . -name 'go.mod'); do go vet -all ./... | fail_on_output gofmt -s -d -l . 2>&1 | fail_on_output goimports -l . 2>&1 | not grep -vE "\.pb\.go" - golint ./... 2>&1 | not grep -vE "/grpc_testing_not_regenerate/.*\.pb\.go:" - go mod tidy -compat=1.17 + go mod tidy -compat=1.19 git status --porcelain 2>&1 | fail_on_output || \ (git status; git --no-pager diff; exit 1) popd done # - Collection of static analysis checks -# -# TODO(dfawley): don't use deprecated functions in examples or first-party -# plugins. -# TODO(dfawley): enable ST1019 (duplicate imports) but allow for protobufs. SC_OUT="$(mktemp)" -staticcheck -go 1.19 -checks 'inherit,-ST1015,-ST1019,-SA1019' ./... > "${SC_OUT}" || true -# Error if anything other than deprecation warnings are printed. -not grep -v "is deprecated:.*SA1019" "${SC_OUT}" -# Only ignore the following deprecated types/fields/functions. -not grep -Fv '.CredsBundle -.HeaderMap -.Metadata is deprecated: use Attributes -.NewAddress -.NewServiceConfig -.Type is deprecated: use Attributes -BuildVersion is deprecated -balancer.ErrTransientFailure -balancer.Picker -extDesc.Filename is deprecated -github.com/golang/protobuf/jsonpb is deprecated -grpc.CallCustomCodec -grpc.Code -grpc.Compressor -grpc.CustomCodec -grpc.Decompressor -grpc.MaxMsgSize -grpc.MethodConfig -grpc.NewGZIPCompressor -grpc.NewGZIPDecompressor -grpc.RPCCompressor -grpc.RPCDecompressor -grpc.ServiceConfig -grpc.WithCompressor -grpc.WithDecompressor -grpc.WithDialer -grpc.WithMaxMsgSize -grpc.WithServiceConfig -grpc.WithTimeout -http.CloseNotifier -info.SecurityVersion -proto is deprecated -proto.InternalMessageInfo is deprecated -proto.EnumName is deprecated -proto.ErrInternalBadWireType is deprecated -proto.FileDescriptor is deprecated -proto.Marshaler is deprecated -proto.MessageType is deprecated -proto.RegisterEnum is deprecated -proto.RegisterFile is deprecated -proto.RegisterType is deprecated -proto.RegisterExtension is deprecated -proto.RegisteredExtension is deprecated -proto.RegisteredExtensions is deprecated -proto.RegisterMapType is deprecated -proto.Unmarshaler is deprecated -resolver.Backend -resolver.GRPCLB +staticcheck -go 1.19 -checks 'all' ./... > "${SC_OUT}" || true + +# Error for anything other than checks that need exclusions. +grep -v "(ST1000)" "${SC_OUT}" | grep -v "(SA1019)" | grep -v "(ST1003)" | not grep -v "(ST1019)\|\(other import of\)" + +# Exclude underscore checks for generated code. +grep "(ST1003)" "${SC_OUT}" | not grep -v '\(.pb.go:\)\|\(code_string_test.go:\)\|\(grpc_testing_not_regenerate\)' + +# Error for duplicate imports not including grpc protos. +grep "(ST1019)\|\(other import of\)" "${SC_OUT}" | not grep -Fv 'XXXXX PleaseIgnoreUnused +channelz/grpc_channelz_v1" +go-control-plane/envoy +grpclb/grpc_lb_v1" +health/grpc_health_v1" +interop/grpc_testing" +orca/v3" +proto/grpc_gcp" +proto/grpc_lookup_v1" +reflection/grpc_reflection_v1" +reflection/grpc_reflection_v1alpha" +XXXXX PleaseIgnoreUnused' + +# Error for any package comments not in generated code. +grep "(ST1000)" "${SC_OUT}" | not grep -v "\.pb\.go:" + +# Only ignore the following deprecated types/fields/functions and exclude +# generated code. +grep "(SA1019)" "${SC_OUT}" | not grep -Fv 'XXXXX PleaseIgnoreUnused +XXXXX Protobuf related deprecation errors: +"github.com/golang/protobuf +.pb.go: +grpc_testing_not_regenerate +: ptypes. +proto.RegisterType +XXXXX gRPC internal usage deprecation errors: +"google.golang.org/grpc +: grpc. +: v1alpha. +: v1alphareflectionpb. +BalancerAttributes is deprecated: +CredsBundle is deprecated: +Metadata is deprecated: use Attributes instead. +NewSubConn is deprecated: +OverrideServerName is deprecated: +RemoveSubConn is deprecated: +SecurityVersion is deprecated: Target is deprecated: Use the Target field in the BuildOptions instead. -xxx_messageInfo_ -' "${SC_OUT}" - -# - special golint on package comments. -lint_package_comment_per_package() { - # Number of files in this go package. - fileCount=$(go list -f '{{len .GoFiles}}' $1) - if [ ${fileCount} -eq 0 ]; then - return 0 - fi - # Number of package errors generated by golint. - lintPackageCommentErrorsCount=$(golint --min_confidence 0 $1 | grep -c "should have a package comment") - # golint complains about every file that's missing the package comment. If the - # number of files for this package is greater than the number of errors, there's - # at least one file with package comment, good. Otherwise, fail. - if [ ${fileCount} -le ${lintPackageCommentErrorsCount} ]; then - echo "Package $1 (with ${fileCount} files) is missing package comment" - return 1 - fi -} -lint_package_comment() { - set +ex - - count=0 - for i in $(go list ./...); do - lint_package_comment_per_package "$i" - ((count += $?)) - done - - set -ex - return $count -} -lint_package_comment +UpdateAddresses is deprecated: +UpdateSubConnState is deprecated: +balancer.ErrTransientFailure is deprecated: +grpc/reflection/v1alpha/reflection.proto +SwitchTo is deprecated: +XXXXX xDS deprecated fields we support +.ExactMatch +.PrefixMatch +.SafeRegexMatch +.SuffixMatch +GetContainsMatch +GetExactMatch +GetMatchSubjectAltNames +GetPrefixMatch +GetSafeRegexMatch +GetSuffixMatch +GetTlsCertificateCertificateProviderInstance +GetValidationContextCertificateProviderInstance +XXXXX PleaseIgnoreUnused' echo SUCCESS diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/encode.go b/vendor/google.golang.org/protobuf/encoding/protojson/encode.go index 3f75098b..29846df2 100644 --- a/vendor/google.golang.org/protobuf/encoding/protojson/encode.go +++ b/vendor/google.golang.org/protobuf/encoding/protojson/encode.go @@ -25,15 +25,17 @@ const defaultIndent = " " // Format formats the message as a multiline string. // This function is only intended for human consumption and ignores errors. -// Do not depend on the output being stable. It may change over time across -// different versions of the program. +// Do not depend on the output being stable. Its output will change across +// different builds of your program, even when using the same version of the +// protobuf module. func Format(m proto.Message) string { return MarshalOptions{Multiline: true}.Format(m) } // Marshal writes the given [proto.Message] in JSON format using default options. -// Do not depend on the output being stable. It may change over time across -// different versions of the program. +// Do not depend on the output being stable. Its output will change across +// different builds of your program, even when using the same version of the +// protobuf module. func Marshal(m proto.Message) ([]byte, error) { return MarshalOptions{}.Marshal(m) } @@ -110,8 +112,9 @@ type MarshalOptions struct { // Format formats the message as a string. // This method is only intended for human consumption and ignores errors. -// Do not depend on the output being stable. It may change over time across -// different versions of the program. +// Do not depend on the output being stable. Its output will change across +// different builds of your program, even when using the same version of the +// protobuf module. func (o MarshalOptions) Format(m proto.Message) string { if m == nil || !m.ProtoReflect().IsValid() { return "" // invalid syntax, but okay since this is for debugging @@ -122,8 +125,9 @@ func (o MarshalOptions) Format(m proto.Message) string { } // Marshal marshals the given [proto.Message] in the JSON format using options in -// MarshalOptions. Do not depend on the output being stable. It may change over -// time across different versions of the program. +// Do not depend on the output being stable. Its output will change across +// different builds of your program, even when using the same version of the +// protobuf module. func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) { return o.marshal(nil, m) } diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/encode.go b/vendor/google.golang.org/protobuf/encoding/prototext/encode.go index 95967e81..1f57e661 100644 --- a/vendor/google.golang.org/protobuf/encoding/prototext/encode.go +++ b/vendor/google.golang.org/protobuf/encoding/prototext/encode.go @@ -27,15 +27,17 @@ const defaultIndent = " " // Format formats the message as a multiline string. // This function is only intended for human consumption and ignores errors. -// Do not depend on the output being stable. It may change over time across -// different versions of the program. +// Do not depend on the output being stable. Its output will change across +// different builds of your program, even when using the same version of the +// protobuf module. func Format(m proto.Message) string { return MarshalOptions{Multiline: true}.Format(m) } // Marshal writes the given [proto.Message] in textproto format using default -// options. Do not depend on the output being stable. It may change over time -// across different versions of the program. +// options. Do not depend on the output being stable. Its output will change +// across different builds of your program, even when using the same version of +// the protobuf module. func Marshal(m proto.Message) ([]byte, error) { return MarshalOptions{}.Marshal(m) } @@ -84,8 +86,9 @@ type MarshalOptions struct { // Format formats the message as a string. // This method is only intended for human consumption and ignores errors. -// Do not depend on the output being stable. It may change over time across -// different versions of the program. +// Do not depend on the output being stable. Its output will change across +// different builds of your program, even when using the same version of the +// protobuf module. func (o MarshalOptions) Format(m proto.Message) string { if m == nil || !m.ProtoReflect().IsValid() { return "" // invalid syntax, but okay since this is for debugging @@ -98,8 +101,9 @@ func (o MarshalOptions) Format(m proto.Message) string { } // Marshal writes the given [proto.Message] in textproto format using options in -// MarshalOptions object. Do not depend on the output being stable. It may -// change over time across different versions of the program. +// MarshalOptions object. Do not depend on the output being stable. Its output +// will change across different builds of your program, even when using the +// same version of the protobuf module. func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) { return o.marshal(nil, m) } diff --git a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go index a45625c8..87e46bd4 100644 --- a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go +++ b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go @@ -252,6 +252,7 @@ func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool, record fu {rv.MethodByName("Values"), "Values"}, {rv.MethodByName("ReservedNames"), "ReservedNames"}, {rv.MethodByName("ReservedRanges"), "ReservedRanges"}, + {rv.MethodByName("IsClosed"), "IsClosed"}, }...) case protoreflect.EnumValueDescriptor: diff --git a/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb b/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb index 18f0756874367adcdb790ffde125b6a7388b4eaa..f691305eb4f73440cd48caba949023eab52ef304 100644 GIT binary patch literal 78 zcmd-Q6B6WL6kw8IQef6#G+?@9$Hc)X@r<1dB+ewjD8Z<}1Qcfki8Dw%hln$xi@#u3 Kc*d^rf*k;APzzxI literal 63 zcmd-Q6yo7v6kw8IQef6#G+>f=#?A#2ViI7KU{qiN3NcDNhX^qu3B6!fc*d^rf*k<7 Cln3+x diff --git a/vendor/google.golang.org/protobuf/internal/editionssupport/editions.go b/vendor/google.golang.org/protobuf/internal/editionssupport/editions.go new file mode 100644 index 00000000..029a6a12 --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/editionssupport/editions.go @@ -0,0 +1,13 @@ +// 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 editionssupport defines constants for editions that are supported. +package editionssupport + +import descriptorpb "google.golang.org/protobuf/types/descriptorpb" + +const ( + Minimum = descriptorpb.Edition_EDITION_PROTO2 + Maximum = descriptorpb.Edition_EDITION_2023 +) diff --git a/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go b/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go index 373d2083..7e87c760 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go @@ -32,6 +32,7 @@ var byteType = reflect.TypeOf(byte(0)) func Unmarshal(tag string, goType reflect.Type, evs protoreflect.EnumValueDescriptors) protoreflect.FieldDescriptor { f := new(filedesc.Field) f.L0.ParentFile = filedesc.SurrogateProto2 + f.L1.EditionFeatures = f.L0.ParentFile.L1.EditionFeatures for len(tag) > 0 { i := strings.IndexByte(tag, ',') if i < 0 { @@ -107,8 +108,7 @@ func Unmarshal(tag string, goType reflect.Type, evs protoreflect.EnumValueDescri f.L1.StringName.InitJSON(jsonName) } case s == "packed": - f.L1.HasPacked = true - f.L1.IsPacked = true + f.L1.EditionFeatures.IsPacked = true case strings.HasPrefix(s, "weak="): f.L1.IsWeak = true f.L1.Message = filedesc.PlaceholderMessage(protoreflect.FullName(s[len("weak="):])) diff --git a/vendor/google.golang.org/protobuf/internal/errors/errors.go b/vendor/google.golang.org/protobuf/internal/errors/errors.go index 20c17b35..d9671982 100644 --- a/vendor/google.golang.org/protobuf/internal/errors/errors.go +++ b/vendor/google.golang.org/protobuf/internal/errors/errors.go @@ -87,3 +87,18 @@ func InvalidUTF8(name string) error { func RequiredNotSet(name string) error { return New("required field %v not set", name) } + +type SizeMismatchError struct { + Calculated, Measured int +} + +func (e *SizeMismatchError) Error() string { + return fmt.Sprintf("size mismatch (see https://github.com/golang/protobuf/issues/1609): calculated=%d, measured=%d", e.Calculated, e.Measured) +} + +func MismatchedSizeCalculation(calculated, measured int) error { + return &SizeMismatchError{ + Calculated: calculated, + Measured: measured, + } +} diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc.go index 8826bcf4..ece53bea 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/desc.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc.go @@ -7,6 +7,7 @@ package filedesc import ( "bytes" "fmt" + "strings" "sync" "sync/atomic" @@ -108,9 +109,12 @@ func (fd *File) ParentFile() protoreflect.FileDescriptor { return fd } func (fd *File) Parent() protoreflect.Descriptor { return nil } func (fd *File) Index() int { return 0 } func (fd *File) Syntax() protoreflect.Syntax { return fd.L1.Syntax } -func (fd *File) Name() protoreflect.Name { return fd.L1.Package.Name() } -func (fd *File) FullName() protoreflect.FullName { return fd.L1.Package } -func (fd *File) IsPlaceholder() bool { return false } + +// Not exported and just used to reconstruct the original FileDescriptor proto +func (fd *File) Edition() int32 { return int32(fd.L1.Edition) } +func (fd *File) Name() protoreflect.Name { return fd.L1.Package.Name() } +func (fd *File) FullName() protoreflect.FullName { return fd.L1.Package } +func (fd *File) IsPlaceholder() bool { return false } func (fd *File) Options() protoreflect.ProtoMessage { if f := fd.lazyInit().Options; f != nil { return f() @@ -202,6 +206,9 @@ func (ed *Enum) lazyInit() *EnumL2 { ed.L0.ParentFile.lazyInit() // implicitly initializes L2 return ed.L2 } +func (ed *Enum) IsClosed() bool { + return !ed.L1.EditionFeatures.IsOpenEnum +} func (ed *EnumValue) Options() protoreflect.ProtoMessage { if f := ed.L1.Options; f != nil { @@ -251,10 +258,6 @@ type ( StringName stringName IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto IsWeak bool // promoted from google.protobuf.FieldOptions - HasPacked bool // promoted from google.protobuf.FieldOptions - IsPacked bool // promoted from google.protobuf.FieldOptions - HasEnforceUTF8 bool // promoted from google.protobuf.FieldOptions - EnforceUTF8 bool // promoted from google.protobuf.FieldOptions Default defaultValue ContainingOneof protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields Enum protoreflect.EnumDescriptor @@ -331,8 +334,7 @@ func (fd *Field) HasPresence() bool { if fd.L1.Cardinality == protoreflect.Repeated { return false } - explicitFieldPresence := fd.Syntax() == protoreflect.Editions && fd.L1.EditionFeatures.IsFieldPresence - return fd.Syntax() == protoreflect.Proto2 || explicitFieldPresence || fd.L1.Message != nil || fd.L1.ContainingOneof != nil + return fd.IsExtension() || fd.L1.EditionFeatures.IsFieldPresence || fd.L1.Message != nil || fd.L1.ContainingOneof != nil } func (fd *Field) HasOptionalKeyword() bool { return (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional @@ -345,14 +347,7 @@ func (fd *Field) IsPacked() bool { case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind: return false } - if fd.L0.ParentFile.L1.Syntax == protoreflect.Editions { - return fd.L1.EditionFeatures.IsPacked - } - if fd.L0.ParentFile.L1.Syntax == protoreflect.Proto3 { - // proto3 repeated fields are packed by default. - return !fd.L1.HasPacked || fd.L1.IsPacked - } - return fd.L1.IsPacked + return fd.L1.EditionFeatures.IsPacked } func (fd *Field) IsExtension() bool { return false } func (fd *Field) IsWeak() bool { return fd.L1.IsWeak } @@ -399,13 +394,7 @@ func (fd *Field) ProtoType(protoreflect.FieldDescriptor) {} // WARNING: This method is exempt from the compatibility promise and may be // removed in the future without warning. func (fd *Field) EnforceUTF8() bool { - if fd.L0.ParentFile.L1.Syntax == protoreflect.Editions { - return fd.L1.EditionFeatures.IsUTF8Validated - } - if fd.L1.HasEnforceUTF8 { - return fd.L1.EnforceUTF8 - } - return fd.L0.ParentFile.L1.Syntax == protoreflect.Proto3 + return fd.L1.EditionFeatures.IsUTF8Validated } func (od *Oneof) IsSynthetic() bool { @@ -438,7 +427,6 @@ type ( Options func() protoreflect.ProtoMessage StringName stringName IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto - IsPacked bool // promoted from google.protobuf.FieldOptions Default defaultValue Enum protoreflect.EnumDescriptor Message protoreflect.MessageDescriptor @@ -461,7 +449,16 @@ func (xd *Extension) HasPresence() bool { return xd.L1.Cardi func (xd *Extension) HasOptionalKeyword() bool { return (xd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && xd.L1.Cardinality == protoreflect.Optional) || xd.lazyInit().IsProto3Optional } -func (xd *Extension) IsPacked() bool { return xd.lazyInit().IsPacked } +func (xd *Extension) IsPacked() bool { + if xd.L1.Cardinality != protoreflect.Repeated { + return false + } + switch xd.L1.Kind { + case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind: + return false + } + return xd.L1.EditionFeatures.IsPacked +} func (xd *Extension) IsExtension() bool { return true } func (xd *Extension) IsWeak() bool { return false } func (xd *Extension) IsList() bool { return xd.Cardinality() == protoreflect.Repeated } @@ -542,8 +539,9 @@ func (md *Method) ProtoInternal(pragma.DoNotImplement) {} // Surrogate files are can be used to create standalone descriptors // where the syntax is only information derived from the parent file. var ( - SurrogateProto2 = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}} - SurrogateProto3 = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}} + SurrogateProto2 = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}} + SurrogateProto3 = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}} + SurrogateEdition2023 = &File{L1: FileL1{Syntax: protoreflect.Editions, Edition: Edition2023}, L2: &FileL2{}} ) type ( @@ -585,6 +583,34 @@ func (s *stringName) InitJSON(name string) { s.nameJSON = name } +// Returns true if this field is structured like the synthetic field of a proto2 +// group. This allows us to expand our treatment of delimited fields without +// breaking proto2 files that have been upgraded to editions. +func isGroupLike(fd protoreflect.FieldDescriptor) bool { + // Groups are always group types. + if fd.Kind() != protoreflect.GroupKind { + return false + } + + // Group fields are always the lowercase type name. + if strings.ToLower(string(fd.Message().Name())) != string(fd.Name()) { + return false + } + + // Groups could only be defined in the same file they're used. + if fd.Message().ParentFile() != fd.ParentFile() { + return false + } + + // Group messages are always defined in the same scope as the field. File + // level extensions will compare NULL == NULL here, which is why the file + // comparison above is necessary to ensure both come from the same file. + if fd.IsExtension() { + return fd.Parent() == fd.Message().Parent() + } + return fd.ContainingMessage() == fd.Message().Parent() +} + func (s *stringName) lazyInit(fd protoreflect.FieldDescriptor) *stringName { s.once.Do(func() { if fd.IsExtension() { @@ -605,7 +631,7 @@ func (s *stringName) lazyInit(fd protoreflect.FieldDescriptor) *stringName { // Format the text name. s.nameText = string(fd.Name()) - if fd.Kind() == protoreflect.GroupKind { + if isGroupLike(fd) { s.nameText = string(fd.Message().Name()) } } diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go index 237e64fd..3bc3b1cd 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go @@ -113,8 +113,10 @@ func (fd *File) unmarshalSeed(b []byte) { switch string(v) { case "proto2": fd.L1.Syntax = protoreflect.Proto2 + fd.L1.Edition = EditionProto2 case "proto3": fd.L1.Syntax = protoreflect.Proto3 + fd.L1.Edition = EditionProto3 case "editions": fd.L1.Syntax = protoreflect.Editions default: @@ -177,11 +179,10 @@ func (fd *File) unmarshalSeed(b []byte) { // If syntax is missing, it is assumed to be proto2. if fd.L1.Syntax == 0 { fd.L1.Syntax = protoreflect.Proto2 + fd.L1.Edition = EditionProto2 } - if fd.L1.Syntax == protoreflect.Editions { - fd.L1.EditionFeatures = getFeaturesFor(fd.L1.Edition) - } + fd.L1.EditionFeatures = getFeaturesFor(fd.L1.Edition) // Parse editions features from options if any if options != nil { @@ -267,6 +268,7 @@ func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protorefl ed.L0.ParentFile = pf ed.L0.Parent = pd ed.L0.Index = i + ed.L1.EditionFeatures = featuresFromParentDesc(ed.Parent()) var numValues int for b := b; len(b) > 0; { @@ -443,6 +445,7 @@ func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd prot xd.L0.ParentFile = pf xd.L0.Parent = pd xd.L0.Index = i + xd.L1.EditionFeatures = featuresFromParentDesc(pd) for len(b) > 0 { num, typ, n := protowire.ConsumeTag(b) @@ -467,6 +470,38 @@ func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd prot xd.L0.FullName = appendFullName(sb, pd.FullName(), v) case genid.FieldDescriptorProto_Extendee_field_number: xd.L1.Extendee = PlaceholderMessage(makeFullName(sb, v)) + case genid.FieldDescriptorProto_Options_field_number: + xd.unmarshalOptions(v) + } + default: + m := protowire.ConsumeFieldValue(num, typ, b) + b = b[m:] + } + } + + if xd.L1.Kind == protoreflect.MessageKind && xd.L1.EditionFeatures.IsDelimitedEncoded { + xd.L1.Kind = protoreflect.GroupKind + } +} + +func (xd *Extension) unmarshalOptions(b []byte) { + for len(b) > 0 { + num, typ, n := protowire.ConsumeTag(b) + b = b[n:] + switch typ { + case protowire.VarintType: + v, m := protowire.ConsumeVarint(b) + b = b[m:] + switch num { + case genid.FieldOptions_Packed_field_number: + xd.L1.EditionFeatures.IsPacked = protowire.DecodeBool(v) + } + case protowire.BytesType: + v, m := protowire.ConsumeBytes(b) + b = b[m:] + switch num { + case genid.FieldOptions_Features_field_number: + xd.L1.EditionFeatures = unmarshalFeatureSet(v, xd.L1.EditionFeatures) } default: m := protowire.ConsumeFieldValue(num, typ, b) diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go index 482a61cc..570181eb 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go @@ -466,10 +466,10 @@ func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoref b = b[m:] } } - if fd.Syntax() == protoreflect.Editions && fd.L1.Kind == protoreflect.MessageKind && fd.L1.EditionFeatures.IsDelimitedEncoded { + if fd.L1.Kind == protoreflect.MessageKind && fd.L1.EditionFeatures.IsDelimitedEncoded { fd.L1.Kind = protoreflect.GroupKind } - if fd.Syntax() == protoreflect.Editions && fd.L1.EditionFeatures.IsLegacyRequired { + if fd.L1.EditionFeatures.IsLegacyRequired { fd.L1.Cardinality = protoreflect.Required } if rawTypeName != nil { @@ -496,13 +496,11 @@ func (fd *Field) unmarshalOptions(b []byte) { b = b[m:] switch num { case genid.FieldOptions_Packed_field_number: - fd.L1.HasPacked = true - fd.L1.IsPacked = protowire.DecodeBool(v) + fd.L1.EditionFeatures.IsPacked = protowire.DecodeBool(v) case genid.FieldOptions_Weak_field_number: fd.L1.IsWeak = protowire.DecodeBool(v) case FieldOptions_EnforceUTF8: - fd.L1.HasEnforceUTF8 = true - fd.L1.EnforceUTF8 = protowire.DecodeBool(v) + fd.L1.EditionFeatures.IsUTF8Validated = protowire.DecodeBool(v) } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) @@ -548,7 +546,6 @@ func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoref func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) { var rawTypeName []byte var rawOptions []byte - xd.L1.EditionFeatures = featuresFromParentDesc(xd.L1.Extendee) xd.L2 = new(ExtensionL2) for len(b) > 0 { num, typ, n := protowire.ConsumeTag(b) @@ -572,7 +569,6 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) { case genid.FieldDescriptorProto_TypeName_field_number: rawTypeName = v case genid.FieldDescriptorProto_Options_field_number: - xd.unmarshalOptions(v) rawOptions = appendOptions(rawOptions, v) } default: @@ -580,12 +576,6 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) { b = b[m:] } } - if xd.Syntax() == protoreflect.Editions && xd.L1.Kind == protoreflect.MessageKind && xd.L1.EditionFeatures.IsDelimitedEncoded { - xd.L1.Kind = protoreflect.GroupKind - } - if xd.Syntax() == protoreflect.Editions && xd.L1.EditionFeatures.IsLegacyRequired { - xd.L1.Cardinality = protoreflect.Required - } if rawTypeName != nil { name := makeFullName(sb, rawTypeName) switch xd.L1.Kind { @@ -598,32 +588,6 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) { xd.L2.Options = xd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Field, rawOptions) } -func (xd *Extension) unmarshalOptions(b []byte) { - for len(b) > 0 { - num, typ, n := protowire.ConsumeTag(b) - b = b[n:] - switch typ { - case protowire.VarintType: - v, m := protowire.ConsumeVarint(b) - b = b[m:] - switch num { - case genid.FieldOptions_Packed_field_number: - xd.L2.IsPacked = protowire.DecodeBool(v) - } - case protowire.BytesType: - v, m := protowire.ConsumeBytes(b) - b = b[m:] - switch num { - case genid.FieldOptions_Features_field_number: - xd.L1.EditionFeatures = unmarshalFeatureSet(v, xd.L1.EditionFeatures) - } - default: - m := protowire.ConsumeFieldValue(num, typ, b) - b = b[m:] - } - } -} - func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) { var rawMethods [][]byte var rawOptions []byte diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/editions.go b/vendor/google.golang.org/protobuf/internal/filedesc/editions.go index 0375a49d..d1e16a26 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/editions.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/editions.go @@ -14,9 +14,13 @@ import ( ) var defaultsCache = make(map[Edition]EditionFeatures) +var defaultsKeys = []Edition{} func init() { unmarshalEditionDefaults(editiondefaults.Defaults) + SurrogateProto2.L1.EditionFeatures = getFeaturesFor(EditionProto2) + SurrogateProto3.L1.EditionFeatures = getFeaturesFor(EditionProto3) + SurrogateEdition2023.L1.EditionFeatures = getFeaturesFor(Edition2023) } func unmarshalGoFeature(b []byte, parent EditionFeatures) EditionFeatures { @@ -110,6 +114,7 @@ func unmarshalEditionDefault(b []byte) { } } defaultsCache[ed] = fs + defaultsKeys = append(defaultsKeys, ed) } func unmarshalEditionDefaults(b []byte) { @@ -135,8 +140,15 @@ func unmarshalEditionDefaults(b []byte) { } func getFeaturesFor(ed Edition) EditionFeatures { - if def, ok := defaultsCache[ed]; ok { - return def + match := EditionUnknown + for _, key := range defaultsKeys { + if key > ed { + break + } + match = key + } + if match == EditionUnknown { + panic(fmt.Sprintf("unsupported edition: %v", ed)) } - panic(fmt.Sprintf("unsupported edition: %v", ed)) + return defaultsCache[match] } diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go b/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go index 28240ebc..bfb3b841 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go @@ -63,6 +63,7 @@ func (e PlaceholderEnum) Options() protoreflect.ProtoMessage { return des func (e PlaceholderEnum) Values() protoreflect.EnumValueDescriptors { return emptyEnumValues } func (e PlaceholderEnum) ReservedNames() protoreflect.Names { return emptyNames } func (e PlaceholderEnum) ReservedRanges() protoreflect.EnumRanges { return emptyEnumRanges } +func (e PlaceholderEnum) IsClosed() bool { return false } func (e PlaceholderEnum) ProtoType(protoreflect.EnumDescriptor) { return } func (e PlaceholderEnum) ProtoInternal(pragma.DoNotImplement) { return } diff --git a/vendor/google.golang.org/protobuf/internal/genid/go_features_gen.go b/vendor/google.golang.org/protobuf/internal/genid/go_features_gen.go index fd9015e8..9a652a2b 100644 --- a/vendor/google.golang.org/protobuf/internal/genid/go_features_gen.go +++ b/vendor/google.golang.org/protobuf/internal/genid/go_features_gen.go @@ -10,7 +10,7 @@ import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" ) -const File_reflect_protodesc_proto_go_features_proto = "reflect/protodesc/proto/go_features.proto" +const File_google_protobuf_go_features_proto = "google/protobuf/go_features.proto" // Names for google.protobuf.GoFeatures. const ( diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_field.go b/vendor/google.golang.org/protobuf/internal/impl/codec_field.go index 3fadd241..78ee47e4 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_field.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_field.go @@ -233,9 +233,15 @@ func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int { } func appendMessageInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) { + calculatedSize := f.mi.sizePointer(p.Elem(), opts) b = protowire.AppendVarint(b, f.wiretag) - b = protowire.AppendVarint(b, uint64(f.mi.sizePointer(p.Elem(), opts))) - return f.mi.marshalAppendPointer(b, p.Elem(), opts) + b = protowire.AppendVarint(b, uint64(calculatedSize)) + before := len(b) + b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts) + if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil { + return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize) + } + return b, err } func consumeMessageInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) { @@ -262,14 +268,21 @@ func isInitMessageInfo(p pointer, f *coderFieldInfo) error { return f.mi.checkInitializedPointer(p.Elem()) } -func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int { - return protowire.SizeBytes(proto.Size(m)) + tagsize +func sizeMessage(m proto.Message, tagsize int, opts marshalOptions) int { + return protowire.SizeBytes(opts.Options().Size(m)) + tagsize } func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) { + mopts := opts.Options() + calculatedSize := mopts.Size(m) b = protowire.AppendVarint(b, wiretag) - b = protowire.AppendVarint(b, uint64(proto.Size(m))) - return opts.Options().MarshalAppend(b, m) + b = protowire.AppendVarint(b, uint64(calculatedSize)) + before := len(b) + b, err := mopts.MarshalAppend(b, m) + if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil { + return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize) + } + return b, err } func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) { @@ -405,8 +418,8 @@ func consumeGroupType(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInf return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts) } -func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int { - return 2*tagsize + proto.Size(m) +func sizeGroup(m proto.Message, tagsize int, opts marshalOptions) int { + return 2*tagsize + opts.Options().Size(m) } func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) { @@ -482,10 +495,14 @@ func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshal b = protowire.AppendVarint(b, f.wiretag) siz := f.mi.sizePointer(v, opts) b = protowire.AppendVarint(b, uint64(siz)) + before := len(b) b, err = f.mi.marshalAppendPointer(b, v, opts) if err != nil { return b, err } + if measuredSize := len(b) - before; siz != measuredSize { + return nil, errors.MismatchedSizeCalculation(siz, measuredSize) + } } return b, nil } @@ -520,28 +537,34 @@ func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error { return nil } -func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int { +func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, opts marshalOptions) int { + mopts := opts.Options() s := p.PointerSlice() n := 0 for _, v := range s { m := asMessage(v.AsValueOf(goType.Elem())) - n += protowire.SizeBytes(proto.Size(m)) + tagsize + n += protowire.SizeBytes(mopts.Size(m)) + tagsize } return n } func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) { + mopts := opts.Options() s := p.PointerSlice() var err error for _, v := range s { m := asMessage(v.AsValueOf(goType.Elem())) b = protowire.AppendVarint(b, wiretag) - siz := proto.Size(m) + siz := mopts.Size(m) b = protowire.AppendVarint(b, uint64(siz)) - b, err = opts.Options().MarshalAppend(b, m) + before := len(b) + b, err = mopts.MarshalAppend(b, m) if err != nil { return b, err } + if measuredSize := len(b) - before; siz != measuredSize { + return nil, errors.MismatchedSizeCalculation(siz, measuredSize) + } } return b, nil } @@ -582,11 +605,12 @@ func isInitMessageSlice(p pointer, goType reflect.Type) error { // Slices of messages func sizeMessageSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int { + mopts := opts.Options() list := listv.List() n := 0 for i, llen := 0, list.Len(); i < llen; i++ { m := list.Get(i).Message().Interface() - n += protowire.SizeBytes(proto.Size(m)) + tagsize + n += protowire.SizeBytes(mopts.Size(m)) + tagsize } return n } @@ -597,13 +621,17 @@ func appendMessageSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, for i, llen := 0, list.Len(); i < llen; i++ { m := list.Get(i).Message().Interface() b = protowire.AppendVarint(b, wiretag) - siz := proto.Size(m) + siz := mopts.Size(m) b = protowire.AppendVarint(b, uint64(siz)) + before := len(b) var err error b, err = mopts.MarshalAppend(b, m) if err != nil { return b, err } + if measuredSize := len(b) - before; siz != measuredSize { + return nil, errors.MismatchedSizeCalculation(siz, measuredSize) + } } return b, nil } @@ -651,11 +679,12 @@ var coderMessageSliceValue = valueCoderFuncs{ } func sizeGroupSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int { + mopts := opts.Options() list := listv.List() n := 0 for i, llen := 0, list.Len(); i < llen; i++ { m := list.Get(i).Message().Interface() - n += 2*tagsize + proto.Size(m) + n += 2*tagsize + mopts.Size(m) } return n } @@ -738,12 +767,13 @@ func makeGroupSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) } } -func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int { +func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, opts marshalOptions) int { + mopts := opts.Options() s := p.PointerSlice() n := 0 for _, v := range s { m := asMessage(v.AsValueOf(messageType.Elem())) - n += 2*tagsize + proto.Size(m) + n += 2*tagsize + mopts.Size(m) } return n } diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_map.go b/vendor/google.golang.org/protobuf/internal/impl/codec_map.go index 111b9d16..fb35f0ba 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_map.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_map.go @@ -9,6 +9,7 @@ import ( "sort" "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -240,11 +241,16 @@ func appendMapItem(b []byte, keyrv, valrv reflect.Value, mapi *mapInfo, f *coder size += mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts) size += mapi.valFuncs.size(val, mapValTagSize, opts) b = protowire.AppendVarint(b, uint64(size)) + before := len(b) b, err := mapi.keyFuncs.marshal(b, key.Value(), mapi.keyWiretag, opts) if err != nil { return nil, err } - return mapi.valFuncs.marshal(b, val, mapi.valWiretag, opts) + b, err = mapi.valFuncs.marshal(b, val, mapi.valWiretag, opts) + if measuredSize := len(b) - before; size != measuredSize && err == nil { + return nil, errors.MismatchedSizeCalculation(size, measuredSize) + } + return b, err } else { key := mapi.conv.keyConv.PBValueOf(keyrv).MapKey() val := pointerOfValue(valrv) @@ -259,7 +265,12 @@ func appendMapItem(b []byte, keyrv, valrv reflect.Value, mapi *mapInfo, f *coder } b = protowire.AppendVarint(b, mapi.valWiretag) b = protowire.AppendVarint(b, uint64(valSize)) - return f.mi.marshalAppendPointer(b, val, opts) + before := len(b) + b, err = f.mi.marshalAppendPointer(b, val, opts) + if measuredSize := len(b) - before; valSize != measuredSize && err == nil { + return nil, errors.MismatchedSizeCalculation(valSize, measuredSize) + } + return b, err } } diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go index c2a803bb..c1c33d00 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go +++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go @@ -167,6 +167,7 @@ func aberrantLoadEnumDesc(t reflect.Type) protoreflect.EnumDescriptor { ed := &filedesc.Enum{L2: new(filedesc.EnumL2)} ed.L0.FullName = AberrantDeriveFullName(t) // e.g., github_com.user.repo.MyEnum ed.L0.ParentFile = filedesc.SurrogateProto3 + ed.L1.EditionFeatures = ed.L0.ParentFile.L1.EditionFeatures ed.L2.Values.List = append(ed.L2.Values.List, filedesc.EnumValue{}) // TODO: Use the presence of a UnmarshalJSON method to determine proto2? diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go index 87b30d05..6e8677ee 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go +++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go @@ -118,7 +118,7 @@ func (xi *ExtensionInfo) initFromLegacy() { xd.L1.Number = protoreflect.FieldNumber(xi.Field) xd.L1.Cardinality = fd.L1.Cardinality xd.L1.Kind = fd.L1.Kind - xd.L2.IsPacked = fd.L1.IsPacked + xd.L1.EditionFeatures = fd.L1.EditionFeatures xd.L2.Default = fd.L1.Default xd.L1.Extendee = Export{}.MessageDescriptorOf(xi.ExtendedType) xd.L2.Enum = ed diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_file.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_file.go index 9ab09108..b649f112 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/legacy_file.go +++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_file.go @@ -7,7 +7,7 @@ package impl import ( "bytes" "compress/gzip" - "io/ioutil" + "io" "sync" "google.golang.org/protobuf/internal/filedesc" @@ -51,7 +51,7 @@ func legacyLoadFileDesc(b []byte) protoreflect.FileDescriptor { if err != nil { panic(err) } - b2, err := ioutil.ReadAll(zr) + b2, err := io.ReadAll(zr) if err != nil { panic(err) } diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go index 2ab2c629..950e9a1f 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go +++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go @@ -204,6 +204,7 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name protoreflect.FullName } } + md.L1.EditionFeatures = md.L0.ParentFile.L1.EditionFeatures // Obtain a list of oneof wrapper types. var oneofWrappers []reflect.Type methods := make([]reflect.Method, 0, 2) @@ -250,6 +251,7 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name protoreflect.FullName od := &md.L2.Oneofs.List[n] od.L0.FullName = md.FullName().Append(protoreflect.Name(tag)) od.L0.ParentFile = md.L0.ParentFile + od.L1.EditionFeatures = md.L1.EditionFeatures od.L0.Parent = md od.L0.Index = n @@ -260,6 +262,7 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name protoreflect.FullName aberrantAppendField(md, f.Type, tag, "", "") fd := &md.L2.Fields.List[len(md.L2.Fields.List)-1] fd.L1.ContainingOneof = od + fd.L1.EditionFeatures = od.L1.EditionFeatures od.L1.Fields.List = append(od.L1.Fields.List, fd) } } @@ -307,14 +310,14 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey, fd.L0.Parent = md fd.L0.Index = n - if fd.L1.IsWeak || fd.L1.HasPacked { + if fd.L1.IsWeak || fd.L1.EditionFeatures.IsPacked { fd.L1.Options = func() protoreflect.ProtoMessage { opts := descopts.Field.ProtoReflect().New() if fd.L1.IsWeak { opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true)) } - if fd.L1.HasPacked { - opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOfBool(fd.L1.IsPacked)) + if fd.L1.EditionFeatures.IsPacked { + opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOfBool(fd.L1.EditionFeatures.IsPacked)) } return opts.Interface() } @@ -344,6 +347,7 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey, md2.L0.ParentFile = md.L0.ParentFile md2.L0.Parent = md md2.L0.Index = n + md2.L1.EditionFeatures = md.L1.EditionFeatures md2.L1.IsMapEntry = true md2.L2.Options = func() protoreflect.ProtoMessage { diff --git a/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go b/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go index d9ea010b..a6f0dbda 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go +++ b/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go @@ -247,11 +247,10 @@ func (m *extensionMap) Range(f func(protoreflect.FieldDescriptor, protoreflect.V } } } -func (m *extensionMap) Has(xt protoreflect.ExtensionType) (ok bool) { +func (m *extensionMap) Has(xd protoreflect.ExtensionTypeDescriptor) (ok bool) { if m == nil { return false } - xd := xt.TypeDescriptor() x, ok := (*m)[int32(xd.Number())] if !ok { return false @@ -261,25 +260,22 @@ func (m *extensionMap) Has(xt protoreflect.ExtensionType) (ok bool) { return x.Value().List().Len() > 0 case xd.IsMap(): return x.Value().Map().Len() > 0 - case xd.Message() != nil: - return x.Value().Message().IsValid() } return true } -func (m *extensionMap) Clear(xt protoreflect.ExtensionType) { - delete(*m, int32(xt.TypeDescriptor().Number())) +func (m *extensionMap) Clear(xd protoreflect.ExtensionTypeDescriptor) { + delete(*m, int32(xd.Number())) } -func (m *extensionMap) Get(xt protoreflect.ExtensionType) protoreflect.Value { - xd := xt.TypeDescriptor() +func (m *extensionMap) Get(xd protoreflect.ExtensionTypeDescriptor) protoreflect.Value { if m != nil { if x, ok := (*m)[int32(xd.Number())]; ok { return x.Value() } } - return xt.Zero() + return xd.Type().Zero() } -func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value) { - xd := xt.TypeDescriptor() +func (m *extensionMap) Set(xd protoreflect.ExtensionTypeDescriptor, v protoreflect.Value) { + xt := xd.Type() isValid := true switch { case !xt.IsValidValue(v): @@ -292,7 +288,7 @@ func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value) isValid = v.Message().IsValid() } if !isValid { - panic(fmt.Sprintf("%v: assigning invalid value", xt.TypeDescriptor().FullName())) + panic(fmt.Sprintf("%v: assigning invalid value", xd.FullName())) } if *m == nil { @@ -302,16 +298,15 @@ func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value) x.Set(xt, v) (*m)[int32(xd.Number())] = x } -func (m *extensionMap) Mutable(xt protoreflect.ExtensionType) protoreflect.Value { - xd := xt.TypeDescriptor() +func (m *extensionMap) Mutable(xd protoreflect.ExtensionTypeDescriptor) protoreflect.Value { if xd.Kind() != protoreflect.MessageKind && xd.Kind() != protoreflect.GroupKind && !xd.IsList() && !xd.IsMap() { panic("invalid Mutable on field with non-composite type") } if x, ok := (*m)[int32(xd.Number())]; ok { return x.Value() } - v := xt.New() - m.Set(xt, v) + v := xd.Type().New() + m.Set(xd, v) return v } @@ -428,7 +423,7 @@ func (m *messageIfaceWrapper) protoUnwrap() interface{} { // checkField verifies that the provided field descriptor is valid. // Exactly one of the returned values is populated. -func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionType) { +func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionTypeDescriptor) { var fi *fieldInfo if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) { fi = mi.denseFields[n] @@ -457,7 +452,7 @@ func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, if !ok { panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName())) } - return nil, xtd.Type() + return nil, xtd } panic(fmt.Sprintf("field %v is invalid", fd.FullName())) } diff --git a/vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go b/vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go index 741d6e5b..29ba6bd3 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go +++ b/vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go @@ -27,8 +27,9 @@ func (m *messageState) protoUnwrap() interface{} { return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem()) } func (m *messageState) ProtoMethods() *protoiface.Methods { - m.messageInfo().init() - return &m.messageInfo().methods + mi := m.messageInfo() + mi.init() + return &mi.methods } // ProtoMessageInfo is a pseudo-internal API for allowing the v1 code @@ -41,8 +42,9 @@ func (m *messageState) ProtoMessageInfo() *MessageInfo { } func (m *messageState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - m.messageInfo().init() - for _, ri := range m.messageInfo().rangeInfos { + mi := m.messageInfo() + mi.init() + for _, ri := range mi.rangeInfos { switch ri := ri.(type) { case *fieldInfo: if ri.has(m.pointer()) { @@ -52,77 +54,86 @@ func (m *messageState) Range(f func(protoreflect.FieldDescriptor, protoreflect.V } case *oneofInfo: if n := ri.which(m.pointer()); n > 0 { - fi := m.messageInfo().fields[n] + fi := mi.fields[n] if !f(fi.fieldDesc, fi.get(m.pointer())) { return } } } } - m.messageInfo().extensionMap(m.pointer()).Range(f) + mi.extensionMap(m.pointer()).Range(f) } func (m *messageState) Has(fd protoreflect.FieldDescriptor) bool { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { return fi.has(m.pointer()) } else { - return m.messageInfo().extensionMap(m.pointer()).Has(xt) + return mi.extensionMap(m.pointer()).Has(xd) } } func (m *messageState) Clear(fd protoreflect.FieldDescriptor) { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { fi.clear(m.pointer()) } else { - m.messageInfo().extensionMap(m.pointer()).Clear(xt) + mi.extensionMap(m.pointer()).Clear(xd) } } func (m *messageState) Get(fd protoreflect.FieldDescriptor) protoreflect.Value { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { return fi.get(m.pointer()) } else { - return m.messageInfo().extensionMap(m.pointer()).Get(xt) + return mi.extensionMap(m.pointer()).Get(xd) } } func (m *messageState) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { fi.set(m.pointer(), v) } else { - m.messageInfo().extensionMap(m.pointer()).Set(xt, v) + mi.extensionMap(m.pointer()).Set(xd, v) } } func (m *messageState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { return fi.mutable(m.pointer()) } else { - return m.messageInfo().extensionMap(m.pointer()).Mutable(xt) + return mi.extensionMap(m.pointer()).Mutable(xd) } } func (m *messageState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { return fi.newField() } else { - return xt.New() + return xd.Type().New() } } func (m *messageState) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - m.messageInfo().init() - if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od { + mi := m.messageInfo() + mi.init() + if oi := mi.oneofs[od.Name()]; oi != nil && oi.oneofDesc == od { return od.Fields().ByNumber(oi.which(m.pointer())) } panic("invalid oneof descriptor " + string(od.FullName()) + " for message " + string(m.Descriptor().FullName())) } func (m *messageState) GetUnknown() protoreflect.RawFields { - m.messageInfo().init() - return m.messageInfo().getUnknown(m.pointer()) + mi := m.messageInfo() + mi.init() + return mi.getUnknown(m.pointer()) } func (m *messageState) SetUnknown(b protoreflect.RawFields) { - m.messageInfo().init() - m.messageInfo().setUnknown(m.pointer(), b) + mi := m.messageInfo() + mi.init() + mi.setUnknown(m.pointer(), b) } func (m *messageState) IsValid() bool { return !m.pointer().IsNil() @@ -147,8 +158,9 @@ func (m *messageReflectWrapper) protoUnwrap() interface{} { return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem()) } func (m *messageReflectWrapper) ProtoMethods() *protoiface.Methods { - m.messageInfo().init() - return &m.messageInfo().methods + mi := m.messageInfo() + mi.init() + return &mi.methods } // ProtoMessageInfo is a pseudo-internal API for allowing the v1 code @@ -161,8 +173,9 @@ func (m *messageReflectWrapper) ProtoMessageInfo() *MessageInfo { } func (m *messageReflectWrapper) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - m.messageInfo().init() - for _, ri := range m.messageInfo().rangeInfos { + mi := m.messageInfo() + mi.init() + for _, ri := range mi.rangeInfos { switch ri := ri.(type) { case *fieldInfo: if ri.has(m.pointer()) { @@ -172,77 +185,86 @@ func (m *messageReflectWrapper) Range(f func(protoreflect.FieldDescriptor, proto } case *oneofInfo: if n := ri.which(m.pointer()); n > 0 { - fi := m.messageInfo().fields[n] + fi := mi.fields[n] if !f(fi.fieldDesc, fi.get(m.pointer())) { return } } } } - m.messageInfo().extensionMap(m.pointer()).Range(f) + mi.extensionMap(m.pointer()).Range(f) } func (m *messageReflectWrapper) Has(fd protoreflect.FieldDescriptor) bool { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { return fi.has(m.pointer()) } else { - return m.messageInfo().extensionMap(m.pointer()).Has(xt) + return mi.extensionMap(m.pointer()).Has(xd) } } func (m *messageReflectWrapper) Clear(fd protoreflect.FieldDescriptor) { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { fi.clear(m.pointer()) } else { - m.messageInfo().extensionMap(m.pointer()).Clear(xt) + mi.extensionMap(m.pointer()).Clear(xd) } } func (m *messageReflectWrapper) Get(fd protoreflect.FieldDescriptor) protoreflect.Value { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { return fi.get(m.pointer()) } else { - return m.messageInfo().extensionMap(m.pointer()).Get(xt) + return mi.extensionMap(m.pointer()).Get(xd) } } func (m *messageReflectWrapper) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { fi.set(m.pointer(), v) } else { - m.messageInfo().extensionMap(m.pointer()).Set(xt, v) + mi.extensionMap(m.pointer()).Set(xd, v) } } func (m *messageReflectWrapper) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { return fi.mutable(m.pointer()) } else { - return m.messageInfo().extensionMap(m.pointer()).Mutable(xt) + return mi.extensionMap(m.pointer()).Mutable(xd) } } func (m *messageReflectWrapper) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - m.messageInfo().init() - if fi, xt := m.messageInfo().checkField(fd); fi != nil { + mi := m.messageInfo() + mi.init() + if fi, xd := mi.checkField(fd); fi != nil { return fi.newField() } else { - return xt.New() + return xd.Type().New() } } func (m *messageReflectWrapper) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - m.messageInfo().init() - if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od { + mi := m.messageInfo() + mi.init() + if oi := mi.oneofs[od.Name()]; oi != nil && oi.oneofDesc == od { return od.Fields().ByNumber(oi.which(m.pointer())) } panic("invalid oneof descriptor " + string(od.FullName()) + " for message " + string(m.Descriptor().FullName())) } func (m *messageReflectWrapper) GetUnknown() protoreflect.RawFields { - m.messageInfo().init() - return m.messageInfo().getUnknown(m.pointer()) + mi := m.messageInfo() + mi.init() + return mi.getUnknown(m.pointer()) } func (m *messageReflectWrapper) SetUnknown(b protoreflect.RawFields) { - m.messageInfo().init() - m.messageInfo().setUnknown(m.pointer(), b) + mi := m.messageInfo() + mi.init() + mi.setUnknown(m.pointer(), b) } func (m *messageReflectWrapper) IsValid() bool { return !m.pointer().IsNil() diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go index a50fcfb4..fc6bfc39 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -51,7 +51,7 @@ import ( // 10. Send out the CL for review and submit it. const ( Major = 1 - Minor = 33 + Minor = 34 Patch = 0 PreRelease = "" ) diff --git a/vendor/google.golang.org/protobuf/proto/decode.go b/vendor/google.golang.org/protobuf/proto/decode.go index e5b03b56..d75a6534 100644 --- a/vendor/google.golang.org/protobuf/proto/decode.go +++ b/vendor/google.golang.org/protobuf/proto/decode.go @@ -51,6 +51,8 @@ type UnmarshalOptions struct { // Unmarshal parses the wire-format message in b and places the result in m. // The provided message must be mutable (e.g., a non-nil pointer to a message). +// +// See the [UnmarshalOptions] type if you need more control. func Unmarshal(b []byte, m Message) error { _, err := UnmarshalOptions{RecursionLimit: protowire.DefaultRecursionLimit}.unmarshal(b, m.ProtoReflect()) return err diff --git a/vendor/google.golang.org/protobuf/proto/encode.go b/vendor/google.golang.org/protobuf/proto/encode.go index 4fed202f..1f847bcc 100644 --- a/vendor/google.golang.org/protobuf/proto/encode.go +++ b/vendor/google.golang.org/protobuf/proto/encode.go @@ -5,12 +5,17 @@ package proto import ( + "errors" + "fmt" + "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/order" "google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/runtime/protoiface" + + protoerrors "google.golang.org/protobuf/internal/errors" ) // MarshalOptions configures the marshaler. @@ -70,7 +75,32 @@ type MarshalOptions struct { UseCachedSize bool } +// flags turns the specified MarshalOptions (user-facing) into +// protoiface.MarshalInputFlags (used internally by the marshaler). +// +// See impl.marshalOptions.Options for the inverse operation. +func (o MarshalOptions) flags() protoiface.MarshalInputFlags { + var flags protoiface.MarshalInputFlags + + // Note: o.AllowPartial is always forced to true by MarshalOptions.marshal, + // which is why it is not a part of MarshalInputFlags. + + if o.Deterministic { + flags |= protoiface.MarshalDeterministic + } + + if o.UseCachedSize { + flags |= protoiface.MarshalUseCachedSize + } + + return flags +} + // Marshal returns the wire-format encoding of m. +// +// This is the most common entry point for encoding a Protobuf message. +// +// See the [MarshalOptions] type if you need more control. func Marshal(m Message) ([]byte, error) { // Treat nil message interface as an empty message; nothing to output. if m == nil { @@ -116,6 +146,9 @@ func emptyBytesForMessage(m Message) []byte { // MarshalAppend appends the wire-format encoding of m to b, // returning the result. +// +// This is a less common entry point than [Marshal], which is only needed if you +// need to supply your own buffers for performance reasons. func (o MarshalOptions) MarshalAppend(b []byte, m Message) ([]byte, error) { // Treat nil message interface as an empty message; nothing to append. if m == nil { @@ -145,12 +178,7 @@ func (o MarshalOptions) marshal(b []byte, m protoreflect.Message) (out protoifac in := protoiface.MarshalInput{ Message: m, Buf: b, - } - if o.Deterministic { - in.Flags |= protoiface.MarshalDeterministic - } - if o.UseCachedSize { - in.Flags |= protoiface.MarshalUseCachedSize + Flags: o.flags(), } if methods.Size != nil { sout := methods.Size(protoiface.SizeInput{ @@ -168,6 +196,10 @@ func (o MarshalOptions) marshal(b []byte, m protoreflect.Message) (out protoifac out.Buf, err = o.marshalMessageSlow(b, m) } if err != nil { + var mismatch *protoerrors.SizeMismatchError + if errors.As(err, &mismatch) { + return out, fmt.Errorf("marshaling %s: %v", string(m.Descriptor().FullName()), err) + } return out, err } if allowPartial { diff --git a/vendor/google.golang.org/protobuf/proto/extension.go b/vendor/google.golang.org/protobuf/proto/extension.go index 17899a3a..c9c8721a 100644 --- a/vendor/google.golang.org/protobuf/proto/extension.go +++ b/vendor/google.golang.org/protobuf/proto/extension.go @@ -11,18 +11,21 @@ import ( // HasExtension reports whether an extension field is populated. // It returns false if m is invalid or if xt does not extend m. func HasExtension(m Message, xt protoreflect.ExtensionType) bool { - // Treat nil message interface as an empty message; no populated fields. - if m == nil { + // Treat nil message interface or descriptor as an empty message; no populated + // fields. + if m == nil || xt == nil { return false } // As a special-case, we reports invalid or mismatching descriptors // as always not being populated (since they aren't). - if xt == nil || m.ProtoReflect().Descriptor() != xt.TypeDescriptor().ContainingMessage() { + mr := m.ProtoReflect() + xd := xt.TypeDescriptor() + if mr.Descriptor() != xd.ContainingMessage() { return false } - return m.ProtoReflect().Has(xt.TypeDescriptor()) + return mr.Has(xd) } // ClearExtension clears an extension field such that subsequent diff --git a/vendor/google.golang.org/protobuf/proto/messageset.go b/vendor/google.golang.org/protobuf/proto/messageset.go index 312d5d45..575d1483 100644 --- a/vendor/google.golang.org/protobuf/proto/messageset.go +++ b/vendor/google.golang.org/protobuf/proto/messageset.go @@ -47,11 +47,16 @@ func (o MarshalOptions) marshalMessageSet(b []byte, m protoreflect.Message) ([]b func (o MarshalOptions) marshalMessageSetField(b []byte, fd protoreflect.FieldDescriptor, value protoreflect.Value) ([]byte, error) { b = messageset.AppendFieldStart(b, fd.Number()) b = protowire.AppendTag(b, messageset.FieldMessage, protowire.BytesType) - b = protowire.AppendVarint(b, uint64(o.Size(value.Message().Interface()))) + calculatedSize := o.Size(value.Message().Interface()) + b = protowire.AppendVarint(b, uint64(calculatedSize)) + before := len(b) b, err := o.marshalMessage(b, value.Message()) if err != nil { return b, err } + if measuredSize := len(b) - before; calculatedSize != measuredSize { + return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize) + } b = messageset.AppendFieldEnd(b) return b, nil } diff --git a/vendor/google.golang.org/protobuf/proto/size.go b/vendor/google.golang.org/protobuf/proto/size.go index f1692b49..052fb5ae 100644 --- a/vendor/google.golang.org/protobuf/proto/size.go +++ b/vendor/google.golang.org/protobuf/proto/size.go @@ -34,6 +34,7 @@ func (o MarshalOptions) size(m protoreflect.Message) (size int) { if methods != nil && methods.Size != nil { out := methods.Size(protoiface.SizeInput{ Message: m, + Flags: o.flags(), }) return out.Size } @@ -42,6 +43,7 @@ func (o MarshalOptions) size(m protoreflect.Message) (size int) { // This case is mainly used for legacy types with a Marshal method. out, _ := methods.Marshal(protoiface.MarshalInput{ Message: m, + Flags: o.flags(), }) return len(out.Buf) } diff --git a/vendor/google.golang.org/protobuf/protoadapt/convert.go b/vendor/google.golang.org/protobuf/protoadapt/convert.go new file mode 100644 index 00000000..ea276d15 --- /dev/null +++ b/vendor/google.golang.org/protobuf/protoadapt/convert.go @@ -0,0 +1,31 @@ +// 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 protoadapt bridges the original and new proto APIs. +package protoadapt + +import ( + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/runtime/protoimpl" +) + +// MessageV1 is the original [github.com/golang/protobuf/proto.Message] type. +type MessageV1 = protoiface.MessageV1 + +// MessageV2 is the [google.golang.org/protobuf/proto.Message] type used by the +// current [google.golang.org/protobuf] module, adding support for reflection. +type MessageV2 = proto.Message + +// MessageV1Of converts a v2 message to a v1 message. +// It returns nil if m is nil. +func MessageV1Of(m MessageV2) MessageV1 { + return protoimpl.X.ProtoMessageV1Of(m) +} + +// MessageV2Of converts a v1 message to a v2 message. +// It returns nil if m is nil. +func MessageV2Of(m MessageV1) MessageV2 { + return protoimpl.X.ProtoMessageV2Of(m) +} diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go index baa0cc62..8fbecb4f 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go @@ -13,6 +13,7 @@ package protodesc import ( + "google.golang.org/protobuf/internal/editionssupport" "google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/pragma" @@ -91,15 +92,17 @@ func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (prot switch fd.GetSyntax() { case "proto2", "": f.L1.Syntax = protoreflect.Proto2 + f.L1.Edition = filedesc.EditionProto2 case "proto3": f.L1.Syntax = protoreflect.Proto3 + f.L1.Edition = filedesc.EditionProto3 case "editions": f.L1.Syntax = protoreflect.Editions f.L1.Edition = fromEditionProto(fd.GetEdition()) default: return nil, errors.New("invalid syntax: %q", fd.GetSyntax()) } - if f.L1.Syntax == protoreflect.Editions && (fd.GetEdition() < SupportedEditionsMinimum || fd.GetEdition() > SupportedEditionsMaximum) { + if f.L1.Syntax == protoreflect.Editions && (fd.GetEdition() < editionssupport.Minimum || fd.GetEdition() > editionssupport.Maximum) { return nil, errors.New("use of edition %v not yet supported by the Go Protobuf runtime", fd.GetEdition()) } f.L1.Path = fd.GetName() @@ -114,9 +117,7 @@ func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (prot opts = proto.Clone(opts).(*descriptorpb.FileOptions) f.L2.Options = func() protoreflect.ProtoMessage { return opts } } - if f.L1.Syntax == protoreflect.Editions { - initFileDescFromFeatureSet(f, fd.GetOptions().GetFeatures()) - } + initFileDescFromFeatureSet(f, fd.GetOptions().GetFeatures()) f.L2.Imports = make(filedesc.FileImports, len(fd.GetDependency())) for _, i := range fd.GetPublicDependency() { @@ -219,10 +220,10 @@ func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (prot if err := validateEnumDeclarations(f.L1.Enums.List, fd.GetEnumType()); err != nil { return nil, err } - if err := validateMessageDeclarations(f.L1.Messages.List, fd.GetMessageType()); err != nil { + if err := validateMessageDeclarations(f, f.L1.Messages.List, fd.GetMessageType()); err != nil { return nil, err } - if err := validateExtensionDeclarations(f.L1.Extensions.List, fd.GetExtension()); err != nil { + if err := validateExtensionDeclarations(f, f.L1.Extensions.List, fd.GetExtension()); err != nil { return nil, err } diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go index b3278163..85617554 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go @@ -69,9 +69,7 @@ func (r descsByName) initMessagesDeclarations(mds []*descriptorpb.DescriptorProt if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil { return nil, err } - if m.Base.L0.ParentFile.Syntax() == protoreflect.Editions { - m.L1.EditionFeatures = mergeEditionFeatures(parent, md.GetOptions().GetFeatures()) - } + m.L1.EditionFeatures = mergeEditionFeatures(parent, md.GetOptions().GetFeatures()) if opts := md.GetOptions(); opts != nil { opts = proto.Clone(opts).(*descriptorpb.MessageOptions) m.L2.Options = func() protoreflect.ProtoMessage { return opts } @@ -146,13 +144,15 @@ func (r descsByName) initFieldsFromDescriptorProto(fds []*descriptorpb.FieldDesc if f.L0, err = r.makeBase(f, parent, fd.GetName(), i, sb); err != nil { return nil, err } + f.L1.EditionFeatures = mergeEditionFeatures(parent, fd.GetOptions().GetFeatures()) f.L1.IsProto3Optional = fd.GetProto3Optional() if opts := fd.GetOptions(); opts != nil { opts = proto.Clone(opts).(*descriptorpb.FieldOptions) f.L1.Options = func() protoreflect.ProtoMessage { return opts } f.L1.IsWeak = opts.GetWeak() - f.L1.HasPacked = opts.Packed != nil - f.L1.IsPacked = opts.GetPacked() + if opts.Packed != nil { + f.L1.EditionFeatures.IsPacked = opts.GetPacked() + } } f.L1.Number = protoreflect.FieldNumber(fd.GetNumber()) f.L1.Cardinality = protoreflect.Cardinality(fd.GetLabel()) @@ -163,32 +163,12 @@ func (r descsByName) initFieldsFromDescriptorProto(fds []*descriptorpb.FieldDesc f.L1.StringName.InitJSON(fd.GetJsonName()) } - if f.Base.L0.ParentFile.Syntax() == protoreflect.Editions { - f.L1.EditionFeatures = mergeEditionFeatures(parent, fd.GetOptions().GetFeatures()) - - if f.L1.EditionFeatures.IsLegacyRequired { - f.L1.Cardinality = protoreflect.Required - } - // We reuse the existing field because the old option `[packed = - // true]` is mutually exclusive with the editions feature. - if canBePacked(fd) { - f.L1.HasPacked = true - f.L1.IsPacked = f.L1.EditionFeatures.IsPacked - } - - // We pretend this option is always explicitly set because the only - // use of HasEnforceUTF8 is to determine whether to use EnforceUTF8 - // or to return the appropriate default. - // When using editions we either parse the option or resolve the - // appropriate default here (instead of later when this option is - // requested from the descriptor). - // In proto2/proto3 syntax HasEnforceUTF8 might be false. - f.L1.HasEnforceUTF8 = true - f.L1.EnforceUTF8 = f.L1.EditionFeatures.IsUTF8Validated + if f.L1.EditionFeatures.IsLegacyRequired { + f.L1.Cardinality = protoreflect.Required + } - if f.L1.Kind == protoreflect.MessageKind && f.L1.EditionFeatures.IsDelimitedEncoded { - f.L1.Kind = protoreflect.GroupKind - } + if f.L1.Kind == protoreflect.MessageKind && f.L1.EditionFeatures.IsDelimitedEncoded { + f.L1.Kind = protoreflect.GroupKind } } return fs, nil @@ -201,12 +181,10 @@ func (r descsByName) initOneofsFromDescriptorProto(ods []*descriptorpb.OneofDesc if o.L0, err = r.makeBase(o, parent, od.GetName(), i, sb); err != nil { return nil, err } + o.L1.EditionFeatures = mergeEditionFeatures(parent, od.GetOptions().GetFeatures()) if opts := od.GetOptions(); opts != nil { opts = proto.Clone(opts).(*descriptorpb.OneofOptions) o.L1.Options = func() protoreflect.ProtoMessage { return opts } - if parent.Syntax() == protoreflect.Editions { - o.L1.EditionFeatures = mergeEditionFeatures(parent, opts.GetFeatures()) - } } } return os, nil @@ -220,10 +198,13 @@ func (r descsByName) initExtensionDeclarations(xds []*descriptorpb.FieldDescript if x.L0, err = r.makeBase(x, parent, xd.GetName(), i, sb); err != nil { return nil, err } + x.L1.EditionFeatures = mergeEditionFeatures(parent, xd.GetOptions().GetFeatures()) if opts := xd.GetOptions(); opts != nil { opts = proto.Clone(opts).(*descriptorpb.FieldOptions) x.L2.Options = func() protoreflect.ProtoMessage { return opts } - x.L2.IsPacked = opts.GetPacked() + if opts.Packed != nil { + x.L1.EditionFeatures.IsPacked = opts.GetPacked() + } } x.L1.Number = protoreflect.FieldNumber(xd.GetNumber()) x.L1.Cardinality = protoreflect.Cardinality(xd.GetLabel()) diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go index e4dcaf87..c6293086 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go @@ -45,11 +45,11 @@ func validateEnumDeclarations(es []filedesc.Enum, eds []*descriptorpb.EnumDescri if allowAlias && !foundAlias { return errors.New("enum %q allows aliases, but none were found", e.FullName()) } - if e.Syntax() == protoreflect.Proto3 { + if !e.IsClosed() { if v := e.Values().Get(0); v.Number() != 0 { - return errors.New("enum %q using proto3 semantics must have zero number for the first value", v.FullName()) + return errors.New("enum %q using open semantics must have zero number for the first value", v.FullName()) } - // Verify that value names in proto3 do not conflict if the + // Verify that value names in open enums do not conflict if the // case-insensitive prefix is removed. // See protoc v3.8.0: src/google/protobuf/descriptor.cc:4991-5055 names := map[string]protoreflect.EnumValueDescriptor{} @@ -58,7 +58,7 @@ func validateEnumDeclarations(es []filedesc.Enum, eds []*descriptorpb.EnumDescri v1 := e.Values().Get(i) s := strs.EnumValueName(strs.TrimEnumPrefix(string(v1.Name()), prefix)) if v2, ok := names[s]; ok && v1.Number() != v2.Number() { - return errors.New("enum %q using proto3 semantics has conflict: %q with %q", e.FullName(), v1.Name(), v2.Name()) + return errors.New("enum %q using open semantics has conflict: %q with %q", e.FullName(), v1.Name(), v2.Name()) } names[s] = v1 } @@ -80,7 +80,9 @@ func validateEnumDeclarations(es []filedesc.Enum, eds []*descriptorpb.EnumDescri return nil } -func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) error { +func validateMessageDeclarations(file *filedesc.File, ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) error { + // There are a few limited exceptions only for proto3 + isProto3 := file.L1.Edition == fromEditionProto(descriptorpb.Edition_EDITION_PROTO3) for i, md := range mds { m := &ms[i] @@ -107,10 +109,10 @@ func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.Desc if isMessageSet && !flags.ProtoLegacy { return errors.New("message %q is a MessageSet, which is a legacy proto1 feature that is no longer supported", m.FullName()) } - if isMessageSet && (m.Syntax() == protoreflect.Proto3 || m.Fields().Len() > 0 || m.ExtensionRanges().Len() == 0) { + if isMessageSet && (isProto3 || m.Fields().Len() > 0 || m.ExtensionRanges().Len() == 0) { return errors.New("message %q is an invalid proto1 MessageSet", m.FullName()) } - if m.Syntax() == protoreflect.Proto3 { + if isProto3 { if m.ExtensionRanges().Len() > 0 { return errors.New("message %q using proto3 semantics cannot have extension ranges", m.FullName()) } @@ -149,7 +151,7 @@ func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.Desc return errors.New("message field %q may not have extendee: %q", f.FullName(), fd.GetExtendee()) } if f.L1.IsProto3Optional { - if f.Syntax() != protoreflect.Proto3 { + if !isProto3 { return errors.New("message field %q under proto3 optional semantics must be specified in the proto3 syntax", f.FullName()) } if f.Cardinality() != protoreflect.Optional { @@ -162,26 +164,29 @@ func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.Desc if f.IsWeak() && !flags.ProtoLegacy { return errors.New("message field %q is a weak field, which is a legacy proto1 feature that is no longer supported", f.FullName()) } - if f.IsWeak() && (f.Syntax() != protoreflect.Proto2 || !isOptionalMessage(f) || f.ContainingOneof() != nil) { + if f.IsWeak() && (!f.HasPresence() || !isOptionalMessage(f) || f.ContainingOneof() != nil) { return errors.New("message field %q may only be weak for an optional message", f.FullName()) } if f.IsPacked() && !isPackable(f) { return errors.New("message field %q is not packable", f.FullName()) } - if err := checkValidGroup(f); err != nil { + if err := checkValidGroup(file, f); err != nil { return errors.New("message field %q is an invalid group: %v", f.FullName(), err) } if err := checkValidMap(f); err != nil { return errors.New("message field %q is an invalid map: %v", f.FullName(), err) } - if f.Syntax() == protoreflect.Proto3 { + if isProto3 { if f.Cardinality() == protoreflect.Required { return errors.New("message field %q using proto3 semantics cannot be required", f.FullName()) } - if f.Enum() != nil && !f.Enum().IsPlaceholder() && f.Enum().Syntax() != protoreflect.Proto3 { - return errors.New("message field %q using proto3 semantics may only depend on a proto3 enum", f.FullName()) + if f.Enum() != nil && !f.Enum().IsPlaceholder() && f.Enum().IsClosed() { + return errors.New("message field %q using proto3 semantics may only depend on open enums", f.FullName()) } } + if f.Cardinality() == protoreflect.Optional && !f.HasPresence() && f.Enum() != nil && !f.Enum().IsPlaceholder() && f.Enum().IsClosed() { + return errors.New("message field %q with implicit presence may only use open enums", f.FullName()) + } } seenSynthetic := false // synthetic oneofs for proto3 optional must come after real oneofs for j := range md.GetOneofDecl() { @@ -215,17 +220,17 @@ func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.Desc if err := validateEnumDeclarations(m.L1.Enums.List, md.GetEnumType()); err != nil { return err } - if err := validateMessageDeclarations(m.L1.Messages.List, md.GetNestedType()); err != nil { + if err := validateMessageDeclarations(file, m.L1.Messages.List, md.GetNestedType()); err != nil { return err } - if err := validateExtensionDeclarations(m.L1.Extensions.List, md.GetExtension()); err != nil { + if err := validateExtensionDeclarations(file, m.L1.Extensions.List, md.GetExtension()); err != nil { return err } } return nil } -func validateExtensionDeclarations(xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) error { +func validateExtensionDeclarations(f *filedesc.File, xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) error { for i, xd := range xds { x := &xs[i] // NOTE: Avoid using the IsValid method since extensions to MessageSet @@ -267,13 +272,13 @@ func validateExtensionDeclarations(xs []filedesc.Extension, xds []*descriptorpb. if x.IsPacked() && !isPackable(x) { return errors.New("extension field %q is not packable", x.FullName()) } - if err := checkValidGroup(x); err != nil { + if err := checkValidGroup(f, x); err != nil { return errors.New("extension field %q is an invalid group: %v", x.FullName(), err) } if md := x.Message(); md != nil && md.IsMapEntry() { return errors.New("extension field %q cannot be a map entry", x.FullName()) } - if x.Syntax() == protoreflect.Proto3 { + if f.L1.Edition == fromEditionProto(descriptorpb.Edition_EDITION_PROTO3) { switch x.ContainingMessage().FullName() { case (*descriptorpb.FileOptions)(nil).ProtoReflect().Descriptor().FullName(): case (*descriptorpb.EnumOptions)(nil).ProtoReflect().Descriptor().FullName(): @@ -309,21 +314,25 @@ func isPackable(fd protoreflect.FieldDescriptor) bool { // checkValidGroup reports whether fd is a valid group according to the same // rules that protoc imposes. -func checkValidGroup(fd protoreflect.FieldDescriptor) error { +func checkValidGroup(f *filedesc.File, fd protoreflect.FieldDescriptor) error { md := fd.Message() switch { case fd.Kind() != protoreflect.GroupKind: return nil - case fd.Syntax() == protoreflect.Proto3: + case f.L1.Edition == fromEditionProto(descriptorpb.Edition_EDITION_PROTO3): return errors.New("invalid under proto3 semantics") case md == nil || md.IsPlaceholder(): return errors.New("message must be resolvable") - case fd.FullName().Parent() != md.FullName().Parent(): - return errors.New("message and field must be declared in the same scope") - case !unicode.IsUpper(rune(md.Name()[0])): - return errors.New("message name must start with an uppercase") - case fd.Name() != protoreflect.Name(strings.ToLower(string(md.Name()))): - return errors.New("field name must be lowercased form of the message name") + } + if f.L1.Edition < fromEditionProto(descriptorpb.Edition_EDITION_2023) { + switch { + case fd.FullName().Parent() != md.FullName().Parent(): + return errors.New("message and field must be declared in the same scope") + case !unicode.IsUpper(rune(md.Name()[0])): + return errors.New("message name must start with an uppercase") + case fd.Name() != protoreflect.Name(strings.ToLower(string(md.Name()))): + return errors.New("field name must be lowercased form of the message name") + } } return nil } diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/editions.go b/vendor/google.golang.org/protobuf/reflect/protodesc/editions.go index 2a6b29d1..f6a1fec6 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/editions.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/editions.go @@ -17,11 +17,6 @@ import ( gofeaturespb "google.golang.org/protobuf/types/gofeaturespb" ) -const ( - SupportedEditionsMinimum = descriptorpb.Edition_EDITION_PROTO2 - SupportedEditionsMaximum = descriptorpb.Edition_EDITION_2023 -) - var defaults = &descriptorpb.FeatureSetDefaults{} var defaultsCacheMu sync.Mutex var defaultsCache = make(map[filedesc.Edition]*descriptorpb.FeatureSet) diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go b/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go index 9d6e0542..a5de8d40 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go @@ -73,6 +73,16 @@ func ToFileDescriptorProto(file protoreflect.FileDescriptor) *descriptorpb.FileD if syntax := file.Syntax(); syntax != protoreflect.Proto2 && syntax.IsValid() { p.Syntax = proto.String(file.Syntax().String()) } + if file.Syntax() == protoreflect.Editions { + desc := file + if fileImportDesc, ok := file.(protoreflect.FileImport); ok { + desc = fileImportDesc.FileDescriptor + } + + if editionsInterface, ok := desc.(interface{ Edition() int32 }); ok { + p.Edition = descriptorpb.Edition(editionsInterface.Edition()).Enum() + } + } return p } @@ -153,6 +163,18 @@ func ToFieldDescriptorProto(field protoreflect.FieldDescriptor) *descriptorpb.Fi if field.Syntax() == protoreflect.Proto3 && field.HasOptionalKeyword() { p.Proto3Optional = proto.Bool(true) } + if field.Syntax() == protoreflect.Editions { + // Editions have no group keyword, this type is only set so that downstream users continue + // treating this as delimited encoding. + if p.GetType() == descriptorpb.FieldDescriptorProto_TYPE_GROUP { + p.Type = descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum() + } + // Editions have no required keyword, this label is only set so that downstream users continue + // treating it as required. + if p.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REQUIRED { + p.Label = descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum() + } + } if field.HasDefault() { def, err := defval.Marshal(field.Default(), field.DefaultEnumValue(), field.Kind(), defval.Descriptor) if err != nil && field.DefaultEnumValue() != nil { diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go index 00b01fbd..c85bfaa5 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go @@ -161,7 +161,7 @@ const ( // IsValid reports whether the syntax is valid. func (s Syntax) IsValid() bool { switch s { - case Proto2, Proto3: + case Proto2, Proto3, Editions: return true default: return false diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go index 60ff62b4..5b80afe5 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go @@ -544,6 +544,12 @@ type EnumDescriptor interface { // ReservedRanges is a list of reserved ranges of enum numbers. ReservedRanges() EnumRanges + // IsClosed reports whether this enum uses closed semantics. + // See https://protobuf.dev/programming-guides/enum/#definitions. + // Note: the Go protobuf implementation is not spec compliant and treats + // all enums as open enums. + IsClosed() bool + isEnumDescriptor } type isEnumDescriptor interface{ ProtoType(EnumDescriptor) } diff --git a/vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.pb.go b/vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.pb.go index 25de5ae0..9f046f97 100644 --- a/vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.pb.go +++ b/vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.pb.go @@ -6,9 +6,9 @@ // https://developers.google.com/open-source/licenses/bsd // Code generated by protoc-gen-go. DO NOT EDIT. -// source: reflect/protodesc/proto/go_features.proto +// source: google/protobuf/go_features.proto -package proto +package gofeaturespb import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -30,7 +30,7 @@ type GoFeatures struct { func (x *GoFeatures) Reset() { *x = GoFeatures{} if protoimpl.UnsafeEnabled { - mi := &file_reflect_protodesc_proto_go_features_proto_msgTypes[0] + mi := &file_google_protobuf_go_features_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -43,7 +43,7 @@ func (x *GoFeatures) String() string { func (*GoFeatures) ProtoMessage() {} func (x *GoFeatures) ProtoReflect() protoreflect.Message { - mi := &file_reflect_protodesc_proto_go_features_proto_msgTypes[0] + mi := &file_google_protobuf_go_features_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -56,7 +56,7 @@ func (x *GoFeatures) ProtoReflect() protoreflect.Message { // Deprecated: Use GoFeatures.ProtoReflect.Descriptor instead. func (*GoFeatures) Descriptor() ([]byte, []int) { - return file_reflect_protodesc_proto_go_features_proto_rawDescGZIP(), []int{0} + return file_google_protobuf_go_features_proto_rawDescGZIP(), []int{0} } func (x *GoFeatures) GetLegacyUnmarshalJsonEnum() bool { @@ -66,69 +66,67 @@ func (x *GoFeatures) GetLegacyUnmarshalJsonEnum() bool { return false } -var file_reflect_protodesc_proto_go_features_proto_extTypes = []protoimpl.ExtensionInfo{ +var file_google_protobuf_go_features_proto_extTypes = []protoimpl.ExtensionInfo{ { ExtendedType: (*descriptorpb.FeatureSet)(nil), ExtensionType: (*GoFeatures)(nil), Field: 1002, - Name: "google.protobuf.go", + Name: "pb.go", Tag: "bytes,1002,opt,name=go", - Filename: "reflect/protodesc/proto/go_features.proto", + Filename: "google/protobuf/go_features.proto", }, } // Extension fields to descriptorpb.FeatureSet. var ( - // optional google.protobuf.GoFeatures go = 1002; - E_Go = &file_reflect_protodesc_proto_go_features_proto_extTypes[0] + // optional pb.GoFeatures go = 1002; + E_Go = &file_google_protobuf_go_features_proto_extTypes[0] ) -var File_reflect_protodesc_proto_go_features_proto protoreflect.FileDescriptor - -var file_reflect_protodesc_proto_go_features_proto_rawDesc = []byte{ - 0x0a, 0x29, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x64, - 0x65, 0x73, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x5f, 0x66, 0x65, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x1a, 0x20, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6a, - 0x0a, 0x0a, 0x47, 0x6f, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x5c, 0x0a, 0x1a, - 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, - 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x42, 0x1f, 0x88, 0x01, 0x01, 0x98, 0x01, 0x06, 0xa2, 0x01, 0x09, 0x12, 0x04, 0x74, 0x72, 0x75, - 0x65, 0x18, 0xe6, 0x07, 0xa2, 0x01, 0x0a, 0x12, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x18, 0xe7, - 0x07, 0x52, 0x17, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, - 0x61, 0x6c, 0x4a, 0x73, 0x6f, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x3a, 0x49, 0x0a, 0x02, 0x67, 0x6f, - 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x18, 0xea, 0x07, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x47, 0x6f, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x73, 0x52, 0x02, 0x67, 0x6f, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x64, 0x65, 0x73, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, +var File_google_protobuf_go_features_proto protoreflect.FileDescriptor + +var file_google_protobuf_go_features_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x67, 0x6f, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6a, 0x0a, 0x0a, 0x47, 0x6f, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x5c, 0x0a, 0x1a, 0x6c, 0x65, 0x67, 0x61, 0x63, + 0x79, 0x5f, 0x75, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, + 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, 0x1f, 0x88, 0x01, 0x01, + 0x98, 0x01, 0x06, 0xa2, 0x01, 0x09, 0x12, 0x04, 0x74, 0x72, 0x75, 0x65, 0x18, 0xe6, 0x07, 0xa2, + 0x01, 0x0a, 0x12, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x18, 0xe7, 0x07, 0x52, 0x17, 0x6c, 0x65, + 0x67, 0x61, 0x63, 0x79, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x4a, 0x73, 0x6f, + 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x3a, 0x3c, 0x0a, 0x02, 0x67, 0x6f, 0x12, 0x1b, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x18, 0xea, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x6f, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, + 0x02, 0x67, 0x6f, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, + 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x67, 0x6f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x70, 0x62, } var ( - file_reflect_protodesc_proto_go_features_proto_rawDescOnce sync.Once - file_reflect_protodesc_proto_go_features_proto_rawDescData = file_reflect_protodesc_proto_go_features_proto_rawDesc + file_google_protobuf_go_features_proto_rawDescOnce sync.Once + file_google_protobuf_go_features_proto_rawDescData = file_google_protobuf_go_features_proto_rawDesc ) -func file_reflect_protodesc_proto_go_features_proto_rawDescGZIP() []byte { - file_reflect_protodesc_proto_go_features_proto_rawDescOnce.Do(func() { - file_reflect_protodesc_proto_go_features_proto_rawDescData = protoimpl.X.CompressGZIP(file_reflect_protodesc_proto_go_features_proto_rawDescData) +func file_google_protobuf_go_features_proto_rawDescGZIP() []byte { + file_google_protobuf_go_features_proto_rawDescOnce.Do(func() { + file_google_protobuf_go_features_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_go_features_proto_rawDescData) }) - return file_reflect_protodesc_proto_go_features_proto_rawDescData + return file_google_protobuf_go_features_proto_rawDescData } -var file_reflect_protodesc_proto_go_features_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_reflect_protodesc_proto_go_features_proto_goTypes = []interface{}{ - (*GoFeatures)(nil), // 0: google.protobuf.GoFeatures +var file_google_protobuf_go_features_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_google_protobuf_go_features_proto_goTypes = []interface{}{ + (*GoFeatures)(nil), // 0: pb.GoFeatures (*descriptorpb.FeatureSet)(nil), // 1: google.protobuf.FeatureSet } -var file_reflect_protodesc_proto_go_features_proto_depIdxs = []int32{ - 1, // 0: google.protobuf.go:extendee -> google.protobuf.FeatureSet - 0, // 1: google.protobuf.go:type_name -> google.protobuf.GoFeatures +var file_google_protobuf_go_features_proto_depIdxs = []int32{ + 1, // 0: pb.go:extendee -> google.protobuf.FeatureSet + 0, // 1: pb.go:type_name -> pb.GoFeatures 2, // [2:2] is the sub-list for method output_type 2, // [2:2] is the sub-list for method input_type 1, // [1:2] is the sub-list for extension type_name @@ -136,13 +134,13 @@ var file_reflect_protodesc_proto_go_features_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for field type_name } -func init() { file_reflect_protodesc_proto_go_features_proto_init() } -func file_reflect_protodesc_proto_go_features_proto_init() { - if File_reflect_protodesc_proto_go_features_proto != nil { +func init() { file_google_protobuf_go_features_proto_init() } +func file_google_protobuf_go_features_proto_init() { + if File_google_protobuf_go_features_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_reflect_protodesc_proto_go_features_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_google_protobuf_go_features_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GoFeatures); i { case 0: return &v.state @@ -159,19 +157,19 @@ func file_reflect_protodesc_proto_go_features_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_reflect_protodesc_proto_go_features_proto_rawDesc, + RawDescriptor: file_google_protobuf_go_features_proto_rawDesc, NumEnums: 0, NumMessages: 1, NumExtensions: 1, NumServices: 0, }, - GoTypes: file_reflect_protodesc_proto_go_features_proto_goTypes, - DependencyIndexes: file_reflect_protodesc_proto_go_features_proto_depIdxs, - MessageInfos: file_reflect_protodesc_proto_go_features_proto_msgTypes, - ExtensionInfos: file_reflect_protodesc_proto_go_features_proto_extTypes, + GoTypes: file_google_protobuf_go_features_proto_goTypes, + DependencyIndexes: file_google_protobuf_go_features_proto_depIdxs, + MessageInfos: file_google_protobuf_go_features_proto_msgTypes, + ExtensionInfos: file_google_protobuf_go_features_proto_extTypes, }.Build() - File_reflect_protodesc_proto_go_features_proto = out.File - file_reflect_protodesc_proto_go_features_proto_rawDesc = nil - file_reflect_protodesc_proto_go_features_proto_goTypes = nil - file_reflect_protodesc_proto_go_features_proto_depIdxs = nil + File_google_protobuf_go_features_proto = out.File + file_google_protobuf_go_features_proto_rawDesc = nil + file_google_protobuf_go_features_proto_goTypes = nil + file_google_protobuf_go_features_proto_depIdxs = nil } diff --git a/vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.proto b/vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.proto deleted file mode 100644 index d2465712..00000000 --- a/vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.proto +++ /dev/null @@ -1,28 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2023 Google Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd - -syntax = "proto2"; - -package google.protobuf; - -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/protobuf/types/gofeaturespb"; - -extend google.protobuf.FeatureSet { - optional GoFeatures go = 1002; -} - -message GoFeatures { - // Whether or not to generate the deprecated UnmarshalJSON method for enums. - optional bool legacy_unmarshal_json_enum = 1 [ - retention = RETENTION_RUNTIME, - targets = TARGET_TYPE_ENUM, - edition_defaults = { edition: EDITION_PROTO2, value: "true" }, - edition_defaults = { edition: EDITION_PROTO3, value: "false" } - ]; -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 3083047b..7e2e871f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,18 +1,18 @@ -# github.com/1Password/connect-sdk-go v1.5.2 +# github.com/1Password/connect-sdk-go v1.5.3 ## explicit; go 1.20 github.com/1Password/connect-sdk-go/connect github.com/1Password/connect-sdk-go/onepassword # github.com/Masterminds/goutils v1.1.1 ## explicit github.com/Masterminds/goutils -# github.com/Masterminds/semver/v3 v3.1.1 -## explicit; go 1.12 +# github.com/Masterminds/semver/v3 v3.2.1 +## explicit; go 1.18 github.com/Masterminds/semver/v3 -# github.com/Masterminds/sprig/v3 v3.2.2 +# github.com/Masterminds/sprig/v3 v3.2.3 ## explicit; go 1.13 github.com/Masterminds/sprig/v3 -# github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 -## explicit; go 1.13 +# github.com/ProtonMail/go-crypto v1.1.0-alpha.0 +## explicit; go 1.17 github.com/ProtonMail/go-crypto/bitcurves github.com/ProtonMail/go-crypto/brainpool github.com/ProtonMail/go-crypto/eax @@ -23,6 +23,8 @@ github.com/ProtonMail/go-crypto/openpgp/aes/keywrap github.com/ProtonMail/go-crypto/openpgp/armor github.com/ProtonMail/go-crypto/openpgp/ecdh github.com/ProtonMail/go-crypto/openpgp/ecdsa +github.com/ProtonMail/go-crypto/openpgp/ed25519 +github.com/ProtonMail/go-crypto/openpgp/ed448 github.com/ProtonMail/go-crypto/openpgp/eddsa github.com/ProtonMail/go-crypto/openpgp/elgamal github.com/ProtonMail/go-crypto/openpgp/errors @@ -31,12 +33,14 @@ github.com/ProtonMail/go-crypto/openpgp/internal/ecc github.com/ProtonMail/go-crypto/openpgp/internal/encoding github.com/ProtonMail/go-crypto/openpgp/packet github.com/ProtonMail/go-crypto/openpgp/s2k +github.com/ProtonMail/go-crypto/openpgp/x25519 +github.com/ProtonMail/go-crypto/openpgp/x448 # github.com/agext/levenshtein v1.2.3 ## explicit github.com/agext/levenshtein -# github.com/apparentlymart/go-textseg/v13 v13.0.0 +# github.com/apparentlymart/go-textseg/v15 v15.0.0 ## explicit; go 1.16 -github.com/apparentlymart/go-textseg/v13/textseg +github.com/apparentlymart/go-textseg/v15/textseg # github.com/armon/go-radix v1.0.0 ## explicit github.com/armon/go-radix @@ -57,26 +61,21 @@ github.com/cloudflare/circl/math/mlsbset github.com/cloudflare/circl/sign github.com/cloudflare/circl/sign/ed25519 github.com/cloudflare/circl/sign/ed448 -# github.com/fatih/color v1.15.0 +# github.com/fatih/color v1.16.0 ## explicit; go 1.17 github.com/fatih/color -# github.com/golang/protobuf v1.5.3 -## explicit; go 1.9 -github.com/golang/protobuf/jsonpb +# github.com/golang/protobuf v1.5.4 +## explicit; go 1.17 github.com/golang/protobuf/proto -github.com/golang/protobuf/ptypes -github.com/golang/protobuf/ptypes/any -github.com/golang/protobuf/ptypes/duration github.com/golang/protobuf/ptypes/empty -github.com/golang/protobuf/ptypes/timestamp -# github.com/google/go-cmp v0.5.9 +# github.com/google/go-cmp v0.6.0 ## explicit; go 1.13 github.com/google/go-cmp/cmp 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/uuid v1.3.0 +# github.com/google/uuid v1.6.0 ## explicit github.com/google/uuid # github.com/hashicorp/errwrap v1.1.0 @@ -96,23 +95,26 @@ github.com/hashicorp/go-cty/cty/gocty github.com/hashicorp/go-cty/cty/json github.com/hashicorp/go-cty/cty/msgpack github.com/hashicorp/go-cty/cty/set -# github.com/hashicorp/go-hclog v1.5.0 +# github.com/hashicorp/go-hclog v1.6.3 ## explicit; go 1.13 github.com/hashicorp/go-hclog # github.com/hashicorp/go-multierror v1.1.1 ## explicit; go 1.13 github.com/hashicorp/go-multierror -# github.com/hashicorp/go-plugin v1.4.10 +# github.com/hashicorp/go-plugin v1.6.0 ## explicit; go 1.17 github.com/hashicorp/go-plugin +github.com/hashicorp/go-plugin/internal/cmdrunner +github.com/hashicorp/go-plugin/internal/grpcmux github.com/hashicorp/go-plugin/internal/plugin +github.com/hashicorp/go-plugin/runner # github.com/hashicorp/go-uuid v1.0.3 ## explicit github.com/hashicorp/go-uuid # github.com/hashicorp/go-version v1.6.0 ## explicit github.com/hashicorp/go-version -# github.com/hashicorp/hc-install v0.5.2 +# github.com/hashicorp/hc-install v0.6.3 ## explicit; go 1.18 github.com/hashicorp/hc-install github.com/hashicorp/hc-install/checkpoint @@ -128,7 +130,7 @@ github.com/hashicorp/hc-install/product github.com/hashicorp/hc-install/releases github.com/hashicorp/hc-install/src github.com/hashicorp/hc-install/version -# github.com/hashicorp/hcl/v2 v2.17.0 +# github.com/hashicorp/hcl/v2 v2.20.1 ## explicit; go 1.18 github.com/hashicorp/hcl/v2 github.com/hashicorp/hcl/v2/ext/customdecode @@ -136,11 +138,11 @@ github.com/hashicorp/hcl/v2/hclsyntax # github.com/hashicorp/logutils v1.0.0 ## explicit github.com/hashicorp/logutils -# github.com/hashicorp/terraform-exec v0.18.1 +# github.com/hashicorp/terraform-exec v0.20.0 ## explicit; go 1.18 github.com/hashicorp/terraform-exec/internal/version github.com/hashicorp/terraform-exec/tfexec -# github.com/hashicorp/terraform-json v0.17.1 +# github.com/hashicorp/terraform-json v0.21.0 ## explicit; go 1.18 github.com/hashicorp/terraform-json # github.com/hashicorp/terraform-plugin-docs v0.16.0 @@ -151,12 +153,13 @@ github.com/hashicorp/terraform-plugin-docs/internal/mdplain github.com/hashicorp/terraform-plugin-docs/internal/provider github.com/hashicorp/terraform-plugin-docs/internal/tmplfuncs github.com/hashicorp/terraform-plugin-docs/schemamd -# github.com/hashicorp/terraform-plugin-go v0.18.0 -## explicit; go 1.19 +# github.com/hashicorp/terraform-plugin-go v0.22.2 +## explicit; go 1.21 github.com/hashicorp/terraform-plugin-go/internal/logging github.com/hashicorp/terraform-plugin-go/tfprotov5 github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/diag github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/fromproto +github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/funcerr github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tf5serverlogging github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5 github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/toproto @@ -164,6 +167,7 @@ github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server github.com/hashicorp/terraform-plugin-go/tfprotov6 github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/diag github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/fromproto +github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/funcerr github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tf6serverlogging github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6 github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/toproto @@ -176,8 +180,8 @@ github.com/hashicorp/terraform-plugin-log/internal/hclogutils github.com/hashicorp/terraform-plugin-log/internal/logging github.com/hashicorp/terraform-plugin-log/tflog github.com/hashicorp/terraform-plugin-log/tfsdklog -# github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0 -## explicit; go 1.19 +# github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 +## explicit; go 1.21 github.com/hashicorp/terraform-plugin-sdk/v2/diag github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema @@ -194,7 +198,7 @@ github.com/hashicorp/terraform-plugin-sdk/v2/internal/tfdiags github.com/hashicorp/terraform-plugin-sdk/v2/meta github.com/hashicorp/terraform-plugin-sdk/v2/plugin github.com/hashicorp/terraform-plugin-sdk/v2/terraform -# github.com/hashicorp/terraform-registry-address v0.2.1 +# github.com/hashicorp/terraform-registry-address v0.2.3 ## explicit; go 1.19 github.com/hashicorp/terraform-registry-address # github.com/hashicorp/terraform-svchost v0.1.1 @@ -203,16 +207,16 @@ github.com/hashicorp/terraform-svchost # github.com/hashicorp/yamux v0.1.1 ## explicit; go 1.15 github.com/hashicorp/yamux -# github.com/huandu/xstrings v1.3.2 +# github.com/huandu/xstrings v1.3.3 ## explicit; go 1.12 github.com/huandu/xstrings -# github.com/imdario/mergo v0.3.13 +# github.com/imdario/mergo v0.3.15 ## explicit; go 1.13 github.com/imdario/mergo # github.com/mattn/go-colorable v0.1.13 ## explicit; go 1.15 github.com/mattn/go-colorable -# github.com/mattn/go-isatty v0.0.19 +# github.com/mattn/go-isatty v0.0.20 ## explicit; go 1.15 github.com/mattn/go-isatty # github.com/mitchellh/cli v1.1.5 @@ -286,8 +290,8 @@ github.com/uber/jaeger-lib/metrics ## explicit github.com/vmihailenco/msgpack github.com/vmihailenco/msgpack/codes -# github.com/vmihailenco/msgpack/v5 v5.3.5 -## explicit; go 1.11 +# github.com/vmihailenco/msgpack/v5 v5.4.1 +## explicit; go 1.19 github.com/vmihailenco/msgpack/v5 github.com/vmihailenco/msgpack/v5/msgpcode # github.com/vmihailenco/tagparser/v2 v2.0.0 @@ -295,7 +299,7 @@ github.com/vmihailenco/msgpack/v5/msgpcode github.com/vmihailenco/tagparser/v2 github.com/vmihailenco/tagparser/v2/internal github.com/vmihailenco/tagparser/v2/internal/parser -# github.com/zclconf/go-cty v1.13.2 +# github.com/zclconf/go-cty v1.14.4 ## explicit; go 1.18 github.com/zclconf/go-cty/cty github.com/zclconf/go-cty/cty/convert @@ -308,9 +312,11 @@ github.com/zclconf/go-cty/cty/set # go.uber.org/atomic v1.11.0 ## explicit; go 1.18 go.uber.org/atomic -# golang.org/x/crypto v0.17.0 +# golang.org/x/crypto v0.22.0 ## explicit; go 1.18 +golang.org/x/crypto/argon2 golang.org/x/crypto/bcrypt +golang.org/x/crypto/blake2b golang.org/x/crypto/blowfish golang.org/x/crypto/cast5 golang.org/x/crypto/hkdf @@ -321,22 +327,24 @@ golang.org/x/crypto/sha3 ## explicit; go 1.20 golang.org/x/exp/constraints golang.org/x/exp/slices -# golang.org/x/mod v0.11.0 -## explicit; go 1.17 +# golang.org/x/mod v0.17.0 +## explicit; go 1.18 golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.17.0 -## explicit; go 1.17 -golang.org/x/net/context +# golang.org/x/net v0.24.0 +## explicit; go 1.18 golang.org/x/net/http/httpguts golang.org/x/net/http2 golang.org/x/net/http2/hpack golang.org/x/net/idna golang.org/x/net/internal/timeseries golang.org/x/net/trace -# golang.org/x/sys v0.15.0 +# golang.org/x/sync v0.7.0 +## explicit; go 1.18 +golang.org/x/sync/errgroup +# golang.org/x/sys v0.19.0 ## explicit; go 1.18 golang.org/x/sys/cpu golang.org/x/sys/unix @@ -353,7 +361,28 @@ golang.org/x/text/secure/bidirule golang.org/x/text/transform golang.org/x/text/unicode/bidi golang.org/x/text/unicode/norm -# google.golang.org/appengine v1.6.7 +# golang.org/x/tools v0.20.0 +## explicit; go 1.19 +golang.org/x/tools/cmd/stringer +golang.org/x/tools/go/gcexportdata +golang.org/x/tools/go/internal/packagesdriver +golang.org/x/tools/go/packages +golang.org/x/tools/go/types/objectpath +golang.org/x/tools/internal/aliases +golang.org/x/tools/internal/event +golang.org/x/tools/internal/event/core +golang.org/x/tools/internal/event/keys +golang.org/x/tools/internal/event/label +golang.org/x/tools/internal/event/tag +golang.org/x/tools/internal/gcimporter +golang.org/x/tools/internal/gocommand +golang.org/x/tools/internal/packagesinternal +golang.org/x/tools/internal/pkgbits +golang.org/x/tools/internal/stdlib +golang.org/x/tools/internal/tokeninternal +golang.org/x/tools/internal/typesinternal +golang.org/x/tools/internal/versions +# google.golang.org/appengine v1.6.8 ## explicit; go 1.11 google.golang.org/appengine google.golang.org/appengine/datastore @@ -366,11 +395,11 @@ google.golang.org/appengine/internal/datastore google.golang.org/appengine/internal/log google.golang.org/appengine/internal/modules google.golang.org/appengine/internal/remote_api -# google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 +# google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 ## explicit; go 1.19 google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.56.3 -## explicit; go 1.17 +# google.golang.org/grpc v1.63.2 +## explicit; go 1.19 google.golang.org/grpc google.golang.org/grpc/attributes google.golang.org/grpc/backoff @@ -402,10 +431,12 @@ google.golang.org/grpc/internal/grpclog google.golang.org/grpc/internal/grpcrand google.golang.org/grpc/internal/grpcsync google.golang.org/grpc/internal/grpcutil +google.golang.org/grpc/internal/idle google.golang.org/grpc/internal/metadata google.golang.org/grpc/internal/pretty google.golang.org/grpc/internal/resolver google.golang.org/grpc/internal/resolver/dns +google.golang.org/grpc/internal/resolver/dns/internal google.golang.org/grpc/internal/resolver/passthrough google.golang.org/grpc/internal/resolver/unix google.golang.org/grpc/internal/serviceconfig @@ -417,13 +448,15 @@ google.golang.org/grpc/keepalive google.golang.org/grpc/metadata google.golang.org/grpc/peer google.golang.org/grpc/reflection +google.golang.org/grpc/reflection/grpc_reflection_v1 google.golang.org/grpc/reflection/grpc_reflection_v1alpha google.golang.org/grpc/resolver +google.golang.org/grpc/resolver/dns google.golang.org/grpc/serviceconfig google.golang.org/grpc/stats google.golang.org/grpc/status google.golang.org/grpc/tap -# google.golang.org/protobuf v1.33.0 +# google.golang.org/protobuf v1.34.0 ## explicit; go 1.17 google.golang.org/protobuf/encoding/protojson google.golang.org/protobuf/encoding/prototext @@ -432,6 +465,7 @@ google.golang.org/protobuf/internal/descfmt google.golang.org/protobuf/internal/descopts google.golang.org/protobuf/internal/detrand google.golang.org/protobuf/internal/editiondefaults +google.golang.org/protobuf/internal/editionssupport google.golang.org/protobuf/internal/encoding/defval google.golang.org/protobuf/internal/encoding/json google.golang.org/protobuf/internal/encoding/messageset @@ -449,6 +483,7 @@ google.golang.org/protobuf/internal/set google.golang.org/protobuf/internal/strs google.golang.org/protobuf/internal/version google.golang.org/protobuf/proto +google.golang.org/protobuf/protoadapt google.golang.org/protobuf/reflect/protodesc google.golang.org/protobuf/reflect/protoreflect google.golang.org/protobuf/reflect/protoregistry From a5f346c1a8f3d32d8cb6953897b5c6a621940a37 Mon Sep 17 00:00:00 2001 From: Eddy Filip Date: Thu, 2 May 2024 19:05:44 +0200 Subject: [PATCH 02/36] Add provider framework dependencies and update packages - Move `github.com/hashicorp/terraform-plugin-framework` package from indirect dependency to direct dependency - `go get -u ./...` - `go mod tidy` - `go mod vendor` --- go.mod | 24 +- go.sum | 68 +- vendor/github.com/BurntSushi/toml/.gitignore | 2 + vendor/github.com/BurntSushi/toml/COPYING | 21 + vendor/github.com/BurntSushi/toml/README.md | 120 + vendor/github.com/BurntSushi/toml/decode.go | 602 ++++ .../BurntSushi/toml/decode_go116.go | 19 + .../github.com/BurntSushi/toml/deprecated.go | 21 + vendor/github.com/BurntSushi/toml/doc.go | 11 + vendor/github.com/BurntSushi/toml/encode.go | 750 ++++ vendor/github.com/BurntSushi/toml/error.go | 279 ++ .../github.com/BurntSushi/toml/internal/tz.go | 36 + vendor/github.com/BurntSushi/toml/lex.go | 1233 +++++++ vendor/github.com/BurntSushi/toml/meta.go | 121 + vendor/github.com/BurntSushi/toml/parse.go | 781 +++++ .../github.com/BurntSushi/toml/type_fields.go | 242 ++ .../github.com/BurntSushi/toml/type_toml.go | 70 + .../github.com/Kunde21/markdownfmt/v3/LICENSE | 22 + .../Kunde21/markdownfmt/v3/markdown/doc.go | 2 + .../Kunde21/markdownfmt/v3/markdown/indent.go | 61 + .../markdownfmt/v3/markdown/renderer.go | 646 ++++ .../v3/markdown/renderer_heading.go | 89 + .../markdownfmt/v3/markdown/renderer_table.go | 140 + .../markdownfmt/v3/markdown/writer_indent.go | 106 + .../go-crypto/openpgp/packet/signature.go | 7 - .../ProtonMail/go-crypto/openpgp/read.go | 45 +- .../bmatcuk/doublestar/v4/.codecov.yml | 10 + .../bmatcuk/doublestar/v4/.gitignore | 32 + .../github.com/bmatcuk/doublestar/v4/LICENSE | 22 + .../bmatcuk/doublestar/v4/README.md | 402 +++ .../bmatcuk/doublestar/v4/UPGRADING.md | 63 + .../bmatcuk/doublestar/v4/doublestar.go | 13 + .../github.com/bmatcuk/doublestar/v4/glob.go | 473 +++ .../bmatcuk/doublestar/v4/globoptions.go | 144 + .../bmatcuk/doublestar/v4/globwalk.go | 414 +++ .../github.com/bmatcuk/doublestar/v4/match.go | 381 +++ .../github.com/bmatcuk/doublestar/v4/utils.go | 147 + .../bmatcuk/doublestar/v4/validate.go | 82 + .../{mitchellh => hashicorp}/cli/LICENSE | 0 .../{mitchellh => hashicorp}/cli/Makefile | 0 .../{mitchellh => hashicorp}/cli/README.md | 6 +- .../cli/autocomplete.go | 3 + .../{mitchellh => hashicorp}/cli/cli.go | 3 + .../{mitchellh => hashicorp}/cli/command.go | 3 + .../cli/command_mock.go | 3 + .../{mitchellh => hashicorp}/cli/help.go | 3 + vendor/github.com/hashicorp/cli/ui.go | 63 + .../cli/ui_colored.go | 5 + .../cli/ui.go => hashicorp/cli/ui_common.go} | 53 - .../cli/ui_concurrent.go | 3 + vendor/github.com/hashicorp/cli/ui_js.go | 10 + .../{mitchellh => hashicorp}/cli/ui_mock.go | 3 + .../{mitchellh => hashicorp}/cli/ui_writer.go | 3 + .../hashicorp/hc-install/version/VERSION | 2 +- .../cmd/tfplugindocs/build/version.go | 18 + .../cmd/tfplugindocs/main.go | 17 +- .../cmd/tfplugindocs/version.go | 10 - .../internal/check/directory.go | 210 ++ .../internal/check/file.go | 39 + .../internal/check/file_extension.go | 64 + .../internal/check/file_mismatch.go | 284 ++ .../internal/check/frontmatter.go | 104 + .../internal/check/provider_file.go | 67 + .../internal/cmd/generate.go | 5 +- .../internal/cmd/migrate.go | 100 + .../terraform-plugin-docs/internal/cmd/run.go | 27 +- .../internal/cmd/validate.go | 21 +- .../internal/functionmd/render.go | 96 + .../internal/mdplain/mdplain.go | 26 +- .../internal/mdplain/renderer.go | 250 +- .../internal/provider/generate.go | 441 +-- .../internal/provider/logger.go | 27 + .../internal/provider/migrate.go | 409 +++ .../internal/provider/schema.go | 136 + .../internal/provider/template.go | 156 +- .../internal/provider/util.go | 58 +- .../internal/provider/validate.go | 500 +-- .../{ => internal}/schemamd/behaviors.go | 0 .../{ => internal}/schemamd/render.go | 60 +- .../schemamd/write_attribute_description.go | 0 .../schemamd/write_block_type_description.go | 0 ...write_nested_attribute_type_description.go | 0 .../{ => internal}/schemamd/write_type.go | 0 .../terraform-plugin-framework/LICENSE | 356 ++ .../terraform-plugin-framework/attr/doc.go | 7 + .../terraform-plugin-framework/attr/type.go | 120 + .../terraform-plugin-framework/attr/value.go | 71 + .../attr/value_state.go | 34 + .../attr/xattr/attribute.go | 38 + .../attr/xattr/doc.go | 6 + .../attr/xattr/type.go | 30 + .../datasource/config_validator.go | 28 + .../datasource/configure.go | 34 + .../datasource/data_source.go | 77 + .../datasource/doc.go | 19 + .../datasource/metadata.go | 24 + .../datasource/read.go | 40 + .../datasource/schema.go | 27 + .../datasource/schema/attribute.go | 36 + .../datasource/schema/block.go | 30 + .../datasource/schema/bool_attribute.go | 187 + .../datasource/schema/doc.go | 8 + .../datasource/schema/dynamic_attribute.go | 188 + .../datasource/schema/float64_attribute.go | 190 ++ .../datasource/schema/int64_attribute.go | 190 ++ .../datasource/schema/list_attribute.go | 222 ++ .../schema/list_nested_attribute.go | 246 ++ .../datasource/schema/list_nested_block.go | 205 ++ .../datasource/schema/map_attribute.go | 225 ++ .../datasource/schema/map_nested_attribute.go | 247 ++ .../datasource/schema/nested_attribute.go | 14 + .../schema/nested_attribute_object.go | 82 + .../datasource/schema/nested_block_object.go | 94 + .../datasource/schema/number_attribute.go | 191 ++ .../datasource/schema/object_attribute.go | 224 ++ .../datasource/schema/schema.go | 187 + .../datasource/schema/set_attribute.go | 220 ++ .../datasource/schema/set_nested_attribute.go | 242 ++ .../datasource/schema/set_nested_block.go | 205 ++ .../schema/single_nested_attribute.go | 246 ++ .../datasource/schema/single_nested_block.go | 213 ++ .../datasource/schema/string_attribute.go | 187 + .../datasource/validate_config.go | 33 + .../diag/attribute_error_diagnostic.go | 16 + .../diag/attribute_warning_diagnostic.go | 16 + .../diag/diagnostic.go | 53 + .../diag/diagnostics.go | 122 + .../terraform-plugin-framework/diag/doc.go | 11 + .../diag/error_diagnostic.go | 46 + .../diag/severity.go | 41 + .../diag/warning_diagnostic.go | 46 + .../diag/with_path.go | 57 + .../function/arguments_data.go | 173 + .../function/bool_parameter.go | 117 + .../function/bool_parameter_validator.go | 33 + .../function/bool_return.go | 50 + .../function/definition.go | 194 ++ .../function/doc.go | 21 + .../function/dynamic_parameter.go | 112 + .../function/dynamic_parameter_validator.go | 33 + .../function/dynamic_return.go | 53 + .../function/float64_parameter.go | 114 + .../function/float64_parameter_validator.go | 33 + .../function/float64_return.go | 51 + .../function/func_error.go | 129 + .../function/function.go | 26 + .../function/int64_parameter.go | 113 + .../function/int64_parameter_validator.go | 33 + .../function/int64_return.go | 50 + .../function/list_parameter.go | 148 + .../function/list_parameter_validator.go | 33 + .../function/list_return.go | 77 + .../function/map_parameter.go | 148 + .../function/map_parameter_validator.go | 33 + .../function/map_return.go | 77 + .../function/metadata.go | 20 + .../function/number_parameter.go | 112 + .../function/number_parameter_validator.go | 33 + .../function/number_return.go | 51 + .../function/object_parameter.go | 150 + .../function/object_parameter_validator.go | 33 + .../function/object_return.go | 73 + .../function/parameter.go | 66 + .../function/parameter_validation.go | 94 + .../function/result_data.go | 60 + .../function/return.go | 25 + .../function/run.go | 27 + .../function/set_parameter.go | 148 + .../function/set_parameter_validator.go | 33 + .../function/set_return.go | 77 + .../function/string_parameter.go | 113 + .../function/string_parameter_validator.go | 33 + .../function/string_return.go | 50 + .../fromproto5/applyresourcechange.go | 77 + .../internal/fromproto5/arguments_data.go | 542 +++ .../internal/fromproto5/callfunction.go | 32 + .../internal/fromproto5/config.go | 53 + .../internal/fromproto5/configureprovider.go | 33 + .../internal/fromproto5/doc.go | 6 + .../internal/fromproto5/dynamic_value.go | 54 + .../internal/fromproto5/getfunctions.go | 23 + .../internal/fromproto5/getmetadata.go | 23 + .../internal/fromproto5/getproviderschema.go | 23 + .../fromproto5/importresourcestate.go | 52 + .../internal/fromproto5/moveresourcestate.go | 57 + .../internal/fromproto5/plan.go | 53 + .../internal/fromproto5/planresourcechange.go | 77 + .../fromproto5/prepareproviderconfig.go | 29 + .../internal/fromproto5/providermeta.go | 54 + .../internal/fromproto5/readdatasource.go | 57 + .../internal/fromproto5/readresource.go | 50 + .../internal/fromproto5/state.go | 53 + .../fromproto5/upgraderesourcestate.go | 48 + .../fromproto5/validatedatasourceconfig.go | 31 + .../fromproto5/validateresourcetypeconfig.go | 31 + .../fromproto6/applyresourcechange.go | 77 + .../internal/fromproto6/arguments_data.go | 542 +++ .../internal/fromproto6/callfunction.go | 32 + .../internal/fromproto6/config.go | 53 + .../internal/fromproto6/configureprovider.go | 33 + .../internal/fromproto6/doc.go | 6 + .../internal/fromproto6/dynamic_value.go | 54 + .../internal/fromproto6/getfunctions.go | 23 + .../internal/fromproto6/getmetadata.go | 23 + .../internal/fromproto6/getproviderschema.go | 23 + .../fromproto6/importresourcestate.go | 52 + .../internal/fromproto6/moveresourcestate.go | 56 + .../internal/fromproto6/plan.go | 53 + .../internal/fromproto6/planresourcechange.go | 77 + .../internal/fromproto6/providermeta.go | 54 + .../internal/fromproto6/readdatasource.go | 57 + .../internal/fromproto6/readresource.go | 50 + .../internal/fromproto6/state.go | 53 + .../fromproto6/upgraderesourcestate.go | 47 + .../fromproto6/validatedatasourceconfig.go | 31 + .../fromproto6/validateproviderconfig.go | 29 + .../fromproto6/validateresourceconfig.go | 31 + .../internal/fromtftypes/attribute_path.go | 91 + .../fromtftypes/attribute_path_step.go | 38 + .../internal/fromtftypes/doc.go | 6 + .../internal/fromtftypes/value.go | 27 + .../internal/fwfunction/doc.go | 6 + .../parameter_validate_implementation.go | 54 + .../return_validate_implementation.go | 43 + .../internal/fwschema/attribute.go | 105 + .../internal/fwschema/attribute_default.go | 88 + .../fwschema/attribute_name_validation.go | 162 + .../fwschema/attribute_nesting_mode.go | 35 + .../attribute_validate_implementation.go | 100 + .../internal/fwschema/block.go | 116 + .../internal/fwschema/block_nested_mode.go | 39 + .../fwschema/block_validate_implementation.go | 125 + .../internal/fwschema/diagnostics.go | 66 + .../internal/fwschema/doc.go | 10 + .../internal/fwschema/errors.go | 22 + .../fwxschema/attribute_plan_modification.go | 99 + .../fwxschema/attribute_validation.go | 99 + .../fwxschema/block_plan_modification.go | 36 + .../fwschema/fwxschema/block_validation.go | 36 + .../internal/fwschema/fwxschema/doc.go | 9 + ...sted_attribute_object_plan_modification.go | 18 + .../nested_attribute_object_validation.go | 18 + .../nested_block_object_plan_modification.go | 18 + .../nested_block_object_validators.go | 18 + .../internal/fwschema/nested_attribute.go | 34 + .../fwschema/nested_attribute_object.go | 93 + .../internal/fwschema/nested_block_object.go | 122 + .../internal/fwschema/schema.go | 270 ++ .../fwschema/underlying_attributes.go | 70 + .../fwschema/validate_implementation.go | 37 + .../internal/fwschemadata/data.go | 27 + .../internal/fwschemadata/data_default.go | 366 ++ .../internal/fwschemadata/data_description.go | 46 + .../internal/fwschemadata/data_get.go | 17 + .../internal/fwschemadata/data_get_at_path.go | 61 + .../data_nullify_collection_blocks.go | 98 + .../internal/fwschemadata/data_path_exists.go | 47 + .../fwschemadata/data_path_matches.go | 80 + .../data_reify_null_collection_blocks.go | 74 + .../internal/fwschemadata/data_set.go | 38 + .../internal/fwschemadata/data_set_at_path.go | 264 ++ .../fwschemadata/data_terraform_value.go | 29 + .../data_valid_path_expression.go | 102 + .../internal/fwschemadata/data_value.go | 130 + .../internal/fwschemadata/doc.go | 6 + .../internal/fwschemadata/tftypes_value.go | 210 ++ .../fwschemadata/value_semantic_equality.go | 89 + .../value_semantic_equality_bool.go | 54 + .../value_semantic_equality_dynamic.go | 78 + .../value_semantic_equality_float64.go | 54 + .../value_semantic_equality_int64.go | 54 + .../value_semantic_equality_list.go | 210 ++ .../value_semantic_equality_map.go | 212 ++ .../value_semantic_equality_number.go | 54 + .../value_semantic_equality_object.go | 212 ++ .../value_semantic_equality_set.go | 210 ++ .../value_semantic_equality_string.go | 54 + .../internal/fwserver/attr_type.go | 162 + .../internal/fwserver/attr_value.go | 244 ++ .../fwserver/attribute_plan_modification.go | 2385 +++++++++++++ .../internal/fwserver/attribute_validation.go | 1058 ++++++ .../fwserver/block_plan_modification.go | 1082 ++++++ .../internal/fwserver/block_validation.go | 456 +++ .../internal/fwserver/diagnostics.go | 45 + .../internal/fwserver/doc.go | 8 + .../fwserver/schema_plan_modification.go | 197 ++ .../fwserver/schema_semantic_equality.go | 146 + .../internal/fwserver/schema_validation.go | 77 + .../internal/fwserver/server.go | 572 ++++ .../fwserver/server_applyresourcechange.go | 107 + .../internal/fwserver/server_callfunction.go | 56 + .../internal/fwserver/server_capabilities.go | 40 + .../fwserver/server_configureprovider.go | 27 + .../fwserver/server_createresource.go | 166 + .../fwserver/server_deleteresource.go | 123 + .../internal/fwserver/server_functions.go | 195 ++ .../internal/fwserver/server_getfunctions.go | 37 + .../internal/fwserver/server_getmetadata.go | 73 + .../fwserver/server_getproviderschema.go | 83 + .../fwserver/server_importresourcestate.go | 138 + .../fwserver/server_moveresourcestate.go | 230 ++ .../fwserver/server_planresourcechange.go | 470 +++ .../fwserver/server_readdatasource.go | 120 + .../internal/fwserver/server_readresource.go | 150 + .../fwserver/server_updateresource.go | 179 + .../fwserver/server_upgraderesourcestate.go | 247 ++ .../server_validatedatasourceconfig.go | 109 + .../fwserver/server_validateproviderconfig.go | 100 + .../fwserver/server_validateresourceconfig.go | 109 + .../internal/fwtype/doc.go | 5 + .../fwtype/static_collection_validation.go | 142 + .../internal/logging/context.go | 25 + .../internal/logging/doc.go | 6 + .../internal/logging/environment_variables.go | 12 + .../internal/logging/framework.go | 43 + .../internal/logging/keys.go | 36 + .../internal/privatestate/data.go | 413 +++ .../internal/privatestate/doc.go | 6 + .../internal/proto5server/doc.go | 6 + .../internal/proto5server/serve.go | 46 + .../server_applyresourcechange.go | 58 + .../proto5server/server_callfunction.go | 55 + .../proto5server/server_configureprovider.go | 42 + .../proto5server/server_getfunctions.go | 27 + .../proto5server/server_getmetadata.go | 27 + .../proto5server/server_getproviderschema.go | 27 + .../server_importresourcestate.go | 50 + .../proto5server/server_moveresourcestate.go | 54 + .../proto5server/server_planresourcechange.go | 58 + .../server_prepareproviderconfig.go | 42 + .../proto5server/server_readdatasource.go | 58 + .../proto5server/server_readresource.go | 59 + .../server_upgraderesourcestate.go | 54 + .../server_validatedatasourceconfig.go | 50 + .../server_validateresourcetypeconfig.go | 50 + .../internal/proto6server/doc.go | 6 + .../internal/proto6server/serve.go | 46 + .../server_applyresourcechange.go | 58 + .../proto6server/server_callfunction.go | 55 + .../proto6server/server_configureprovider.go | 42 + .../proto6server/server_getfunctions.go | 27 + .../proto6server/server_getmetadata.go | 27 + .../proto6server/server_getproviderschema.go | 27 + .../server_importresourcestate.go | 50 + .../proto6server/server_moveresourcestate.go | 54 + .../proto6server/server_planresourcechange.go | 58 + .../proto6server/server_readdatasource.go | 58 + .../proto6server/server_readresource.go | 58 + .../server_upgraderesourcestate.go | 54 + .../server_validatedataresourceconfig.go | 50 + .../server_validateproviderconfig.go | 42 + .../server_validateresourceconfig.go | 50 + .../internal/reflect/diags.go | 116 + .../internal/reflect/doc.go | 6 + .../internal/reflect/generic_attr_value.go | 15 + .../internal/reflect/helpers.go | 99 + .../internal/reflect/interfaces.go | 491 +++ .../internal/reflect/into.go | 212 ++ .../internal/reflect/map.go | 254 ++ .../internal/reflect/number.go | 400 +++ .../internal/reflect/options.go | 18 + .../internal/reflect/outof.go | 95 + .../internal/reflect/pointer.go | 142 + .../internal/reflect/primitive.go | 151 + .../internal/reflect/slice.go | 437 +++ .../internal/reflect/struct.go | 310 ++ .../internal/toproto5/applyresourcechange.go | 36 + .../internal/toproto5/block.go | 97 + .../internal/toproto5/callfunction.go | 30 + .../internal/toproto5/config.go | 28 + .../internal/toproto5/configureprovider.go | 25 + .../internal/toproto5/datasourcemetadata.go | 19 + .../internal/toproto5/diagnostics.go | 52 + .../internal/toproto5/doc.go | 6 + .../internal/toproto5/dynamic_value.go | 47 + .../internal/toproto5/function.go | 125 + .../internal/toproto5/function_errors.go | 24 + .../internal/toproto5/getfunctions.go | 30 + .../internal/toproto5/getmetadata.go | 41 + .../internal/toproto5/getproviderschema.go | 87 + .../internal/toproto5/importedresource.go | 36 + .../internal/toproto5/importresourcestate.go | 37 + .../internal/toproto5/moveresourcestate.go | 36 + .../internal/toproto5/planresourcechange.go | 42 + .../toproto5/prepareproviderconfig.go | 30 + .../internal/toproto5/readdatasource.go | 30 + .../internal/toproto5/readresource.go | 36 + .../internal/toproto5/resourcemetadata.go | 19 + .../internal/toproto5/schema.go | 91 + .../internal/toproto5/schema_attribute.go | 54 + .../internal/toproto5/server_capabilities.go | 24 + .../internal/toproto5/state.go | 28 + .../internal/toproto5/upgraderesourcestate.go | 30 + .../toproto5/validatedatasourceconfig.go | 25 + .../toproto5/validateresourcetypeconfig.go | 25 + .../internal/toproto6/applyresourcechange.go | 36 + .../internal/toproto6/block.go | 97 + .../internal/toproto6/callfunction.go | 30 + .../internal/toproto6/config.go | 28 + .../internal/toproto6/configureprovider.go | 25 + .../internal/toproto6/datasourcemetadata.go | 19 + .../internal/toproto6/diagnostics.go | 52 + .../internal/toproto6/doc.go | 6 + .../internal/toproto6/dynamic_value.go | 47 + .../internal/toproto6/function.go | 125 + .../internal/toproto6/function_errors.go | 24 + .../internal/toproto6/getfunctions.go | 30 + .../internal/toproto6/getmetadata.go | 41 + .../internal/toproto6/getproviderschema.go | 87 + .../internal/toproto6/importedresource.go | 36 + .../internal/toproto6/importresourcestate.go | 37 + .../internal/toproto6/moveresourcestate.go | 36 + .../internal/toproto6/planresourcechange.go | 42 + .../internal/toproto6/readdatasource.go | 30 + .../internal/toproto6/readresource.go | 36 + .../internal/toproto6/resourcemetadata.go | 19 + .../internal/toproto6/schema.go | 91 + .../internal/toproto6/schema_attribute.go | 93 + .../internal/toproto6/server_capabilities.go | 24 + .../internal/toproto6/state.go | 28 + .../internal/toproto6/upgraderesourcestate.go | 30 + .../toproto6/validatedatasourceconfig.go | 25 + .../toproto6/validateproviderconfig.go | 30 + .../toproto6/validateresourceconfig.go | 25 + .../internal/totftypes/attribute_path.go | 43 + .../internal/totftypes/attribute_path_step.go | 36 + .../internal/totftypes/attribute_paths.go | 33 + .../internal/totftypes/doc.go | 6 + .../terraform-plugin-framework/path/doc.go | 6 + .../path/expression.go | 280 ++ .../path/expression_step.go | 23 + .../expression_step_attribute_name_exact.go | 46 + .../expression_step_element_key_int_any.go | 38 + .../expression_step_element_key_int_exact.go | 50 + .../expression_step_element_key_string_any.go | 38 + ...xpression_step_element_key_string_exact.go | 50 + .../expression_step_element_key_value_any.go | 38 + ...expression_step_element_key_value_exact.go | 54 + .../path/expression_step_parent.go | 38 + .../path/expression_steps.go | 189 + .../path/expressions.go | 80 + .../terraform-plugin-framework/path/path.go | 176 + .../path/path_step.go | 24 + .../path/path_step_attribute_name.go | 42 + .../path/path_step_element_key_int.go | 44 + .../path/path_step_element_key_string.go | 44 + .../path/path_step_element_key_value.go | 51 + .../path/path_steps.go | 101 + .../terraform-plugin-framework/path/paths.go | 67 + .../provider/config_validator.go | 28 + .../provider/configure.go | 48 + .../provider/doc.go | 25 + .../provider/metadata.go | 24 + .../provider/metaschema.go | 27 + .../provider/metaschema/attribute.go | 36 + .../provider/metaschema/bool_attribute.go | 119 + .../provider/metaschema/doc.go | 8 + .../provider/metaschema/float64_attribute.go | 122 + .../provider/metaschema/int64_attribute.go | 122 + .../provider/metaschema/list_attribute.go | 145 + .../metaschema/list_nested_attribute.go | 161 + .../provider/metaschema/map_attribute.go | 148 + .../metaschema/map_nested_attribute.go | 161 + .../provider/metaschema/nested_attribute.go | 14 + .../metaschema/nested_attribute_object.go | 63 + .../provider/metaschema/number_attribute.go | 123 + .../provider/metaschema/object_attribute.go | 147 + .../provider/metaschema/schema.go | 139 + .../provider/metaschema/set_attribute.go | 143 + .../metaschema/set_nested_attribute.go | 156 + .../metaschema/single_nested_attribute.go | 176 + .../provider/metaschema/string_attribute.go | 119 + .../provider/provider.go | 122 + .../provider/schema.go | 27 + .../provider/schema/attribute.go | 36 + .../provider/schema/block.go | 30 + .../provider/schema/bool_attribute.go | 180 + .../provider/schema/doc.go | 8 + .../provider/schema/dynamic_attribute.go | 177 + .../provider/schema/float64_attribute.go | 183 + .../provider/schema/int64_attribute.go | 183 + .../provider/schema/list_attribute.go | 215 ++ .../provider/schema/list_nested_attribute.go | 239 ++ .../provider/schema/list_nested_block.go | 205 ++ .../provider/schema/map_attribute.go | 218 ++ .../provider/schema/map_nested_attribute.go | 239 ++ .../provider/schema/nested_attribute.go | 14 + .../schema/nested_attribute_object.go | 82 + .../provider/schema/nested_block_object.go | 94 + .../provider/schema/number_attribute.go | 184 + .../provider/schema/object_attribute.go | 217 ++ .../provider/schema/schema.go | 185 + .../provider/schema/set_attribute.go | 213 ++ .../provider/schema/set_nested_attribute.go | 235 ++ .../provider/schema/set_nested_block.go | 205 ++ .../schema/single_nested_attribute.go | 239 ++ .../provider/schema/single_nested_block.go | 213 ++ .../provider/schema/string_attribute.go | 180 + .../provider/validate_config.go | 33 + .../providerserver/doc.go | 17 + .../providerserver/providerserver.go | 128 + .../providerserver/serve_opts.go | 87 + .../resource/config_validator.go | 28 + .../resource/configure.go | 34 + .../resource/create.go | 49 + .../resource/delete.go | 52 + .../resource/doc.go | 24 + .../resource/import_state.go | 62 + .../resource/metadata.go | 24 + .../resource/modify_plan.go | 68 + .../resource/move_state.go | 110 + .../resource/read.go | 53 + .../resource/resource.go | 198 ++ .../resource/schema.go | 27 + .../resource/schema/attribute.go | 36 + .../resource/schema/block.go | 30 + .../resource/schema/bool_attribute.go | 240 ++ .../resource/schema/defaults/bool.go | 36 + .../resource/schema/defaults/describer.go | 30 + .../resource/schema/defaults/doc.go | 36 + .../resource/schema/defaults/dynamic.go | 36 + .../resource/schema/defaults/float64.go | 36 + .../resource/schema/defaults/int64.go | 36 + .../resource/schema/defaults/list.go | 36 + .../resource/schema/defaults/map.go | 36 + .../resource/schema/defaults/number.go | 36 + .../resource/schema/defaults/object.go | 36 + .../resource/schema/defaults/set.go | 36 + .../resource/schema/defaults/string.go | 36 + .../resource/schema/doc.go | 8 + .../resource/schema/dynamic_attribute.go | 241 ++ .../resource/schema/float64_attribute.go | 243 ++ .../resource/schema/int64_attribute.go | 243 ++ .../resource/schema/list_attribute.go | 289 ++ .../resource/schema/list_nested_attribute.go | 313 ++ .../resource/schema/list_nested_block.go | 229 ++ .../resource/schema/map_attribute.go | 292 ++ .../resource/schema/map_nested_attribute.go | 313 ++ .../resource/schema/nested_attribute.go | 14 + .../schema/nested_attribute_object.go | 108 + .../resource/schema/nested_block_object.go | 120 + .../resource/schema/number_attribute.go | 244 ++ .../resource/schema/object_attribute.go | 291 ++ .../resource/schema/planmodifier/bool.go | 88 + .../resource/schema/planmodifier/describer.go | 32 + .../resource/schema/planmodifier/doc.go | 36 + .../resource/schema/planmodifier/dynamic.go | 88 + .../resource/schema/planmodifier/float64.go | 88 + .../resource/schema/planmodifier/int64.go | 88 + .../resource/schema/planmodifier/list.go | 88 + .../resource/schema/planmodifier/map.go | 88 + .../resource/schema/planmodifier/number.go | 88 + .../resource/schema/planmodifier/object.go | 88 + .../resource/schema/planmodifier/set.go | 88 + .../resource/schema/planmodifier/string.go | 88 + .../resource/schema/schema.go | 211 ++ .../resource/schema/set_attribute.go | 287 ++ .../resource/schema/set_nested_attribute.go | 308 ++ .../resource/schema/set_nested_block.go | 229 ++ .../schema/single_nested_attribute.go | 324 ++ .../resource/schema/single_nested_block.go | 237 ++ .../resource/schema/string_attribute.go | 240 ++ .../resource/schema/stringdefault/doc.go | 5 + .../schema/stringdefault/static_value.go | 42 + .../resource/schema/stringplanmodifier/doc.go | 5 + .../stringplanmodifier/requires_replace.go | 30 + .../stringplanmodifier/requires_replace_if.go | 73 + .../requires_replace_if_configured.go | 34 + .../requires_replace_if_func.go | 25 + .../use_state_for_unknown.go | 55 + .../resource/state_mover.go | 69 + .../resource/state_upgrader.go | 39 + .../resource/update.go | 61 + .../resource/upgrade_state.go | 74 + .../resource/validate_config.go | 33 + .../schema/validator/bool.go | 46 + .../schema/validator/describer.go | 40 + .../schema/validator/doc.go | 36 + .../schema/validator/dynamic.go | 46 + .../schema/validator/float64.go | 46 + .../schema/validator/int64.go | 46 + .../schema/validator/list.go | 46 + .../schema/validator/map.go | 46 + .../schema/validator/number.go | 46 + .../schema/validator/object.go | 46 + .../schema/validator/set.go | 46 + .../schema/validator/string.go | 46 + .../tfsdk/config.go | 53 + .../tfsdk/convert.go | 31 + .../terraform-plugin-framework/tfsdk/doc.go | 5 + .../terraform-plugin-framework/tfsdk/plan.go | 94 + .../terraform-plugin-framework/tfsdk/state.go | 114 + .../tfsdk/value_as.go | 31 + .../tfsdk/value_from.go | 26 + .../types/basetypes/bool_type.go | 86 + .../types/basetypes/bool_value.go | 175 + .../types/basetypes/doc.go | 7 + .../types/basetypes/dynamic_type.go | 198 ++ .../types/basetypes/dynamic_value.go | 197 ++ .../types/basetypes/float64_type.go | 171 + .../types/basetypes/float64_value.go | 223 ++ .../types/basetypes/int64_type.go | 158 + .../types/basetypes/int64_value.go | 175 + .../types/basetypes/list_type.go | 201 ++ .../types/basetypes/list_value.go | 334 ++ .../types/basetypes/map_type.go | 204 ++ .../types/basetypes/map_value.go | 348 ++ .../types/basetypes/missing_type.go | 59 + .../types/basetypes/missing_value.go | 61 + .../types/basetypes/number_type.go | 87 + .../types/basetypes/number_value.go | 165 + .../types/basetypes/object_type.go | 174 + .../types/basetypes/object_value.go | 400 +++ .../types/basetypes/set_type.go | 236 ++ .../types/basetypes/set_value.go | 342 ++ .../types/basetypes/string_type.go | 86 + .../types/basetypes/string_value.go | 187 + .../types/basetypes/tuple_type.go | 138 + .../types/basetypes/tuple_value.go | 254 ++ .../types/bool_type.go | 8 + .../types/bool_value.go | 31 + .../terraform-plugin-framework/types/doc.go | 11 + .../types/dynamic_type.go | 8 + .../types/dynamic_value.go | 29 + .../types/float64_type.go | 8 + .../types/float64_value.go | 31 + .../types/int64_type.go | 8 + .../types/int64_value.go | 31 + .../types/list_type.go | 8 + .../types/list_value.go | 50 + .../types/map_type.go | 8 + .../types/map_value.go | 50 + .../types/number_type.go | 8 + .../types/number_value.go | 30 + .../types/object_type.go | 8 + .../types/object_value.go | 50 + .../types/set_type.go | 8 + .../types/set_value.go | 50 + .../types/string_type.go | 8 + .../types/string_value.go | 31 + .../types/tuple_type.go | 8 + .../types/tuple_value.go | 39 + .../terraform-plugin-testing/LICENSE | 375 ++ .../terraform-plugin-testing/config/config.go | 38 + .../config/constraints.go | 27 + .../config/directory.go | 63 + .../terraform-plugin-testing/config/doc.go | 6 + .../terraform-plugin-testing/config/file.go | 63 + .../config/variable.go | 324 ++ .../helper/resource/environment_variables.go | 35 + .../helper/resource/error.go | 132 + .../helper/resource/id.go | 62 + .../helper/resource/json.go | 15 + .../helper/resource/plan_checks.go | 28 + .../helper/resource/plugin.go | 492 +++ .../helper/resource/state.go | 292 ++ .../helper/resource/state_checks.go | 29 + .../helper/resource/state_shim.go | 326 ++ .../helper/resource/testcase_providers.go | 61 + .../helper/resource/testcase_validate.go | 113 + .../helper/resource/testing.go | 2097 ++++++++++++ .../helper/resource/testing_config.go | 29 + .../helper/resource/testing_new.go | 668 ++++ .../helper/resource/testing_new_config.go | 410 +++ .../resource/testing_new_import_state.go | 318 ++ .../resource/testing_new_refresh_state.go | 105 + .../helper/resource/testing_sets.go | 492 +++ .../helper/resource/teststep_providers.go | 258 ++ .../helper/resource/teststep_validate.go | 245 ++ .../helper/resource/tfversion_checks.go | 31 + .../helper/resource/wait.go | 135 + .../internal/addrs/doc.go | 20 + .../internal/addrs/instance_key.go | 50 + .../internal/addrs/module.go | 16 + .../internal/addrs/module_instance.go | 242 ++ .../configs/configschema/coerce_value.go | 253 ++ .../internal/configs/configschema/doc.go | 17 + .../configs/configschema/empty_value.go | 62 + .../configs/configschema/implied_type.go | 71 + .../configschema/nestingmode_string.go | 28 + .../internal/configs/configschema/schema.go | 161 + .../internal/configs/hcl2shim/flatmap.go | 426 +++ .../internal/configs/hcl2shim/paths.go | 279 ++ .../internal/configs/hcl2shim/values.go | 233 ++ .../internal/configs/hcl2shim/values_equiv.go | 217 ++ .../internal/logging/context.go | 78 + .../internal/logging/environment_variables.go | 27 + .../internal/logging/helper_resource.go | 35 + .../internal/logging/helper_schema.go | 35 + .../internal/logging/keys.go | 63 + .../internal/plugintest/config.go | 96 + .../internal/plugintest/doc.go | 10 + .../plugintest/environment_variables.go | 119 + .../internal/plugintest/guard.go | 52 + .../internal/plugintest/helper.go | 322 ++ .../internal/plugintest/util.go | 186 + .../internal/plugintest/working_dir.go | 395 +++ .../internal/teststep/config.go | 250 ++ .../internal/teststep/directory.go | 94 + .../internal/teststep/file.go | 94 + .../internal/teststep/string.go | 61 + .../internal/tfdiags/config_traversals.go | 59 + .../internal/tfdiags/contextual.go | 84 + .../internal/tfdiags/diagnostic.go | 26 + .../internal/tfdiags/diagnostic_base.go | 34 + .../internal/tfdiags/diagnostics.go | 196 ++ .../internal/tfdiags/doc.go | 19 + .../internal/tfdiags/error.go | 27 + .../internal/tfdiags/severity_string.go | 29 + .../internal/tfdiags/simple_warning.go | 23 + .../knownvalue/bool.go | 44 + .../knownvalue/check.go | 14 + .../knownvalue/doc.go | 5 + .../knownvalue/float64.go | 51 + .../knownvalue/int64.go | 51 + .../knownvalue/list.go | 67 + .../knownvalue/list_partial.go | 89 + .../knownvalue/list_size.go | 55 + .../knownvalue/map.go | 93 + .../knownvalue/map_partial.go | 80 + .../knownvalue/map_size.go | 55 + .../knownvalue/not_null.go | 32 + .../knownvalue/null.go | 32 + .../knownvalue/number.go | 56 + .../knownvalue/object.go | 94 + .../knownvalue/object_partial.go | 80 + .../knownvalue/set.go | 86 + .../knownvalue/set_partial.go | 72 + .../knownvalue/set_size.go | 55 + .../knownvalue/string.go | 41 + .../knownvalue/string_regexp.go | 45 + .../terraform-plugin-testing/plancheck/doc.go | 5 + .../plancheck/expect_empty_plan.go | 39 + .../plancheck/expect_known_output_value.go | 68 + .../expect_known_output_value_at_path.go | 71 + .../plancheck/expect_known_value.go | 70 + .../plancheck/expect_non_empty_plan.go | 35 + .../plancheck/expect_null_output_value.go | 74 + .../expect_null_output_value_at_path.go | 76 + .../plancheck/expect_resource_action.go | 90 + .../plancheck/expect_sensitive_value.go | 61 + .../plancheck/expect_unknown_output_value.go | 71 + .../expect_unknown_output_value_at_path.go | 73 + .../plancheck/expect_unknown_value.go | 61 + .../plancheck/plan_check.go | 30 + .../plancheck/resource_action.go | 50 + .../statecheck/doc.go | 5 + .../statecheck/expect_known_output_value.go | 76 + .../expect_known_output_value_at_path.go | 78 + .../statecheck/expect_known_value.go | 84 + .../statecheck/expect_sensitive_value.go | 101 + .../statecheck/state_check.go | 30 + .../terraform/diff.go | 1055 ++++++ .../terraform/instancetype.go | 19 + .../terraform/instancetype_string.go | 26 + .../terraform/resource.go | 362 ++ .../terraform/resource_address.go | 229 ++ .../terraform/resource_mode.go | 18 + .../terraform/resource_mode_string.go | 24 + .../terraform/resource_provider.go | 37 + .../terraform/schemas.go | 37 + .../terraform/state.go | 1876 ++++++++++ .../terraform/state_filter.go | 273 ++ .../terraform/unknown_value_walk.go | 85 + .../terraform/util.go | 25 + .../tfjsonpath/doc.go | 6 + .../tfjsonpath/path.go | 135 + .../tfjsonpath/step.go | 14 + .../terraform-plugin-testing/tfversion/all.go | 45 + .../terraform-plugin-testing/tfversion/any.go | 54 + .../terraform-plugin-testing/tfversion/doc.go | 5 + .../tfversion/require_above.go | 35 + .../tfversion/require_below.go | 35 + .../tfversion/require_between.go | 38 + .../tfversion/require_not.go | 32 + .../tfversion/skip_above.go | 35 + .../tfversion/skip_below.go | 35 + .../tfversion/skip_between.go | 38 + .../tfversion/skip_if.go | 32 + .../tfversion/version_check.go | 39 + .../tfversion/versions.go | 38 + .../github.com/mattn/go-runewidth/.travis.yml | 16 + vendor/github.com/mattn/go-runewidth/LICENSE | 21 + .../github.com/mattn/go-runewidth/README.md | 27 + .../github.com/mattn/go-runewidth/go.test.sh | 12 + .../mattn/go-runewidth/runewidth.go | 257 ++ .../mattn/go-runewidth/runewidth_appengine.go | 8 + .../mattn/go-runewidth/runewidth_js.go | 9 + .../mattn/go-runewidth/runewidth_posix.go | 82 + .../mattn/go-runewidth/runewidth_table.go | 437 +++ .../mattn/go-runewidth/runewidth_windows.go | 28 + .../russross/blackfriday/.gitignore | 8 - .../russross/blackfriday/.travis.yml | 18 - .../russross/blackfriday/LICENSE.txt | 28 - .../github.com/russross/blackfriday/README.md | 364 -- .../github.com/russross/blackfriday/block.go | 1480 -------- vendor/github.com/russross/blackfriday/doc.go | 32 - .../github.com/russross/blackfriday/html.go | 945 ----- .../github.com/russross/blackfriday/inline.go | 1154 ------- .../github.com/russross/blackfriday/latex.go | 334 -- .../russross/blackfriday/markdown.go | 943 ----- .../russross/blackfriday/smartypants.go | 430 --- .../github.com/yuin/goldmark-meta/.gitignore | 13 + vendor/github.com/yuin/goldmark-meta/LICENSE | 21 + .../github.com/yuin/goldmark-meta/README.md | 187 + vendor/github.com/yuin/goldmark-meta/meta.go | 320 ++ vendor/github.com/yuin/goldmark/.gitignore | 19 + vendor/github.com/yuin/goldmark/.golangci.yml | 105 + vendor/github.com/yuin/goldmark/LICENSE | 21 + vendor/github.com/yuin/goldmark/Makefile | 13 + vendor/github.com/yuin/goldmark/README.md | 568 +++ vendor/github.com/yuin/goldmark/ast/ast.go | 508 +++ vendor/github.com/yuin/goldmark/ast/block.go | 508 +++ vendor/github.com/yuin/goldmark/ast/inline.go | 549 +++ .../goldmark/extension/ast/definition_list.go | 83 + .../yuin/goldmark/extension/ast/footnote.go | 138 + .../goldmark/extension/ast/strikethrough.go | 29 + .../yuin/goldmark/extension/ast/table.go | 158 + .../yuin/goldmark/extension/ast/tasklist.go | 35 + .../github.com/yuin/goldmark/extension/cjk.go | 72 + .../goldmark/extension/definition_list.go | 274 ++ .../yuin/goldmark/extension/footnote.go | 691 ++++ .../github.com/yuin/goldmark/extension/gfm.go | 18 + .../yuin/goldmark/extension/linkify.go | 322 ++ .../yuin/goldmark/extension/package.go | 2 + .../yuin/goldmark/extension/strikethrough.go | 117 + .../yuin/goldmark/extension/table.go | 564 +++ .../yuin/goldmark/extension/tasklist.go | 120 + .../yuin/goldmark/extension/typographer.go | 348 ++ vendor/github.com/yuin/goldmark/markdown.go | 140 + .../yuin/goldmark/parser/attribute.go | 329 ++ .../yuin/goldmark/parser/atx_heading.go | 248 ++ .../yuin/goldmark/parser/auto_link.go | 42 + .../yuin/goldmark/parser/blockquote.go | 69 + .../yuin/goldmark/parser/code_block.go | 100 + .../yuin/goldmark/parser/code_span.go | 84 + .../yuin/goldmark/parser/delimiter.go | 238 ++ .../yuin/goldmark/parser/emphasis.go | 50 + .../yuin/goldmark/parser/fcode_block.go | 121 + .../yuin/goldmark/parser/html_block.go | 229 ++ .../github.com/yuin/goldmark/parser/link.go | 410 +++ .../yuin/goldmark/parser/link_ref.go | 152 + .../github.com/yuin/goldmark/parser/list.go | 287 ++ .../yuin/goldmark/parser/list_item.go | 90 + .../yuin/goldmark/parser/paragraph.go | 72 + .../github.com/yuin/goldmark/parser/parser.go | 1259 +++++++ .../yuin/goldmark/parser/raw_html.go | 153 + .../yuin/goldmark/parser/setext_headings.go | 126 + .../yuin/goldmark/parser/thematic_break.go | 75 + .../yuin/goldmark/renderer/html/html.go | 1026 ++++++ .../yuin/goldmark/renderer/renderer.go | 174 + .../github.com/yuin/goldmark/text/package.go | 2 + .../github.com/yuin/goldmark/text/reader.go | 660 ++++ .../github.com/yuin/goldmark/text/segment.go | 209 ++ .../yuin/goldmark/util/html5entities.go | 2143 ++++++++++++ .../goldmark/util/unicode_case_folding.go | 1535 +++++++++ vendor/github.com/yuin/goldmark/util/util.go | 982 ++++++ .../github.com/yuin/goldmark/util/util_cjk.go | 469 +++ .../yuin/goldmark/util/util_safe.go | 14 + .../yuin/goldmark/util/util_unsafe.go | 24 + .../goldmark/frontmatter/.changie.yaml | 26 + .../goldmark/frontmatter/.gitignore | 4 + .../goldmark/frontmatter/.golangci.yml | 26 + .../goldmark/frontmatter/CHANGELOG.md | 13 + .../go.abhg.dev/goldmark/frontmatter/LICENSE | 28 + .../go.abhg.dev/goldmark/frontmatter/Makefile | 63 + .../goldmark/frontmatter/README.md | 197 ++ .../go.abhg.dev/goldmark/frontmatter/data.go | 45 + .../go.abhg.dev/goldmark/frontmatter/doc.go | 6 + .../goldmark/frontmatter/extend.go | 70 + .../goldmark/frontmatter/format.go | 58 + .../goldmark/frontmatter/mode_string.go | 24 + .../go.abhg.dev/goldmark/frontmatter/parse.go | 192 ++ .../goldmark/frontmatter/transform.go | 35 + vendor/gopkg.in/yaml.v2/.travis.yml | 16 + vendor/gopkg.in/yaml.v2/LICENSE | 201 ++ vendor/gopkg.in/yaml.v2/LICENSE.libyaml | 31 + vendor/gopkg.in/yaml.v2/NOTICE | 13 + vendor/gopkg.in/yaml.v2/README.md | 133 + vendor/gopkg.in/yaml.v2/apic.go | 740 ++++ vendor/gopkg.in/yaml.v2/decode.go | 815 +++++ vendor/gopkg.in/yaml.v2/emitterc.go | 1685 +++++++++ vendor/gopkg.in/yaml.v2/encode.go | 390 +++ vendor/gopkg.in/yaml.v2/parserc.go | 1095 ++++++ vendor/gopkg.in/yaml.v2/readerc.go | 412 +++ vendor/gopkg.in/yaml.v2/resolve.go | 258 ++ vendor/gopkg.in/yaml.v2/scannerc.go | 2711 +++++++++++++++ vendor/gopkg.in/yaml.v2/sorter.go | 113 + vendor/gopkg.in/yaml.v2/writerc.go | 26 + vendor/gopkg.in/yaml.v2/yaml.go | 466 +++ vendor/gopkg.in/yaml.v2/yamlh.go | 739 ++++ vendor/gopkg.in/yaml.v2/yamlprivateh.go | 173 + vendor/gopkg.in/yaml.v3/LICENSE | 50 + vendor/gopkg.in/yaml.v3/NOTICE | 13 + 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 ++ vendor/modules.txt | 115 +- 909 files changed, 124693 insertions(+), 6549 deletions(-) create mode 100644 vendor/github.com/BurntSushi/toml/.gitignore create mode 100644 vendor/github.com/BurntSushi/toml/COPYING create mode 100644 vendor/github.com/BurntSushi/toml/README.md create mode 100644 vendor/github.com/BurntSushi/toml/decode.go create mode 100644 vendor/github.com/BurntSushi/toml/decode_go116.go create mode 100644 vendor/github.com/BurntSushi/toml/deprecated.go create mode 100644 vendor/github.com/BurntSushi/toml/doc.go create mode 100644 vendor/github.com/BurntSushi/toml/encode.go create mode 100644 vendor/github.com/BurntSushi/toml/error.go create mode 100644 vendor/github.com/BurntSushi/toml/internal/tz.go create mode 100644 vendor/github.com/BurntSushi/toml/lex.go create mode 100644 vendor/github.com/BurntSushi/toml/meta.go create mode 100644 vendor/github.com/BurntSushi/toml/parse.go create mode 100644 vendor/github.com/BurntSushi/toml/type_fields.go create mode 100644 vendor/github.com/BurntSushi/toml/type_toml.go create mode 100644 vendor/github.com/Kunde21/markdownfmt/v3/LICENSE create mode 100644 vendor/github.com/Kunde21/markdownfmt/v3/markdown/doc.go create mode 100644 vendor/github.com/Kunde21/markdownfmt/v3/markdown/indent.go create mode 100644 vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer.go create mode 100644 vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer_heading.go create mode 100644 vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer_table.go create mode 100644 vendor/github.com/Kunde21/markdownfmt/v3/markdown/writer_indent.go create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/.codecov.yml create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/.gitignore create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/LICENSE create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/README.md create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/UPGRADING.md create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/doublestar.go create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/glob.go create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/globoptions.go create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/globwalk.go create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/match.go create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/utils.go create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/validate.go rename vendor/github.com/{mitchellh => hashicorp}/cli/LICENSE (100%) rename vendor/github.com/{mitchellh => hashicorp}/cli/Makefile (100%) rename vendor/github.com/{mitchellh => hashicorp}/cli/README.md (88%) rename vendor/github.com/{mitchellh => hashicorp}/cli/autocomplete.go (94%) rename vendor/github.com/{mitchellh => hashicorp}/cli/cli.go (99%) rename vendor/github.com/{mitchellh => hashicorp}/cli/command.go (97%) rename vendor/github.com/{mitchellh => hashicorp}/cli/command_mock.go (94%) rename vendor/github.com/{mitchellh => hashicorp}/cli/help.go (96%) create mode 100644 vendor/github.com/hashicorp/cli/ui.go rename vendor/github.com/{mitchellh => hashicorp}/cli/ui_colored.go (94%) rename vendor/github.com/{mitchellh/cli/ui.go => hashicorp/cli/ui_common.go} (72%) rename vendor/github.com/{mitchellh => hashicorp}/cli/ui_concurrent.go (92%) create mode 100644 vendor/github.com/hashicorp/cli/ui_js.go rename vendor/github.com/{mitchellh => hashicorp}/cli/ui_mock.go (96%) rename vendor/github.com/{mitchellh => hashicorp}/cli/ui_writer.go (83%) create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/build/version.go delete mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/version.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/directory.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file_extension.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file_mismatch.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/frontmatter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/provider_file.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/migrate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/internal/functionmd/render.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/logger.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/migrate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/schema.go rename vendor/github.com/hashicorp/terraform-plugin-docs/{ => internal}/schemamd/behaviors.go (100%) rename vendor/github.com/hashicorp/terraform-plugin-docs/{ => internal}/schemamd/render.go (92%) rename vendor/github.com/hashicorp/terraform-plugin-docs/{ => internal}/schemamd/write_attribute_description.go (100%) rename vendor/github.com/hashicorp/terraform-plugin-docs/{ => internal}/schemamd/write_block_type_description.go (100%) rename vendor/github.com/hashicorp/terraform-plugin-docs/{ => internal}/schemamd/write_nested_attribute_type_description.go (100%) rename vendor/github.com/hashicorp/terraform-plugin-docs/{ => internal}/schemamd/write_type.go (100%) create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/LICENSE create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/attr/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/attr/type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/attr/value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/attr/value_state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/config_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/configure.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/data_source.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/metadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/read.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/bool_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/dynamic_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/float64_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/int64_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_nested_block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/map_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/map_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_attribute_object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_block_object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/number_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/object_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_nested_block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/single_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/single_nested_block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/string_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/datasource/validate_config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/diag/attribute_error_diagnostic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/diag/attribute_warning_diagnostic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/diag/diagnostic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/diag/diagnostics.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/diag/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/diag/error_diagnostic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/diag/severity.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/diag/warning_diagnostic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/diag/with_path.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/arguments_data.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_parameter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_parameter_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_return.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/definition.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_parameter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_parameter_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_return.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_parameter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_parameter_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_return.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/func_error.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/function.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_parameter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_parameter_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_return.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/list_parameter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/list_parameter_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/list_return.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/map_parameter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/map_parameter_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/map_return.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/metadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/number_parameter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/number_parameter_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/number_return.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/object_parameter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/object_parameter_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/object_return.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/parameter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/parameter_validation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/result_data.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/return.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/run.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/set_parameter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/set_parameter_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/set_return.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/string_parameter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/string_parameter_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/function/string_return.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/applyresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/arguments_data.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/callfunction.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/configureprovider.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/dynamic_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getfunctions.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getmetadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getproviderschema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/importresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/moveresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/plan.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/planresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/prepareproviderconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/providermeta.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/readdatasource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/readresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/upgraderesourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/validatedatasourceconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/validateresourcetypeconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/applyresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/arguments_data.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/callfunction.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/configureprovider.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/dynamic_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getfunctions.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getmetadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getproviderschema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/importresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/moveresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/plan.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/planresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/providermeta.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/readdatasource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/readresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/upgraderesourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validatedatasourceconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validateproviderconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validateresourceconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/attribute_path.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/attribute_path_step.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/parameter_validate_implementation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/return_validate_implementation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_default.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_name_validation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_nesting_mode.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_validate_implementation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block_nested_mode.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block_validate_implementation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/diagnostics.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/errors.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/attribute_plan_modification.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/attribute_validation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/block_plan_modification.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/block_validation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_attribute_object_plan_modification.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_attribute_object_validation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_block_object_plan_modification.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_block_object_validators.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_attribute_object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_block_object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/underlying_attributes.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/validate_implementation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_default.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_description.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_get.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_get_at_path.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_nullify_collection_blocks.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_path_exists.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_path_matches.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_reify_null_collection_blocks.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_set.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_set_at_path.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_terraform_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_valid_path_expression.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/tftypes_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_bool.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_dynamic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_float64.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_int64.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_list.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_map.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_number.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_set.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_string.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attr_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attr_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attribute_plan_modification.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attribute_validation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/block_plan_modification.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/block_validation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/diagnostics.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_plan_modification.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_semantic_equality.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_validation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_applyresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_callfunction.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_capabilities.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_configureprovider.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_createresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_deleteresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_functions.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getfunctions.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getmetadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getproviderschema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_importresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_moveresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_planresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_readdatasource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_readresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_updateresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_upgraderesourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validatedatasourceconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validateproviderconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validateresourceconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwtype/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwtype/static_collection_validation.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/context.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/environment_variables.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/framework.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/keys.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/privatestate/data.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/privatestate/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/serve.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_applyresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_callfunction.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_configureprovider.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getfunctions.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getmetadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getproviderschema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_importresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_moveresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_planresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_prepareproviderconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_readdatasource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_readresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_upgraderesourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_validatedatasourceconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_validateresourcetypeconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/serve.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_applyresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_callfunction.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_configureprovider.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getfunctions.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getmetadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getproviderschema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_importresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_moveresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_planresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_readdatasource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_readresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_upgraderesourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validatedataresourceconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validateproviderconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validateresourceconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/diags.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/generic_attr_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/helpers.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/interfaces.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/into.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/map.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/number.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/options.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/outof.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/pointer.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/primitive.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/slice.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/struct.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/applyresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/callfunction.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/configureprovider.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/datasourcemetadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/diagnostics.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/dynamic_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/function.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/function_errors.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getfunctions.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getmetadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getproviderschema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/importedresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/importresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/moveresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/planresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/prepareproviderconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/readdatasource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/readresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/resourcemetadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/schema_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/server_capabilities.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/upgraderesourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/validatedatasourceconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/validateresourcetypeconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/applyresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/callfunction.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/configureprovider.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/datasourcemetadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/diagnostics.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/dynamic_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/function.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/function_errors.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getfunctions.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getmetadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getproviderschema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/importedresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/importresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/moveresourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/planresourcechange.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/readdatasource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/readresource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/resourcemetadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/schema_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/server_capabilities.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/upgraderesourcestate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validatedatasourceconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validateproviderconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validateresourceconfig.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_path.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_path_step.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_paths.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expression.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_attribute_name_exact.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_int_any.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_int_exact.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_string_any.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_string_exact.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_value_any.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_value_exact.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_parent.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_steps.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/expressions.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/path.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_attribute_name.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_int.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_string.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/path_steps.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/path/paths.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/config_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/configure.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/bool_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/float64_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/int64_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/list_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/list_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/map_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/map_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/nested_attribute_object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/number_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/object_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/set_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/set_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/single_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/string_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/provider.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/bool_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/dynamic_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/float64_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/int64_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_nested_block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/map_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/map_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_attribute_object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_block_object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/number_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/object_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_nested_block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/single_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/single_nested_block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/string_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/provider/validate_config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/providerserver.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/serve_opts.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/config_validator.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/configure.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/create.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/delete.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/import_state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/metadata.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/modify_plan.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/move_state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/read.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/resource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/bool_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/bool.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/describer.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/dynamic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/float64.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/int64.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/list.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/map.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/number.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/set.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/string.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/dynamic_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/float64_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/int64_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_nested_block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/map_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/map_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_attribute_object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_block_object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/number_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/object_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/bool.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/describer.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/dynamic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/float64.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/int64.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/list.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/map.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/number.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/set.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/string.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_nested_block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/single_nested_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/single_nested_block.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/string_attribute.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault/static_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if_configured.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if_func.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/use_state_for_unknown.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/state_mover.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/state_upgrader.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/update.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/upgrade_state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/resource/validate_config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/bool.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/describer.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/dynamic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/float64.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/int64.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/list.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/map.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/number.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/set.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/string.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/convert.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/plan.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/value_as.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/value_from.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/bool_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/bool_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/dynamic_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/dynamic_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/float64_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/float64_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/int64_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/int64_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/list_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/list_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/map_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/map_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/missing_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/missing_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/number_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/number_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/object_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/object_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/set_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/set_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/string_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/string_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/tuple_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/tuple_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/bool_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/bool_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/dynamic_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/dynamic_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/float64_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/float64_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/int64_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/int64_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/list_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/list_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/map_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/map_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/number_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/number_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/object_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/object_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/set_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/set_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/string_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/string_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/tuple_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-framework/types/tuple_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/LICENSE create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/config/config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/config/constraints.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/config/directory.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/config/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/config/file.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/config/variable.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/environment_variables.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/error.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/id.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/json.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/plan_checks.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/plugin.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state_checks.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state_shim.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testcase_providers.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testcase_validate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_import_state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_refresh_state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_sets.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/teststep_providers.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/teststep_validate.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/tfversion_checks.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/wait.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/instance_key.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/module.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/module_instance.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/coerce_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/empty_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/implied_type.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/nestingmode_string.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/flatmap.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/paths.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/values.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/values_equiv.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/context.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/environment_variables.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/helper_resource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/helper_schema.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/keys.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/environment_variables.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/guard.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/helper.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/util.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/working_dir.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/config.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/directory.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/file.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/string.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/config_traversals.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/contextual.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostic.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostic_base.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostics.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/error.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/severity_string.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/simple_warning.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/bool.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/check.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/float64.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/int64.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list_partial.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list_size.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map_partial.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map_size.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/not_null.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/null.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/number.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/object.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/object_partial.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set_partial.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set_size.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/string.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/string_regexp.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_empty_plan.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_output_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_output_value_at_path.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_non_empty_plan.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_null_output_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_null_output_value_at_path.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_resource_action.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_sensitive_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_output_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_output_value_at_path.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/plan_check.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/resource_action.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_output_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_output_value_at_path.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_sensitive_value.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/state_check.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/diff.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/instancetype.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/instancetype_string.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_address.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_mode.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_mode_string.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_provider.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/schemas.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/state.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/state_filter.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/unknown_value_walk.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/terraform/util.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/path.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/step.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/all.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/any.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/doc.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_above.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_below.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_between.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_not.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_above.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_below.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_between.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_if.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/version_check.go create mode 100644 vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/versions.go create mode 100644 vendor/github.com/mattn/go-runewidth/.travis.yml create mode 100644 vendor/github.com/mattn/go-runewidth/LICENSE create mode 100644 vendor/github.com/mattn/go-runewidth/README.md create mode 100644 vendor/github.com/mattn/go-runewidth/go.test.sh create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_appengine.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_js.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_posix.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_table.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_windows.go delete mode 100644 vendor/github.com/russross/blackfriday/.gitignore delete mode 100644 vendor/github.com/russross/blackfriday/.travis.yml delete mode 100644 vendor/github.com/russross/blackfriday/LICENSE.txt delete mode 100644 vendor/github.com/russross/blackfriday/README.md delete mode 100644 vendor/github.com/russross/blackfriday/block.go delete mode 100644 vendor/github.com/russross/blackfriday/doc.go delete mode 100644 vendor/github.com/russross/blackfriday/html.go delete mode 100644 vendor/github.com/russross/blackfriday/inline.go delete mode 100644 vendor/github.com/russross/blackfriday/latex.go delete mode 100644 vendor/github.com/russross/blackfriday/markdown.go delete mode 100644 vendor/github.com/russross/blackfriday/smartypants.go create mode 100644 vendor/github.com/yuin/goldmark-meta/.gitignore create mode 100644 vendor/github.com/yuin/goldmark-meta/LICENSE create mode 100644 vendor/github.com/yuin/goldmark-meta/README.md create mode 100644 vendor/github.com/yuin/goldmark-meta/meta.go create mode 100644 vendor/github.com/yuin/goldmark/.gitignore create mode 100644 vendor/github.com/yuin/goldmark/.golangci.yml create mode 100644 vendor/github.com/yuin/goldmark/LICENSE create mode 100644 vendor/github.com/yuin/goldmark/Makefile create mode 100644 vendor/github.com/yuin/goldmark/README.md create mode 100644 vendor/github.com/yuin/goldmark/ast/ast.go create mode 100644 vendor/github.com/yuin/goldmark/ast/block.go create mode 100644 vendor/github.com/yuin/goldmark/ast/inline.go create mode 100644 vendor/github.com/yuin/goldmark/extension/ast/definition_list.go create mode 100644 vendor/github.com/yuin/goldmark/extension/ast/footnote.go create mode 100644 vendor/github.com/yuin/goldmark/extension/ast/strikethrough.go create mode 100644 vendor/github.com/yuin/goldmark/extension/ast/table.go create mode 100644 vendor/github.com/yuin/goldmark/extension/ast/tasklist.go create mode 100644 vendor/github.com/yuin/goldmark/extension/cjk.go create mode 100644 vendor/github.com/yuin/goldmark/extension/definition_list.go create mode 100644 vendor/github.com/yuin/goldmark/extension/footnote.go create mode 100644 vendor/github.com/yuin/goldmark/extension/gfm.go create mode 100644 vendor/github.com/yuin/goldmark/extension/linkify.go create mode 100644 vendor/github.com/yuin/goldmark/extension/package.go create mode 100644 vendor/github.com/yuin/goldmark/extension/strikethrough.go create mode 100644 vendor/github.com/yuin/goldmark/extension/table.go create mode 100644 vendor/github.com/yuin/goldmark/extension/tasklist.go create mode 100644 vendor/github.com/yuin/goldmark/extension/typographer.go create mode 100644 vendor/github.com/yuin/goldmark/markdown.go create mode 100644 vendor/github.com/yuin/goldmark/parser/attribute.go create mode 100644 vendor/github.com/yuin/goldmark/parser/atx_heading.go create mode 100644 vendor/github.com/yuin/goldmark/parser/auto_link.go create mode 100644 vendor/github.com/yuin/goldmark/parser/blockquote.go create mode 100644 vendor/github.com/yuin/goldmark/parser/code_block.go create mode 100644 vendor/github.com/yuin/goldmark/parser/code_span.go create mode 100644 vendor/github.com/yuin/goldmark/parser/delimiter.go create mode 100644 vendor/github.com/yuin/goldmark/parser/emphasis.go create mode 100644 vendor/github.com/yuin/goldmark/parser/fcode_block.go create mode 100644 vendor/github.com/yuin/goldmark/parser/html_block.go create mode 100644 vendor/github.com/yuin/goldmark/parser/link.go create mode 100644 vendor/github.com/yuin/goldmark/parser/link_ref.go create mode 100644 vendor/github.com/yuin/goldmark/parser/list.go create mode 100644 vendor/github.com/yuin/goldmark/parser/list_item.go create mode 100644 vendor/github.com/yuin/goldmark/parser/paragraph.go create mode 100644 vendor/github.com/yuin/goldmark/parser/parser.go create mode 100644 vendor/github.com/yuin/goldmark/parser/raw_html.go create mode 100644 vendor/github.com/yuin/goldmark/parser/setext_headings.go create mode 100644 vendor/github.com/yuin/goldmark/parser/thematic_break.go create mode 100644 vendor/github.com/yuin/goldmark/renderer/html/html.go create mode 100644 vendor/github.com/yuin/goldmark/renderer/renderer.go create mode 100644 vendor/github.com/yuin/goldmark/text/package.go create mode 100644 vendor/github.com/yuin/goldmark/text/reader.go create mode 100644 vendor/github.com/yuin/goldmark/text/segment.go create mode 100644 vendor/github.com/yuin/goldmark/util/html5entities.go create mode 100644 vendor/github.com/yuin/goldmark/util/unicode_case_folding.go create mode 100644 vendor/github.com/yuin/goldmark/util/util.go create mode 100644 vendor/github.com/yuin/goldmark/util/util_cjk.go create mode 100644 vendor/github.com/yuin/goldmark/util/util_safe.go create mode 100644 vendor/github.com/yuin/goldmark/util/util_unsafe.go create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/.changie.yaml create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/.gitignore create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/.golangci.yml create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/CHANGELOG.md create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/LICENSE create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/Makefile create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/README.md create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/data.go create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/doc.go create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/extend.go create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/format.go create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/mode_string.go create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/parse.go create mode 100644 vendor/go.abhg.dev/goldmark/frontmatter/transform.go create mode 100644 vendor/gopkg.in/yaml.v2/.travis.yml create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE.libyaml create mode 100644 vendor/gopkg.in/yaml.v2/NOTICE create mode 100644 vendor/gopkg.in/yaml.v2/README.md create mode 100644 vendor/gopkg.in/yaml.v2/apic.go create mode 100644 vendor/gopkg.in/yaml.v2/decode.go create mode 100644 vendor/gopkg.in/yaml.v2/emitterc.go create mode 100644 vendor/gopkg.in/yaml.v2/encode.go create mode 100644 vendor/gopkg.in/yaml.v2/parserc.go create mode 100644 vendor/gopkg.in/yaml.v2/readerc.go create mode 100644 vendor/gopkg.in/yaml.v2/resolve.go create mode 100644 vendor/gopkg.in/yaml.v2/scannerc.go create mode 100644 vendor/gopkg.in/yaml.v2/sorter.go create mode 100644 vendor/gopkg.in/yaml.v2/writerc.go create mode 100644 vendor/gopkg.in/yaml.v2/yaml.go create mode 100644 vendor/gopkg.in/yaml.v2/yamlh.go create mode 100644 vendor/gopkg.in/yaml.v2/yamlprivateh.go create mode 100644 vendor/gopkg.in/yaml.v3/LICENSE create mode 100644 vendor/gopkg.in/yaml.v3/NOTICE create mode 100644 vendor/gopkg.in/yaml.v3/README.md create mode 100644 vendor/gopkg.in/yaml.v3/apic.go create mode 100644 vendor/gopkg.in/yaml.v3/decode.go create mode 100644 vendor/gopkg.in/yaml.v3/emitterc.go create mode 100644 vendor/gopkg.in/yaml.v3/encode.go create mode 100644 vendor/gopkg.in/yaml.v3/parserc.go create mode 100644 vendor/gopkg.in/yaml.v3/readerc.go create mode 100644 vendor/gopkg.in/yaml.v3/resolve.go create mode 100644 vendor/gopkg.in/yaml.v3/scannerc.go create mode 100644 vendor/gopkg.in/yaml.v3/sorter.go create mode 100644 vendor/gopkg.in/yaml.v3/writerc.go create mode 100644 vendor/gopkg.in/yaml.v3/yaml.go create mode 100644 vendor/gopkg.in/yaml.v3/yamlh.go create mode 100644 vendor/gopkg.in/yaml.v3/yamlprivateh.go diff --git a/go.mod b/go.mod index dcac12bd..0e4c937e 100644 --- a/go.mod +++ b/go.mod @@ -8,24 +8,32 @@ require ( github.com/1Password/connect-sdk-go v1.5.3 github.com/Masterminds/semver/v3 v3.2.1 github.com/hashicorp/go-uuid v1.0.3 - github.com/hashicorp/terraform-plugin-docs v0.16.0 + github.com/hashicorp/go-version v1.6.0 + github.com/hashicorp/terraform-plugin-docs v0.19.2 + github.com/hashicorp/terraform-plugin-framework v1.8.0 + github.com/hashicorp/terraform-plugin-go v0.22.2 github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 + github.com/hashicorp/terraform-plugin-testing v1.7.0 ) require ( + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/ProtonMail/go-crypto v1.1.0-alpha.0 // indirect + github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect + github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/fatih/color v1.16.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/cli v1.1.6 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -33,13 +41,11 @@ require ( github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.6.0 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hc-install v0.6.3 // indirect + github.com/hashicorp/hc-install v0.6.4 // indirect github.com/hashicorp/hcl/v2 v2.20.1 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.20.0 // indirect github.com/hashicorp/terraform-json v0.21.0 // indirect - github.com/hashicorp/terraform-plugin-go v0.22.2 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect @@ -47,7 +53,7 @@ require ( github.com/imdario/mergo v0.3.15 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mitchellh/cli v1.1.5 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect @@ -57,7 +63,6 @@ require ( github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/posener/complete v1.2.3 // indirect - github.com/russross/blackfriday v1.6.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect @@ -65,7 +70,10 @@ require ( github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/yuin/goldmark v1.7.1 // indirect + github.com/yuin/goldmark-meta v1.1.0 // indirect github.com/zclconf/go-cty v1.14.4 // indirect + go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect @@ -79,4 +87,6 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect google.golang.org/grpc v1.63.2 // indirect google.golang.org/protobuf v1.34.0 // indirect + gopkg.in/yaml.v2 v2.3.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0be63d3b..d005b5f3 100644 --- a/go.sum +++ b/go.sum @@ -2,31 +2,34 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/1Password/connect-sdk-go v1.5.3 h1:KyjJ+kCKj6BwB2Y8tPM1Ixg5uIS6HsB0uWA8U38p/Uk= github.com/1Password/connect-sdk-go v1.5.3/go.mod h1:5rSymY4oIYtS4G3t0oMkGAXBeoYiukV3vkqlnEjIDJs= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0= +github.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v1.1.0-alpha.0 h1:nHGfwXmFvJrSR9xu8qL7BkO4DqTHXE9N5vPhgY2I+j0= -github.com/ProtonMail/go-crypto v1.1.0-alpha.0/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= +github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= @@ -38,7 +41,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= @@ -48,8 +50,8 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66D github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= -github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -64,9 +66,10 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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= +github.com/hashicorp/cli v1.1.6 h1:CMOV+/LJfL1tXCOKrgAX0uRKnzjj/mpmqNXloRSy2K8= +github.com/hashicorp/cli v1.1.6/go.mod h1:MPon5QYlgjjo0BSoAiN0ESeT5fRzDjVRp+uioJ0piz4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -89,8 +92,8 @@ github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/C github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.6.3 h1:yE/r1yJvWbtrJ0STwScgEnCanb0U9v7zp0Gbkmcoxqs= -github.com/hashicorp/hc-install v0.6.3/go.mod h1:KamGdbodYzlufbWh4r9NRo8y6GLHWZP2GBtdnms1Ln0= +github.com/hashicorp/hc-install v0.6.4 h1:QLqlM56/+SIIGvGcfFiwMY3z5WGXT066suo/v9Km8e0= +github.com/hashicorp/hc-install v0.6.4/go.mod h1:05LWLy8TD842OtgcfBbOT0WMoInBMUSHjmDx10zuBIA= github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= @@ -99,22 +102,24 @@ github.com/hashicorp/terraform-exec v0.20.0 h1:DIZnPsqzPGuUnq6cH8jWcPunBfY+C+M8J github.com/hashicorp/terraform-exec v0.20.0/go.mod h1:ckKGkJWbsNqFKV1itgMnE0hY9IYf1HoiekpuN0eWoDw= github.com/hashicorp/terraform-json v0.21.0 h1:9NQxbLNqPbEMze+S6+YluEdXgJmhQykRyRNd+zTI05U= github.com/hashicorp/terraform-json v0.21.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk= -github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI= -github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA= +github.com/hashicorp/terraform-plugin-docs v0.19.2 h1:YjdKa1vuqt9EnPYkkrv9HnGZz175HhSJ7Vsn8yZeWus= +github.com/hashicorp/terraform-plugin-docs v0.19.2/go.mod h1:gad2aP6uObFKhgNE8DR9nsEuEQnibp7il0jZYYOunWY= +github.com/hashicorp/terraform-plugin-framework v1.8.0 h1:P07qy8RKLcoBkCrY2RHJer5AEvJnDuXomBgou6fD8kI= +github.com/hashicorp/terraform-plugin-framework v1.8.0/go.mod h1:/CpTukO88PcL/62noU7cuyaSJ4Rsim+A/pa+3rUVufY= github.com/hashicorp/terraform-plugin-go v0.22.2 h1:5o8uveu6eZUf5J7xGPV0eY0TPXg3qpmwX9sce03Bxnc= github.com/hashicorp/terraform-plugin-go v0.22.2/go.mod h1:drq8Snexp9HsbFZddvyLHN6LuWHHndSQg+gV+FPkcIM= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 h1:qHprzXy/As0rxedphECBEQAh3R4yp6pKksKHcqZx5G8= github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0/go.mod h1:H+8tjs9TjV2w57QFVSMBQacf8k/E1XwLXGCARgViC6A= +github.com/hashicorp/terraform-plugin-testing v1.7.0 h1:I6aeCyZ30z4NiI3tzyDoO6fS7YxP5xSL1ceOon3gTe8= +github.com/hashicorp/terraform-plugin-testing v1.7.0/go.mod h1:sbAreCleJNOCz+y5vVHV8EJkIWZKi/t4ndKiUjM9vao= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= -github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= @@ -133,19 +138,17 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= -github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -170,20 +173,17 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= -github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= -github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= @@ -193,7 +193,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -211,15 +210,19 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= +github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= +github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +go.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ5JnxRw= +go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= @@ -242,7 +245,6 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -293,7 +295,7 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/BurntSushi/toml/.gitignore b/vendor/github.com/BurntSushi/toml/.gitignore new file mode 100644 index 00000000..fe79e3ad --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/.gitignore @@ -0,0 +1,2 @@ +/toml.test +/toml-test diff --git a/vendor/github.com/BurntSushi/toml/COPYING b/vendor/github.com/BurntSushi/toml/COPYING new file mode 100644 index 00000000..01b57432 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/COPYING @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 TOML authors + +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/BurntSushi/toml/README.md b/vendor/github.com/BurntSushi/toml/README.md new file mode 100644 index 00000000..3651cfa9 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/README.md @@ -0,0 +1,120 @@ +TOML stands for Tom's Obvious, Minimal Language. This Go package provides a +reflection interface similar to Go's standard library `json` and `xml` packages. + +Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0). + +Documentation: https://godocs.io/github.com/BurntSushi/toml + +See the [releases page](https://github.com/BurntSushi/toml/releases) for a +changelog; this information is also in the git tag annotations (e.g. `git show +v0.4.0`). + +This library requires Go 1.13 or newer; add it to your go.mod with: + + % go get github.com/BurntSushi/toml@latest + +It also comes with a TOML validator CLI tool: + + % go install github.com/BurntSushi/toml/cmd/tomlv@latest + % tomlv some-toml-file.toml + +### Examples +For the simplest example, consider some TOML file as just a list of keys and +values: + +```toml +Age = 25 +Cats = [ "Cauchy", "Plato" ] +Pi = 3.14 +Perfection = [ 6, 28, 496, 8128 ] +DOB = 1987-07-05T05:45:00Z +``` + +Which can be decoded with: + +```go +type Config struct { + Age int + Cats []string + Pi float64 + Perfection []int + DOB time.Time +} + +var conf Config +_, err := toml.Decode(tomlData, &conf) +``` + +You can also use struct tags if your struct field name doesn't map to a TOML key +value directly: + +```toml +some_key_NAME = "wat" +``` + +```go +type TOML struct { + ObscureKey string `toml:"some_key_NAME"` +} +``` + +Beware that like other decoders **only exported fields** are considered when +encoding and decoding; private fields are silently ignored. + +### Using the `Marshaler` and `encoding.TextUnmarshaler` interfaces +Here's an example that automatically parses values in a `mail.Address`: + +```toml +contacts = [ + "Donald Duck ", + "Scrooge McDuck ", +] +``` + +Can be decoded with: + +```go +// Create address type which satisfies the encoding.TextUnmarshaler interface. +type address struct { + *mail.Address +} + +func (a *address) UnmarshalText(text []byte) error { + var err error + a.Address, err = mail.ParseAddress(string(text)) + return err +} + +// Decode it. +func decode() { + blob := ` + contacts = [ + "Donald Duck ", + "Scrooge McDuck ", + ] + ` + + var contacts struct { + Contacts []address + } + + _, err := toml.Decode(blob, &contacts) + if err != nil { + log.Fatal(err) + } + + for _, c := range contacts.Contacts { + fmt.Printf("%#v\n", c.Address) + } + + // Output: + // &mail.Address{Name:"Donald Duck", Address:"donald@duckburg.com"} + // &mail.Address{Name:"Scrooge McDuck", Address:"scrooge@duckburg.com"} +} +``` + +To target TOML specifically you can implement `UnmarshalTOML` TOML interface in +a similar way. + +### More complex usage +See the [`_example/`](/_example) directory for a more complex example. diff --git a/vendor/github.com/BurntSushi/toml/decode.go b/vendor/github.com/BurntSushi/toml/decode.go new file mode 100644 index 00000000..0ca1dc4f --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/decode.go @@ -0,0 +1,602 @@ +package toml + +import ( + "bytes" + "encoding" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "math" + "os" + "reflect" + "strconv" + "strings" + "time" +) + +// Unmarshaler is the interface implemented by objects that can unmarshal a +// TOML description of themselves. +type Unmarshaler interface { + UnmarshalTOML(interface{}) error +} + +// Unmarshal decodes the contents of data in TOML format into a pointer v. +// +// See [Decoder] for a description of the decoding process. +func Unmarshal(data []byte, v interface{}) error { + _, err := NewDecoder(bytes.NewReader(data)).Decode(v) + return err +} + +// Decode the TOML data in to the pointer v. +// +// See [Decoder] for a description of the decoding process. +func Decode(data string, v interface{}) (MetaData, error) { + return NewDecoder(strings.NewReader(data)).Decode(v) +} + +// DecodeFile reads the contents of a file and decodes it with [Decode]. +func DecodeFile(path string, v interface{}) (MetaData, error) { + fp, err := os.Open(path) + if err != nil { + return MetaData{}, err + } + defer fp.Close() + return NewDecoder(fp).Decode(v) +} + +// Primitive is a TOML value that hasn't been decoded into a Go value. +// +// This type can be used for any value, which will cause decoding to be delayed. +// You can use [PrimitiveDecode] to "manually" decode these values. +// +// NOTE: The underlying representation of a `Primitive` value is subject to +// change. Do not rely on it. +// +// NOTE: Primitive values are still parsed, so using them will only avoid the +// overhead of reflection. They can be useful when you don't know the exact type +// of TOML data until runtime. +type Primitive struct { + undecoded interface{} + context Key +} + +// The significand precision for float32 and float64 is 24 and 53 bits; this is +// the range a natural number can be stored in a float without loss of data. +const ( + maxSafeFloat32Int = 16777215 // 2^24-1 + maxSafeFloat64Int = int64(9007199254740991) // 2^53-1 +) + +// Decoder decodes TOML data. +// +// TOML tables correspond to Go structs or maps; they can be used +// interchangeably, but structs offer better type safety. +// +// TOML table arrays correspond to either a slice of structs or a slice of maps. +// +// TOML datetimes correspond to [time.Time]. Local datetimes are parsed in the +// local timezone. +// +// [time.Duration] types are treated as nanoseconds if the TOML value is an +// integer, or they're parsed with time.ParseDuration() if they're strings. +// +// All other TOML types (float, string, int, bool and array) correspond to the +// obvious Go types. +// +// An exception to the above rules is if a type implements the TextUnmarshaler +// interface, in which case any primitive TOML value (floats, strings, integers, +// booleans, datetimes) will be converted to a []byte and given to the value's +// UnmarshalText method. See the Unmarshaler example for a demonstration with +// email addresses. +// +// ### Key mapping +// +// TOML keys can map to either keys in a Go map or field names in a Go struct. +// The special `toml` struct tag can be used to map TOML keys to struct fields +// that don't match the key name exactly (see the example). A case insensitive +// match to struct names will be tried if an exact match can't be found. +// +// The mapping between TOML values and Go values is loose. That is, there may +// exist TOML values that cannot be placed into your representation, and there +// may be parts of your representation that do not correspond to TOML values. +// This loose mapping can be made stricter by using the IsDefined and/or +// Undecoded methods on the MetaData returned. +// +// This decoder does not handle cyclic types. Decode will not terminate if a +// cyclic type is passed. +type Decoder struct { + r io.Reader +} + +// NewDecoder creates a new Decoder. +func NewDecoder(r io.Reader) *Decoder { + return &Decoder{r: r} +} + +var ( + unmarshalToml = reflect.TypeOf((*Unmarshaler)(nil)).Elem() + unmarshalText = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() + primitiveType = reflect.TypeOf((*Primitive)(nil)).Elem() +) + +// Decode TOML data in to the pointer `v`. +func (dec *Decoder) Decode(v interface{}) (MetaData, error) { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr { + s := "%q" + if reflect.TypeOf(v) == nil { + s = "%v" + } + + return MetaData{}, fmt.Errorf("toml: cannot decode to non-pointer "+s, reflect.TypeOf(v)) + } + if rv.IsNil() { + return MetaData{}, fmt.Errorf("toml: cannot decode to nil value of %q", reflect.TypeOf(v)) + } + + // Check if this is a supported type: struct, map, interface{}, or something + // that implements UnmarshalTOML or UnmarshalText. + rv = indirect(rv) + rt := rv.Type() + if rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map && + !(rv.Kind() == reflect.Interface && rv.NumMethod() == 0) && + !rt.Implements(unmarshalToml) && !rt.Implements(unmarshalText) { + return MetaData{}, fmt.Errorf("toml: cannot decode to type %s", rt) + } + + // TODO: parser should read from io.Reader? Or at the very least, make it + // read from []byte rather than string + data, err := ioutil.ReadAll(dec.r) + if err != nil { + return MetaData{}, err + } + + p, err := parse(string(data)) + if err != nil { + return MetaData{}, err + } + + md := MetaData{ + mapping: p.mapping, + keyInfo: p.keyInfo, + keys: p.ordered, + decoded: make(map[string]struct{}, len(p.ordered)), + context: nil, + data: data, + } + return md, md.unify(p.mapping, rv) +} + +// PrimitiveDecode is just like the other Decode* functions, except it decodes a +// TOML value that has already been parsed. Valid primitive values can *only* be +// obtained from values filled by the decoder functions, including this method. +// (i.e., v may contain more [Primitive] values.) +// +// Meta data for primitive values is included in the meta data returned by the +// Decode* functions with one exception: keys returned by the Undecoded method +// will only reflect keys that were decoded. Namely, any keys hidden behind a +// Primitive will be considered undecoded. Executing this method will update the +// undecoded keys in the meta data. (See the example.) +func (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error { + md.context = primValue.context + defer func() { md.context = nil }() + return md.unify(primValue.undecoded, rvalue(v)) +} + +// unify performs a sort of type unification based on the structure of `rv`, +// which is the client representation. +// +// Any type mismatch produces an error. Finding a type that we don't know +// how to handle produces an unsupported type error. +func (md *MetaData) unify(data interface{}, rv reflect.Value) error { + // Special case. Look for a `Primitive` value. + // TODO: #76 would make this superfluous after implemented. + if rv.Type() == primitiveType { + // Save the undecoded data and the key context into the primitive + // value. + context := make(Key, len(md.context)) + copy(context, md.context) + rv.Set(reflect.ValueOf(Primitive{ + undecoded: data, + context: context, + })) + return nil + } + + rvi := rv.Interface() + if v, ok := rvi.(Unmarshaler); ok { + return v.UnmarshalTOML(data) + } + if v, ok := rvi.(encoding.TextUnmarshaler); ok { + return md.unifyText(data, v) + } + + // TODO: + // The behavior here is incorrect whenever a Go type satisfies the + // encoding.TextUnmarshaler interface but also corresponds to a TOML hash or + // array. In particular, the unmarshaler should only be applied to primitive + // TOML values. But at this point, it will be applied to all kinds of values + // and produce an incorrect error whenever those values are hashes or arrays + // (including arrays of tables). + + k := rv.Kind() + + if k >= reflect.Int && k <= reflect.Uint64 { + return md.unifyInt(data, rv) + } + switch k { + case reflect.Ptr: + elem := reflect.New(rv.Type().Elem()) + err := md.unify(data, reflect.Indirect(elem)) + if err != nil { + return err + } + rv.Set(elem) + return nil + case reflect.Struct: + return md.unifyStruct(data, rv) + case reflect.Map: + return md.unifyMap(data, rv) + case reflect.Array: + return md.unifyArray(data, rv) + case reflect.Slice: + return md.unifySlice(data, rv) + case reflect.String: + return md.unifyString(data, rv) + case reflect.Bool: + return md.unifyBool(data, rv) + case reflect.Interface: + if rv.NumMethod() > 0 { // Only support empty interfaces are supported. + return md.e("unsupported type %s", rv.Type()) + } + return md.unifyAnything(data, rv) + case reflect.Float32, reflect.Float64: + return md.unifyFloat64(data, rv) + } + return md.e("unsupported type %s", rv.Kind()) +} + +func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error { + tmap, ok := mapping.(map[string]interface{}) + if !ok { + if mapping == nil { + return nil + } + return md.e("type mismatch for %s: expected table but found %T", + rv.Type().String(), mapping) + } + + for key, datum := range tmap { + var f *field + fields := cachedTypeFields(rv.Type()) + for i := range fields { + ff := &fields[i] + if ff.name == key { + f = ff + break + } + if f == nil && strings.EqualFold(ff.name, key) { + f = ff + } + } + if f != nil { + subv := rv + for _, i := range f.index { + subv = indirect(subv.Field(i)) + } + + if isUnifiable(subv) { + md.decoded[md.context.add(key).String()] = struct{}{} + md.context = append(md.context, key) + + err := md.unify(datum, subv) + if err != nil { + return err + } + md.context = md.context[0 : len(md.context)-1] + } else if f.name != "" { + return md.e("cannot write unexported field %s.%s", rv.Type().String(), f.name) + } + } + } + return nil +} + +func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error { + keyType := rv.Type().Key().Kind() + if keyType != reflect.String && keyType != reflect.Interface { + return fmt.Errorf("toml: cannot decode to a map with non-string key type (%s in %q)", + keyType, rv.Type()) + } + + tmap, ok := mapping.(map[string]interface{}) + if !ok { + if tmap == nil { + return nil + } + return md.badtype("map", mapping) + } + if rv.IsNil() { + rv.Set(reflect.MakeMap(rv.Type())) + } + for k, v := range tmap { + md.decoded[md.context.add(k).String()] = struct{}{} + md.context = append(md.context, k) + + rvval := reflect.Indirect(reflect.New(rv.Type().Elem())) + + err := md.unify(v, indirect(rvval)) + if err != nil { + return err + } + md.context = md.context[0 : len(md.context)-1] + + rvkey := indirect(reflect.New(rv.Type().Key())) + + switch keyType { + case reflect.Interface: + rvkey.Set(reflect.ValueOf(k)) + case reflect.String: + rvkey.SetString(k) + } + + rv.SetMapIndex(rvkey, rvval) + } + return nil +} + +func (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error { + datav := reflect.ValueOf(data) + if datav.Kind() != reflect.Slice { + if !datav.IsValid() { + return nil + } + return md.badtype("slice", data) + } + if l := datav.Len(); l != rv.Len() { + return md.e("expected array length %d; got TOML array of length %d", rv.Len(), l) + } + return md.unifySliceArray(datav, rv) +} + +func (md *MetaData) unifySlice(data interface{}, rv reflect.Value) error { + datav := reflect.ValueOf(data) + if datav.Kind() != reflect.Slice { + if !datav.IsValid() { + return nil + } + return md.badtype("slice", data) + } + n := datav.Len() + if rv.IsNil() || rv.Cap() < n { + rv.Set(reflect.MakeSlice(rv.Type(), n, n)) + } + rv.SetLen(n) + return md.unifySliceArray(datav, rv) +} + +func (md *MetaData) unifySliceArray(data, rv reflect.Value) error { + l := data.Len() + for i := 0; i < l; i++ { + err := md.unify(data.Index(i).Interface(), indirect(rv.Index(i))) + if err != nil { + return err + } + } + return nil +} + +func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error { + _, ok := rv.Interface().(json.Number) + if ok { + if i, ok := data.(int64); ok { + rv.SetString(strconv.FormatInt(i, 10)) + } else if f, ok := data.(float64); ok { + rv.SetString(strconv.FormatFloat(f, 'f', -1, 64)) + } else { + return md.badtype("string", data) + } + return nil + } + + if s, ok := data.(string); ok { + rv.SetString(s) + return nil + } + return md.badtype("string", data) +} + +func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error { + rvk := rv.Kind() + + if num, ok := data.(float64); ok { + switch rvk { + case reflect.Float32: + if num < -math.MaxFloat32 || num > math.MaxFloat32 { + return md.parseErr(errParseRange{i: num, size: rvk.String()}) + } + fallthrough + case reflect.Float64: + rv.SetFloat(num) + default: + panic("bug") + } + return nil + } + + if num, ok := data.(int64); ok { + if (rvk == reflect.Float32 && (num < -maxSafeFloat32Int || num > maxSafeFloat32Int)) || + (rvk == reflect.Float64 && (num < -maxSafeFloat64Int || num > maxSafeFloat64Int)) { + return md.parseErr(errParseRange{i: num, size: rvk.String()}) + } + rv.SetFloat(float64(num)) + return nil + } + + return md.badtype("float", data) +} + +func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error { + _, ok := rv.Interface().(time.Duration) + if ok { + // Parse as string duration, and fall back to regular integer parsing + // (as nanosecond) if this is not a string. + if s, ok := data.(string); ok { + dur, err := time.ParseDuration(s) + if err != nil { + return md.parseErr(errParseDuration{s}) + } + rv.SetInt(int64(dur)) + return nil + } + } + + num, ok := data.(int64) + if !ok { + return md.badtype("integer", data) + } + + rvk := rv.Kind() + switch { + case rvk >= reflect.Int && rvk <= reflect.Int64: + if (rvk == reflect.Int8 && (num < math.MinInt8 || num > math.MaxInt8)) || + (rvk == reflect.Int16 && (num < math.MinInt16 || num > math.MaxInt16)) || + (rvk == reflect.Int32 && (num < math.MinInt32 || num > math.MaxInt32)) { + return md.parseErr(errParseRange{i: num, size: rvk.String()}) + } + rv.SetInt(num) + case rvk >= reflect.Uint && rvk <= reflect.Uint64: + unum := uint64(num) + if rvk == reflect.Uint8 && (num < 0 || unum > math.MaxUint8) || + rvk == reflect.Uint16 && (num < 0 || unum > math.MaxUint16) || + rvk == reflect.Uint32 && (num < 0 || unum > math.MaxUint32) { + return md.parseErr(errParseRange{i: num, size: rvk.String()}) + } + rv.SetUint(unum) + default: + panic("unreachable") + } + return nil +} + +func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error { + if b, ok := data.(bool); ok { + rv.SetBool(b) + return nil + } + return md.badtype("boolean", data) +} + +func (md *MetaData) unifyAnything(data interface{}, rv reflect.Value) error { + rv.Set(reflect.ValueOf(data)) + return nil +} + +func (md *MetaData) unifyText(data interface{}, v encoding.TextUnmarshaler) error { + var s string + switch sdata := data.(type) { + case Marshaler: + text, err := sdata.MarshalTOML() + if err != nil { + return err + } + s = string(text) + case encoding.TextMarshaler: + text, err := sdata.MarshalText() + if err != nil { + return err + } + s = string(text) + case fmt.Stringer: + s = sdata.String() + case string: + s = sdata + case bool: + s = fmt.Sprintf("%v", sdata) + case int64: + s = fmt.Sprintf("%d", sdata) + case float64: + s = fmt.Sprintf("%f", sdata) + default: + return md.badtype("primitive (string-like)", data) + } + if err := v.UnmarshalText([]byte(s)); err != nil { + return err + } + return nil +} + +func (md *MetaData) badtype(dst string, data interface{}) error { + return md.e("incompatible types: TOML value has type %T; destination has type %s", data, dst) +} + +func (md *MetaData) parseErr(err error) error { + k := md.context.String() + return ParseError{ + LastKey: k, + Position: md.keyInfo[k].pos, + Line: md.keyInfo[k].pos.Line, + err: err, + input: string(md.data), + } +} + +func (md *MetaData) e(format string, args ...interface{}) error { + f := "toml: " + if len(md.context) > 0 { + f = fmt.Sprintf("toml: (last key %q): ", md.context) + p := md.keyInfo[md.context.String()].pos + if p.Line > 0 { + f = fmt.Sprintf("toml: line %d (last key %q): ", p.Line, md.context) + } + } + return fmt.Errorf(f+format, args...) +} + +// rvalue returns a reflect.Value of `v`. All pointers are resolved. +func rvalue(v interface{}) reflect.Value { + return indirect(reflect.ValueOf(v)) +} + +// indirect returns the value pointed to by a pointer. +// +// Pointers are followed until the value is not a pointer. New values are +// allocated for each nil pointer. +// +// An exception to this rule is if the value satisfies an interface of interest +// to us (like encoding.TextUnmarshaler). +func indirect(v reflect.Value) reflect.Value { + if v.Kind() != reflect.Ptr { + if v.CanSet() { + pv := v.Addr() + pvi := pv.Interface() + if _, ok := pvi.(encoding.TextUnmarshaler); ok { + return pv + } + if _, ok := pvi.(Unmarshaler); ok { + return pv + } + } + return v + } + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + return indirect(reflect.Indirect(v)) +} + +func isUnifiable(rv reflect.Value) bool { + if rv.CanSet() { + return true + } + rvi := rv.Interface() + if _, ok := rvi.(encoding.TextUnmarshaler); ok { + return true + } + if _, ok := rvi.(Unmarshaler); ok { + return true + } + return false +} diff --git a/vendor/github.com/BurntSushi/toml/decode_go116.go b/vendor/github.com/BurntSushi/toml/decode_go116.go new file mode 100644 index 00000000..086d0b68 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/decode_go116.go @@ -0,0 +1,19 @@ +//go:build go1.16 +// +build go1.16 + +package toml + +import ( + "io/fs" +) + +// DecodeFS reads the contents of a file from [fs.FS] and decodes it with +// [Decode]. +func DecodeFS(fsys fs.FS, path string, v interface{}) (MetaData, error) { + fp, err := fsys.Open(path) + if err != nil { + return MetaData{}, err + } + defer fp.Close() + return NewDecoder(fp).Decode(v) +} diff --git a/vendor/github.com/BurntSushi/toml/deprecated.go b/vendor/github.com/BurntSushi/toml/deprecated.go new file mode 100644 index 00000000..c6af3f23 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/deprecated.go @@ -0,0 +1,21 @@ +package toml + +import ( + "encoding" + "io" +) + +// Deprecated: use encoding.TextMarshaler +type TextMarshaler encoding.TextMarshaler + +// Deprecated: use encoding.TextUnmarshaler +type TextUnmarshaler encoding.TextUnmarshaler + +// Deprecated: use MetaData.PrimitiveDecode. +func PrimitiveDecode(primValue Primitive, v interface{}) error { + md := MetaData{decoded: make(map[string]struct{})} + return md.unify(primValue.undecoded, rvalue(v)) +} + +// Deprecated: use NewDecoder(reader).Decode(&value). +func DecodeReader(r io.Reader, v interface{}) (MetaData, error) { return NewDecoder(r).Decode(v) } diff --git a/vendor/github.com/BurntSushi/toml/doc.go b/vendor/github.com/BurntSushi/toml/doc.go new file mode 100644 index 00000000..81a7c0fe --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/doc.go @@ -0,0 +1,11 @@ +// Package toml implements decoding and encoding of TOML files. +// +// This package supports TOML v1.0.0, as specified at https://toml.io +// +// There is also support for delaying decoding with the Primitive type, and +// querying the set of keys in a TOML document with the MetaData type. +// +// The github.com/BurntSushi/toml/cmd/tomlv package implements a TOML validator, +// and can be used to verify if TOML document is valid. It can also be used to +// print the type of each key. +package toml diff --git a/vendor/github.com/BurntSushi/toml/encode.go b/vendor/github.com/BurntSushi/toml/encode.go new file mode 100644 index 00000000..930e1d52 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/encode.go @@ -0,0 +1,750 @@ +package toml + +import ( + "bufio" + "encoding" + "encoding/json" + "errors" + "fmt" + "io" + "math" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/BurntSushi/toml/internal" +) + +type tomlEncodeError struct{ error } + +var ( + errArrayNilElement = errors.New("toml: cannot encode array with nil element") + errNonString = errors.New("toml: cannot encode a map with non-string key type") + errNoKey = errors.New("toml: top-level values must be Go maps or structs") + errAnything = errors.New("") // used in testing +) + +var dblQuotedReplacer = strings.NewReplacer( + "\"", "\\\"", + "\\", "\\\\", + "\x00", `\u0000`, + "\x01", `\u0001`, + "\x02", `\u0002`, + "\x03", `\u0003`, + "\x04", `\u0004`, + "\x05", `\u0005`, + "\x06", `\u0006`, + "\x07", `\u0007`, + "\b", `\b`, + "\t", `\t`, + "\n", `\n`, + "\x0b", `\u000b`, + "\f", `\f`, + "\r", `\r`, + "\x0e", `\u000e`, + "\x0f", `\u000f`, + "\x10", `\u0010`, + "\x11", `\u0011`, + "\x12", `\u0012`, + "\x13", `\u0013`, + "\x14", `\u0014`, + "\x15", `\u0015`, + "\x16", `\u0016`, + "\x17", `\u0017`, + "\x18", `\u0018`, + "\x19", `\u0019`, + "\x1a", `\u001a`, + "\x1b", `\u001b`, + "\x1c", `\u001c`, + "\x1d", `\u001d`, + "\x1e", `\u001e`, + "\x1f", `\u001f`, + "\x7f", `\u007f`, +) + +var ( + marshalToml = reflect.TypeOf((*Marshaler)(nil)).Elem() + marshalText = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + timeType = reflect.TypeOf((*time.Time)(nil)).Elem() +) + +// Marshaler is the interface implemented by types that can marshal themselves +// into valid TOML. +type Marshaler interface { + MarshalTOML() ([]byte, error) +} + +// Encoder encodes a Go to a TOML document. +// +// The mapping between Go values and TOML values should be precisely the same as +// for [Decode]. +// +// time.Time is encoded as a RFC 3339 string, and time.Duration as its string +// representation. +// +// The [Marshaler] and [encoding.TextMarshaler] interfaces are supported to +// encoding the value as custom TOML. +// +// If you want to write arbitrary binary data then you will need to use +// something like base64 since TOML does not have any binary types. +// +// When encoding TOML hashes (Go maps or structs), keys without any sub-hashes +// are encoded first. +// +// Go maps will be sorted alphabetically by key for deterministic output. +// +// The toml struct tag can be used to provide the key name; if omitted the +// struct field name will be used. If the "omitempty" option is present the +// following value will be skipped: +// +// - arrays, slices, maps, and string with len of 0 +// - struct with all zero values +// - bool false +// +// If omitzero is given all int and float types with a value of 0 will be +// skipped. +// +// Encoding Go values without a corresponding TOML representation will return an +// error. Examples of this includes maps with non-string keys, slices with nil +// elements, embedded non-struct types, and nested slices containing maps or +// structs. (e.g. [][]map[string]string is not allowed but []map[string]string +// is okay, as is []map[string][]string). +// +// NOTE: only exported keys are encoded due to the use of reflection. Unexported +// keys are silently discarded. +type Encoder struct { + // String to use for a single indentation level; default is two spaces. + Indent string + + w *bufio.Writer + hasWritten bool // written any output to w yet? +} + +// NewEncoder create a new Encoder. +func NewEncoder(w io.Writer) *Encoder { + return &Encoder{ + w: bufio.NewWriter(w), + Indent: " ", + } +} + +// Encode writes a TOML representation of the Go value to the [Encoder]'s writer. +// +// An error is returned if the value given cannot be encoded to a valid TOML +// document. +func (enc *Encoder) Encode(v interface{}) error { + rv := eindirect(reflect.ValueOf(v)) + if err := enc.safeEncode(Key([]string{}), rv); err != nil { + return err + } + return enc.w.Flush() +} + +func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) { + defer func() { + if r := recover(); r != nil { + if terr, ok := r.(tomlEncodeError); ok { + err = terr.error + return + } + panic(r) + } + }() + enc.encode(key, rv) + return nil +} + +func (enc *Encoder) encode(key Key, rv reflect.Value) { + // If we can marshal the type to text, then we use that. This prevents the + // encoder for handling these types as generic structs (or whatever the + // underlying type of a TextMarshaler is). + switch { + case isMarshaler(rv): + enc.writeKeyValue(key, rv, false) + return + case rv.Type() == primitiveType: // TODO: #76 would make this superfluous after implemented. + enc.encode(key, reflect.ValueOf(rv.Interface().(Primitive).undecoded)) + return + } + + k := rv.Kind() + switch k { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, + reflect.Uint64, + reflect.Float32, reflect.Float64, reflect.String, reflect.Bool: + enc.writeKeyValue(key, rv, false) + case reflect.Array, reflect.Slice: + if typeEqual(tomlArrayHash, tomlTypeOfGo(rv)) { + enc.eArrayOfTables(key, rv) + } else { + enc.writeKeyValue(key, rv, false) + } + case reflect.Interface: + if rv.IsNil() { + return + } + enc.encode(key, rv.Elem()) + case reflect.Map: + if rv.IsNil() { + return + } + enc.eTable(key, rv) + case reflect.Ptr: + if rv.IsNil() { + return + } + enc.encode(key, rv.Elem()) + case reflect.Struct: + enc.eTable(key, rv) + default: + encPanic(fmt.Errorf("unsupported type for key '%s': %s", key, k)) + } +} + +// eElement encodes any value that can be an array element. +func (enc *Encoder) eElement(rv reflect.Value) { + switch v := rv.Interface().(type) { + case time.Time: // Using TextMarshaler adds extra quotes, which we don't want. + format := time.RFC3339Nano + switch v.Location() { + case internal.LocalDatetime: + format = "2006-01-02T15:04:05.999999999" + case internal.LocalDate: + format = "2006-01-02" + case internal.LocalTime: + format = "15:04:05.999999999" + } + switch v.Location() { + default: + enc.wf(v.Format(format)) + case internal.LocalDatetime, internal.LocalDate, internal.LocalTime: + enc.wf(v.In(time.UTC).Format(format)) + } + return + case Marshaler: + s, err := v.MarshalTOML() + if err != nil { + encPanic(err) + } + if s == nil { + encPanic(errors.New("MarshalTOML returned nil and no error")) + } + enc.w.Write(s) + return + case encoding.TextMarshaler: + s, err := v.MarshalText() + if err != nil { + encPanic(err) + } + if s == nil { + encPanic(errors.New("MarshalText returned nil and no error")) + } + enc.writeQuoted(string(s)) + return + case time.Duration: + enc.writeQuoted(v.String()) + return + case json.Number: + n, _ := rv.Interface().(json.Number) + + if n == "" { /// Useful zero value. + enc.w.WriteByte('0') + return + } else if v, err := n.Int64(); err == nil { + enc.eElement(reflect.ValueOf(v)) + return + } else if v, err := n.Float64(); err == nil { + enc.eElement(reflect.ValueOf(v)) + return + } + encPanic(fmt.Errorf("unable to convert %q to int64 or float64", n)) + } + + switch rv.Kind() { + case reflect.Ptr: + enc.eElement(rv.Elem()) + return + case reflect.String: + enc.writeQuoted(rv.String()) + case reflect.Bool: + enc.wf(strconv.FormatBool(rv.Bool())) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + enc.wf(strconv.FormatInt(rv.Int(), 10)) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + enc.wf(strconv.FormatUint(rv.Uint(), 10)) + case reflect.Float32: + f := rv.Float() + if math.IsNaN(f) { + enc.wf("nan") + } else if math.IsInf(f, 0) { + enc.wf("%cinf", map[bool]byte{true: '-', false: '+'}[math.Signbit(f)]) + } else { + enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 32))) + } + case reflect.Float64: + f := rv.Float() + if math.IsNaN(f) { + enc.wf("nan") + } else if math.IsInf(f, 0) { + enc.wf("%cinf", map[bool]byte{true: '-', false: '+'}[math.Signbit(f)]) + } else { + enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 64))) + } + case reflect.Array, reflect.Slice: + enc.eArrayOrSliceElement(rv) + case reflect.Struct: + enc.eStruct(nil, rv, true) + case reflect.Map: + enc.eMap(nil, rv, true) + case reflect.Interface: + enc.eElement(rv.Elem()) + default: + encPanic(fmt.Errorf("unexpected type: %T", rv.Interface())) + } +} + +// By the TOML spec, all floats must have a decimal with at least one number on +// either side. +func floatAddDecimal(fstr string) string { + if !strings.Contains(fstr, ".") { + return fstr + ".0" + } + return fstr +} + +func (enc *Encoder) writeQuoted(s string) { + enc.wf("\"%s\"", dblQuotedReplacer.Replace(s)) +} + +func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) { + length := rv.Len() + enc.wf("[") + for i := 0; i < length; i++ { + elem := eindirect(rv.Index(i)) + enc.eElement(elem) + if i != length-1 { + enc.wf(", ") + } + } + enc.wf("]") +} + +func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) { + if len(key) == 0 { + encPanic(errNoKey) + } + for i := 0; i < rv.Len(); i++ { + trv := eindirect(rv.Index(i)) + if isNil(trv) { + continue + } + enc.newline() + enc.wf("%s[[%s]]", enc.indentStr(key), key) + enc.newline() + enc.eMapOrStruct(key, trv, false) + } +} + +func (enc *Encoder) eTable(key Key, rv reflect.Value) { + if len(key) == 1 { + // Output an extra newline between top-level tables. + // (The newline isn't written if nothing else has been written though.) + enc.newline() + } + if len(key) > 0 { + enc.wf("%s[%s]", enc.indentStr(key), key) + enc.newline() + } + enc.eMapOrStruct(key, rv, false) +} + +func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value, inline bool) { + switch rv.Kind() { + case reflect.Map: + enc.eMap(key, rv, inline) + case reflect.Struct: + enc.eStruct(key, rv, inline) + default: + // Should never happen? + panic("eTable: unhandled reflect.Value Kind: " + rv.Kind().String()) + } +} + +func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) { + rt := rv.Type() + if rt.Key().Kind() != reflect.String { + encPanic(errNonString) + } + + // Sort keys so that we have deterministic output. And write keys directly + // underneath this key first, before writing sub-structs or sub-maps. + var mapKeysDirect, mapKeysSub []string + for _, mapKey := range rv.MapKeys() { + k := mapKey.String() + if typeIsTable(tomlTypeOfGo(eindirect(rv.MapIndex(mapKey)))) { + mapKeysSub = append(mapKeysSub, k) + } else { + mapKeysDirect = append(mapKeysDirect, k) + } + } + + var writeMapKeys = func(mapKeys []string, trailC bool) { + sort.Strings(mapKeys) + for i, mapKey := range mapKeys { + val := eindirect(rv.MapIndex(reflect.ValueOf(mapKey))) + if isNil(val) { + continue + } + + if inline { + enc.writeKeyValue(Key{mapKey}, val, true) + if trailC || i != len(mapKeys)-1 { + enc.wf(", ") + } + } else { + enc.encode(key.add(mapKey), val) + } + } + } + + if inline { + enc.wf("{") + } + writeMapKeys(mapKeysDirect, len(mapKeysSub) > 0) + writeMapKeys(mapKeysSub, false) + if inline { + enc.wf("}") + } +} + +const is32Bit = (32 << (^uint(0) >> 63)) == 32 + +func pointerTo(t reflect.Type) reflect.Type { + if t.Kind() == reflect.Ptr { + return pointerTo(t.Elem()) + } + return t +} + +func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) { + // Write keys for fields directly under this key first, because if we write + // a field that creates a new table then all keys under it will be in that + // table (not the one we're writing here). + // + // Fields is a [][]int: for fieldsDirect this always has one entry (the + // struct index). For fieldsSub it contains two entries: the parent field + // index from tv, and the field indexes for the fields of the sub. + var ( + rt = rv.Type() + fieldsDirect, fieldsSub [][]int + addFields func(rt reflect.Type, rv reflect.Value, start []int) + ) + addFields = func(rt reflect.Type, rv reflect.Value, start []int) { + for i := 0; i < rt.NumField(); i++ { + f := rt.Field(i) + isEmbed := f.Anonymous && pointerTo(f.Type).Kind() == reflect.Struct + if f.PkgPath != "" && !isEmbed { /// Skip unexported fields. + continue + } + opts := getOptions(f.Tag) + if opts.skip { + continue + } + + frv := eindirect(rv.Field(i)) + + // Treat anonymous struct fields with tag names as though they are + // not anonymous, like encoding/json does. + // + // Non-struct anonymous fields use the normal encoding logic. + if isEmbed { + if getOptions(f.Tag).name == "" && frv.Kind() == reflect.Struct { + addFields(frv.Type(), frv, append(start, f.Index...)) + continue + } + } + + if typeIsTable(tomlTypeOfGo(frv)) { + fieldsSub = append(fieldsSub, append(start, f.Index...)) + } else { + // Copy so it works correct on 32bit archs; not clear why this + // is needed. See #314, and https://www.reddit.com/r/golang/comments/pnx8v4 + // This also works fine on 64bit, but 32bit archs are somewhat + // rare and this is a wee bit faster. + if is32Bit { + copyStart := make([]int, len(start)) + copy(copyStart, start) + fieldsDirect = append(fieldsDirect, append(copyStart, f.Index...)) + } else { + fieldsDirect = append(fieldsDirect, append(start, f.Index...)) + } + } + } + } + addFields(rt, rv, nil) + + writeFields := func(fields [][]int) { + for _, fieldIndex := range fields { + fieldType := rt.FieldByIndex(fieldIndex) + fieldVal := eindirect(rv.FieldByIndex(fieldIndex)) + + if isNil(fieldVal) { /// Don't write anything for nil fields. + continue + } + + opts := getOptions(fieldType.Tag) + if opts.skip { + continue + } + keyName := fieldType.Name + if opts.name != "" { + keyName = opts.name + } + + if opts.omitempty && enc.isEmpty(fieldVal) { + continue + } + if opts.omitzero && isZero(fieldVal) { + continue + } + + if inline { + enc.writeKeyValue(Key{keyName}, fieldVal, true) + if fieldIndex[0] != len(fields)-1 { + enc.wf(", ") + } + } else { + enc.encode(key.add(keyName), fieldVal) + } + } + } + + if inline { + enc.wf("{") + } + writeFields(fieldsDirect) + writeFields(fieldsSub) + if inline { + enc.wf("}") + } +} + +// tomlTypeOfGo returns the TOML type name of the Go value's type. +// +// It is used to determine whether the types of array elements are mixed (which +// is forbidden). If the Go value is nil, then it is illegal for it to be an +// array element, and valueIsNil is returned as true. +// +// The type may be `nil`, which means no concrete TOML type could be found. +func tomlTypeOfGo(rv reflect.Value) tomlType { + if isNil(rv) || !rv.IsValid() { + return nil + } + + if rv.Kind() == reflect.Struct { + if rv.Type() == timeType { + return tomlDatetime + } + if isMarshaler(rv) { + return tomlString + } + return tomlHash + } + + if isMarshaler(rv) { + return tomlString + } + + switch rv.Kind() { + case reflect.Bool: + return tomlBool + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, + reflect.Uint64: + return tomlInteger + case reflect.Float32, reflect.Float64: + return tomlFloat + case reflect.Array, reflect.Slice: + if isTableArray(rv) { + return tomlArrayHash + } + return tomlArray + case reflect.Ptr, reflect.Interface: + return tomlTypeOfGo(rv.Elem()) + case reflect.String: + return tomlString + case reflect.Map: + return tomlHash + default: + encPanic(errors.New("unsupported type: " + rv.Kind().String())) + panic("unreachable") + } +} + +func isMarshaler(rv reflect.Value) bool { + return rv.Type().Implements(marshalText) || rv.Type().Implements(marshalToml) +} + +// isTableArray reports if all entries in the array or slice are a table. +func isTableArray(arr reflect.Value) bool { + if isNil(arr) || !arr.IsValid() || arr.Len() == 0 { + return false + } + + ret := true + for i := 0; i < arr.Len(); i++ { + tt := tomlTypeOfGo(eindirect(arr.Index(i))) + // Don't allow nil. + if tt == nil { + encPanic(errArrayNilElement) + } + + if ret && !typeEqual(tomlHash, tt) { + ret = false + } + } + return ret +} + +type tagOptions struct { + skip bool // "-" + name string + omitempty bool + omitzero bool +} + +func getOptions(tag reflect.StructTag) tagOptions { + t := tag.Get("toml") + if t == "-" { + return tagOptions{skip: true} + } + var opts tagOptions + parts := strings.Split(t, ",") + opts.name = parts[0] + for _, s := range parts[1:] { + switch s { + case "omitempty": + opts.omitempty = true + case "omitzero": + opts.omitzero = true + } + } + return opts +} + +func isZero(rv reflect.Value) bool { + switch rv.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return rv.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return rv.Uint() == 0 + case reflect.Float32, reflect.Float64: + return rv.Float() == 0.0 + } + return false +} + +func (enc *Encoder) isEmpty(rv reflect.Value) bool { + switch rv.Kind() { + case reflect.Array, reflect.Slice, reflect.Map, reflect.String: + return rv.Len() == 0 + case reflect.Struct: + if rv.Type().Comparable() { + return reflect.Zero(rv.Type()).Interface() == rv.Interface() + } + // Need to also check if all the fields are empty, otherwise something + // like this with uncomparable types will always return true: + // + // type a struct{ field b } + // type b struct{ s []string } + // s := a{field: b{s: []string{"AAA"}}} + for i := 0; i < rv.NumField(); i++ { + if !enc.isEmpty(rv.Field(i)) { + return false + } + } + return true + case reflect.Bool: + return !rv.Bool() + } + return false +} + +func (enc *Encoder) newline() { + if enc.hasWritten { + enc.wf("\n") + } +} + +// Write a key/value pair: +// +// key = +// +// This is also used for "k = v" in inline tables; so something like this will +// be written in three calls: +// +// ┌───────────────────┐ +// │ ┌───┐ ┌────┐│ +// v v v v vv +// key = {k = 1, k2 = 2} +func (enc *Encoder) writeKeyValue(key Key, val reflect.Value, inline bool) { + if len(key) == 0 { + encPanic(errNoKey) + } + enc.wf("%s%s = ", enc.indentStr(key), key.maybeQuoted(len(key)-1)) + enc.eElement(val) + if !inline { + enc.newline() + } +} + +func (enc *Encoder) wf(format string, v ...interface{}) { + _, err := fmt.Fprintf(enc.w, format, v...) + if err != nil { + encPanic(err) + } + enc.hasWritten = true +} + +func (enc *Encoder) indentStr(key Key) string { + return strings.Repeat(enc.Indent, len(key)-1) +} + +func encPanic(err error) { + panic(tomlEncodeError{err}) +} + +// Resolve any level of pointers to the actual value (e.g. **string → string). +func eindirect(v reflect.Value) reflect.Value { + if v.Kind() != reflect.Ptr && v.Kind() != reflect.Interface { + if isMarshaler(v) { + return v + } + if v.CanAddr() { /// Special case for marshalers; see #358. + if pv := v.Addr(); isMarshaler(pv) { + return pv + } + } + return v + } + + if v.IsNil() { + return v + } + + return eindirect(v.Elem()) +} + +func isNil(rv reflect.Value) bool { + switch rv.Kind() { + case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return rv.IsNil() + default: + return false + } +} diff --git a/vendor/github.com/BurntSushi/toml/error.go b/vendor/github.com/BurntSushi/toml/error.go new file mode 100644 index 00000000..f4f390e6 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/error.go @@ -0,0 +1,279 @@ +package toml + +import ( + "fmt" + "strings" +) + +// ParseError is returned when there is an error parsing the TOML syntax such as +// invalid syntax, duplicate keys, etc. +// +// In addition to the error message itself, you can also print detailed location +// information with context by using [ErrorWithPosition]: +// +// toml: error: Key 'fruit' was already created and cannot be used as an array. +// +// At line 4, column 2-7: +// +// 2 | fruit = [] +// 3 | +// 4 | [[fruit]] # Not allowed +// ^^^^^ +// +// [ErrorWithUsage] can be used to print the above with some more detailed usage +// guidance: +// +// toml: error: newlines not allowed within inline tables +// +// At line 1, column 18: +// +// 1 | x = [{ key = 42 # +// ^ +// +// Error help: +// +// Inline tables must always be on a single line: +// +// table = {key = 42, second = 43} +// +// It is invalid to split them over multiple lines like so: +// +// # INVALID +// table = { +// key = 42, +// second = 43 +// } +// +// Use regular for this: +// +// [table] +// key = 42 +// second = 43 +type ParseError struct { + Message string // Short technical message. + Usage string // Longer message with usage guidance; may be blank. + Position Position // Position of the error + LastKey string // Last parsed key, may be blank. + + // Line the error occurred. + // + // Deprecated: use [Position]. + Line int + + err error + input string +} + +// Position of an error. +type Position struct { + Line int // Line number, starting at 1. + Start int // Start of error, as byte offset starting at 0. + Len int // Lenght in bytes. +} + +func (pe ParseError) Error() string { + msg := pe.Message + if msg == "" { // Error from errorf() + msg = pe.err.Error() + } + + if pe.LastKey == "" { + return fmt.Sprintf("toml: line %d: %s", pe.Position.Line, msg) + } + return fmt.Sprintf("toml: line %d (last key %q): %s", + pe.Position.Line, pe.LastKey, msg) +} + +// ErrorWithUsage() returns the error with detailed location context. +// +// See the documentation on [ParseError]. +func (pe ParseError) ErrorWithPosition() string { + if pe.input == "" { // Should never happen, but just in case. + return pe.Error() + } + + var ( + lines = strings.Split(pe.input, "\n") + col = pe.column(lines) + b = new(strings.Builder) + ) + + msg := pe.Message + if msg == "" { + msg = pe.err.Error() + } + + // TODO: don't show control characters as literals? This may not show up + // well everywhere. + + if pe.Position.Len == 1 { + fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d:\n\n", + msg, pe.Position.Line, col+1) + } else { + fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d-%d:\n\n", + msg, pe.Position.Line, col, col+pe.Position.Len) + } + if pe.Position.Line > 2 { + fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-2, lines[pe.Position.Line-3]) + } + if pe.Position.Line > 1 { + fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-1, lines[pe.Position.Line-2]) + } + fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line, lines[pe.Position.Line-1]) + fmt.Fprintf(b, "% 10s%s%s\n", "", strings.Repeat(" ", col), strings.Repeat("^", pe.Position.Len)) + return b.String() +} + +// ErrorWithUsage() returns the error with detailed location context and usage +// guidance. +// +// See the documentation on [ParseError]. +func (pe ParseError) ErrorWithUsage() string { + m := pe.ErrorWithPosition() + if u, ok := pe.err.(interface{ Usage() string }); ok && u.Usage() != "" { + lines := strings.Split(strings.TrimSpace(u.Usage()), "\n") + for i := range lines { + if lines[i] != "" { + lines[i] = " " + lines[i] + } + } + return m + "Error help:\n\n" + strings.Join(lines, "\n") + "\n" + } + return m +} + +func (pe ParseError) column(lines []string) int { + var pos, col int + for i := range lines { + ll := len(lines[i]) + 1 // +1 for the removed newline + if pos+ll >= pe.Position.Start { + col = pe.Position.Start - pos + if col < 0 { // Should never happen, but just in case. + col = 0 + } + break + } + pos += ll + } + + return col +} + +type ( + errLexControl struct{ r rune } + errLexEscape struct{ r rune } + errLexUTF8 struct{ b byte } + errLexInvalidNum struct{ v string } + errLexInvalidDate struct{ v string } + errLexInlineTableNL struct{} + errLexStringNL struct{} + errParseRange struct { + i interface{} // int or float + size string // "int64", "uint16", etc. + } + errParseDuration struct{ d string } +) + +func (e errLexControl) Error() string { + return fmt.Sprintf("TOML files cannot contain control characters: '0x%02x'", e.r) +} +func (e errLexControl) Usage() string { return "" } + +func (e errLexEscape) Error() string { return fmt.Sprintf(`invalid escape in string '\%c'`, e.r) } +func (e errLexEscape) Usage() string { return usageEscape } +func (e errLexUTF8) Error() string { return fmt.Sprintf("invalid UTF-8 byte: 0x%02x", e.b) } +func (e errLexUTF8) Usage() string { return "" } +func (e errLexInvalidNum) Error() string { return fmt.Sprintf("invalid number: %q", e.v) } +func (e errLexInvalidNum) Usage() string { return "" } +func (e errLexInvalidDate) Error() string { return fmt.Sprintf("invalid date: %q", e.v) } +func (e errLexInvalidDate) Usage() string { return "" } +func (e errLexInlineTableNL) Error() string { return "newlines not allowed within inline tables" } +func (e errLexInlineTableNL) Usage() string { return usageInlineNewline } +func (e errLexStringNL) Error() string { return "strings cannot contain newlines" } +func (e errLexStringNL) Usage() string { return usageStringNewline } +func (e errParseRange) Error() string { return fmt.Sprintf("%v is out of range for %s", e.i, e.size) } +func (e errParseRange) Usage() string { return usageIntOverflow } +func (e errParseDuration) Error() string { return fmt.Sprintf("invalid duration: %q", e.d) } +func (e errParseDuration) Usage() string { return usageDuration } + +const usageEscape = ` +A '\' inside a "-delimited string is interpreted as an escape character. + +The following escape sequences are supported: +\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX + +To prevent a '\' from being recognized as an escape character, use either: + +- a ' or '''-delimited string; escape characters aren't processed in them; or +- write two backslashes to get a single backslash: '\\'. + +If you're trying to add a Windows path (e.g. "C:\Users\martin") then using '/' +instead of '\' will usually also work: "C:/Users/martin". +` + +const usageInlineNewline = ` +Inline tables must always be on a single line: + + table = {key = 42, second = 43} + +It is invalid to split them over multiple lines like so: + + # INVALID + table = { + key = 42, + second = 43 + } + +Use regular for this: + + [table] + key = 42 + second = 43 +` + +const usageStringNewline = ` +Strings must always be on a single line, and cannot span more than one line: + + # INVALID + string = "Hello, + world!" + +Instead use """ or ''' to split strings over multiple lines: + + string = """Hello, + world!""" +` + +const usageIntOverflow = ` +This number is too large; this may be an error in the TOML, but it can also be a +bug in the program that uses too small of an integer. + +The maximum and minimum values are: + + size │ lowest │ highest + ───────┼────────────────┼────────── + int8 │ -128 │ 127 + int16 │ -32,768 │ 32,767 + int32 │ -2,147,483,648 │ 2,147,483,647 + int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷ + uint8 │ 0 │ 255 + uint16 │ 0 │ 65535 + uint32 │ 0 │ 4294967295 + uint64 │ 0 │ 1.8 × 10¹⁸ + +int refers to int32 on 32-bit systems and int64 on 64-bit systems. +` + +const usageDuration = ` +A duration must be as "number", without any spaces. Valid units are: + + ns nanoseconds (billionth of a second) + us, µs microseconds (millionth of a second) + ms milliseconds (thousands of a second) + s seconds + m minutes + h hours + +You can combine multiple units; for example "5m10s" for 5 minutes and 10 +seconds. +` diff --git a/vendor/github.com/BurntSushi/toml/internal/tz.go b/vendor/github.com/BurntSushi/toml/internal/tz.go new file mode 100644 index 00000000..022f15bc --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/internal/tz.go @@ -0,0 +1,36 @@ +package internal + +import "time" + +// Timezones used for local datetime, date, and time TOML types. +// +// The exact way times and dates without a timezone should be interpreted is not +// well-defined in the TOML specification and left to the implementation. These +// defaults to current local timezone offset of the computer, but this can be +// changed by changing these variables before decoding. +// +// TODO: +// Ideally we'd like to offer people the ability to configure the used timezone +// by setting Decoder.Timezone and Encoder.Timezone; however, this is a bit +// tricky: the reason we use three different variables for this is to support +// round-tripping – without these specific TZ names we wouldn't know which +// format to use. +// +// There isn't a good way to encode this right now though, and passing this sort +// of information also ties in to various related issues such as string format +// encoding, encoding of comments, etc. +// +// So, for the time being, just put this in internal until we can write a good +// comprehensive API for doing all of this. +// +// The reason they're exported is because they're referred from in e.g. +// internal/tag. +// +// Note that this behaviour is valid according to the TOML spec as the exact +// behaviour is left up to implementations. +var ( + localOffset = func() int { _, o := time.Now().Zone(); return o }() + LocalDatetime = time.FixedZone("datetime-local", localOffset) + LocalDate = time.FixedZone("date-local", localOffset) + LocalTime = time.FixedZone("time-local", localOffset) +) diff --git a/vendor/github.com/BurntSushi/toml/lex.go b/vendor/github.com/BurntSushi/toml/lex.go new file mode 100644 index 00000000..d4d70871 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/lex.go @@ -0,0 +1,1233 @@ +package toml + +import ( + "fmt" + "reflect" + "runtime" + "strings" + "unicode" + "unicode/utf8" +) + +type itemType int + +const ( + itemError itemType = iota + itemNIL // used in the parser to indicate no type + itemEOF + itemText + itemString + itemRawString + itemMultilineString + itemRawMultilineString + itemBool + itemInteger + itemFloat + itemDatetime + itemArray // the start of an array + itemArrayEnd + itemTableStart + itemTableEnd + itemArrayTableStart + itemArrayTableEnd + itemKeyStart + itemKeyEnd + itemCommentStart + itemInlineTableStart + itemInlineTableEnd +) + +const eof = 0 + +type stateFn func(lx *lexer) stateFn + +func (p Position) String() string { + return fmt.Sprintf("at line %d; start %d; length %d", p.Line, p.Start, p.Len) +} + +type lexer struct { + input string + start int + pos int + line int + state stateFn + items chan item + + // Allow for backing up up to 4 runes. This is necessary because TOML + // contains 3-rune tokens (""" and '''). + prevWidths [4]int + nprev int // how many of prevWidths are in use + atEOF bool // If we emit an eof, we can still back up, but it is not OK to call next again. + + // A stack of state functions used to maintain context. + // + // The idea is to reuse parts of the state machine in various places. For + // example, values can appear at the top level or within arbitrarily nested + // arrays. The last state on the stack is used after a value has been lexed. + // Similarly for comments. + stack []stateFn +} + +type item struct { + typ itemType + val string + err error + pos Position +} + +func (lx *lexer) nextItem() item { + for { + select { + case item := <-lx.items: + return item + default: + lx.state = lx.state(lx) + //fmt.Printf(" STATE %-24s current: %-10s stack: %s\n", lx.state, lx.current(), lx.stack) + } + } +} + +func lex(input string) *lexer { + lx := &lexer{ + input: input, + state: lexTop, + items: make(chan item, 10), + stack: make([]stateFn, 0, 10), + line: 1, + } + return lx +} + +func (lx *lexer) push(state stateFn) { + lx.stack = append(lx.stack, state) +} + +func (lx *lexer) pop() stateFn { + if len(lx.stack) == 0 { + return lx.errorf("BUG in lexer: no states to pop") + } + last := lx.stack[len(lx.stack)-1] + lx.stack = lx.stack[0 : len(lx.stack)-1] + return last +} + +func (lx *lexer) current() string { + return lx.input[lx.start:lx.pos] +} + +func (lx lexer) getPos() Position { + p := Position{ + Line: lx.line, + Start: lx.start, + Len: lx.pos - lx.start, + } + if p.Len <= 0 { + p.Len = 1 + } + return p +} + +func (lx *lexer) emit(typ itemType) { + // Needed for multiline strings ending with an incomplete UTF-8 sequence. + if lx.start > lx.pos { + lx.error(errLexUTF8{lx.input[lx.pos]}) + return + } + lx.items <- item{typ: typ, pos: lx.getPos(), val: lx.current()} + lx.start = lx.pos +} + +func (lx *lexer) emitTrim(typ itemType) { + lx.items <- item{typ: typ, pos: lx.getPos(), val: strings.TrimSpace(lx.current())} + lx.start = lx.pos +} + +func (lx *lexer) next() (r rune) { + if lx.atEOF { + panic("BUG in lexer: next called after EOF") + } + if lx.pos >= len(lx.input) { + lx.atEOF = true + return eof + } + + if lx.input[lx.pos] == '\n' { + lx.line++ + } + lx.prevWidths[3] = lx.prevWidths[2] + lx.prevWidths[2] = lx.prevWidths[1] + lx.prevWidths[1] = lx.prevWidths[0] + if lx.nprev < 4 { + lx.nprev++ + } + + r, w := utf8.DecodeRuneInString(lx.input[lx.pos:]) + if r == utf8.RuneError { + lx.error(errLexUTF8{lx.input[lx.pos]}) + return utf8.RuneError + } + + // Note: don't use peek() here, as this calls next(). + if isControl(r) || (r == '\r' && (len(lx.input)-1 == lx.pos || lx.input[lx.pos+1] != '\n')) { + lx.errorControlChar(r) + return utf8.RuneError + } + + lx.prevWidths[0] = w + lx.pos += w + return r +} + +// ignore skips over the pending input before this point. +func (lx *lexer) ignore() { + lx.start = lx.pos +} + +// backup steps back one rune. Can be called 4 times between calls to next. +func (lx *lexer) backup() { + if lx.atEOF { + lx.atEOF = false + return + } + if lx.nprev < 1 { + panic("BUG in lexer: backed up too far") + } + w := lx.prevWidths[0] + lx.prevWidths[0] = lx.prevWidths[1] + lx.prevWidths[1] = lx.prevWidths[2] + lx.prevWidths[2] = lx.prevWidths[3] + lx.nprev-- + + lx.pos -= w + if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' { + lx.line-- + } +} + +// accept consumes the next rune if it's equal to `valid`. +func (lx *lexer) accept(valid rune) bool { + if lx.next() == valid { + return true + } + lx.backup() + return false +} + +// peek returns but does not consume the next rune in the input. +func (lx *lexer) peek() rune { + r := lx.next() + lx.backup() + return r +} + +// skip ignores all input that matches the given predicate. +func (lx *lexer) skip(pred func(rune) bool) { + for { + r := lx.next() + if pred(r) { + continue + } + lx.backup() + lx.ignore() + return + } +} + +// error stops all lexing by emitting an error and returning `nil`. +// +// Note that any value that is a character is escaped if it's a special +// character (newlines, tabs, etc.). +func (lx *lexer) error(err error) stateFn { + if lx.atEOF { + return lx.errorPrevLine(err) + } + lx.items <- item{typ: itemError, pos: lx.getPos(), err: err} + return nil +} + +// errorfPrevline is like error(), but sets the position to the last column of +// the previous line. +// +// This is so that unexpected EOF or NL errors don't show on a new blank line. +func (lx *lexer) errorPrevLine(err error) stateFn { + pos := lx.getPos() + pos.Line-- + pos.Len = 1 + pos.Start = lx.pos - 1 + lx.items <- item{typ: itemError, pos: pos, err: err} + return nil +} + +// errorPos is like error(), but allows explicitly setting the position. +func (lx *lexer) errorPos(start, length int, err error) stateFn { + pos := lx.getPos() + pos.Start = start + pos.Len = length + lx.items <- item{typ: itemError, pos: pos, err: err} + return nil +} + +// errorf is like error, and creates a new error. +func (lx *lexer) errorf(format string, values ...interface{}) stateFn { + if lx.atEOF { + pos := lx.getPos() + pos.Line-- + pos.Len = 1 + pos.Start = lx.pos - 1 + lx.items <- item{typ: itemError, pos: pos, err: fmt.Errorf(format, values...)} + return nil + } + lx.items <- item{typ: itemError, pos: lx.getPos(), err: fmt.Errorf(format, values...)} + return nil +} + +func (lx *lexer) errorControlChar(cc rune) stateFn { + return lx.errorPos(lx.pos-1, 1, errLexControl{cc}) +} + +// lexTop consumes elements at the top level of TOML data. +func lexTop(lx *lexer) stateFn { + r := lx.next() + if isWhitespace(r) || isNL(r) { + return lexSkip(lx, lexTop) + } + switch r { + case '#': + lx.push(lexTop) + return lexCommentStart + case '[': + return lexTableStart + case eof: + if lx.pos > lx.start { + return lx.errorf("unexpected EOF") + } + lx.emit(itemEOF) + return nil + } + + // At this point, the only valid item can be a key, so we back up + // and let the key lexer do the rest. + lx.backup() + lx.push(lexTopEnd) + return lexKeyStart +} + +// lexTopEnd is entered whenever a top-level item has been consumed. (A value +// or a table.) It must see only whitespace, and will turn back to lexTop +// upon a newline. If it sees EOF, it will quit the lexer successfully. +func lexTopEnd(lx *lexer) stateFn { + r := lx.next() + switch { + case r == '#': + // a comment will read to a newline for us. + lx.push(lexTop) + return lexCommentStart + case isWhitespace(r): + return lexTopEnd + case isNL(r): + lx.ignore() + return lexTop + case r == eof: + lx.emit(itemEOF) + return nil + } + return lx.errorf( + "expected a top-level item to end with a newline, comment, or EOF, but got %q instead", + r) +} + +// lexTable lexes the beginning of a table. Namely, it makes sure that +// it starts with a character other than '.' and ']'. +// It assumes that '[' has already been consumed. +// It also handles the case that this is an item in an array of tables. +// e.g., '[[name]]'. +func lexTableStart(lx *lexer) stateFn { + if lx.peek() == '[' { + lx.next() + lx.emit(itemArrayTableStart) + lx.push(lexArrayTableEnd) + } else { + lx.emit(itemTableStart) + lx.push(lexTableEnd) + } + return lexTableNameStart +} + +func lexTableEnd(lx *lexer) stateFn { + lx.emit(itemTableEnd) + return lexTopEnd +} + +func lexArrayTableEnd(lx *lexer) stateFn { + if r := lx.next(); r != ']' { + return lx.errorf("expected end of table array name delimiter ']', but got %q instead", r) + } + lx.emit(itemArrayTableEnd) + return lexTopEnd +} + +func lexTableNameStart(lx *lexer) stateFn { + lx.skip(isWhitespace) + switch r := lx.peek(); { + case r == ']' || r == eof: + return lx.errorf("unexpected end of table name (table names cannot be empty)") + case r == '.': + return lx.errorf("unexpected table separator (table names cannot be empty)") + case r == '"' || r == '\'': + lx.ignore() + lx.push(lexTableNameEnd) + return lexQuotedName + default: + lx.push(lexTableNameEnd) + return lexBareName + } +} + +// lexTableNameEnd reads the end of a piece of a table name, optionally +// consuming whitespace. +func lexTableNameEnd(lx *lexer) stateFn { + lx.skip(isWhitespace) + switch r := lx.next(); { + case isWhitespace(r): + return lexTableNameEnd + case r == '.': + lx.ignore() + return lexTableNameStart + case r == ']': + return lx.pop() + default: + return lx.errorf("expected '.' or ']' to end table name, but got %q instead", r) + } +} + +// lexBareName lexes one part of a key or table. +// +// It assumes that at least one valid character for the table has already been +// read. +// +// Lexes only one part, e.g. only 'a' inside 'a.b'. +func lexBareName(lx *lexer) stateFn { + r := lx.next() + if isBareKeyChar(r) { + return lexBareName + } + lx.backup() + lx.emit(itemText) + return lx.pop() +} + +// lexBareName lexes one part of a key or table. +// +// It assumes that at least one valid character for the table has already been +// read. +// +// Lexes only one part, e.g. only '"a"' inside '"a".b'. +func lexQuotedName(lx *lexer) stateFn { + r := lx.next() + switch { + case isWhitespace(r): + return lexSkip(lx, lexValue) + case r == '"': + lx.ignore() // ignore the '"' + return lexString + case r == '\'': + lx.ignore() // ignore the "'" + return lexRawString + case r == eof: + return lx.errorf("unexpected EOF; expected value") + default: + return lx.errorf("expected value but found %q instead", r) + } +} + +// lexKeyStart consumes all key parts until a '='. +func lexKeyStart(lx *lexer) stateFn { + lx.skip(isWhitespace) + switch r := lx.peek(); { + case r == '=' || r == eof: + return lx.errorf("unexpected '=': key name appears blank") + case r == '.': + return lx.errorf("unexpected '.': keys cannot start with a '.'") + case r == '"' || r == '\'': + lx.ignore() + fallthrough + default: // Bare key + lx.emit(itemKeyStart) + return lexKeyNameStart + } +} + +func lexKeyNameStart(lx *lexer) stateFn { + lx.skip(isWhitespace) + switch r := lx.peek(); { + case r == '=' || r == eof: + return lx.errorf("unexpected '='") + case r == '.': + return lx.errorf("unexpected '.'") + case r == '"' || r == '\'': + lx.ignore() + lx.push(lexKeyEnd) + return lexQuotedName + default: + lx.push(lexKeyEnd) + return lexBareName + } +} + +// lexKeyEnd consumes the end of a key and trims whitespace (up to the key +// separator). +func lexKeyEnd(lx *lexer) stateFn { + lx.skip(isWhitespace) + switch r := lx.next(); { + case isWhitespace(r): + return lexSkip(lx, lexKeyEnd) + case r == eof: + return lx.errorf("unexpected EOF; expected key separator '='") + case r == '.': + lx.ignore() + return lexKeyNameStart + case r == '=': + lx.emit(itemKeyEnd) + return lexSkip(lx, lexValue) + default: + return lx.errorf("expected '.' or '=', but got %q instead", r) + } +} + +// lexValue starts the consumption of a value anywhere a value is expected. +// lexValue will ignore whitespace. +// After a value is lexed, the last state on the next is popped and returned. +func lexValue(lx *lexer) stateFn { + // We allow whitespace to precede a value, but NOT newlines. + // In array syntax, the array states are responsible for ignoring newlines. + r := lx.next() + switch { + case isWhitespace(r): + return lexSkip(lx, lexValue) + case isDigit(r): + lx.backup() // avoid an extra state and use the same as above + return lexNumberOrDateStart + } + switch r { + case '[': + lx.ignore() + lx.emit(itemArray) + return lexArrayValue + case '{': + lx.ignore() + lx.emit(itemInlineTableStart) + return lexInlineTableValue + case '"': + if lx.accept('"') { + if lx.accept('"') { + lx.ignore() // Ignore """ + return lexMultilineString + } + lx.backup() + } + lx.ignore() // ignore the '"' + return lexString + case '\'': + if lx.accept('\'') { + if lx.accept('\'') { + lx.ignore() // Ignore """ + return lexMultilineRawString + } + lx.backup() + } + lx.ignore() // ignore the "'" + return lexRawString + case '.': // special error case, be kind to users + return lx.errorf("floats must start with a digit, not '.'") + case 'i', 'n': + if (lx.accept('n') && lx.accept('f')) || (lx.accept('a') && lx.accept('n')) { + lx.emit(itemFloat) + return lx.pop() + } + case '-', '+': + return lexDecimalNumberStart + } + if unicode.IsLetter(r) { + // Be permissive here; lexBool will give a nice error if the + // user wrote something like + // x = foo + // (i.e. not 'true' or 'false' but is something else word-like.) + lx.backup() + return lexBool + } + if r == eof { + return lx.errorf("unexpected EOF; expected value") + } + return lx.errorf("expected value but found %q instead", r) +} + +// lexArrayValue consumes one value in an array. It assumes that '[' or ',' +// have already been consumed. All whitespace and newlines are ignored. +func lexArrayValue(lx *lexer) stateFn { + r := lx.next() + switch { + case isWhitespace(r) || isNL(r): + return lexSkip(lx, lexArrayValue) + case r == '#': + lx.push(lexArrayValue) + return lexCommentStart + case r == ',': + return lx.errorf("unexpected comma") + case r == ']': + return lexArrayEnd + } + + lx.backup() + lx.push(lexArrayValueEnd) + return lexValue +} + +// lexArrayValueEnd consumes everything between the end of an array value and +// the next value (or the end of the array): it ignores whitespace and newlines +// and expects either a ',' or a ']'. +func lexArrayValueEnd(lx *lexer) stateFn { + switch r := lx.next(); { + case isWhitespace(r) || isNL(r): + return lexSkip(lx, lexArrayValueEnd) + case r == '#': + lx.push(lexArrayValueEnd) + return lexCommentStart + case r == ',': + lx.ignore() + return lexArrayValue // move on to the next value + case r == ']': + return lexArrayEnd + default: + return lx.errorf("expected a comma (',') or array terminator (']'), but got %s", runeOrEOF(r)) + } +} + +// lexArrayEnd finishes the lexing of an array. +// It assumes that a ']' has just been consumed. +func lexArrayEnd(lx *lexer) stateFn { + lx.ignore() + lx.emit(itemArrayEnd) + return lx.pop() +} + +// lexInlineTableValue consumes one key/value pair in an inline table. +// It assumes that '{' or ',' have already been consumed. Whitespace is ignored. +func lexInlineTableValue(lx *lexer) stateFn { + r := lx.next() + switch { + case isWhitespace(r): + return lexSkip(lx, lexInlineTableValue) + case isNL(r): + return lx.errorPrevLine(errLexInlineTableNL{}) + case r == '#': + lx.push(lexInlineTableValue) + return lexCommentStart + case r == ',': + return lx.errorf("unexpected comma") + case r == '}': + return lexInlineTableEnd + } + lx.backup() + lx.push(lexInlineTableValueEnd) + return lexKeyStart +} + +// lexInlineTableValueEnd consumes everything between the end of an inline table +// key/value pair and the next pair (or the end of the table): +// it ignores whitespace and expects either a ',' or a '}'. +func lexInlineTableValueEnd(lx *lexer) stateFn { + switch r := lx.next(); { + case isWhitespace(r): + return lexSkip(lx, lexInlineTableValueEnd) + case isNL(r): + return lx.errorPrevLine(errLexInlineTableNL{}) + case r == '#': + lx.push(lexInlineTableValueEnd) + return lexCommentStart + case r == ',': + lx.ignore() + lx.skip(isWhitespace) + if lx.peek() == '}' { + return lx.errorf("trailing comma not allowed in inline tables") + } + return lexInlineTableValue + case r == '}': + return lexInlineTableEnd + default: + return lx.errorf("expected a comma or an inline table terminator '}', but got %s instead", runeOrEOF(r)) + } +} + +func runeOrEOF(r rune) string { + if r == eof { + return "end of file" + } + return "'" + string(r) + "'" +} + +// lexInlineTableEnd finishes the lexing of an inline table. +// It assumes that a '}' has just been consumed. +func lexInlineTableEnd(lx *lexer) stateFn { + lx.ignore() + lx.emit(itemInlineTableEnd) + return lx.pop() +} + +// lexString consumes the inner contents of a string. It assumes that the +// beginning '"' has already been consumed and ignored. +func lexString(lx *lexer) stateFn { + r := lx.next() + switch { + case r == eof: + return lx.errorf(`unexpected EOF; expected '"'`) + case isNL(r): + return lx.errorPrevLine(errLexStringNL{}) + case r == '\\': + lx.push(lexString) + return lexStringEscape + case r == '"': + lx.backup() + lx.emit(itemString) + lx.next() + lx.ignore() + return lx.pop() + } + return lexString +} + +// lexMultilineString consumes the inner contents of a string. It assumes that +// the beginning '"""' has already been consumed and ignored. +func lexMultilineString(lx *lexer) stateFn { + r := lx.next() + switch r { + default: + return lexMultilineString + case eof: + return lx.errorf(`unexpected EOF; expected '"""'`) + case '\\': + return lexMultilineStringEscape + case '"': + /// Found " → try to read two more "". + if lx.accept('"') { + if lx.accept('"') { + /// Peek ahead: the string can contain " and "", including at the + /// end: """str""""" + /// 6 or more at the end, however, is an error. + if lx.peek() == '"' { + /// Check if we already lexed 5 's; if so we have 6 now, and + /// that's just too many man! + /// + /// Second check is for the edge case: + /// + /// two quotes allowed. + /// vv + /// """lol \"""""" + /// ^^ ^^^---- closing three + /// escaped + /// + /// But ugly, but it works + if strings.HasSuffix(lx.current(), `"""""`) && !strings.HasSuffix(lx.current(), `\"""""`) { + return lx.errorf(`unexpected '""""""'`) + } + lx.backup() + lx.backup() + return lexMultilineString + } + + lx.backup() /// backup: don't include the """ in the item. + lx.backup() + lx.backup() + lx.emit(itemMultilineString) + lx.next() /// Read over ''' again and discard it. + lx.next() + lx.next() + lx.ignore() + return lx.pop() + } + lx.backup() + } + return lexMultilineString + } +} + +// lexRawString consumes a raw string. Nothing can be escaped in such a string. +// It assumes that the beginning "'" has already been consumed and ignored. +func lexRawString(lx *lexer) stateFn { + r := lx.next() + switch { + default: + return lexRawString + case r == eof: + return lx.errorf(`unexpected EOF; expected "'"`) + case isNL(r): + return lx.errorPrevLine(errLexStringNL{}) + case r == '\'': + lx.backup() + lx.emit(itemRawString) + lx.next() + lx.ignore() + return lx.pop() + } +} + +// lexMultilineRawString consumes a raw string. Nothing can be escaped in such +// a string. It assumes that the beginning ''' has already been consumed and +// ignored. +func lexMultilineRawString(lx *lexer) stateFn { + r := lx.next() + switch r { + default: + return lexMultilineRawString + case eof: + return lx.errorf(`unexpected EOF; expected "'''"`) + case '\'': + /// Found ' → try to read two more ''. + if lx.accept('\'') { + if lx.accept('\'') { + /// Peek ahead: the string can contain ' and '', including at the + /// end: '''str''''' + /// 6 or more at the end, however, is an error. + if lx.peek() == '\'' { + /// Check if we already lexed 5 's; if so we have 6 now, and + /// that's just too many man! + if strings.HasSuffix(lx.current(), "'''''") { + return lx.errorf(`unexpected "''''''"`) + } + lx.backup() + lx.backup() + return lexMultilineRawString + } + + lx.backup() /// backup: don't include the ''' in the item. + lx.backup() + lx.backup() + lx.emit(itemRawMultilineString) + lx.next() /// Read over ''' again and discard it. + lx.next() + lx.next() + lx.ignore() + return lx.pop() + } + lx.backup() + } + return lexMultilineRawString + } +} + +// lexMultilineStringEscape consumes an escaped character. It assumes that the +// preceding '\\' has already been consumed. +func lexMultilineStringEscape(lx *lexer) stateFn { + if isNL(lx.next()) { /// \ escaping newline. + return lexMultilineString + } + lx.backup() + lx.push(lexMultilineString) + return lexStringEscape(lx) +} + +func lexStringEscape(lx *lexer) stateFn { + r := lx.next() + switch r { + case 'b': + fallthrough + case 't': + fallthrough + case 'n': + fallthrough + case 'f': + fallthrough + case 'r': + fallthrough + case '"': + fallthrough + case ' ', '\t': + // Inside """ .. """ strings you can use \ to escape newlines, and any + // amount of whitespace can be between the \ and \n. + fallthrough + case '\\': + return lx.pop() + case 'u': + return lexShortUnicodeEscape + case 'U': + return lexLongUnicodeEscape + } + return lx.error(errLexEscape{r}) +} + +func lexShortUnicodeEscape(lx *lexer) stateFn { + var r rune + for i := 0; i < 4; i++ { + r = lx.next() + if !isHexadecimal(r) { + return lx.errorf( + `expected four hexadecimal digits after '\u', but got %q instead`, + lx.current()) + } + } + return lx.pop() +} + +func lexLongUnicodeEscape(lx *lexer) stateFn { + var r rune + for i := 0; i < 8; i++ { + r = lx.next() + if !isHexadecimal(r) { + return lx.errorf( + `expected eight hexadecimal digits after '\U', but got %q instead`, + lx.current()) + } + } + return lx.pop() +} + +// lexNumberOrDateStart processes the first character of a value which begins +// with a digit. It exists to catch values starting with '0', so that +// lexBaseNumberOrDate can differentiate base prefixed integers from other +// types. +func lexNumberOrDateStart(lx *lexer) stateFn { + r := lx.next() + switch r { + case '0': + return lexBaseNumberOrDate + } + + if !isDigit(r) { + // The only way to reach this state is if the value starts + // with a digit, so specifically treat anything else as an + // error. + return lx.errorf("expected a digit but got %q", r) + } + + return lexNumberOrDate +} + +// lexNumberOrDate consumes either an integer, float or datetime. +func lexNumberOrDate(lx *lexer) stateFn { + r := lx.next() + if isDigit(r) { + return lexNumberOrDate + } + switch r { + case '-', ':': + return lexDatetime + case '_': + return lexDecimalNumber + case '.', 'e', 'E': + return lexFloat + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexDatetime consumes a Datetime, to a first approximation. +// The parser validates that it matches one of the accepted formats. +func lexDatetime(lx *lexer) stateFn { + r := lx.next() + if isDigit(r) { + return lexDatetime + } + switch r { + case '-', ':', 'T', 't', ' ', '.', 'Z', 'z', '+': + return lexDatetime + } + + lx.backup() + lx.emitTrim(itemDatetime) + return lx.pop() +} + +// lexHexInteger consumes a hexadecimal integer after seeing the '0x' prefix. +func lexHexInteger(lx *lexer) stateFn { + r := lx.next() + if isHexadecimal(r) { + return lexHexInteger + } + switch r { + case '_': + return lexHexInteger + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexOctalInteger consumes an octal integer after seeing the '0o' prefix. +func lexOctalInteger(lx *lexer) stateFn { + r := lx.next() + if isOctal(r) { + return lexOctalInteger + } + switch r { + case '_': + return lexOctalInteger + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexBinaryInteger consumes a binary integer after seeing the '0b' prefix. +func lexBinaryInteger(lx *lexer) stateFn { + r := lx.next() + if isBinary(r) { + return lexBinaryInteger + } + switch r { + case '_': + return lexBinaryInteger + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexDecimalNumber consumes a decimal float or integer. +func lexDecimalNumber(lx *lexer) stateFn { + r := lx.next() + if isDigit(r) { + return lexDecimalNumber + } + switch r { + case '.', 'e', 'E': + return lexFloat + case '_': + return lexDecimalNumber + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexDecimalNumber consumes the first digit of a number beginning with a sign. +// It assumes the sign has already been consumed. Values which start with a sign +// are only allowed to be decimal integers or floats. +// +// The special "nan" and "inf" values are also recognized. +func lexDecimalNumberStart(lx *lexer) stateFn { + r := lx.next() + + // Special error cases to give users better error messages + switch r { + case 'i': + if !lx.accept('n') || !lx.accept('f') { + return lx.errorf("invalid float: '%s'", lx.current()) + } + lx.emit(itemFloat) + return lx.pop() + case 'n': + if !lx.accept('a') || !lx.accept('n') { + return lx.errorf("invalid float: '%s'", lx.current()) + } + lx.emit(itemFloat) + return lx.pop() + case '0': + p := lx.peek() + switch p { + case 'b', 'o', 'x': + return lx.errorf("cannot use sign with non-decimal numbers: '%s%c'", lx.current(), p) + } + case '.': + return lx.errorf("floats must start with a digit, not '.'") + } + + if isDigit(r) { + return lexDecimalNumber + } + + return lx.errorf("expected a digit but got %q", r) +} + +// lexBaseNumberOrDate differentiates between the possible values which +// start with '0'. It assumes that before reaching this state, the initial '0' +// has been consumed. +func lexBaseNumberOrDate(lx *lexer) stateFn { + r := lx.next() + // Note: All datetimes start with at least two digits, so we don't + // handle date characters (':', '-', etc.) here. + if isDigit(r) { + return lexNumberOrDate + } + switch r { + case '_': + // Can only be decimal, because there can't be an underscore + // between the '0' and the base designator, and dates can't + // contain underscores. + return lexDecimalNumber + case '.', 'e', 'E': + return lexFloat + case 'b': + r = lx.peek() + if !isBinary(r) { + lx.errorf("not a binary number: '%s%c'", lx.current(), r) + } + return lexBinaryInteger + case 'o': + r = lx.peek() + if !isOctal(r) { + lx.errorf("not an octal number: '%s%c'", lx.current(), r) + } + return lexOctalInteger + case 'x': + r = lx.peek() + if !isHexadecimal(r) { + lx.errorf("not a hexidecimal number: '%s%c'", lx.current(), r) + } + return lexHexInteger + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexFloat consumes the elements of a float. It allows any sequence of +// float-like characters, so floats emitted by the lexer are only a first +// approximation and must be validated by the parser. +func lexFloat(lx *lexer) stateFn { + r := lx.next() + if isDigit(r) { + return lexFloat + } + switch r { + case '_', '.', '-', '+', 'e', 'E': + return lexFloat + } + + lx.backup() + lx.emit(itemFloat) + return lx.pop() +} + +// lexBool consumes a bool string: 'true' or 'false. +func lexBool(lx *lexer) stateFn { + var rs []rune + for { + r := lx.next() + if !unicode.IsLetter(r) { + lx.backup() + break + } + rs = append(rs, r) + } + s := string(rs) + switch s { + case "true", "false": + lx.emit(itemBool) + return lx.pop() + } + return lx.errorf("expected value but found %q instead", s) +} + +// lexCommentStart begins the lexing of a comment. It will emit +// itemCommentStart and consume no characters, passing control to lexComment. +func lexCommentStart(lx *lexer) stateFn { + lx.ignore() + lx.emit(itemCommentStart) + return lexComment +} + +// lexComment lexes an entire comment. It assumes that '#' has been consumed. +// It will consume *up to* the first newline character, and pass control +// back to the last state on the stack. +func lexComment(lx *lexer) stateFn { + switch r := lx.next(); { + case isNL(r) || r == eof: + lx.backup() + lx.emit(itemText) + return lx.pop() + default: + return lexComment + } +} + +// lexSkip ignores all slurped input and moves on to the next state. +func lexSkip(lx *lexer, nextState stateFn) stateFn { + lx.ignore() + return nextState +} + +func (s stateFn) String() string { + name := runtime.FuncForPC(reflect.ValueOf(s).Pointer()).Name() + if i := strings.LastIndexByte(name, '.'); i > -1 { + name = name[i+1:] + } + if s == nil { + name = "" + } + return name + "()" +} + +func (itype itemType) String() string { + switch itype { + case itemError: + return "Error" + case itemNIL: + return "NIL" + case itemEOF: + return "EOF" + case itemText: + return "Text" + case itemString, itemRawString, itemMultilineString, itemRawMultilineString: + return "String" + case itemBool: + return "Bool" + case itemInteger: + return "Integer" + case itemFloat: + return "Float" + case itemDatetime: + return "DateTime" + case itemTableStart: + return "TableStart" + case itemTableEnd: + return "TableEnd" + case itemKeyStart: + return "KeyStart" + case itemKeyEnd: + return "KeyEnd" + case itemArray: + return "Array" + case itemArrayEnd: + return "ArrayEnd" + case itemCommentStart: + return "CommentStart" + case itemInlineTableStart: + return "InlineTableStart" + case itemInlineTableEnd: + return "InlineTableEnd" + } + panic(fmt.Sprintf("BUG: Unknown type '%d'.", int(itype))) +} + +func (item item) String() string { + return fmt.Sprintf("(%s, %s)", item.typ.String(), item.val) +} + +func isWhitespace(r rune) bool { return r == '\t' || r == ' ' } +func isNL(r rune) bool { return r == '\n' || r == '\r' } +func isControl(r rune) bool { // Control characters except \t, \r, \n + switch r { + case '\t', '\r', '\n': + return false + default: + return (r >= 0x00 && r <= 0x1f) || r == 0x7f + } +} +func isDigit(r rune) bool { return r >= '0' && r <= '9' } +func isBinary(r rune) bool { return r == '0' || r == '1' } +func isOctal(r rune) bool { return r >= '0' && r <= '7' } +func isHexadecimal(r rune) bool { + return (r >= '0' && r <= '9') || (r >= 'a' && r <= 'f') || (r >= 'A' && r <= 'F') +} +func isBareKeyChar(r rune) bool { + return (r >= 'A' && r <= 'Z') || + (r >= 'a' && r <= 'z') || + (r >= '0' && r <= '9') || + r == '_' || r == '-' +} diff --git a/vendor/github.com/BurntSushi/toml/meta.go b/vendor/github.com/BurntSushi/toml/meta.go new file mode 100644 index 00000000..71847a04 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/meta.go @@ -0,0 +1,121 @@ +package toml + +import ( + "strings" +) + +// MetaData allows access to meta information about TOML data that's not +// accessible otherwise. +// +// It allows checking if a key is defined in the TOML data, whether any keys +// were undecoded, and the TOML type of a key. +type MetaData struct { + context Key // Used only during decoding. + + keyInfo map[string]keyInfo + mapping map[string]interface{} + keys []Key + decoded map[string]struct{} + data []byte // Input file; for errors. +} + +// IsDefined reports if the key exists in the TOML data. +// +// The key should be specified hierarchically, for example to access the TOML +// key "a.b.c" you would use IsDefined("a", "b", "c"). Keys are case sensitive. +// +// Returns false for an empty key. +func (md *MetaData) IsDefined(key ...string) bool { + if len(key) == 0 { + return false + } + + var ( + hash map[string]interface{} + ok bool + hashOrVal interface{} = md.mapping + ) + for _, k := range key { + if hash, ok = hashOrVal.(map[string]interface{}); !ok { + return false + } + if hashOrVal, ok = hash[k]; !ok { + return false + } + } + return true +} + +// Type returns a string representation of the type of the key specified. +// +// Type will return the empty string if given an empty key or a key that does +// not exist. Keys are case sensitive. +func (md *MetaData) Type(key ...string) string { + if ki, ok := md.keyInfo[Key(key).String()]; ok { + return ki.tomlType.typeString() + } + return "" +} + +// Keys returns a slice of every key in the TOML data, including key groups. +// +// Each key is itself a slice, where the first element is the top of the +// hierarchy and the last is the most specific. The list will have the same +// order as the keys appeared in the TOML data. +// +// All keys returned are non-empty. +func (md *MetaData) Keys() []Key { + return md.keys +} + +// Undecoded returns all keys that have not been decoded in the order in which +// they appear in the original TOML document. +// +// This includes keys that haven't been decoded because of a [Primitive] value. +// Once the Primitive value is decoded, the keys will be considered decoded. +// +// Also note that decoding into an empty interface will result in no decoding, +// and so no keys will be considered decoded. +// +// In this sense, the Undecoded keys correspond to keys in the TOML document +// that do not have a concrete type in your representation. +func (md *MetaData) Undecoded() []Key { + undecoded := make([]Key, 0, len(md.keys)) + for _, key := range md.keys { + if _, ok := md.decoded[key.String()]; !ok { + undecoded = append(undecoded, key) + } + } + return undecoded +} + +// Key represents any TOML key, including key groups. Use [MetaData.Keys] to get +// values of this type. +type Key []string + +func (k Key) String() string { + ss := make([]string, len(k)) + for i := range k { + ss[i] = k.maybeQuoted(i) + } + return strings.Join(ss, ".") +} + +func (k Key) maybeQuoted(i int) string { + if k[i] == "" { + return `""` + } + for _, c := range k[i] { + if !isBareKeyChar(c) { + return `"` + dblQuotedReplacer.Replace(k[i]) + `"` + } + } + return k[i] +} + +func (k Key) add(piece string) Key { + newKey := make(Key, len(k)+1) + copy(newKey, k) + newKey[len(k)] = piece + return newKey +} diff --git a/vendor/github.com/BurntSushi/toml/parse.go b/vendor/github.com/BurntSushi/toml/parse.go new file mode 100644 index 00000000..d2542d6f --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/parse.go @@ -0,0 +1,781 @@ +package toml + +import ( + "fmt" + "strconv" + "strings" + "time" + "unicode/utf8" + + "github.com/BurntSushi/toml/internal" +) + +type parser struct { + lx *lexer + context Key // Full key for the current hash in scope. + currentKey string // Base key name for everything except hashes. + pos Position // Current position in the TOML file. + + ordered []Key // List of keys in the order that they appear in the TOML data. + + keyInfo map[string]keyInfo // Map keyname → info about the TOML key. + mapping map[string]interface{} // Map keyname → key value. + implicits map[string]struct{} // Record implicit keys (e.g. "key.group.names"). +} + +type keyInfo struct { + pos Position + tomlType tomlType +} + +func parse(data string) (p *parser, err error) { + defer func() { + if r := recover(); r != nil { + if pErr, ok := r.(ParseError); ok { + pErr.input = data + err = pErr + return + } + panic(r) + } + }() + + // Read over BOM; do this here as the lexer calls utf8.DecodeRuneInString() + // which mangles stuff. + if strings.HasPrefix(data, "\xff\xfe") || strings.HasPrefix(data, "\xfe\xff") { + data = data[2:] + } + + // Examine first few bytes for NULL bytes; this probably means it's a UTF-16 + // file (second byte in surrogate pair being NULL). Again, do this here to + // avoid having to deal with UTF-8/16 stuff in the lexer. + ex := 6 + if len(data) < 6 { + ex = len(data) + } + if i := strings.IndexRune(data[:ex], 0); i > -1 { + return nil, ParseError{ + Message: "files cannot contain NULL bytes; probably using UTF-16; TOML files must be UTF-8", + Position: Position{Line: 1, Start: i, Len: 1}, + Line: 1, + input: data, + } + } + + p = &parser{ + keyInfo: make(map[string]keyInfo), + mapping: make(map[string]interface{}), + lx: lex(data), + ordered: make([]Key, 0), + implicits: make(map[string]struct{}), + } + for { + item := p.next() + if item.typ == itemEOF { + break + } + p.topLevel(item) + } + + return p, nil +} + +func (p *parser) panicErr(it item, err error) { + panic(ParseError{ + err: err, + Position: it.pos, + Line: it.pos.Len, + LastKey: p.current(), + }) +} + +func (p *parser) panicItemf(it item, format string, v ...interface{}) { + panic(ParseError{ + Message: fmt.Sprintf(format, v...), + Position: it.pos, + Line: it.pos.Len, + LastKey: p.current(), + }) +} + +func (p *parser) panicf(format string, v ...interface{}) { + panic(ParseError{ + Message: fmt.Sprintf(format, v...), + Position: p.pos, + Line: p.pos.Line, + LastKey: p.current(), + }) +} + +func (p *parser) next() item { + it := p.lx.nextItem() + //fmt.Printf("ITEM %-18s line %-3d │ %q\n", it.typ, it.pos.Line, it.val) + if it.typ == itemError { + if it.err != nil { + panic(ParseError{ + Position: it.pos, + Line: it.pos.Line, + LastKey: p.current(), + err: it.err, + }) + } + + p.panicItemf(it, "%s", it.val) + } + return it +} + +func (p *parser) nextPos() item { + it := p.next() + p.pos = it.pos + return it +} + +func (p *parser) bug(format string, v ...interface{}) { + panic(fmt.Sprintf("BUG: "+format+"\n\n", v...)) +} + +func (p *parser) expect(typ itemType) item { + it := p.next() + p.assertEqual(typ, it.typ) + return it +} + +func (p *parser) assertEqual(expected, got itemType) { + if expected != got { + p.bug("Expected '%s' but got '%s'.", expected, got) + } +} + +func (p *parser) topLevel(item item) { + switch item.typ { + case itemCommentStart: // # .. + p.expect(itemText) + case itemTableStart: // [ .. ] + name := p.nextPos() + + var key Key + for ; name.typ != itemTableEnd && name.typ != itemEOF; name = p.next() { + key = append(key, p.keyString(name)) + } + p.assertEqual(itemTableEnd, name.typ) + + p.addContext(key, false) + p.setType("", tomlHash, item.pos) + p.ordered = append(p.ordered, key) + case itemArrayTableStart: // [[ .. ]] + name := p.nextPos() + + var key Key + for ; name.typ != itemArrayTableEnd && name.typ != itemEOF; name = p.next() { + key = append(key, p.keyString(name)) + } + p.assertEqual(itemArrayTableEnd, name.typ) + + p.addContext(key, true) + p.setType("", tomlArrayHash, item.pos) + p.ordered = append(p.ordered, key) + case itemKeyStart: // key = .. + outerContext := p.context + /// Read all the key parts (e.g. 'a' and 'b' in 'a.b') + k := p.nextPos() + var key Key + for ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() { + key = append(key, p.keyString(k)) + } + p.assertEqual(itemKeyEnd, k.typ) + + /// The current key is the last part. + p.currentKey = key[len(key)-1] + + /// All the other parts (if any) are the context; need to set each part + /// as implicit. + context := key[:len(key)-1] + for i := range context { + p.addImplicitContext(append(p.context, context[i:i+1]...)) + } + + /// Set value. + vItem := p.next() + val, typ := p.value(vItem, false) + p.set(p.currentKey, val, typ, vItem.pos) + p.ordered = append(p.ordered, p.context.add(p.currentKey)) + + /// Remove the context we added (preserving any context from [tbl] lines). + p.context = outerContext + p.currentKey = "" + default: + p.bug("Unexpected type at top level: %s", item.typ) + } +} + +// Gets a string for a key (or part of a key in a table name). +func (p *parser) keyString(it item) string { + switch it.typ { + case itemText: + return it.val + case itemString, itemMultilineString, + itemRawString, itemRawMultilineString: + s, _ := p.value(it, false) + return s.(string) + default: + p.bug("Unexpected key type: %s", it.typ) + } + panic("unreachable") +} + +var datetimeRepl = strings.NewReplacer( + "z", "Z", + "t", "T", + " ", "T") + +// value translates an expected value from the lexer into a Go value wrapped +// as an empty interface. +func (p *parser) value(it item, parentIsArray bool) (interface{}, tomlType) { + switch it.typ { + case itemString: + return p.replaceEscapes(it, it.val), p.typeOfPrimitive(it) + case itemMultilineString: + return p.replaceEscapes(it, stripFirstNewline(p.stripEscapedNewlines(it.val))), p.typeOfPrimitive(it) + case itemRawString: + return it.val, p.typeOfPrimitive(it) + case itemRawMultilineString: + return stripFirstNewline(it.val), p.typeOfPrimitive(it) + case itemInteger: + return p.valueInteger(it) + case itemFloat: + return p.valueFloat(it) + case itemBool: + switch it.val { + case "true": + return true, p.typeOfPrimitive(it) + case "false": + return false, p.typeOfPrimitive(it) + default: + p.bug("Expected boolean value, but got '%s'.", it.val) + } + case itemDatetime: + return p.valueDatetime(it) + case itemArray: + return p.valueArray(it) + case itemInlineTableStart: + return p.valueInlineTable(it, parentIsArray) + default: + p.bug("Unexpected value type: %s", it.typ) + } + panic("unreachable") +} + +func (p *parser) valueInteger(it item) (interface{}, tomlType) { + if !numUnderscoresOK(it.val) { + p.panicItemf(it, "Invalid integer %q: underscores must be surrounded by digits", it.val) + } + if numHasLeadingZero(it.val) { + p.panicItemf(it, "Invalid integer %q: cannot have leading zeroes", it.val) + } + + num, err := strconv.ParseInt(it.val, 0, 64) + if err != nil { + // Distinguish integer values. Normally, it'd be a bug if the lexer + // provides an invalid integer, but it's possible that the number is + // out of range of valid values (which the lexer cannot determine). + // So mark the former as a bug but the latter as a legitimate user + // error. + if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange { + p.panicErr(it, errParseRange{i: it.val, size: "int64"}) + } else { + p.bug("Expected integer value, but got '%s'.", it.val) + } + } + return num, p.typeOfPrimitive(it) +} + +func (p *parser) valueFloat(it item) (interface{}, tomlType) { + parts := strings.FieldsFunc(it.val, func(r rune) bool { + switch r { + case '.', 'e', 'E': + return true + } + return false + }) + for _, part := range parts { + if !numUnderscoresOK(part) { + p.panicItemf(it, "Invalid float %q: underscores must be surrounded by digits", it.val) + } + } + if len(parts) > 0 && numHasLeadingZero(parts[0]) { + p.panicItemf(it, "Invalid float %q: cannot have leading zeroes", it.val) + } + if !numPeriodsOK(it.val) { + // As a special case, numbers like '123.' or '1.e2', + // which are valid as far as Go/strconv are concerned, + // must be rejected because TOML says that a fractional + // part consists of '.' followed by 1+ digits. + p.panicItemf(it, "Invalid float %q: '.' must be followed by one or more digits", it.val) + } + val := strings.Replace(it.val, "_", "", -1) + if val == "+nan" || val == "-nan" { // Go doesn't support this, but TOML spec does. + val = "nan" + } + num, err := strconv.ParseFloat(val, 64) + if err != nil { + if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange { + p.panicErr(it, errParseRange{i: it.val, size: "float64"}) + } else { + p.panicItemf(it, "Invalid float value: %q", it.val) + } + } + return num, p.typeOfPrimitive(it) +} + +var dtTypes = []struct { + fmt string + zone *time.Location +}{ + {time.RFC3339Nano, time.Local}, + {"2006-01-02T15:04:05.999999999", internal.LocalDatetime}, + {"2006-01-02", internal.LocalDate}, + {"15:04:05.999999999", internal.LocalTime}, +} + +func (p *parser) valueDatetime(it item) (interface{}, tomlType) { + it.val = datetimeRepl.Replace(it.val) + var ( + t time.Time + ok bool + err error + ) + for _, dt := range dtTypes { + t, err = time.ParseInLocation(dt.fmt, it.val, dt.zone) + if err == nil { + ok = true + break + } + } + if !ok { + p.panicItemf(it, "Invalid TOML Datetime: %q.", it.val) + } + return t, p.typeOfPrimitive(it) +} + +func (p *parser) valueArray(it item) (interface{}, tomlType) { + p.setType(p.currentKey, tomlArray, it.pos) + + var ( + types []tomlType + + // Initialize to a non-nil empty slice. This makes it consistent with + // how S = [] decodes into a non-nil slice inside something like struct + // { S []string }. See #338 + array = []interface{}{} + ) + for it = p.next(); it.typ != itemArrayEnd; it = p.next() { + if it.typ == itemCommentStart { + p.expect(itemText) + continue + } + + val, typ := p.value(it, true) + array = append(array, val) + types = append(types, typ) + + // XXX: types isn't used here, we need it to record the accurate type + // information. + // + // Not entirely sure how to best store this; could use "key[0]", + // "key[1]" notation, or maybe store it on the Array type? + } + return array, tomlArray +} + +func (p *parser) valueInlineTable(it item, parentIsArray bool) (interface{}, tomlType) { + var ( + hash = make(map[string]interface{}) + outerContext = p.context + outerKey = p.currentKey + ) + + p.context = append(p.context, p.currentKey) + prevContext := p.context + p.currentKey = "" + + p.addImplicit(p.context) + p.addContext(p.context, parentIsArray) + + /// Loop over all table key/value pairs. + for it := p.next(); it.typ != itemInlineTableEnd; it = p.next() { + if it.typ == itemCommentStart { + p.expect(itemText) + continue + } + + /// Read all key parts. + k := p.nextPos() + var key Key + for ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() { + key = append(key, p.keyString(k)) + } + p.assertEqual(itemKeyEnd, k.typ) + + /// The current key is the last part. + p.currentKey = key[len(key)-1] + + /// All the other parts (if any) are the context; need to set each part + /// as implicit. + context := key[:len(key)-1] + for i := range context { + p.addImplicitContext(append(p.context, context[i:i+1]...)) + } + + /// Set the value. + val, typ := p.value(p.next(), false) + p.set(p.currentKey, val, typ, it.pos) + p.ordered = append(p.ordered, p.context.add(p.currentKey)) + hash[p.currentKey] = val + + /// Restore context. + p.context = prevContext + } + p.context = outerContext + p.currentKey = outerKey + return hash, tomlHash +} + +// numHasLeadingZero checks if this number has leading zeroes, allowing for '0', +// +/- signs, and base prefixes. +func numHasLeadingZero(s string) bool { + if len(s) > 1 && s[0] == '0' && !(s[1] == 'b' || s[1] == 'o' || s[1] == 'x') { // Allow 0b, 0o, 0x + return true + } + if len(s) > 2 && (s[0] == '-' || s[0] == '+') && s[1] == '0' { + return true + } + return false +} + +// numUnderscoresOK checks whether each underscore in s is surrounded by +// characters that are not underscores. +func numUnderscoresOK(s string) bool { + switch s { + case "nan", "+nan", "-nan", "inf", "-inf", "+inf": + return true + } + accept := false + for _, r := range s { + if r == '_' { + if !accept { + return false + } + } + + // isHexadecimal is a superset of all the permissable characters + // surrounding an underscore. + accept = isHexadecimal(r) + } + return accept +} + +// numPeriodsOK checks whether every period in s is followed by a digit. +func numPeriodsOK(s string) bool { + period := false + for _, r := range s { + if period && !isDigit(r) { + return false + } + period = r == '.' + } + return !period +} + +// Set the current context of the parser, where the context is either a hash or +// an array of hashes, depending on the value of the `array` parameter. +// +// Establishing the context also makes sure that the key isn't a duplicate, and +// will create implicit hashes automatically. +func (p *parser) addContext(key Key, array bool) { + var ok bool + + // Always start at the top level and drill down for our context. + hashContext := p.mapping + keyContext := make(Key, 0) + + // We only need implicit hashes for key[0:-1] + for _, k := range key[0 : len(key)-1] { + _, ok = hashContext[k] + keyContext = append(keyContext, k) + + // No key? Make an implicit hash and move on. + if !ok { + p.addImplicit(keyContext) + hashContext[k] = make(map[string]interface{}) + } + + // If the hash context is actually an array of tables, then set + // the hash context to the last element in that array. + // + // Otherwise, it better be a table, since this MUST be a key group (by + // virtue of it not being the last element in a key). + switch t := hashContext[k].(type) { + case []map[string]interface{}: + hashContext = t[len(t)-1] + case map[string]interface{}: + hashContext = t + default: + p.panicf("Key '%s' was already created as a hash.", keyContext) + } + } + + p.context = keyContext + if array { + // If this is the first element for this array, then allocate a new + // list of tables for it. + k := key[len(key)-1] + if _, ok := hashContext[k]; !ok { + hashContext[k] = make([]map[string]interface{}, 0, 4) + } + + // Add a new table. But make sure the key hasn't already been used + // for something else. + if hash, ok := hashContext[k].([]map[string]interface{}); ok { + hashContext[k] = append(hash, make(map[string]interface{})) + } else { + p.panicf("Key '%s' was already created and cannot be used as an array.", key) + } + } else { + p.setValue(key[len(key)-1], make(map[string]interface{})) + } + p.context = append(p.context, key[len(key)-1]) +} + +// set calls setValue and setType. +func (p *parser) set(key string, val interface{}, typ tomlType, pos Position) { + p.setValue(key, val) + p.setType(key, typ, pos) + +} + +// setValue sets the given key to the given value in the current context. +// It will make sure that the key hasn't already been defined, account for +// implicit key groups. +func (p *parser) setValue(key string, value interface{}) { + var ( + tmpHash interface{} + ok bool + hash = p.mapping + keyContext Key + ) + for _, k := range p.context { + keyContext = append(keyContext, k) + if tmpHash, ok = hash[k]; !ok { + p.bug("Context for key '%s' has not been established.", keyContext) + } + switch t := tmpHash.(type) { + case []map[string]interface{}: + // The context is a table of hashes. Pick the most recent table + // defined as the current hash. + hash = t[len(t)-1] + case map[string]interface{}: + hash = t + default: + p.panicf("Key '%s' has already been defined.", keyContext) + } + } + keyContext = append(keyContext, key) + + if _, ok := hash[key]; ok { + // Normally redefining keys isn't allowed, but the key could have been + // defined implicitly and it's allowed to be redefined concretely. (See + // the `valid/implicit-and-explicit-after.toml` in toml-test) + // + // But we have to make sure to stop marking it as an implicit. (So that + // another redefinition provokes an error.) + // + // Note that since it has already been defined (as a hash), we don't + // want to overwrite it. So our business is done. + if p.isArray(keyContext) { + p.removeImplicit(keyContext) + hash[key] = value + return + } + if p.isImplicit(keyContext) { + p.removeImplicit(keyContext) + return + } + + // Otherwise, we have a concrete key trying to override a previous + // key, which is *always* wrong. + p.panicf("Key '%s' has already been defined.", keyContext) + } + + hash[key] = value +} + +// setType sets the type of a particular value at a given key. It should be +// called immediately AFTER setValue. +// +// Note that if `key` is empty, then the type given will be applied to the +// current context (which is either a table or an array of tables). +func (p *parser) setType(key string, typ tomlType, pos Position) { + keyContext := make(Key, 0, len(p.context)+1) + keyContext = append(keyContext, p.context...) + if len(key) > 0 { // allow type setting for hashes + keyContext = append(keyContext, key) + } + // Special case to make empty keys ("" = 1) work. + // Without it it will set "" rather than `""`. + // TODO: why is this needed? And why is this only needed here? + if len(keyContext) == 0 { + keyContext = Key{""} + } + p.keyInfo[keyContext.String()] = keyInfo{tomlType: typ, pos: pos} +} + +// Implicit keys need to be created when tables are implied in "a.b.c.d = 1" and +// "[a.b.c]" (the "a", "b", and "c" hashes are never created explicitly). +func (p *parser) addImplicit(key Key) { p.implicits[key.String()] = struct{}{} } +func (p *parser) removeImplicit(key Key) { delete(p.implicits, key.String()) } +func (p *parser) isImplicit(key Key) bool { _, ok := p.implicits[key.String()]; return ok } +func (p *parser) isArray(key Key) bool { return p.keyInfo[key.String()].tomlType == tomlArray } +func (p *parser) addImplicitContext(key Key) { + p.addImplicit(key) + p.addContext(key, false) +} + +// current returns the full key name of the current context. +func (p *parser) current() string { + if len(p.currentKey) == 0 { + return p.context.String() + } + if len(p.context) == 0 { + return p.currentKey + } + return fmt.Sprintf("%s.%s", p.context, p.currentKey) +} + +func stripFirstNewline(s string) string { + if len(s) > 0 && s[0] == '\n' { + return s[1:] + } + if len(s) > 1 && s[0] == '\r' && s[1] == '\n' { + return s[2:] + } + return s +} + +// Remove newlines inside triple-quoted strings if a line ends with "\". +func (p *parser) stripEscapedNewlines(s string) string { + split := strings.Split(s, "\n") + if len(split) < 1 { + return s + } + + escNL := false // Keep track of the last non-blank line was escaped. + for i, line := range split { + line = strings.TrimRight(line, " \t\r") + + if len(line) == 0 || line[len(line)-1] != '\\' { + split[i] = strings.TrimRight(split[i], "\r") + if !escNL && i != len(split)-1 { + split[i] += "\n" + } + continue + } + + escBS := true + for j := len(line) - 1; j >= 0 && line[j] == '\\'; j-- { + escBS = !escBS + } + if escNL { + line = strings.TrimLeft(line, " \t\r") + } + escNL = !escBS + + if escBS { + split[i] += "\n" + continue + } + + if i == len(split)-1 { + p.panicf("invalid escape: '\\ '") + } + + split[i] = line[:len(line)-1] // Remove \ + if len(split)-1 > i { + split[i+1] = strings.TrimLeft(split[i+1], " \t\r") + } + } + return strings.Join(split, "") +} + +func (p *parser) replaceEscapes(it item, str string) string { + replaced := make([]rune, 0, len(str)) + s := []byte(str) + r := 0 + for r < len(s) { + if s[r] != '\\' { + c, size := utf8.DecodeRune(s[r:]) + r += size + replaced = append(replaced, c) + continue + } + r += 1 + if r >= len(s) { + p.bug("Escape sequence at end of string.") + return "" + } + switch s[r] { + default: + p.bug("Expected valid escape code after \\, but got %q.", s[r]) + case ' ', '\t': + p.panicItemf(it, "invalid escape: '\\%c'", s[r]) + case 'b': + replaced = append(replaced, rune(0x0008)) + r += 1 + case 't': + replaced = append(replaced, rune(0x0009)) + r += 1 + case 'n': + replaced = append(replaced, rune(0x000A)) + r += 1 + case 'f': + replaced = append(replaced, rune(0x000C)) + r += 1 + case 'r': + replaced = append(replaced, rune(0x000D)) + r += 1 + case '"': + replaced = append(replaced, rune(0x0022)) + r += 1 + case '\\': + replaced = append(replaced, rune(0x005C)) + r += 1 + case 'u': + // At this point, we know we have a Unicode escape of the form + // `uXXXX` at [r, r+5). (Because the lexer guarantees this + // for us.) + escaped := p.asciiEscapeToUnicode(it, s[r+1:r+5]) + replaced = append(replaced, escaped) + r += 5 + case 'U': + // At this point, we know we have a Unicode escape of the form + // `uXXXX` at [r, r+9). (Because the lexer guarantees this + // for us.) + escaped := p.asciiEscapeToUnicode(it, s[r+1:r+9]) + replaced = append(replaced, escaped) + r += 9 + } + } + return string(replaced) +} + +func (p *parser) asciiEscapeToUnicode(it item, bs []byte) rune { + s := string(bs) + hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32) + if err != nil { + p.bug("Could not parse '%s' as a hexadecimal number, but the lexer claims it's OK: %s", s, err) + } + if !utf8.ValidRune(rune(hex)) { + p.panicItemf(it, "Escaped character '\\u%s' is not valid UTF-8.", s) + } + return rune(hex) +} diff --git a/vendor/github.com/BurntSushi/toml/type_fields.go b/vendor/github.com/BurntSushi/toml/type_fields.go new file mode 100644 index 00000000..254ca82e --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/type_fields.go @@ -0,0 +1,242 @@ +package toml + +// Struct field handling is adapted from code in encoding/json: +// +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the Go distribution. + +import ( + "reflect" + "sort" + "sync" +) + +// A field represents a single field found in a struct. +type field struct { + name string // the name of the field (`toml` tag included) + tag bool // whether field has a `toml` tag + index []int // represents the depth of an anonymous field + typ reflect.Type // the type of the field +} + +// byName sorts field by name, breaking ties with depth, +// then breaking ties with "name came from toml tag", then +// breaking ties with index sequence. +type byName []field + +func (x byName) Len() int { return len(x) } + +func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } + +func (x byName) Less(i, j int) bool { + if x[i].name != x[j].name { + return x[i].name < x[j].name + } + if len(x[i].index) != len(x[j].index) { + return len(x[i].index) < len(x[j].index) + } + if x[i].tag != x[j].tag { + return x[i].tag + } + return byIndex(x).Less(i, j) +} + +// byIndex sorts field by index sequence. +type byIndex []field + +func (x byIndex) Len() int { return len(x) } + +func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } + +func (x byIndex) Less(i, j int) bool { + for k, xik := range x[i].index { + if k >= len(x[j].index) { + return false + } + if xik != x[j].index[k] { + return xik < x[j].index[k] + } + } + return len(x[i].index) < len(x[j].index) +} + +// typeFields returns a list of fields that TOML should recognize for the given +// type. The algorithm is breadth-first search over the set of structs to +// include - the top struct and then any reachable anonymous structs. +func typeFields(t reflect.Type) []field { + // Anonymous fields to explore at the current level and the next. + current := []field{} + next := []field{{typ: t}} + + // Count of queued names for current level and the next. + var count map[reflect.Type]int + var nextCount map[reflect.Type]int + + // Types already visited at an earlier level. + visited := map[reflect.Type]bool{} + + // Fields found. + var fields []field + + for len(next) > 0 { + current, next = next, current[:0] + count, nextCount = nextCount, map[reflect.Type]int{} + + for _, f := range current { + if visited[f.typ] { + continue + } + visited[f.typ] = true + + // Scan f.typ for fields to include. + for i := 0; i < f.typ.NumField(); i++ { + sf := f.typ.Field(i) + if sf.PkgPath != "" && !sf.Anonymous { // unexported + continue + } + opts := getOptions(sf.Tag) + if opts.skip { + continue + } + index := make([]int, len(f.index)+1) + copy(index, f.index) + index[len(f.index)] = i + + ft := sf.Type + if ft.Name() == "" && ft.Kind() == reflect.Ptr { + // Follow pointer. + ft = ft.Elem() + } + + // Record found field and index sequence. + if opts.name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { + tagged := opts.name != "" + name := opts.name + if name == "" { + name = sf.Name + } + fields = append(fields, field{name, tagged, index, ft}) + if count[f.typ] > 1 { + // If there were multiple instances, add a second, + // so that the annihilation code will see a duplicate. + // It only cares about the distinction between 1 or 2, + // so don't bother generating any more copies. + fields = append(fields, fields[len(fields)-1]) + } + continue + } + + // Record new anonymous struct to explore in next round. + nextCount[ft]++ + if nextCount[ft] == 1 { + f := field{name: ft.Name(), index: index, typ: ft} + next = append(next, f) + } + } + } + } + + sort.Sort(byName(fields)) + + // Delete all fields that are hidden by the Go rules for embedded fields, + // except that fields with TOML tags are promoted. + + // The fields are sorted in primary order of name, secondary order + // of field index length. Loop over names; for each name, delete + // hidden fields by choosing the one dominant field that survives. + out := fields[:0] + for advance, i := 0, 0; i < len(fields); i += advance { + // One iteration per name. + // Find the sequence of fields with the name of this first field. + fi := fields[i] + name := fi.name + for advance = 1; i+advance < len(fields); advance++ { + fj := fields[i+advance] + if fj.name != name { + break + } + } + if advance == 1 { // Only one field with this name + out = append(out, fi) + continue + } + dominant, ok := dominantField(fields[i : i+advance]) + if ok { + out = append(out, dominant) + } + } + + fields = out + sort.Sort(byIndex(fields)) + + return fields +} + +// dominantField looks through the fields, all of which are known to +// have the same name, to find the single field that dominates the +// others using Go's embedding rules, modified by the presence of +// TOML tags. If there are multiple top-level fields, the boolean +// will be false: This condition is an error in Go and we skip all +// the fields. +func dominantField(fields []field) (field, bool) { + // The fields are sorted in increasing index-length order. The winner + // must therefore be one with the shortest index length. Drop all + // longer entries, which is easy: just truncate the slice. + length := len(fields[0].index) + tagged := -1 // Index of first tagged field. + for i, f := range fields { + if len(f.index) > length { + fields = fields[:i] + break + } + if f.tag { + if tagged >= 0 { + // Multiple tagged fields at the same level: conflict. + // Return no field. + return field{}, false + } + tagged = i + } + } + if tagged >= 0 { + return fields[tagged], true + } + // All remaining fields have the same length. If there's more than one, + // we have a conflict (two fields named "X" at the same level) and we + // return no field. + if len(fields) > 1 { + return field{}, false + } + return fields[0], true +} + +var fieldCache struct { + sync.RWMutex + m map[reflect.Type][]field +} + +// cachedTypeFields is like typeFields but uses a cache to avoid repeated work. +func cachedTypeFields(t reflect.Type) []field { + fieldCache.RLock() + f := fieldCache.m[t] + fieldCache.RUnlock() + if f != nil { + return f + } + + // Compute fields without lock. + // Might duplicate effort but won't hold other computations back. + f = typeFields(t) + if f == nil { + f = []field{} + } + + fieldCache.Lock() + if fieldCache.m == nil { + fieldCache.m = map[reflect.Type][]field{} + } + fieldCache.m[t] = f + fieldCache.Unlock() + return f +} diff --git a/vendor/github.com/BurntSushi/toml/type_toml.go b/vendor/github.com/BurntSushi/toml/type_toml.go new file mode 100644 index 00000000..4e90d773 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/type_toml.go @@ -0,0 +1,70 @@ +package toml + +// tomlType represents any Go type that corresponds to a TOML type. +// While the first draft of the TOML spec has a simplistic type system that +// probably doesn't need this level of sophistication, we seem to be militating +// toward adding real composite types. +type tomlType interface { + typeString() string +} + +// typeEqual accepts any two types and returns true if they are equal. +func typeEqual(t1, t2 tomlType) bool { + if t1 == nil || t2 == nil { + return false + } + return t1.typeString() == t2.typeString() +} + +func typeIsTable(t tomlType) bool { + return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash) +} + +type tomlBaseType string + +func (btype tomlBaseType) typeString() string { + return string(btype) +} + +func (btype tomlBaseType) String() string { + return btype.typeString() +} + +var ( + tomlInteger tomlBaseType = "Integer" + tomlFloat tomlBaseType = "Float" + tomlDatetime tomlBaseType = "Datetime" + tomlString tomlBaseType = "String" + tomlBool tomlBaseType = "Bool" + tomlArray tomlBaseType = "Array" + tomlHash tomlBaseType = "Hash" + tomlArrayHash tomlBaseType = "ArrayHash" +) + +// typeOfPrimitive returns a tomlType of any primitive value in TOML. +// Primitive values are: Integer, Float, Datetime, String and Bool. +// +// Passing a lexer item other than the following will cause a BUG message +// to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime. +func (p *parser) typeOfPrimitive(lexItem item) tomlType { + switch lexItem.typ { + case itemInteger: + return tomlInteger + case itemFloat: + return tomlFloat + case itemDatetime: + return tomlDatetime + case itemString: + return tomlString + case itemMultilineString: + return tomlString + case itemRawString: + return tomlString + case itemRawMultilineString: + return tomlString + case itemBool: + return tomlBool + } + p.bug("Cannot infer primitive type of lex item '%s'.", lexItem) + panic("unreachable") +} diff --git a/vendor/github.com/Kunde21/markdownfmt/v3/LICENSE b/vendor/github.com/Kunde21/markdownfmt/v3/LICENSE new file mode 100644 index 00000000..972d527d --- /dev/null +++ b/vendor/github.com/Kunde21/markdownfmt/v3/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2014 Dmitri Shuralyov +Copyright (c) 2021 Chad Kunde + +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/Kunde21/markdownfmt/v3/markdown/doc.go b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/doc.go new file mode 100644 index 00000000..5579f1fd --- /dev/null +++ b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/doc.go @@ -0,0 +1,2 @@ +// Package markdown renders the given goldmark AST to Markdown. +package markdown diff --git a/vendor/github.com/Kunde21/markdownfmt/v3/markdown/indent.go b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/indent.go new file mode 100644 index 00000000..875fac97 --- /dev/null +++ b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/indent.go @@ -0,0 +1,61 @@ +package markdown + +// indentation tracks indentation data for a mardown writer. +type indentation struct { + // Indentation is comprised of multiple sections of indentations. + // indents tracks the combined full indentation, + // and lengths tracks the length of each appended section. + indents []byte + lengths []int + + // index at which trailing spaces start in indents. + trailSpaceIdx int +} + +// Indent reports the fixed text prefix pushed so far. +// +// Invariant: This does not end with whitespace. +func (id *indentation) Indent() []byte { + return id.indents[:id.trailSpaceIdx] +} + +// Whitespace reports the trailing whitespace of the indentation pushed so far. +func (id *indentation) Whitespace() []byte { + return id.indents[id.trailSpaceIdx:] +} + +// Push adds a block of text to the indentation stack. +// +// Indent and Whitespace will report this in consescutive calls. +func (id *indentation) Push(bs []byte) { + id.indents = append(id.indents, bs...) + id.lengths = append(id.lengths, len(bs)) + id.trailSpaceIdx = trailingSpaceIdx(id.indents) +} + +// Pop removes the last pushed block of text from the stack. +func (id *indentation) Pop() { + count := len(id.lengths) + if count == 0 { + panic("bug: indentation.Pop called for empty indentation") + } + lastLen := id.lengths[count-1] + + id.lengths = id.lengths[:count-1] + id.indents = id.indents[:len(id.indents)-lastLen] + id.trailSpaceIdx = trailingSpaceIdx(id.indents) +} + +// trailingSpaceIdx returns the index at which trailing space +// starts in the given byte slice. +// +// Returns 0 if the slice is entirely whitespace, +// and len(bs) if the slice is entirely non-whitespace. +func trailingSpaceIdx(bs []byte) int { + for idx := len(bs); idx > 0; idx-- { + if bs[idx-1] != ' ' { + return idx + } + } + return 0 +} diff --git a/vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer.go b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer.go new file mode 100644 index 00000000..99d66676 --- /dev/null +++ b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer.go @@ -0,0 +1,646 @@ +package markdown + +import ( + "bytes" + "fmt" + "go/format" + "io" + "strconv" + "unicode/utf8" + "unsafe" + + "github.com/yuin/goldmark/ast" + extAST "github.com/yuin/goldmark/extension/ast" + "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/text" +) + +var ( + newLineChar = []byte{'\n'} + spaceChar = []byte{' '} + strikeThroughChars = []byte("~~") + thematicBreakChars = []byte("---") + blockquoteChars = []byte{'>', ' '} + codeBlockChars = []byte("```") + tableHeaderColChar = []byte{'-'} + tableHeaderAlignColChar = []byte{':'} + heading1UnderlineChar = []byte{'='} + heading2UnderlineChar = []byte{'-'} + fourSpacesChars = bytes.Repeat([]byte{' '}, 4) +) + +// Ensure compatibility with Goldmark parser. +var _ renderer.Renderer = &Renderer{} + +// Renderer allows to render markdown AST into markdown bytes in consistent format. +// Render is reusable across Renders, it holds configuration only. +type Renderer struct { + underlineHeadings bool + softWraps bool + emphToken []byte + strongToken []byte // if nil, use emphToken*2 + listIndentStyle ListIndentStyle + + // language name => format function + formatters map[string]func([]byte) []byte +} + +// AddOptions pulls Markdown renderer specific options from the given list, +// and applies them to the renderer. +func (mr *Renderer) AddOptions(opts ...renderer.Option) { + mdopts := make([]Option, 0, len(opts)) + for _, o := range opts { + if mo, ok := o.(Option); ok { + mdopts = append(mdopts, mo) + } + } + mr.AddMarkdownOptions(mdopts...) +} + +// AddMarkdownOptions modifies the Renderer with the given options. +func (mr *Renderer) AddMarkdownOptions(opts ...Option) { + for _, o := range opts { + o.apply(mr) + } +} + +// Option customizes the behavior of the markdown renderer. +type Option interface { + renderer.Option + + apply(r *Renderer) +} + +type optionFunc func(*Renderer) + +func (f optionFunc) SetConfig(*renderer.Config) {} + +func (f optionFunc) apply(r *Renderer) { + f(r) +} + +// WithUnderlineHeadings configures the renderer to use +// Setext-style headers (=== and ---). +func WithUnderlineHeadings() Option { + return optionFunc(func(r *Renderer) { + r.underlineHeadings = true + }) +} + +// WithSoftWraps allows you to wrap lines even on soft line breaks. +func WithSoftWraps() Option { + return optionFunc(func(r *Renderer) { + r.softWraps = true + }) +} + +// WithEmphasisToken specifies the character used to wrap emphasised text. +// Per the CommonMark spec, valid values are '*' and '_'. +// +// Defaults to '*'. +func WithEmphasisToken(c rune) Option { + return optionFunc(func(r *Renderer) { + buf := make([]byte, 4) // enough to encode any utf8 rune + n := utf8.EncodeRune(buf, c) + r.emphToken = buf[:n] + }) +} + +// WithStrongToken specifies the string used to wrap bold text. +// Per the CommonMark spec, valid values are '**' and '__'. +// +// Defaults to repeating the emphasis token twice. +// See [WithEmphasisToken] for how to change that. +func WithStrongToken(s string) Option { + return optionFunc(func(r *Renderer) { + r.strongToken = []byte(s) + }) +} + +// ListIndentStyle specifies how items nested inside lists +// should be indented. +type ListIndentStyle int + +const ( + // ListIndentAligned specifies that items inside a list item + // should be aligned to the content in the first item. + // + // - First paragraph. + // + // Second paragraph aligned with the first. + // + // This applies to ordered lists too. + // + // 1. First paragraph. + // + // Second paragraph aligned with the first. + // + // ... + // + // 10. Contents. + // + // Long lists indent content further. + // + // This is the default. + ListIndentAligned ListIndentStyle = iota + + // ListIndentUniform specifies that items inside a list item + // should be aligned uniformly with 4 spaces. + // + // For example: + // + // - First paragraph. + // + // Second paragraph indented 4 spaces. + // + // For ordered lists: + // + // 1. First paragraph. + // + // Second paragraph indented 4 spaces. + // + // ... + // + // 10. Contents. + // + // Always indented 4 spaces. + ListIndentUniform +) + +// WithListIndentStyle specifies how contents nested under a list item +// should be indented. +// +// Defaults to [ListIndentAligned]. +func WithListIndentStyle(style ListIndentStyle) Option { + return optionFunc(func(r *Renderer) { + r.listIndentStyle = style + }) +} + +// CodeFormatter reformats code samples found in the document, +// matching them by name. +type CodeFormatter struct { + // Name of the language. + Name string + + // Aliases for the language, if any. + Aliases []string + + // Function to format the code snippet. + // In case of errors, format functions should typically return + // the original string unchanged. + Format func([]byte) []byte +} + +// GoCodeFormatter is a [CodeFormatter] that reformats Go source code inside +// fenced code blocks tagged with 'go' or 'Go'. +// +// ```go +// func main() { +// } +// ``` +// +// Supply it to the renderer with [WithCodeFormatters]. +var GoCodeFormatter = CodeFormatter{ + Name: "go", + Aliases: []string{"Go"}, + Format: formatGo, +} + +func formatGo(src []byte) []byte { + gofmt, err := format.Source(src) + if err != nil { + // We don't handle gofmt errors. + // If code is not compilable we just + // don't format it without any warning. + return src + } + return gofmt +} + +// WithCodeFormatters changes the functions used to reformat code blocks found +// in the original file. +// +// formatters := []markdown.CodeFormatter{ +// markdown.GoCodeFormatter, +// // ... +// } +// r := NewRenderer() +// r.AddMarkdownOptions(WithCodeFormatters(formatters...)) +// +// Defaults to empty. +func WithCodeFormatters(fs ...CodeFormatter) Option { + return optionFunc(func(r *Renderer) { + formatters := make(map[string]func([]byte) []byte, len(fs)) + for _, f := range fs { + formatters[f.Name] = f.Format + for _, alias := range f.Aliases { + formatters[alias] = f.Format + } + } + r.formatters = formatters + }) +} + +// NewRenderer builds a new Markdown renderer with default settings. +// To use this with goldmark.Markdown, use the goldmark.WithRenderer option. +// +// r := markdown.NewRenderer() +// md := goldmark.New(goldmark.WithRenderer(r)) +// md.Convert(src, w) +// +// Alternatively, you can call [Renderer.Render] directly. +// +// r := markdown.NewRenderer() +// r.Render(w, src, node) +// +// Use [Renderer.AddMarkdownOptions] to customize the output of the renderer. +func NewRenderer() *Renderer { + return &Renderer{ + emphToken: []byte{'*'}, + // Leave strongToken as nil by default. + // At render time, we'll use what was specified, + // or repeat emphToken twice to get the strong token. + } +} + +// render represents a single markdown rendering operation. +type render struct { + mr *Renderer + + emphToken []byte + strongToken []byte + + // TODO(bwplotka): Wrap it with something that catch errors. + w *lineIndentWriter + source []byte +} + +func (mr *Renderer) newRender(w io.Writer, source []byte) *render { + strongToken := mr.strongToken + if len(strongToken) == 0 { + strongToken = bytes.Repeat(mr.emphToken, 2) + } + + return &render{ + mr: mr, + w: wrapWithLineIndentWriter(w), + source: source, + strongToken: strongToken, + emphToken: mr.emphToken, + } +} + +// Render renders the given AST node to the given writer, +// given the original source from which the node was parsed. +// +// NOTE: This is the entry point used by Goldmark. +func (mr *Renderer) Render(w io.Writer, source []byte, node ast.Node) error { + // Perform DFS. + return ast.Walk(node, mr.newRender(w, source).renderNode) +} + +func (r *render) renderNode(node ast.Node, entering bool) (ast.WalkStatus, error) { + if entering && node.PreviousSibling() != nil { + switch node.(type) { + // All Block types (except few) usually have 2x new lines before itself when they are non-first siblings. + case *ast.Paragraph, *ast.Heading, *ast.FencedCodeBlock, + *ast.CodeBlock, *ast.ThematicBreak, *extAST.Table, + *ast.Blockquote: + _, _ = r.w.Write(newLineChar) + _, _ = r.w.Write(newLineChar) + case *ast.List, *ast.HTMLBlock: + _, _ = r.w.Write(newLineChar) + if node.HasBlankPreviousLines() { + _, _ = r.w.Write(newLineChar) + } + case *ast.ListItem: + // TODO(bwplotka): Handle tight/loose rule explicitly. + // See: https://github.github.com/gfm/#loose + if node.HasBlankPreviousLines() { + _, _ = r.w.Write(newLineChar) + } + } + } + + switch tnode := node.(type) { + case *ast.Document: + if entering { + break + } + + _, _ = r.w.Write(newLineChar) + + // Spans, meaning no newlines before or after. + case *ast.Text: + if entering { + text := tnode.Segment.Value(r.source) + _ = writeClean(r.w, text) + break + } + + if tnode.SoftLineBreak() { + char := spaceChar + if r.mr.softWraps { + char = newLineChar + } + _, _ = r.w.Write(char) + } + + if tnode.HardLineBreak() { + if tnode.SoftLineBreak() { + _, _ = r.w.Write(spaceChar) + } + _, _ = r.w.Write(newLineChar) + } + case *ast.String: + if entering { + _, _ = r.w.Write(tnode.Value) + } + case *ast.AutoLink: + // We treat autolink as normal string. + if entering { + _, _ = r.w.Write(tnode.Label(r.source)) + } + case *extAST.TaskCheckBox: + if !entering { + break + } + if tnode.IsChecked { + _, _ = r.w.Write([]byte("[X] ")) + break + } + _, _ = r.w.Write([]byte("[ ] ")) + case *ast.CodeSpan: + if entering { + _, _ = r.w.Write([]byte{'`'}) + break + } + + _, _ = r.w.Write([]byte{'`'}) + case *extAST.Strikethrough: + return r.wrapNonEmptyContentWith(strikeThroughChars, entering), nil + case *ast.Emphasis: + var emWrapper []byte + switch tnode.Level { + case 1: + emWrapper = r.emphToken + case 2: + emWrapper = r.strongToken + default: + emWrapper = bytes.Repeat(r.emphToken, tnode.Level) + } + return r.wrapNonEmptyContentWith(emWrapper, entering), nil + case *ast.Link: + if entering { + r.w.AddIndentOnFirstWrite([]byte("[")) + break + } + + _, _ = fmt.Fprintf(r.w, "](%s", tnode.Destination) + if len(tnode.Title) > 0 { + _, _ = fmt.Fprintf(r.w, ` "%s"`, tnode.Title) + } + _, _ = r.w.Write([]byte{')'}) + case *ast.Image: + if entering { + r.w.AddIndentOnFirstWrite([]byte("![")) + break + } + + _, _ = fmt.Fprintf(r.w, "](%s", tnode.Destination) + if len(tnode.Title) > 0 { + _, _ = fmt.Fprintf(r.w, ` "%s"`, tnode.Title) + } + _, _ = r.w.Write([]byte{')'}) + case *ast.RawHTML: + if !entering { + break + } + + for i := 0; i < tnode.Segments.Len(); i++ { + segment := tnode.Segments.At(i) + _, _ = r.w.Write(segment.Value(r.source)) + } + return ast.WalkSkipChildren, nil + + // Blocks. + case *ast.Paragraph, *ast.TextBlock, *ast.List, *extAST.TableCell: + // Things that has no content, just children elements, go there. + break + case *ast.Heading: + if !entering { + break + } + + // Render it straight away. No nested headings are supported and we expect + // headings to have limited content, so limit WALK. + if err := r.renderHeading(tnode); err != nil { + return ast.WalkStop, fmt.Errorf("rendering heading: %w", err) + } + return ast.WalkSkipChildren, nil + case *ast.HTMLBlock: + if !entering { + break + } + + var segments []text.Segment + for i := 0; i < node.Lines().Len(); i++ { + segments = append(segments, node.Lines().At(i)) + } + + if tnode.ClosureLine.Len() != 0 { + segments = append(segments, tnode.ClosureLine) + } + for i, s := range segments { + o := s.Value(r.source) + if i == len(segments)-1 { + o = bytes.TrimSuffix(o, []byte("\n")) + } + _, _ = r.w.Write(o) + } + return ast.WalkSkipChildren, nil + case *ast.CodeBlock, *ast.FencedCodeBlock: + if !entering { + break + } + + _, _ = r.w.Write(codeBlockChars) + + var lang []byte + if fencedNode, isFenced := node.(*ast.FencedCodeBlock); isFenced && fencedNode.Info != nil { + lang = fencedNode.Info.Text(r.source) + _, _ = r.w.Write(lang) + for _, elt := range bytes.Fields(lang) { + elt = bytes.TrimSpace(bytes.TrimLeft(elt, ". ")) + if len(elt) == 0 { + continue + } + lang = elt + break + } + } + + _, _ = r.w.Write(newLineChar) + codeBuf := bytes.Buffer{} + for i := 0; i < tnode.Lines().Len(); i++ { + line := tnode.Lines().At(i) + _, _ = codeBuf.Write(line.Value(r.source)) + } + + if formatCode, ok := r.mr.formatters[noAllocString(lang)]; ok { + code := formatCode(codeBuf.Bytes()) + if !bytes.HasSuffix(code, newLineChar) { + // Ensure code sample ends with a newline. + code = append(code, newLineChar...) + } + _, _ = r.w.Write(code) + } else { + _, _ = r.w.Write(codeBuf.Bytes()) + } + + _, _ = r.w.Write(codeBlockChars) + return ast.WalkSkipChildren, nil + case *ast.ThematicBreak: + if !entering { + break + } + + _, _ = r.w.Write(thematicBreakChars) + case *ast.Blockquote: + if entering { + r.w.PushIndent(blockquoteChars) + if node.Parent() != nil && node.Parent().Kind() == ast.KindListItem && + node.PreviousSibling() == nil { + _, _ = r.w.Write(blockquoteChars) + } + } else { + r.w.PopIndent() + } + + case *ast.ListItem: + if entering { + liMarker := listItemMarkerChars(tnode) + _, _ = r.w.Write(liMarker) + if r.mr.listIndentStyle == ListIndentUniform && + // We can use 4 spaces for indentation only if + // that would still qualify as part of the list + // item text. e.g., given "123. foo", + // for content to be part of that list item, + // it must be indented 5 spaces. + // + // 123. foo + // + // bar + len(liMarker) <= len(fourSpacesChars) { + r.w.PushIndent(fourSpacesChars) + } else { + r.w.PushIndent(bytes.Repeat(spaceChar, len(liMarker))) + } + } else { + if tnode.NextSibling() != nil && tnode.NextSibling().Kind() == ast.KindListItem { + // Newline after list item. + _, _ = r.w.Write(newLineChar) + } + r.w.PopIndent() + } + + case *extAST.Table: + if !entering { + break + } + + // Render it straight away. No nested tables are supported and we expect + // tables to have limited content, so limit WALK. + if err := r.renderTable(tnode); err != nil { + return ast.WalkStop, fmt.Errorf("rendering table: %w", err) + } + return ast.WalkSkipChildren, nil + case *extAST.TableRow, *extAST.TableHeader: + return ast.WalkStop, fmt.Errorf("%v element detected, but table should be rendered in renderTable instead", tnode.Kind()) + default: + return ast.WalkStop, fmt.Errorf("detected unexpected tree type %v", tnode.Kind()) + } + return ast.WalkContinue, nil +} + +func (r *render) wrapNonEmptyContentWith(b []byte, entering bool) ast.WalkStatus { + if entering { + r.w.AddIndentOnFirstWrite(b) + return ast.WalkContinue + } + + if r.w.WasIndentOnFirstWriteWritten() { + _, _ = r.w.Write(b) + return ast.WalkContinue + } + r.w.DelIndentOnFirstWrite(b) + return ast.WalkContinue +} + +func listItemMarkerChars(tnode *ast.ListItem) []byte { + parList := tnode.Parent().(*ast.List) + if parList.IsOrdered() { + cnt := 1 + if parList.Start != 0 { + cnt = parList.Start + } + s := tnode.PreviousSibling() + for s != nil { + cnt++ + s = s.PreviousSibling() + } + return append(strconv.AppendInt(nil, int64(cnt), 10), parList.Marker, ' ') + } + return []byte{parList.Marker, spaceChar[0]} +} + +func noAllocString(buf []byte) string { + return *(*string)(unsafe.Pointer(&buf)) +} + +// writeClean writes the given byte slice to the writer +// replacing consecutive spaces, newlines, and tabs +// with single spaces. +func writeClean(w io.Writer, bs []byte) error { + // This works by scanning the byte slice, + // and writing sub-slices of bs + // as we see and skip blank sections. + + var ( + // Start of the current sub-slice to be written. + startIdx int + // Normalized last character we saw: + // for whitespace, this is ' ', + // for everything else, it's left as-is. + p byte + ) + + for idx, q := range bs { + if q == '\n' || q == '\r' || q == '\t' { + q = ' ' + } + + if q == ' ' { + if p != ' ' { + // Going from non-blank to blank. + // Write the current sub-slice and the blank. + if _, err := w.Write(bs[startIdx:idx]); err != nil { + return err + } + if _, err := w.Write(spaceChar); err != nil { + return err + } + } + startIdx = idx + 1 + } else if p == ' ' { + // Going from blank to non-blank. + // Start a new sub-slice. + startIdx = idx + } + p = q + } + + _, err := w.Write(bs[startIdx:]) + return err +} diff --git a/vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer_heading.go b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer_heading.go new file mode 100644 index 00000000..dd700796 --- /dev/null +++ b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer_heading.go @@ -0,0 +1,89 @@ +package markdown + +import ( + "bytes" + "fmt" + "sort" + "strings" + + "github.com/mattn/go-runewidth" + "github.com/yuin/goldmark/ast" +) + +func (r *render) renderHeading(node *ast.Heading) error { + underlineHeading := false + if r.mr.underlineHeadings { + underlineHeading = node.Level <= 2 + } + + if !underlineHeading { + r.w.Write(bytes.Repeat([]byte{'#'}, node.Level)) + r.w.Write(spaceChar) + } + + var headBuf bytes.Buffer + headBuf.Reset() + + for n := node.FirstChild(); n != nil; n = n.NextSibling() { + if err := ast.Walk(n, func(inner ast.Node, entering bool) (ast.WalkStatus, error) { + if entering { + if err := ast.Walk(inner, r.mr.newRender(&headBuf, r.source).renderNode); err != nil { + return ast.WalkStop, err + } + } + return ast.WalkSkipChildren, nil + }); err != nil { + return err + } + } + a := node.Attributes() + sort.SliceStable(a, func(i, j int) bool { + switch { + case bytes.Equal(a[i].Name, []byte("id")): + return true + case bytes.Equal(a[j].Name, []byte("id")): + return false + case bytes.Equal(a[i].Name, []byte("class")): + return true + case bytes.Equal(a[j].Name, []byte("class")): + return false + } + return bytes.Compare(a[i].Name, a[j].Name) == -1 + }) + + hAttr := []string{} + for _, attr := range node.Attributes() { + switch string(attr.Name) { + case "id": + hAttr = append(hAttr, fmt.Sprintf("#%s", attr.Value)) + case "class": + hAttr = append(hAttr, strings.ReplaceAll(fmt.Sprintf(".%s", attr.Value), " ", " .")) + default: + if attr.Value == nil { + hAttr = append(hAttr, string(attr.Name)) + continue + } + hAttr = append(hAttr, fmt.Sprintf("%s=%s", string(attr.Name), attr.Value)) + } + } + if len(hAttr) != 0 { + _, _ = fmt.Fprintf(&headBuf, " {%s}", strings.Join(hAttr, " ")) + } + + _, _ = r.w.Write(headBuf.Bytes()) + + if underlineHeading { + width := runewidth.StringWidth(headBuf.String()) + + _, _ = r.w.Write(newLineChar) + + switch node.Level { + case 1: + r.w.Write(bytes.Repeat(heading1UnderlineChar, width)) + case 2: + r.w.Write(bytes.Repeat(heading2UnderlineChar, width)) + } + } + + return nil +} diff --git a/vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer_table.go b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer_table.go new file mode 100644 index 00000000..09dba2e2 --- /dev/null +++ b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/renderer_table.go @@ -0,0 +1,140 @@ +package markdown + +import ( + "bytes" + "fmt" + + "github.com/mattn/go-runewidth" + "github.com/yuin/goldmark/ast" + extAST "github.com/yuin/goldmark/extension/ast" +) + +func (r *render) renderTable(node *extAST.Table) error { + var ( + columnAligns []extAST.Alignment + columnWidths []int + colIndex int + cellBuf bytes.Buffer + ) + + // Walk tree initially to count column widths and alignments. + for n := node.FirstChild(); n != nil; n = n.NextSibling() { + if err := ast.Walk(n, func(inner ast.Node, entering bool) (ast.WalkStatus, error) { + switch tnode := inner.(type) { + case *extAST.TableRow, *extAST.TableHeader: + if entering { + colIndex = 0 + } + case *extAST.TableCell: + if entering { + if _, isHeader := tnode.Parent().(*extAST.TableHeader); isHeader { + columnAligns = append(columnAligns, tnode.Alignment) + } + + cellBuf.Reset() + if err := ast.Walk(tnode, r.mr.newRender(&cellBuf, r.source).renderNode); err != nil { + return ast.WalkStop, err + } + width := runewidth.StringWidth(cellBuf.String()) + if len(columnWidths) <= colIndex { + columnWidths = append(columnWidths, width) + } else if width > columnWidths[colIndex] { + columnWidths[colIndex] = width + } + colIndex++ + return ast.WalkSkipChildren, nil + } + default: + return ast.WalkStop, fmt.Errorf("detected unexpected tree type %v", tnode.Kind()) + } + return ast.WalkContinue, nil + }); err != nil { + return err + } + } + + // Write all according to alignments and width. + for n := node.FirstChild(); n != nil; n = n.NextSibling() { + if err := ast.Walk(n, func(inner ast.Node, entering bool) (ast.WalkStatus, error) { + switch tnode := inner.(type) { + case *extAST.TableRow: + if entering { + colIndex = 0 + _, _ = r.w.Write(newLineChar) + break + } + + _, _ = r.w.Write([]byte("|")) + case *extAST.TableHeader: + if entering { + colIndex = 0 + break + } + + _, _ = r.w.Write([]byte("|\n")) + for i, align := range columnAligns { + _, _ = r.w.Write([]byte{'|'}) + width := columnWidths[i] + + left, right := tableHeaderColChar, tableHeaderColChar + switch align { + case extAST.AlignLeft: + left = tableHeaderAlignColChar + case extAST.AlignRight: + right = tableHeaderAlignColChar + case extAST.AlignCenter: + left, right = tableHeaderAlignColChar, tableHeaderAlignColChar + } + _, _ = r.w.Write(left) + _, _ = r.w.Write(bytes.Repeat(tableHeaderColChar, width)) + _, _ = r.w.Write(right) + } + _, _ = r.w.Write([]byte("|")) + case *extAST.TableCell: + if !entering { + break + } + + width := columnWidths[colIndex] + align := columnAligns[colIndex] + + if tnode.Parent().Kind() == extAST.KindTableHeader { + align = extAST.AlignLeft + } + + cellBuf.Reset() + if err := ast.Walk(tnode, r.mr.newRender(&cellBuf, r.source).renderNode); err != nil { + return ast.WalkStop, err + } + + _, _ = r.w.Write([]byte("| ")) + whitespaceWidth := width - runewidth.StringWidth(cellBuf.String()) + switch align { + default: + fallthrough + case extAST.AlignLeft: + _, _ = r.w.Write(cellBuf.Bytes()) + _, _ = r.w.Write(bytes.Repeat([]byte{' '}, 1+whitespaceWidth)) + case extAST.AlignCenter: + first := whitespaceWidth / 2 + _, _ = r.w.Write(bytes.Repeat([]byte{' '}, first)) + _, _ = r.w.Write(cellBuf.Bytes()) + _, _ = r.w.Write(bytes.Repeat([]byte{' '}, whitespaceWidth-first)) + _, _ = r.w.Write([]byte{' '}) + case extAST.AlignRight: + _, _ = r.w.Write(bytes.Repeat([]byte{' '}, whitespaceWidth)) + _, _ = r.w.Write(cellBuf.Bytes()) + _, _ = r.w.Write([]byte{' '}) + } + colIndex++ + return ast.WalkSkipChildren, nil + default: + return ast.WalkStop, fmt.Errorf("detected unexpected tree type %v", tnode.Kind()) + } + return ast.WalkContinue, nil + }); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/Kunde21/markdownfmt/v3/markdown/writer_indent.go b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/writer_indent.go new file mode 100644 index 00000000..a763f18a --- /dev/null +++ b/vendor/github.com/Kunde21/markdownfmt/v3/markdown/writer_indent.go @@ -0,0 +1,106 @@ +package markdown + +import ( + "io" +) + +// lineIndentWriter wraps io.Writer and adds given indent everytime new line is created . +type lineIndentWriter struct { + io.Writer + + id indentation + firstWriteExtraIndent []byte + + previousCharWasNewLine bool +} + +func wrapWithLineIndentWriter(w io.Writer) *lineIndentWriter { + return &lineIndentWriter{Writer: w, previousCharWasNewLine: true} +} + +func (l *lineIndentWriter) PushIndent(indent []byte) { + l.id.Push(indent) +} + +func (l *lineIndentWriter) PopIndent() { + l.id.Pop() +} + +func (l *lineIndentWriter) AddIndentOnFirstWrite(add []byte) { + l.firstWriteExtraIndent = append(l.firstWriteExtraIndent, add...) +} + +func (l *lineIndentWriter) DelIndentOnFirstWrite(del []byte) { + l.firstWriteExtraIndent = l.firstWriteExtraIndent[:len(l.firstWriteExtraIndent)-len(del)] +} + +func (l *lineIndentWriter) WasIndentOnFirstWriteWritten() bool { + return len(l.firstWriteExtraIndent) == 0 +} + +func (l *lineIndentWriter) Write(b []byte) (n int, _ error) { + if len(b) == 0 { + return 0, nil + } + + writtenFromB := 0 + for i, c := range b { + if l.previousCharWasNewLine { + ns, err := l.Writer.Write(l.id.Indent()) + n += ns + if err != nil { + return n, err + } + } + + if c == newLineChar[0] { + if !l.WasIndentOnFirstWriteWritten() { + ns, err := l.Writer.Write(l.firstWriteExtraIndent) + n += ns + if err != nil { + return n, err + } + l.firstWriteExtraIndent = nil + } + + ns, err := l.Writer.Write(b[writtenFromB : i+1]) + n += ns + writtenFromB += ns + if err != nil { + return n, err + } + l.previousCharWasNewLine = true + continue + } + + // Not a newline, make a space if indent was created. + if l.previousCharWasNewLine { + ws := l.id.Whitespace() + if len(ws) > 0 { + ns, err := l.Writer.Write(ws) + n += ns + if err != nil { + return n, err + } + } + } + l.previousCharWasNewLine = false + } + + if writtenFromB >= len(b) { + return n, nil + } + + if !l.WasIndentOnFirstWriteWritten() { + ns, err := l.Writer.Write(l.firstWriteExtraIndent) + n += ns + if err != nil { + return n, err + } + l.firstWriteExtraIndent = nil + } + + ns, err := l.Writer.Write(b[writtenFromB:]) + n += ns + return n, err +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go index ff14da31..42062538 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go @@ -127,13 +127,6 @@ type VerifiableSignature struct { Packet *Signature } -// SaltedHashSpecifier specifies that the given salt and hash are -// used by a v6 signature. -type SaltedHashSpecifier struct { - Hash crypto.Hash - Salt []byte -} - // NewVerifiableSig returns a struct of type VerifiableSignature referencing the input signature. func NewVerifiableSig(signature *Signature) *VerifiableSignature { return &VerifiableSignature{ diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go index ac897d70..40850659 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go @@ -6,7 +6,6 @@ package openpgp // import "github.com/ProtonMail/go-crypto/openpgp" import ( - "bytes" "crypto" _ "crypto/sha256" _ "crypto/sha512" @@ -455,19 +454,13 @@ func (scr *signatureCheckReader) Read(buf []byte) (int, error) { // if any, and a possible signature verification error. // If the signer isn't known, ErrUnknownIssuer is returned. func VerifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) { - return verifyDetachedSignature(keyring, signed, signature, nil, nil, false, config) + return verifyDetachedSignature(keyring, signed, signature, nil, false, config) } // VerifyDetachedSignatureAndHash performs the same actions as // VerifyDetachedSignature and checks that the expected hash functions were used. func VerifyDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) { - return verifyDetachedSignature(keyring, signed, signature, expectedHashes, nil, true, config) -} - -// VerifyDetachedSignatureAndSaltedHash performs the same actions as -// VerifyDetachedSignature and checks that the expected hash functions and salts were used. -func VerifyDetachedSignatureAndSaltedHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, expectedSaltedHashes []*packet.SaltedHashSpecifier, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) { - return verifyDetachedSignature(keyring, signed, signature, expectedHashes, expectedSaltedHashes, true, config) + return verifyDetachedSignature(keyring, signed, signature, expectedHashes, true, config) } // CheckDetachedSignature takes a signed file and a detached signature and @@ -475,25 +468,18 @@ func VerifyDetachedSignatureAndSaltedHash(keyring KeyRing, signed, signature io. // signature verification error. If the signer isn't known, // ErrUnknownIssuer is returned. func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) { - _, signer, err = verifyDetachedSignature(keyring, signed, signature, nil, nil, false, config) - return -} - -// CheckDetachedSignatureAndSaltedHash performs the same actions as -// CheckDetachedSignature and checks that the expected hash functions or salted hash functions were used. -func CheckDetachedSignatureAndSaltedHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, expectedSaltedHashes []*packet.SaltedHashSpecifier, config *packet.Config) (signer *Entity, err error) { - _, signer, err = verifyDetachedSignature(keyring, signed, signature, expectedHashes, expectedSaltedHashes, true, config) + _, signer, err = verifyDetachedSignature(keyring, signed, signature, nil, false, config) return } // CheckDetachedSignatureAndHash performs the same actions as // CheckDetachedSignature and checks that the expected hash functions were used. func CheckDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (signer *Entity, err error) { - _, signer, err = verifyDetachedSignature(keyring, signed, signature, expectedHashes, nil, true, config) + _, signer, err = verifyDetachedSignature(keyring, signed, signature, expectedHashes, true, config) return } -func verifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, expectedSaltedHashes []*packet.SaltedHashSpecifier, checkHashes bool, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) { +func verifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, checkHashes bool, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) { var issuerKeyId uint64 var hashFunc crypto.Hash var sigType packet.SignatureType @@ -523,22 +509,11 @@ func verifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, expec sigType = sig.SigType if checkHashes { matchFound := false - if sig.Version == 6 { - // check for salted hashes - for _, expectedSaltedHash := range expectedSaltedHashes { - if hashFunc == expectedSaltedHash.Hash && bytes.Equal(sig.Salt(), expectedSaltedHash.Salt) { - matchFound = true - break - } - } - - } else { - // check for hashes - for _, expectedHash := range expectedHashes { - if hashFunc == expectedHash { - matchFound = true - break - } + // check for hashes + for _, expectedHash := range expectedHashes { + if hashFunc == expectedHash { + matchFound = true + break } } if !matchFound { diff --git a/vendor/github.com/bmatcuk/doublestar/v4/.codecov.yml b/vendor/github.com/bmatcuk/doublestar/v4/.codecov.yml new file mode 100644 index 00000000..db6e504a --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/.codecov.yml @@ -0,0 +1,10 @@ +coverage: + status: + project: + default: + threshold: 1% + patch: + default: + target: 70% +ignore: + - globoptions.go diff --git a/vendor/github.com/bmatcuk/doublestar/v4/.gitignore b/vendor/github.com/bmatcuk/doublestar/v4/.gitignore new file mode 100644 index 00000000..af212ecc --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/.gitignore @@ -0,0 +1,32 @@ +# vi +*~ +*.swp +*.swo + +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +# test directory +test/ diff --git a/vendor/github.com/bmatcuk/doublestar/v4/LICENSE b/vendor/github.com/bmatcuk/doublestar/v4/LICENSE new file mode 100644 index 00000000..309c9d1d --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 Bob Matcuk + +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/bmatcuk/doublestar/v4/README.md b/vendor/github.com/bmatcuk/doublestar/v4/README.md new file mode 100644 index 00000000..70117eff --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/README.md @@ -0,0 +1,402 @@ +# doublestar + +Path pattern matching and globbing supporting `doublestar` (`**`) patterns. + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/bmatcuk/doublestar)](https://pkg.go.dev/github.com/bmatcuk/doublestar/v4) +[![Release](https://img.shields.io/github/release/bmatcuk/doublestar.svg?branch=master)](https://github.com/bmatcuk/doublestar/releases) +[![Build Status](https://github.com/bmatcuk/doublestar/actions/workflows/test.yml/badge.svg)](https://github.com/bmatcuk/doublestar/actions) +[![codecov.io](https://img.shields.io/codecov/c/github/bmatcuk/doublestar.svg?branch=master)](https://codecov.io/github/bmatcuk/doublestar?branch=master) +[![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/bmatcuk) + +## About + +#### [Upgrading?](UPGRADING.md) + +**doublestar** is a [golang] implementation of path pattern matching and +globbing with support for "doublestar" (aka globstar: `**`) patterns. + +doublestar patterns match files and directories recursively. For example, if +you had the following directory structure: + +```bash +grandparent +`-- parent + |-- child1 + `-- child2 +``` + +You could find the children with patterns such as: `**/child*`, +`grandparent/**/child?`, `**/parent/*`, or even just `**` by itself (which will +return all files and directories recursively). + +Bash's globstar is doublestar's inspiration and, as such, works similarly. +Note that the doublestar must appear as a path component by itself. A pattern +such as `/path**` is invalid and will be treated the same as `/path*`, but +`/path*/**` should achieve the desired result. Additionally, `/path/**` will +match all directories and files under the path directory, but `/path/**/` will +only match directories. + +v4 is a complete rewrite with a focus on performance. Additionally, +[doublestar] has been updated to use the new [io/fs] package for filesystem +access. As a result, it is only supported by [golang] v1.16+. + +## Installation + +**doublestar** can be installed via `go get`: + +```bash +go get github.com/bmatcuk/doublestar/v4 +``` + +To use it in your code, you must import it: + +```go +import "github.com/bmatcuk/doublestar/v4" +``` + +## Usage + +### ErrBadPattern + +```go +doublestar.ErrBadPattern +``` + +Returned by various functions to report that the pattern is malformed. At the +moment, this value is equal to `path.ErrBadPattern`, but, for portability, this +equivalence should probably not be relied upon. + +### Match + +```go +func Match(pattern, name string) (bool, error) +``` + +Match returns true if `name` matches the file name `pattern` ([see +"patterns"]). `name` and `pattern` are split on forward slash (`/`) characters +and may be relative or absolute. + +Match requires pattern to match all of name, not just a substring. The only +possible returned error is `ErrBadPattern`, when pattern is malformed. + +Note: this is meant as a drop-in replacement for `path.Match()` which always +uses `'/'` as the path separator. If you want to support systems which use a +different path separator (such as Windows), what you want is `PathMatch()`. +Alternatively, you can run `filepath.ToSlash()` on both pattern and name and +then use this function. + +Note: users should _not_ count on the returned error, +`doublestar.ErrBadPattern`, being equal to `path.ErrBadPattern`. + + +### PathMatch + +```go +func PathMatch(pattern, name string) (bool, error) +``` + +PathMatch returns true if `name` matches the file name `pattern` ([see +"patterns"]). The difference between Match and PathMatch is that PathMatch will +automatically use your system's path separator to split `name` and `pattern`. +On systems where the path separator is `'\'`, escaping will be disabled. + +Note: this is meant as a drop-in replacement for `filepath.Match()`. It assumes +that both `pattern` and `name` are using the system's path separator. If you +can't be sure of that, use `filepath.ToSlash()` on both `pattern` and `name`, +and then use the `Match()` function instead. + +### GlobOption + +Options that may be passed to `Glob`, `GlobWalk`, or `FilepathGlob`. Any number +of options may be passed to these functions, and in any order, as the last +argument(s). + +```go +WithFailOnIOErrors() +``` + +If passed, doublestar will abort and return IO errors when encountered. Note +that if the glob pattern references a path that does not exist (such as +`nonexistent/path/*`), this is _not_ considered an IO error: it is considered a +pattern with no matches. + +```go +WithFailOnPatternNotExist() +``` + +If passed, doublestar will abort and return `doublestar.ErrPatternNotExist` if +the pattern references a path that does not exist before any meta characters +such as `nonexistent/path/*`. Note that alts (ie, `{...}`) are expanded before +this check. In other words, a pattern such as `{a,b}/*` may fail if either `a` +or `b` do not exist but `*/{a,b}` will never fail because the star may match +nothing. + +```go +WithFilesOnly() +``` + +If passed, doublestar will only return "files" from `Glob`, `GlobWalk`, or +`FilepathGlob`. In this context, "files" are anything that is not a directory +or a symlink to a directory. + +Note: if combined with the WithNoFollow option, symlinks to directories _will_ +be included in the result since no attempt is made to follow the symlink. + +```go +WithNoFollow() +``` + +If passed, doublestar will not follow symlinks while traversing the filesystem. +However, due to io/fs's _very_ poor support for querying the filesystem about +symlinks, there's a caveat here: if part of the pattern before any meta +characters contains a reference to a symlink, it will be followed. For example, +a pattern such as `path/to/symlink/*` will be followed assuming it is a valid +symlink to a directory. However, from this same example, a pattern such as +`path/to/**` will not traverse the `symlink`, nor would `path/*/symlink/*` + +Note: if combined with the WithFilesOnly option, symlinks to directories _will_ +be included in the result since no attempt is made to follow the symlink. + +### Glob + +```go +func Glob(fsys fs.FS, pattern string, opts ...GlobOption) ([]string, error) +``` + +Glob returns the names of all files matching pattern or nil if there is no +matching file. The syntax of patterns is the same as in `Match()`. The pattern +may describe hierarchical names such as `usr/*/bin/ed`. + +Glob ignores file system errors such as I/O errors reading directories by +default. The only possible returned error is `ErrBadPattern`, reporting that +the pattern is malformed. + +To enable aborting on I/O errors, the `WithFailOnIOErrors` option can be +passed. + +Note: this is meant as a drop-in replacement for `io/fs.Glob()`. Like +`io/fs.Glob()`, this function assumes that your pattern uses `/` as the path +separator even if that's not correct for your OS (like Windows). If you aren't +sure if that's the case, you can use `filepath.ToSlash()` on your pattern +before calling `Glob()`. + +Like `io/fs.Glob()`, patterns containing `/./`, `/../`, or starting with `/` +will return no results and no errors. This seems to be a [conscious +decision](https://github.com/golang/go/issues/44092#issuecomment-774132549), +even if counter-intuitive. You can use [SplitPattern] to divide a pattern into +a base path (to initialize an `FS` object) and pattern. + +Note: users should _not_ count on the returned error, +`doublestar.ErrBadPattern`, being equal to `path.ErrBadPattern`. + +### GlobWalk + +```go +type GlobWalkFunc func(path string, d fs.DirEntry) error + +func GlobWalk(fsys fs.FS, pattern string, fn GlobWalkFunc, opts ...GlobOption) error +``` + +GlobWalk calls the callback function `fn` for every file matching pattern. The +syntax of pattern is the same as in Match() and the behavior is the same as +Glob(), with regard to limitations (such as patterns containing `/./`, `/../`, +or starting with `/`). The pattern may describe hierarchical names such as +usr/*/bin/ed. + +GlobWalk may have a small performance benefit over Glob if you do not need a +slice of matches because it can avoid allocating memory for the matches. +Additionally, GlobWalk gives you access to the `fs.DirEntry` objects for each +match, and lets you quit early by returning a non-nil error from your callback +function. Like `io/fs.WalkDir`, if your callback returns `SkipDir`, GlobWalk +will skip the current directory. This means that if the current path _is_ a +directory, GlobWalk will not recurse into it. If the current path is not a +directory, the rest of the parent directory will be skipped. + +GlobWalk ignores file system errors such as I/O errors reading directories by +default. GlobWalk may return `ErrBadPattern`, reporting that the pattern is +malformed. + +To enable aborting on I/O errors, the `WithFailOnIOErrors` option can be +passed. + +Additionally, if the callback function `fn` returns an error, GlobWalk will +exit immediately and return that error. + +Like Glob(), this function assumes that your pattern uses `/` as the path +separator even if that's not correct for your OS (like Windows). If you aren't +sure if that's the case, you can use filepath.ToSlash() on your pattern before +calling GlobWalk(). + +Note: users should _not_ count on the returned error, +`doublestar.ErrBadPattern`, being equal to `path.ErrBadPattern`. + +### FilepathGlob + +```go +func FilepathGlob(pattern string, opts ...GlobOption) (matches []string, err error) +``` + +FilepathGlob returns the names of all files matching pattern or nil if there is +no matching file. The syntax of pattern is the same as in Match(). The pattern +may describe hierarchical names such as usr/*/bin/ed. + +FilepathGlob ignores file system errors such as I/O errors reading directories +by default. The only possible returned error is `ErrBadPattern`, reporting that +the pattern is malformed. + +To enable aborting on I/O errors, the `WithFailOnIOErrors` option can be +passed. + +Note: FilepathGlob is a convenience function that is meant as a drop-in +replacement for `path/filepath.Glob()` for users who don't need the +complication of io/fs. Basically, it: + +* Runs `filepath.Clean()` and `ToSlash()` on the pattern +* Runs `SplitPattern()` to get a base path and a pattern to Glob +* Creates an FS object from the base path and `Glob()s` on the pattern +* Joins the base path with all of the matches from `Glob()` + +Returned paths will use the system's path separator, just like +`filepath.Glob()`. + +Note: the returned error `doublestar.ErrBadPattern` is not equal to +`filepath.ErrBadPattern`. + +### SplitPattern + +```go +func SplitPattern(p string) (base, pattern string) +``` + +SplitPattern is a utility function. Given a pattern, SplitPattern will return +two strings: the first string is everything up to the last slash (`/`) that +appears _before_ any unescaped "meta" characters (ie, `*?[{`). The second +string is everything after that slash. For example, given the pattern: + +``` +../../path/to/meta*/** + ^----------- split here +``` + +SplitPattern returns "../../path/to" and "meta*/**". This is useful for +initializing os.DirFS() to call Glob() because Glob() will silently fail if +your pattern includes `/./` or `/../`. For example: + +```go +base, pattern := SplitPattern("../../path/to/meta*/**") +fsys := os.DirFS(base) +matches, err := Glob(fsys, pattern) +``` + +If SplitPattern cannot find somewhere to split the pattern (for example, +`meta*/**`), it will return "." and the unaltered pattern (`meta*/**` in this +example). + +Of course, it is your responsibility to decide if the returned base path is +"safe" in the context of your application. Perhaps you could use Match() to +validate against a list of approved base directories? + +### ValidatePattern + +```go +func ValidatePattern(s string) bool +``` + +Validate a pattern. Patterns are validated while they run in Match(), +PathMatch(), and Glob(), so, you normally wouldn't need to call this. However, +there are cases where this might be useful: for example, if your program allows +a user to enter a pattern that you'll run at a later time, you might want to +validate it. + +ValidatePattern assumes your pattern uses '/' as the path separator. + +### ValidatePathPattern + +```go +func ValidatePathPattern(s string) bool +``` + +Like ValidatePattern, only uses your OS path separator. In other words, use +ValidatePattern if you would normally use Match() or Glob(). Use +ValidatePathPattern if you would normally use PathMatch(). Keep in mind, Glob() +requires '/' separators, even if your OS uses something else. + +### Patterns + +**doublestar** supports the following special terms in the patterns: + +Special Terms | Meaning +------------- | ------- +`*` | matches any sequence of non-path-separators +`/**/` | matches zero or more directories +`?` | matches any single non-path-separator character +`[class]` | matches any single non-path-separator character against a class of characters ([see "character classes"]) +`{alt1,...}` | matches a sequence of characters if one of the comma-separated alternatives matches + +Any character with a special meaning can be escaped with a backslash (`\`). + +A doublestar (`**`) should appear surrounded by path separators such as `/**/`. +A mid-pattern doublestar (`**`) behaves like bash's globstar option: a pattern +such as `path/to/**.txt` would return the same results as `path/to/*.txt`. The +pattern you're looking for is `path/to/**/*.txt`. + +#### Character Classes + +Character classes support the following: + +Class | Meaning +---------- | ------- +`[abc]` | matches any single character within the set +`[a-z]` | matches any single character in the range +`[^class]` | matches any single character which does *not* match the class +`[!class]` | same as `^`: negates the class + +## Performance + +``` +goos: darwin +goarch: amd64 +pkg: github.com/bmatcuk/doublestar/v4 +cpu: Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz +BenchmarkMatch-8 285639 3868 ns/op 0 B/op 0 allocs/op +BenchmarkGoMatch-8 286945 3726 ns/op 0 B/op 0 allocs/op +BenchmarkPathMatch-8 320511 3493 ns/op 0 B/op 0 allocs/op +BenchmarkGoPathMatch-8 304236 3434 ns/op 0 B/op 0 allocs/op +BenchmarkGlob-8 466 2501123 ns/op 190225 B/op 2849 allocs/op +BenchmarkGlobWalk-8 476 2536293 ns/op 184017 B/op 2750 allocs/op +BenchmarkGoGlob-8 463 2574836 ns/op 194249 B/op 2929 allocs/op +``` + +These benchmarks (in `doublestar_test.go`) compare Match() to path.Match(), +PathMath() to filepath.Match(), and Glob() + GlobWalk() to io/fs.Glob(). They +only run patterns that the standard go packages can understand as well (so, no +`{alts}` or `**`) for a fair comparison. Of course, alts and doublestars will +be less performant than the other pattern meta characters. + +Alts are essentially like running multiple patterns, the number of which can +get large if your pattern has alts nested inside alts. This affects both +matching (ie, Match()) and globbing (Glob()). + +`**` performance in matching is actually pretty similar to a regular `*`, but +can cause a large number of reads when globbing as it will need to recursively +traverse your filesystem. + +## Sponsors +I started this project in 2014 in my spare time and have been maintaining it +ever since. In that time, it has grown into one of the most popular globbing +libraries in the Go ecosystem. So, if **doublestar** is a useful library in +your project, consider [sponsoring] my work! I'd really appreciate it! + +Thanks for sponsoring me! + +## License + +[MIT License](LICENSE) + +[SplitPattern]: #splitpattern +[doublestar]: https://github.com/bmatcuk/doublestar +[golang]: http://golang.org/ +[io/fs]: https://pkg.go.dev/io/fs +[see "character classes"]: #character-classes +[see "patterns"]: #patterns +[sponsoring]: https://github.com/sponsors/bmatcuk diff --git a/vendor/github.com/bmatcuk/doublestar/v4/UPGRADING.md b/vendor/github.com/bmatcuk/doublestar/v4/UPGRADING.md new file mode 100644 index 00000000..25aace3d --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/UPGRADING.md @@ -0,0 +1,63 @@ +# Upgrading from v3 to v4 + +v4 is a complete rewrite with a focus on performance. Additionally, +[doublestar] has been updated to use the new [io/fs] package for filesystem +access. As a result, it is only supported by [golang] v1.16+. + +`Match()` and `PathMatch()` mostly did not change, besides big performance +improvements. Their API is the same. However, note the following corner cases: + +* In previous versions of [doublestar], `PathMatch()` could accept patterns + that used either platform-specific path separators, or `/`. This was + undocumented and didn't match `filepath.Match()`. In v4, both `pattern` and + `name` must be using appropriate path separators for the platform. You can + use `filepath.FromSlash()` to change `/` to platform-specific separators if + you aren't sure. +* In previous versions of [doublestar], a pattern such as `path/to/a/**` would + _not_ match `path/to/a`. In v4, this pattern _will_ match because if `a` was + a directory, `Glob()` would return it. In other words, the following returns + true: `Match("path/to/a/**", "path/to/a")` + +`Glob()` changed from using a [doublestar]-specific filesystem abstraction (the +`OS` interface) to the [io/fs] package. As a result, it now takes a `fs.FS` as +its first argument. This change has a couple ramifications: + +* Like `io/fs.Glob`, `pattern` must use a `/` as path separator, even on + platforms that use something else. You can use `filepath.ToSlash()` on your + patterns if you aren't sure. +* Patterns that contain `/./` or `/../` are invalid. The [io/fs] package + rejects them, returning an IO error. Since `Glob()` ignores IO errors, it'll + end up being silently rejected. You can run `path.Clean()` to ensure they are + removed from the pattern. + +v4 also added a `GlobWalk()` function that is slightly more performant than +`Glob()` if you just need to iterate over the results and don't need a string +slice. You also get `fs.DirEntry` objects for each result, and can quit early +if your callback returns an error. + +# Upgrading from v2 to v3 + +v3 introduced using `!` to negate character classes, in addition to `^`. If any +of your patterns include a character class that starts with an exclamation mark +(ie, `[!...]`), you'll need to update the pattern to escape or move the +exclamation mark. Note that, like the caret (`^`), it only negates the +character class if it is the first character in the character class. + +# Upgrading from v1 to v2 + +The change from v1 to v2 was fairly minor: the return type of the `Open` method +on the `OS` interface was changed from `*os.File` to `File`, a new interface +exported by doublestar. The new `File` interface only defines the functionality +doublestar actually needs (`io.Closer` and `Readdir`), making it easier to use +doublestar with [go-billy], [afero], or something similar. If you were using +this functionality, updating should be as easy as updating `Open's` return +type, since `os.File` already implements `doublestar.File`. + +If you weren't using this functionality, updating should be as easy as changing +your dependencies to point to v2. + +[afero]: https://github.com/spf13/afero +[doublestar]: https://github.com/bmatcuk/doublestar +[go-billy]: https://github.com/src-d/go-billy +[golang]: http://golang.org/ +[io/fs]: https://golang.org/pkg/io/fs/ diff --git a/vendor/github.com/bmatcuk/doublestar/v4/doublestar.go b/vendor/github.com/bmatcuk/doublestar/v4/doublestar.go new file mode 100644 index 00000000..210fd40c --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/doublestar.go @@ -0,0 +1,13 @@ +package doublestar + +import ( + "errors" + "path" +) + +// ErrBadPattern indicates a pattern was malformed. +var ErrBadPattern = path.ErrBadPattern + +// ErrPatternNotExist indicates that the pattern passed to Glob, GlobWalk, or +// FilepathGlob references a path that does not exist. +var ErrPatternNotExist = errors.New("pattern does not exist") diff --git a/vendor/github.com/bmatcuk/doublestar/v4/glob.go b/vendor/github.com/bmatcuk/doublestar/v4/glob.go new file mode 100644 index 00000000..519601b1 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/glob.go @@ -0,0 +1,473 @@ +package doublestar + +import ( + "errors" + "io/fs" + "path" +) + +// Glob returns the names of all files matching pattern or nil if there is no +// matching file. The syntax of pattern is the same as in Match(). The pattern +// may describe hierarchical names such as usr/*/bin/ed. +// +// Glob ignores file system errors such as I/O errors reading directories by +// default. The only possible returned error is ErrBadPattern, reporting that +// the pattern is malformed. +// +// To enable aborting on I/O errors, the WithFailOnIOErrors option can be +// passed. +// +// Note: this is meant as a drop-in replacement for io/fs.Glob(). Like +// io/fs.Glob(), this function assumes that your pattern uses `/` as the path +// separator even if that's not correct for your OS (like Windows). If you +// aren't sure if that's the case, you can use filepath.ToSlash() on your +// pattern before calling Glob(). +// +// Like `io/fs.Glob()`, patterns containing `/./`, `/../`, or starting with `/` +// will return no results and no errors. You can use SplitPattern to divide a +// pattern into a base path (to initialize an `FS` object) and pattern. +// +// Note: users should _not_ count on the returned error, +// doublestar.ErrBadPattern, being equal to path.ErrBadPattern. +// +func Glob(fsys fs.FS, pattern string, opts ...GlobOption) ([]string, error) { + if !ValidatePattern(pattern) { + return nil, ErrBadPattern + } + + g := newGlob(opts...) + + if hasMidDoubleStar(pattern) { + // If the pattern has a `**` anywhere but the very end, GlobWalk is more + // performant because it can get away with less allocations. If the pattern + // ends in a `**`, both methods are pretty much the same, but Glob has a + // _very_ slight advantage because of lower function call overhead. + var matches []string + err := g.doGlobWalk(fsys, pattern, true, true, func(p string, d fs.DirEntry) error { + matches = append(matches, p) + return nil + }) + return matches, err + } + return g.doGlob(fsys, pattern, nil, true, true) +} + +// Does the actual globbin' +// - firstSegment is true if we're in the first segment of the pattern, ie, +// the right-most part where we can match files. If it's false, we're +// somewhere in the middle (or at the beginning) and can only match +// directories since there are path segments above us. +// - beforeMeta is true if we're exploring segments before any meta +// characters, ie, in a pattern such as `path/to/file*.txt`, the `path/to/` +// bit does not contain any meta characters. +func (g *glob) doGlob(fsys fs.FS, pattern string, m []string, firstSegment, beforeMeta bool) (matches []string, err error) { + matches = m + patternStart := indexMeta(pattern) + if patternStart == -1 { + // pattern doesn't contain any meta characters - does a file matching the + // pattern exist? + // The pattern may contain escaped wildcard characters for an exact path match. + path := unescapeMeta(pattern) + pathInfo, pathExists, pathErr := g.exists(fsys, path, beforeMeta) + if pathErr != nil { + return nil, pathErr + } + + if pathExists && (!firstSegment || !g.filesOnly || !pathInfo.IsDir()) { + matches = append(matches, path) + } + + return + } + + dir := "." + splitIdx := lastIndexSlashOrAlt(pattern) + if splitIdx != -1 { + if pattern[splitIdx] == '}' { + openingIdx := indexMatchedOpeningAlt(pattern[:splitIdx]) + if openingIdx == -1 { + // if there's no matching opening index, technically Match() will treat + // an unmatched `}` as nothing special, so... we will, too! + splitIdx = lastIndexSlash(pattern[:splitIdx]) + if splitIdx != -1 { + dir = pattern[:splitIdx] + pattern = pattern[splitIdx+1:] + } + } else { + // otherwise, we have to handle the alts: + return g.globAlts(fsys, pattern, openingIdx, splitIdx, matches, firstSegment, beforeMeta) + } + } else { + dir = pattern[:splitIdx] + pattern = pattern[splitIdx+1:] + } + } + + // if `splitIdx` is less than `patternStart`, we know `dir` has no meta + // characters. They would be equal if they are both -1, which means `dir` + // will be ".", and we know that doesn't have meta characters either. + if splitIdx <= patternStart { + return g.globDir(fsys, dir, pattern, matches, firstSegment, beforeMeta) + } + + var dirs []string + dirs, err = g.doGlob(fsys, dir, matches, false, beforeMeta) + if err != nil { + return + } + for _, d := range dirs { + matches, err = g.globDir(fsys, d, pattern, matches, firstSegment, false) + if err != nil { + return + } + } + + return +} + +// handle alts in the glob pattern - `openingIdx` and `closingIdx` are the +// indexes of `{` and `}`, respectively +func (g *glob) globAlts(fsys fs.FS, pattern string, openingIdx, closingIdx int, m []string, firstSegment, beforeMeta bool) (matches []string, err error) { + matches = m + + var dirs []string + startIdx := 0 + afterIdx := closingIdx + 1 + splitIdx := lastIndexSlashOrAlt(pattern[:openingIdx]) + if splitIdx == -1 || pattern[splitIdx] == '}' { + // no common prefix + dirs = []string{""} + } else { + // our alts have a common prefix that we can process first + dirs, err = g.doGlob(fsys, pattern[:splitIdx], matches, false, beforeMeta) + if err != nil { + return + } + + startIdx = splitIdx + 1 + } + + for _, d := range dirs { + patIdx := openingIdx + 1 + altResultsStartIdx := len(matches) + thisResultStartIdx := altResultsStartIdx + for patIdx < closingIdx { + nextIdx := indexNextAlt(pattern[patIdx:closingIdx], true) + if nextIdx == -1 { + nextIdx = closingIdx + } else { + nextIdx += patIdx + } + + alt := buildAlt(d, pattern, startIdx, openingIdx, patIdx, nextIdx, afterIdx) + matches, err = g.doGlob(fsys, alt, matches, firstSegment, beforeMeta) + if err != nil { + return + } + + matchesLen := len(matches) + if altResultsStartIdx != thisResultStartIdx && thisResultStartIdx != matchesLen { + // Alts can result in matches that aren't sorted, or, worse, duplicates + // (consider the trivial pattern `path/to/{a,*}`). Since doGlob returns + // sorted results, we can do a sort of in-place merge and remove + // duplicates. But, we only need to do this if this isn't the first alt + // (ie, `altResultsStartIdx != thisResultsStartIdx`) and if the latest + // alt actually added some matches (`thisResultStartIdx != + // len(matches)`) + matches = sortAndRemoveDups(matches, altResultsStartIdx, thisResultStartIdx, matchesLen) + + // length of matches may have changed + thisResultStartIdx = len(matches) + } else { + thisResultStartIdx = matchesLen + } + + patIdx = nextIdx + 1 + } + } + + return +} + +// find files/subdirectories in the given `dir` that match `pattern` +func (g *glob) globDir(fsys fs.FS, dir, pattern string, matches []string, canMatchFiles, beforeMeta bool) (m []string, e error) { + m = matches + + if pattern == "" { + if !canMatchFiles || !g.filesOnly { + // pattern can be an empty string if the original pattern ended in a + // slash, in which case, we should just return dir, but only if it + // actually exists and it's a directory (or a symlink to a directory) + _, isDir, err := g.isPathDir(fsys, dir, beforeMeta) + if err != nil { + return nil, err + } + if isDir { + m = append(m, dir) + } + } + return + } + + if pattern == "**" { + return g.globDoubleStar(fsys, dir, m, canMatchFiles, beforeMeta) + } + + dirs, err := fs.ReadDir(fsys, dir) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + e = g.handlePatternNotExist(beforeMeta) + } else { + e = g.forwardErrIfFailOnIOErrors(err) + } + return + } + + var matched bool + for _, info := range dirs { + name := info.Name() + matched, e = matchWithSeparator(pattern, name, '/', false) + if e != nil { + return + } + if matched { + matched = canMatchFiles + if !matched || g.filesOnly { + matched, e = g.isDir(fsys, dir, name, info) + if e != nil { + return + } + if canMatchFiles { + // if we're here, it's because g.filesOnly + // is set and we don't want directories + matched = !matched + } + } + if matched { + m = append(m, path.Join(dir, name)) + } + } + } + + return +} + +func (g *glob) globDoubleStar(fsys fs.FS, dir string, matches []string, canMatchFiles, beforeMeta bool) ([]string, error) { + dirs, err := fs.ReadDir(fsys, dir) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return matches, g.handlePatternNotExist(beforeMeta) + } else { + return matches, g.forwardErrIfFailOnIOErrors(err) + } + } + + if !g.filesOnly { + // `**` can match *this* dir, so add it + matches = append(matches, dir) + } + + for _, info := range dirs { + name := info.Name() + isDir, err := g.isDir(fsys, dir, name, info) + if err != nil { + return nil, err + } + if isDir { + matches, err = g.globDoubleStar(fsys, path.Join(dir, name), matches, canMatchFiles, false) + if err != nil { + return nil, err + } + } else if canMatchFiles { + matches = append(matches, path.Join(dir, name)) + } + } + + return matches, nil +} + +// Returns true if the pattern has a doublestar in the middle of the pattern. +// In this case, GlobWalk is faster because it can get away with less +// allocations. However, Glob has a _very_ slight edge if the pattern ends in +// `**`. +func hasMidDoubleStar(p string) bool { + // subtract 3: 2 because we want to return false if the pattern ends in `**` + // (Glob is _very_ slightly faster in that case), and the extra 1 because our + // loop checks p[i] and p[i+1]. + l := len(p) - 3 + for i := 0; i < l; i++ { + if p[i] == '\\' { + // escape next byte + i++ + } else if p[i] == '*' && p[i+1] == '*' { + return true + } + } + return false +} + +// Returns the index of the first unescaped meta character, or negative 1. +func indexMeta(s string) int { + var c byte + l := len(s) + for i := 0; i < l; i++ { + c = s[i] + if c == '*' || c == '?' || c == '[' || c == '{' { + return i + } else if c == '\\' { + // skip next byte + i++ + } + } + return -1 +} + +// Returns the index of the last unescaped slash or closing alt (`}`) in the +// string, or negative 1. +func lastIndexSlashOrAlt(s string) int { + for i := len(s) - 1; i >= 0; i-- { + if (s[i] == '/' || s[i] == '}') && (i == 0 || s[i-1] != '\\') { + return i + } + } + return -1 +} + +// Returns the index of the last unescaped slash in the string, or negative 1. +func lastIndexSlash(s string) int { + for i := len(s) - 1; i >= 0; i-- { + if s[i] == '/' && (i == 0 || s[i-1] != '\\') { + return i + } + } + return -1 +} + +// Assuming the byte after the end of `s` is a closing `}`, this function will +// find the index of the matching `{`. That is, it'll skip over any nested `{}` +// and account for escaping. +func indexMatchedOpeningAlt(s string) int { + alts := 1 + for i := len(s) - 1; i >= 0; i-- { + if s[i] == '}' && (i == 0 || s[i-1] != '\\') { + alts++ + } else if s[i] == '{' && (i == 0 || s[i-1] != '\\') { + if alts--; alts == 0 { + return i + } + } + } + return -1 +} + +// Returns true if the path exists +func (g *glob) exists(fsys fs.FS, name string, beforeMeta bool) (fs.FileInfo, bool, error) { + // name might end in a slash, but Stat doesn't like that + namelen := len(name) + if namelen > 1 && name[namelen-1] == '/' { + name = name[:namelen-1] + } + + info, err := fs.Stat(fsys, name) + if errors.Is(err, fs.ErrNotExist) { + return nil, false, g.handlePatternNotExist(beforeMeta) + } + return info, err == nil, g.forwardErrIfFailOnIOErrors(err) +} + +// Returns true if the path exists and is a directory or a symlink to a +// directory +func (g *glob) isPathDir(fsys fs.FS, name string, beforeMeta bool) (fs.FileInfo, bool, error) { + info, err := fs.Stat(fsys, name) + if errors.Is(err, fs.ErrNotExist) { + return nil, false, g.handlePatternNotExist(beforeMeta) + } + return info, err == nil && info.IsDir(), g.forwardErrIfFailOnIOErrors(err) +} + +// Returns whether or not the given DirEntry is a directory. If the DirEntry +// represents a symbolic link, the link is followed by running fs.Stat() on +// `path.Join(dir, name)` (if dir is "", name will be used without joining) +func (g *glob) isDir(fsys fs.FS, dir, name string, info fs.DirEntry) (bool, error) { + if !g.noFollow && (info.Type()&fs.ModeSymlink) > 0 { + p := name + if dir != "" { + p = path.Join(dir, name) + } + finfo, err := fs.Stat(fsys, p) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + // this function is only ever called while expanding a glob, so it can + // never return ErrPatternNotExist + return false, nil + } + return false, g.forwardErrIfFailOnIOErrors(err) + } + return finfo.IsDir(), nil + } + return info.IsDir(), nil +} + +// Builds a string from an alt +func buildAlt(prefix, pattern string, startIdx, openingIdx, currentIdx, nextIdx, afterIdx int) string { + // pattern: + // ignored/start{alts,go,here}remaining - len = 36 + // | | | | ^--- afterIdx = 27 + // | | | \--------- nextIdx = 21 + // | | \----------- currentIdx = 19 + // | \----------------- openingIdx = 13 + // \---------------------- startIdx = 8 + // + // result: + // prefix/startgoremaining - len = 7 + 5 + 2 + 9 = 23 + var buf []byte + patLen := len(pattern) + size := (openingIdx - startIdx) + (nextIdx - currentIdx) + (patLen - afterIdx) + if prefix != "" && prefix != "." { + buf = make([]byte, 0, size+len(prefix)+1) + buf = append(buf, prefix...) + buf = append(buf, '/') + } else { + buf = make([]byte, 0, size) + } + buf = append(buf, pattern[startIdx:openingIdx]...) + buf = append(buf, pattern[currentIdx:nextIdx]...) + if afterIdx < patLen { + buf = append(buf, pattern[afterIdx:]...) + } + return string(buf) +} + +// Running alts can produce results that are not sorted, and, worse, can cause +// duplicates (consider the trivial pattern `path/to/{a,*}`). Since we know +// each run of doGlob is sorted, we can basically do the "merge" step of a +// merge sort in-place. +func sortAndRemoveDups(matches []string, idx1, idx2, l int) []string { + var tmp string + for ; idx1 < idx2; idx1++ { + if matches[idx1] < matches[idx2] { + // order is correct + continue + } else if matches[idx1] > matches[idx2] { + // need to swap and then re-sort matches above idx2 + tmp = matches[idx1] + matches[idx1] = matches[idx2] + + shft := idx2 + 1 + for ; shft < l && matches[shft] < tmp; shft++ { + matches[shft-1] = matches[shft] + } + matches[shft-1] = tmp + } else { + // duplicate - shift matches above idx2 down one and decrement l + for shft := idx2 + 1; shft < l; shft++ { + matches[shft-1] = matches[shft] + } + if l--; idx2 == l { + // nothing left to do... matches[idx2:] must have been full of dups + break + } + } + } + return matches[:l] +} diff --git a/vendor/github.com/bmatcuk/doublestar/v4/globoptions.go b/vendor/github.com/bmatcuk/doublestar/v4/globoptions.go new file mode 100644 index 00000000..9483c4bb --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/globoptions.go @@ -0,0 +1,144 @@ +package doublestar + +import "strings" + +// glob is an internal type to store options during globbing. +type glob struct { + failOnIOErrors bool + failOnPatternNotExist bool + filesOnly bool + noFollow bool +} + +// GlobOption represents a setting that can be passed to Glob, GlobWalk, and +// FilepathGlob. +type GlobOption func(*glob) + +// Construct a new glob object with the given options +func newGlob(opts ...GlobOption) *glob { + g := &glob{} + for _, opt := range opts { + opt(g) + } + return g +} + +// WithFailOnIOErrors is an option that can be passed to Glob, GlobWalk, or +// FilepathGlob. If passed, doublestar will abort and return IO errors when +// encountered. Note that if the glob pattern references a path that does not +// exist (such as `nonexistent/path/*`), this is _not_ considered an IO error: +// it is considered a pattern with no matches. +// +func WithFailOnIOErrors() GlobOption { + return func(g *glob) { + g.failOnIOErrors = true + } +} + +// WithFailOnPatternNotExist is an option that can be passed to Glob, GlobWalk, +// or FilepathGlob. If passed, doublestar will abort and return +// ErrPatternNotExist if the pattern references a path that does not exist +// before any meta charcters such as `nonexistent/path/*`. Note that alts (ie, +// `{...}`) are expanded before this check. In other words, a pattern such as +// `{a,b}/*` may fail if either `a` or `b` do not exist but `*/{a,b}` will +// never fail because the star may match nothing. +// +func WithFailOnPatternNotExist() GlobOption { + return func(g *glob) { + g.failOnPatternNotExist = true + } +} + +// WithFilesOnly is an option that can be passed to Glob, GlobWalk, or +// FilepathGlob. If passed, doublestar will only return files that match the +// pattern, not directories. +// +// Note: if combined with the WithNoFollow option, symlinks to directories +// _will_ be included in the result since no attempt is made to follow the +// symlink. +// +func WithFilesOnly() GlobOption { + return func(g *glob) { + g.filesOnly = true + } +} + +// WithNoFollow is an option that can be passed to Glob, GlobWalk, or +// FilepathGlob. If passed, doublestar will not follow symlinks while +// traversing the filesystem. However, due to io/fs's _very_ poor support for +// querying the filesystem about symlinks, there's a caveat here: if part of +// the pattern before any meta characters contains a reference to a symlink, it +// will be followed. For example, a pattern such as `path/to/symlink/*` will be +// followed assuming it is a valid symlink to a directory. However, from this +// same example, a pattern such as `path/to/**` will not traverse the +// `symlink`, nor would `path/*/symlink/*` +// +// Note: if combined with the WithFilesOnly option, symlinks to directories +// _will_ be included in the result since no attempt is made to follow the +// symlink. +// +func WithNoFollow() GlobOption { + return func(g *glob) { + g.noFollow = true + } +} + +// forwardErrIfFailOnIOErrors is used to wrap the return values of I/O +// functions. When failOnIOErrors is enabled, it will return err; otherwise, it +// always returns nil. +// +func (g *glob) forwardErrIfFailOnIOErrors(err error) error { + if g.failOnIOErrors { + return err + } + return nil +} + +// handleErrNotExist handles fs.ErrNotExist errors. If +// WithFailOnPatternNotExist has been enabled and canFail is true, this will +// return ErrPatternNotExist. Otherwise, it will return nil. +// +func (g *glob) handlePatternNotExist(canFail bool) error { + if canFail && g.failOnPatternNotExist { + return ErrPatternNotExist + } + return nil +} + +// Format options for debugging/testing purposes +func (g *glob) GoString() string { + var b strings.Builder + b.WriteString("opts: ") + + hasOpts := false + if g.failOnIOErrors { + b.WriteString("WithFailOnIOErrors") + hasOpts = true + } + if g.failOnPatternNotExist { + if hasOpts { + b.WriteString(", ") + } + b.WriteString("WithFailOnPatternNotExist") + hasOpts = true + } + if g.filesOnly { + if hasOpts { + b.WriteString(", ") + } + b.WriteString("WithFilesOnly") + hasOpts = true + } + if g.noFollow { + if hasOpts { + b.WriteString(", ") + } + b.WriteString("WithNoFollow") + hasOpts = true + } + + if !hasOpts { + b.WriteString("nil") + } + return b.String() +} diff --git a/vendor/github.com/bmatcuk/doublestar/v4/globwalk.go b/vendor/github.com/bmatcuk/doublestar/v4/globwalk.go new file mode 100644 index 00000000..84e764f0 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/globwalk.go @@ -0,0 +1,414 @@ +package doublestar + +import ( + "errors" + "io/fs" + "path" + "path/filepath" + "strings" +) + +// If returned from GlobWalkFunc, will cause GlobWalk to skip the current +// directory. In other words, if the current path is a directory, GlobWalk will +// not recurse into it. Otherwise, GlobWalk will skip the rest of the current +// directory. +var SkipDir = fs.SkipDir + +// Callback function for GlobWalk(). If the function returns an error, GlobWalk +// will end immediately and return the same error. +type GlobWalkFunc func(path string, d fs.DirEntry) error + +// GlobWalk calls the callback function `fn` for every file matching pattern. +// The syntax of pattern is the same as in Match() and the behavior is the same +// as Glob(), with regard to limitations (such as patterns containing `/./`, +// `/../`, or starting with `/`). The pattern may describe hierarchical names +// such as usr/*/bin/ed. +// +// GlobWalk may have a small performance benefit over Glob if you do not need a +// slice of matches because it can avoid allocating memory for the matches. +// Additionally, GlobWalk gives you access to the `fs.DirEntry` objects for +// each match, and lets you quit early by returning a non-nil error from your +// callback function. Like `io/fs.WalkDir`, if your callback returns `SkipDir`, +// GlobWalk will skip the current directory. This means that if the current +// path _is_ a directory, GlobWalk will not recurse into it. If the current +// path is not a directory, the rest of the parent directory will be skipped. +// +// GlobWalk ignores file system errors such as I/O errors reading directories +// by default. GlobWalk may return ErrBadPattern, reporting that the pattern is +// malformed. +// +// To enable aborting on I/O errors, the WithFailOnIOErrors option can be +// passed. +// +// Additionally, if the callback function `fn` returns an error, GlobWalk will +// exit immediately and return that error. +// +// Like Glob(), this function assumes that your pattern uses `/` as the path +// separator even if that's not correct for your OS (like Windows). If you +// aren't sure if that's the case, you can use filepath.ToSlash() on your +// pattern before calling GlobWalk(). +// +// Note: users should _not_ count on the returned error, +// doublestar.ErrBadPattern, being equal to path.ErrBadPattern. +// +func GlobWalk(fsys fs.FS, pattern string, fn GlobWalkFunc, opts ...GlobOption) error { + if !ValidatePattern(pattern) { + return ErrBadPattern + } + + g := newGlob(opts...) + return g.doGlobWalk(fsys, pattern, true, true, fn) +} + +// Actually execute GlobWalk +// - firstSegment is true if we're in the first segment of the pattern, ie, +// the right-most part where we can match files. If it's false, we're +// somewhere in the middle (or at the beginning) and can only match +// directories since there are path segments above us. +// - beforeMeta is true if we're exploring segments before any meta +// characters, ie, in a pattern such as `path/to/file*.txt`, the `path/to/` +// bit does not contain any meta characters. +func (g *glob) doGlobWalk(fsys fs.FS, pattern string, firstSegment, beforeMeta bool, fn GlobWalkFunc) error { + patternStart := indexMeta(pattern) + if patternStart == -1 { + // pattern doesn't contain any meta characters - does a file matching the + // pattern exist? + // The pattern may contain escaped wildcard characters for an exact path match. + path := unescapeMeta(pattern) + info, pathExists, err := g.exists(fsys, path, beforeMeta) + if pathExists && (!firstSegment || !g.filesOnly || !info.IsDir()) { + err = fn(path, dirEntryFromFileInfo(info)) + if err == SkipDir { + err = nil + } + } + return err + } + + dir := "." + splitIdx := lastIndexSlashOrAlt(pattern) + if splitIdx != -1 { + if pattern[splitIdx] == '}' { + openingIdx := indexMatchedOpeningAlt(pattern[:splitIdx]) + if openingIdx == -1 { + // if there's no matching opening index, technically Match() will treat + // an unmatched `}` as nothing special, so... we will, too! + splitIdx = lastIndexSlash(pattern[:splitIdx]) + if splitIdx != -1 { + dir = pattern[:splitIdx] + pattern = pattern[splitIdx+1:] + } + } else { + // otherwise, we have to handle the alts: + return g.globAltsWalk(fsys, pattern, openingIdx, splitIdx, firstSegment, beforeMeta, fn) + } + } else { + dir = pattern[:splitIdx] + pattern = pattern[splitIdx+1:] + } + } + + // if `splitIdx` is less than `patternStart`, we know `dir` has no meta + // characters. They would be equal if they are both -1, which means `dir` + // will be ".", and we know that doesn't have meta characters either. + if splitIdx <= patternStart { + return g.globDirWalk(fsys, dir, pattern, firstSegment, beforeMeta, fn) + } + + return g.doGlobWalk(fsys, dir, false, beforeMeta, func(p string, d fs.DirEntry) error { + if err := g.globDirWalk(fsys, p, pattern, firstSegment, false, fn); err != nil { + return err + } + return nil + }) +} + +// handle alts in the glob pattern - `openingIdx` and `closingIdx` are the +// indexes of `{` and `}`, respectively +func (g *glob) globAltsWalk(fsys fs.FS, pattern string, openingIdx, closingIdx int, firstSegment, beforeMeta bool, fn GlobWalkFunc) (err error) { + var matches []DirEntryWithFullPath + startIdx := 0 + afterIdx := closingIdx + 1 + splitIdx := lastIndexSlashOrAlt(pattern[:openingIdx]) + if splitIdx == -1 || pattern[splitIdx] == '}' { + // no common prefix + matches, err = g.doGlobAltsWalk(fsys, "", pattern, startIdx, openingIdx, closingIdx, afterIdx, firstSegment, beforeMeta, matches) + if err != nil { + return + } + } else { + // our alts have a common prefix that we can process first + startIdx = splitIdx + 1 + innerBeforeMeta := beforeMeta && !hasMetaExceptAlts(pattern[:splitIdx]) + err = g.doGlobWalk(fsys, pattern[:splitIdx], false, beforeMeta, func(p string, d fs.DirEntry) (e error) { + matches, e = g.doGlobAltsWalk(fsys, p, pattern, startIdx, openingIdx, closingIdx, afterIdx, firstSegment, innerBeforeMeta, matches) + return e + }) + if err != nil { + return + } + } + + skip := "" + for _, m := range matches { + if skip != "" { + // Because matches are sorted, we know that descendants of the skipped + // item must come immediately after the skipped item. If we find an item + // that does not have a prefix matching the skipped item, we know we're + // done skipping. I'm using strings.HasPrefix here because + // filepath.HasPrefix has been marked deprecated (and just calls + // strings.HasPrefix anyway). The reason it's deprecated is because it + // doesn't handle case-insensitive paths, nor does it guarantee that the + // prefix is actually a parent directory. Neither is an issue here: the + // paths come from the system so their cases will match, and we guarantee + // a parent directory by appending a slash to the prefix. + // + // NOTE: m.Path will always use slashes as path separators. + if strings.HasPrefix(m.Path, skip) { + continue + } + skip = "" + } + if err = fn(m.Path, m.Entry); err != nil { + if err == SkipDir { + isDir, err := g.isDir(fsys, "", m.Path, m.Entry) + if err != nil { + return err + } + if isDir { + // append a slash to guarantee `skip` will be treated as a parent dir + skip = m.Path + "/" + } else { + // Dir() calls Clean() which calls FromSlash(), so we need to convert + // back to slashes + skip = filepath.ToSlash(filepath.Dir(m.Path)) + "/" + } + err = nil + continue + } + return + } + } + + return +} + +// runs actual matching for alts +func (g *glob) doGlobAltsWalk(fsys fs.FS, d, pattern string, startIdx, openingIdx, closingIdx, afterIdx int, firstSegment, beforeMeta bool, m []DirEntryWithFullPath) (matches []DirEntryWithFullPath, err error) { + matches = m + matchesLen := len(m) + patIdx := openingIdx + 1 + for patIdx < closingIdx { + nextIdx := indexNextAlt(pattern[patIdx:closingIdx], true) + if nextIdx == -1 { + nextIdx = closingIdx + } else { + nextIdx += patIdx + } + + alt := buildAlt(d, pattern, startIdx, openingIdx, patIdx, nextIdx, afterIdx) + err = g.doGlobWalk(fsys, alt, firstSegment, beforeMeta, func(p string, d fs.DirEntry) error { + // insertion sort, ignoring dups + insertIdx := matchesLen + for insertIdx > 0 && matches[insertIdx-1].Path > p { + insertIdx-- + } + if insertIdx > 0 && matches[insertIdx-1].Path == p { + // dup + return nil + } + + // append to grow the slice, then insert + entry := DirEntryWithFullPath{d, p} + matches = append(matches, entry) + for i := matchesLen; i > insertIdx; i-- { + matches[i] = matches[i-1] + } + matches[insertIdx] = entry + matchesLen++ + + return nil + }) + if err != nil { + return + } + + patIdx = nextIdx + 1 + } + + return +} + +func (g *glob) globDirWalk(fsys fs.FS, dir, pattern string, canMatchFiles, beforeMeta bool, fn GlobWalkFunc) (e error) { + if pattern == "" { + if !canMatchFiles || !g.filesOnly { + // pattern can be an empty string if the original pattern ended in a + // slash, in which case, we should just return dir, but only if it + // actually exists and it's a directory (or a symlink to a directory) + info, isDir, err := g.isPathDir(fsys, dir, beforeMeta) + if err != nil { + return err + } + if isDir { + e = fn(dir, dirEntryFromFileInfo(info)) + if e == SkipDir { + e = nil + } + } + } + return + } + + if pattern == "**" { + // `**` can match *this* dir + info, dirExists, err := g.exists(fsys, dir, beforeMeta) + if err != nil { + return err + } + if !dirExists || !info.IsDir() { + return nil + } + if !canMatchFiles || !g.filesOnly { + if e = fn(dir, dirEntryFromFileInfo(info)); e != nil { + if e == SkipDir { + e = nil + } + return + } + } + return g.globDoubleStarWalk(fsys, dir, canMatchFiles, fn) + } + + dirs, err := fs.ReadDir(fsys, dir) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return g.handlePatternNotExist(beforeMeta) + } + return g.forwardErrIfFailOnIOErrors(err) + } + + var matched bool + for _, info := range dirs { + name := info.Name() + matched, e = matchWithSeparator(pattern, name, '/', false) + if e != nil { + return + } + if matched { + matched = canMatchFiles + if !matched || g.filesOnly { + matched, e = g.isDir(fsys, dir, name, info) + if e != nil { + return e + } + if canMatchFiles { + // if we're here, it's because g.filesOnly + // is set and we don't want directories + matched = !matched + } + } + if matched { + if e = fn(path.Join(dir, name), info); e != nil { + if e == SkipDir { + e = nil + } + return + } + } + } + } + + return +} + +// recursively walk files/directories in a directory +func (g *glob) globDoubleStarWalk(fsys fs.FS, dir string, canMatchFiles bool, fn GlobWalkFunc) (e error) { + dirs, err := fs.ReadDir(fsys, dir) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + // This function is only ever called after we know the top-most directory + // exists, so, if we ever get here, we know we'll never return + // ErrPatternNotExist. + return nil + } + return g.forwardErrIfFailOnIOErrors(err) + } + + for _, info := range dirs { + name := info.Name() + isDir, err := g.isDir(fsys, dir, name, info) + if err != nil { + return err + } + + if isDir { + p := path.Join(dir, name) + if !canMatchFiles || !g.filesOnly { + // `**` can match *this* dir, so add it + if e = fn(p, info); e != nil { + if e == SkipDir { + e = nil + continue + } + return + } + } + if e = g.globDoubleStarWalk(fsys, p, canMatchFiles, fn); e != nil { + return + } + } else if canMatchFiles { + if e = fn(path.Join(dir, name), info); e != nil { + if e == SkipDir { + e = nil + } + return + } + } + } + + return +} + +type DirEntryFromFileInfo struct { + fi fs.FileInfo +} + +func (d *DirEntryFromFileInfo) Name() string { + return d.fi.Name() +} + +func (d *DirEntryFromFileInfo) IsDir() bool { + return d.fi.IsDir() +} + +func (d *DirEntryFromFileInfo) Type() fs.FileMode { + return d.fi.Mode().Type() +} + +func (d *DirEntryFromFileInfo) Info() (fs.FileInfo, error) { + return d.fi, nil +} + +func dirEntryFromFileInfo(fi fs.FileInfo) fs.DirEntry { + return &DirEntryFromFileInfo{fi} +} + +type DirEntryWithFullPath struct { + Entry fs.DirEntry + Path string +} + +func hasMetaExceptAlts(s string) bool { + var c byte + l := len(s) + for i := 0; i < l; i++ { + c = s[i] + if c == '*' || c == '?' || c == '[' { + return true + } else if c == '\\' { + // skip next byte + i++ + } + } + return false +} diff --git a/vendor/github.com/bmatcuk/doublestar/v4/match.go b/vendor/github.com/bmatcuk/doublestar/v4/match.go new file mode 100644 index 00000000..4232c79f --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/match.go @@ -0,0 +1,381 @@ +package doublestar + +import ( + "path/filepath" + "unicode/utf8" +) + +// Match reports whether name matches the shell pattern. +// The pattern syntax is: +// +// pattern: +// { term } +// term: +// '*' matches any sequence of non-path-separators +// '/**/' matches zero or more directories +// '?' matches any single non-path-separator character +// '[' [ '^' '!' ] { character-range } ']' +// character class (must be non-empty) +// starting with `^` or `!` negates the class +// '{' { term } [ ',' { term } ... ] '}' +// alternatives +// c matches character c (c != '*', '?', '\\', '[') +// '\\' c matches character c +// +// character-range: +// c matches character c (c != '\\', '-', ']') +// '\\' c matches character c +// lo '-' hi matches character c for lo <= c <= hi +// +// Match returns true if `name` matches the file name `pattern`. `name` and +// `pattern` are split on forward slash (`/`) characters and may be relative or +// absolute. +// +// Match requires pattern to match all of name, not just a substring. +// The only possible returned error is ErrBadPattern, when pattern +// is malformed. +// +// A doublestar (`**`) should appear surrounded by path separators such as +// `/**/`. A mid-pattern doublestar (`**`) behaves like bash's globstar +// option: a pattern such as `path/to/**.txt` would return the same results as +// `path/to/*.txt`. The pattern you're looking for is `path/to/**/*.txt`. +// +// Note: this is meant as a drop-in replacement for path.Match() which +// always uses '/' as the path separator. If you want to support systems +// which use a different path separator (such as Windows), what you want +// is PathMatch(). Alternatively, you can run filepath.ToSlash() on both +// pattern and name and then use this function. +// +// Note: users should _not_ count on the returned error, +// doublestar.ErrBadPattern, being equal to path.ErrBadPattern. +// +func Match(pattern, name string) (bool, error) { + return matchWithSeparator(pattern, name, '/', true) +} + +// PathMatch returns true if `name` matches the file name `pattern`. The +// difference between Match and PathMatch is that PathMatch will automatically +// use your system's path separator to split `name` and `pattern`. On systems +// where the path separator is `'\'`, escaping will be disabled. +// +// Note: this is meant as a drop-in replacement for filepath.Match(). It +// assumes that both `pattern` and `name` are using the system's path +// separator. If you can't be sure of that, use filepath.ToSlash() on both +// `pattern` and `name`, and then use the Match() function instead. +// +func PathMatch(pattern, name string) (bool, error) { + return matchWithSeparator(pattern, name, filepath.Separator, true) +} + +func matchWithSeparator(pattern, name string, separator rune, validate bool) (matched bool, err error) { + return doMatchWithSeparator(pattern, name, separator, validate, -1, -1, -1, -1, 0, 0) +} + +func doMatchWithSeparator(pattern, name string, separator rune, validate bool, doublestarPatternBacktrack, doublestarNameBacktrack, starPatternBacktrack, starNameBacktrack, patIdx, nameIdx int) (matched bool, err error) { + patLen := len(pattern) + nameLen := len(name) + startOfSegment := true +MATCH: + for nameIdx < nameLen { + if patIdx < patLen { + switch pattern[patIdx] { + case '*': + if patIdx++; patIdx < patLen && pattern[patIdx] == '*' { + // doublestar - must begin with a path separator, otherwise we'll + // treat it like a single star like bash + patIdx++ + if startOfSegment { + if patIdx >= patLen { + // pattern ends in `/**`: return true + return true, nil + } + + // doublestar must also end with a path separator, otherwise we're + // just going to treat the doublestar as a single star like bash + patRune, patRuneLen := utf8.DecodeRuneInString(pattern[patIdx:]) + if patRune == separator { + patIdx += patRuneLen + + doublestarPatternBacktrack = patIdx + doublestarNameBacktrack = nameIdx + starPatternBacktrack = -1 + starNameBacktrack = -1 + continue + } + } + } + startOfSegment = false + + starPatternBacktrack = patIdx + starNameBacktrack = nameIdx + continue + + case '?': + startOfSegment = false + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + if nameRune == separator { + // `?` cannot match the separator + break + } + + patIdx++ + nameIdx += nameRuneLen + continue + + case '[': + startOfSegment = false + if patIdx++; patIdx >= patLen { + // class didn't end + return false, ErrBadPattern + } + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + + matched := false + negate := pattern[patIdx] == '!' || pattern[patIdx] == '^' + if negate { + patIdx++ + } + + if patIdx >= patLen || pattern[patIdx] == ']' { + // class didn't end or empty character class + return false, ErrBadPattern + } + + last := utf8.MaxRune + for patIdx < patLen && pattern[patIdx] != ']' { + patRune, patRuneLen := utf8.DecodeRuneInString(pattern[patIdx:]) + patIdx += patRuneLen + + // match a range + if last < utf8.MaxRune && patRune == '-' && patIdx < patLen && pattern[patIdx] != ']' { + if pattern[patIdx] == '\\' { + // next character is escaped + patIdx++ + } + patRune, patRuneLen = utf8.DecodeRuneInString(pattern[patIdx:]) + patIdx += patRuneLen + + if last <= nameRune && nameRune <= patRune { + matched = true + break + } + + // didn't match range - reset `last` + last = utf8.MaxRune + continue + } + + // not a range - check if the next rune is escaped + if patRune == '\\' { + patRune, patRuneLen = utf8.DecodeRuneInString(pattern[patIdx:]) + patIdx += patRuneLen + } + + // check if the rune matches + if patRune == nameRune { + matched = true + break + } + + // no matches yet + last = patRune + } + + if matched == negate { + // failed to match - if we reached the end of the pattern, that means + // we never found a closing `]` + if patIdx >= patLen { + return false, ErrBadPattern + } + break + } + + closingIdx := indexUnescapedByte(pattern[patIdx:], ']', true) + if closingIdx == -1 { + // no closing `]` + return false, ErrBadPattern + } + + patIdx += closingIdx + 1 + nameIdx += nameRuneLen + continue + + case '{': + startOfSegment = false + beforeIdx := patIdx + patIdx++ + closingIdx := indexMatchedClosingAlt(pattern[patIdx:], separator != '\\') + if closingIdx == -1 { + // no closing `}` + return false, ErrBadPattern + } + closingIdx += patIdx + + for { + commaIdx := indexNextAlt(pattern[patIdx:closingIdx], separator != '\\') + if commaIdx == -1 { + break + } + commaIdx += patIdx + + result, err := doMatchWithSeparator(pattern[:beforeIdx]+pattern[patIdx:commaIdx]+pattern[closingIdx+1:], name, separator, validate, doublestarPatternBacktrack, doublestarNameBacktrack, starPatternBacktrack, starNameBacktrack, beforeIdx, nameIdx) + if result || err != nil { + return result, err + } + + patIdx = commaIdx + 1 + } + return doMatchWithSeparator(pattern[:beforeIdx]+pattern[patIdx:closingIdx]+pattern[closingIdx+1:], name, separator, validate, doublestarPatternBacktrack, doublestarNameBacktrack, starPatternBacktrack, starNameBacktrack, beforeIdx, nameIdx) + + case '\\': + if separator != '\\' { + // next rune is "escaped" in the pattern - literal match + if patIdx++; patIdx >= patLen { + // pattern ended + return false, ErrBadPattern + } + } + fallthrough + + default: + patRune, patRuneLen := utf8.DecodeRuneInString(pattern[patIdx:]) + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + if patRune != nameRune { + if separator != '\\' && patIdx > 0 && pattern[patIdx-1] == '\\' { + // if this rune was meant to be escaped, we need to move patIdx + // back to the backslash before backtracking or validating below + patIdx-- + } + break + } + + patIdx += patRuneLen + nameIdx += nameRuneLen + startOfSegment = patRune == separator + continue + } + } + + if starPatternBacktrack >= 0 { + // `*` backtrack, but only if the `name` rune isn't the separator + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[starNameBacktrack:]) + if nameRune != separator { + starNameBacktrack += nameRuneLen + patIdx = starPatternBacktrack + nameIdx = starNameBacktrack + startOfSegment = false + continue + } + } + + if doublestarPatternBacktrack >= 0 { + // `**` backtrack, advance `name` past next separator + nameIdx = doublestarNameBacktrack + for nameIdx < nameLen { + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + nameIdx += nameRuneLen + if nameRune == separator { + doublestarNameBacktrack = nameIdx + patIdx = doublestarPatternBacktrack + startOfSegment = true + continue MATCH + } + } + } + + if validate && patIdx < patLen && !doValidatePattern(pattern[patIdx:], separator) { + return false, ErrBadPattern + } + return false, nil + } + + if nameIdx < nameLen { + // we reached the end of `pattern` before the end of `name` + return false, nil + } + + // we've reached the end of `name`; we've successfully matched if we've also + // reached the end of `pattern`, or if the rest of `pattern` can match a + // zero-length string + return isZeroLengthPattern(pattern[patIdx:], separator) +} + +func isZeroLengthPattern(pattern string, separator rune) (ret bool, err error) { + // `/**`, `**/`, and `/**/` are special cases - a pattern such as `path/to/a/**` or `path/to/a/**/` + // *should* match `path/to/a` because `a` might be a directory + if pattern == "" || + pattern == "*" || + pattern == "**" || + pattern == string(separator)+"**" || + pattern == "**"+string(separator) || + pattern == string(separator)+"**"+string(separator) { + return true, nil + } + + if pattern[0] == '{' { + closingIdx := indexMatchedClosingAlt(pattern[1:], separator != '\\') + if closingIdx == -1 { + // no closing '}' + return false, ErrBadPattern + } + closingIdx += 1 + + patIdx := 1 + for { + commaIdx := indexNextAlt(pattern[patIdx:closingIdx], separator != '\\') + if commaIdx == -1 { + break + } + commaIdx += patIdx + + ret, err = isZeroLengthPattern(pattern[patIdx:commaIdx]+pattern[closingIdx+1:], separator) + if ret || err != nil { + return + } + + patIdx = commaIdx + 1 + } + return isZeroLengthPattern(pattern[patIdx:closingIdx]+pattern[closingIdx+1:], separator) + } + + // no luck - validate the rest of the pattern + if !doValidatePattern(pattern, separator) { + return false, ErrBadPattern + } + return false, nil +} + +// Finds the index of the first unescaped byte `c`, or negative 1. +func indexUnescapedByte(s string, c byte, allowEscaping bool) int { + l := len(s) + for i := 0; i < l; i++ { + if allowEscaping && s[i] == '\\' { + // skip next byte + i++ + } else if s[i] == c { + return i + } + } + return -1 +} + +// Assuming the byte before the beginning of `s` is an opening `{`, this +// function will find the index of the matching `}`. That is, it'll skip over +// any nested `{}` and account for escaping +func indexMatchedClosingAlt(s string, allowEscaping bool) int { + alts := 1 + l := len(s) + for i := 0; i < l; i++ { + if allowEscaping && s[i] == '\\' { + // skip next byte + i++ + } else if s[i] == '{' { + alts++ + } else if s[i] == '}' { + if alts--; alts == 0 { + return i + } + } + } + return -1 +} diff --git a/vendor/github.com/bmatcuk/doublestar/v4/utils.go b/vendor/github.com/bmatcuk/doublestar/v4/utils.go new file mode 100644 index 00000000..0ab1dc98 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/utils.go @@ -0,0 +1,147 @@ +package doublestar + +import ( + "errors" + "os" + "path" + "path/filepath" + "strings" +) + +// SplitPattern is a utility function. Given a pattern, SplitPattern will +// return two strings: the first string is everything up to the last slash +// (`/`) that appears _before_ any unescaped "meta" characters (ie, `*?[{`). +// The second string is everything after that slash. For example, given the +// pattern: +// +// ../../path/to/meta*/** +// ^----------- split here +// +// SplitPattern returns "../../path/to" and "meta*/**". This is useful for +// initializing os.DirFS() to call Glob() because Glob() will silently fail if +// your pattern includes `/./` or `/../`. For example: +// +// base, pattern := SplitPattern("../../path/to/meta*/**") +// fsys := os.DirFS(base) +// matches, err := Glob(fsys, pattern) +// +// If SplitPattern cannot find somewhere to split the pattern (for example, +// `meta*/**`), it will return "." and the unaltered pattern (`meta*/**` in +// this example). +// +// Of course, it is your responsibility to decide if the returned base path is +// "safe" in the context of your application. Perhaps you could use Match() to +// validate against a list of approved base directories? +// +func SplitPattern(p string) (base, pattern string) { + base = "." + pattern = p + + splitIdx := -1 + for i := 0; i < len(p); i++ { + c := p[i] + if c == '\\' { + i++ + } else if c == '/' { + splitIdx = i + } else if c == '*' || c == '?' || c == '[' || c == '{' { + break + } + } + + if splitIdx == 0 { + return "/", p[1:] + } else if splitIdx > 0 { + return p[:splitIdx], p[splitIdx+1:] + } + + return +} + +// FilepathGlob returns the names of all files matching pattern or nil if there +// is no matching file. The syntax of pattern is the same as in Match(). The +// pattern may describe hierarchical names such as usr/*/bin/ed. +// +// FilepathGlob ignores file system errors such as I/O errors reading +// directories by default. The only possible returned error is ErrBadPattern, +// reporting that the pattern is malformed. +// +// To enable aborting on I/O errors, the WithFailOnIOErrors option can be +// passed. +// +// Note: FilepathGlob is a convenience function that is meant as a drop-in +// replacement for `path/filepath.Glob()` for users who don't need the +// complication of io/fs. Basically, it: +// - Runs `filepath.Clean()` and `ToSlash()` on the pattern +// - Runs `SplitPattern()` to get a base path and a pattern to Glob +// - Creates an FS object from the base path and `Glob()s` on the pattern +// - Joins the base path with all of the matches from `Glob()` +// +// Returned paths will use the system's path separator, just like +// `filepath.Glob()`. +// +// Note: the returned error doublestar.ErrBadPattern is not equal to +// filepath.ErrBadPattern. +// +func FilepathGlob(pattern string, opts ...GlobOption) (matches []string, err error) { + pattern = filepath.Clean(pattern) + pattern = filepath.ToSlash(pattern) + base, f := SplitPattern(pattern) + if f == "" || f == "." || f == ".." { + // some special cases to match filepath.Glob behavior + if !ValidatePathPattern(pattern) { + return nil, ErrBadPattern + } + + if filepath.Separator != '\\' { + pattern = unescapeMeta(pattern) + } + + if _, err = os.Lstat(pattern); err != nil { + g := newGlob(opts...) + if errors.Is(err, os.ErrNotExist) { + return nil, g.handlePatternNotExist(true) + } + return nil, g.forwardErrIfFailOnIOErrors(err) + } + return []string{filepath.FromSlash(pattern)}, nil + } + + fs := os.DirFS(base) + if matches, err = Glob(fs, f, opts...); err != nil { + return nil, err + } + for i := range matches { + // use path.Join because we used ToSlash above to ensure our paths are made + // of forward slashes, no matter what the system uses + matches[i] = filepath.FromSlash(path.Join(base, matches[i])) + } + return +} + +// Finds the next comma, but ignores any commas that appear inside nested `{}`. +// Assumes that each opening bracket has a corresponding closing bracket. +func indexNextAlt(s string, allowEscaping bool) int { + alts := 1 + l := len(s) + for i := 0; i < l; i++ { + if allowEscaping && s[i] == '\\' { + // skip next byte + i++ + } else if s[i] == '{' { + alts++ + } else if s[i] == '}' { + alts-- + } else if s[i] == ',' && alts == 1 { + return i + } + } + return -1 +} + +var metaReplacer = strings.NewReplacer("\\*", "*", "\\?", "?", "\\[", "[", "\\]", "]", "\\{", "{", "\\}", "}") + +// Unescapes meta characters (*?[]{}) +func unescapeMeta(pattern string) string { + return metaReplacer.Replace(pattern) +} diff --git a/vendor/github.com/bmatcuk/doublestar/v4/validate.go b/vendor/github.com/bmatcuk/doublestar/v4/validate.go new file mode 100644 index 00000000..c689b9eb --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/validate.go @@ -0,0 +1,82 @@ +package doublestar + +import "path/filepath" + +// Validate a pattern. Patterns are validated while they run in Match(), +// PathMatch(), and Glob(), so, you normally wouldn't need to call this. +// However, there are cases where this might be useful: for example, if your +// program allows a user to enter a pattern that you'll run at a later time, +// you might want to validate it. +// +// ValidatePattern assumes your pattern uses '/' as the path separator. +// +func ValidatePattern(s string) bool { + return doValidatePattern(s, '/') +} + +// Like ValidatePattern, only uses your OS path separator. In other words, use +// ValidatePattern if you would normally use Match() or Glob(). Use +// ValidatePathPattern if you would normally use PathMatch(). Keep in mind, +// Glob() requires '/' separators, even if your OS uses something else. +// +func ValidatePathPattern(s string) bool { + return doValidatePattern(s, filepath.Separator) +} + +func doValidatePattern(s string, separator rune) bool { + altDepth := 0 + l := len(s) +VALIDATE: + for i := 0; i < l; i++ { + switch s[i] { + case '\\': + if separator != '\\' { + // skip the next byte - return false if there is no next byte + if i++; i >= l { + return false + } + } + continue + + case '[': + if i++; i >= l { + // class didn't end + return false + } + if s[i] == '^' || s[i] == '!' { + i++ + } + if i >= l || s[i] == ']' { + // class didn't end or empty character class + return false + } + + for ; i < l; i++ { + if separator != '\\' && s[i] == '\\' { + i++ + } else if s[i] == ']' { + // looks good + continue VALIDATE + } + } + + // class didn't end + return false + + case '{': + altDepth++ + continue + + case '}': + if altDepth == 0 { + // alt end without a corresponding start + return false + } + altDepth-- + continue + } + } + + // valid as long as all alts are closed + return altDepth == 0 +} diff --git a/vendor/github.com/mitchellh/cli/LICENSE b/vendor/github.com/hashicorp/cli/LICENSE similarity index 100% rename from vendor/github.com/mitchellh/cli/LICENSE rename to vendor/github.com/hashicorp/cli/LICENSE diff --git a/vendor/github.com/mitchellh/cli/Makefile b/vendor/github.com/hashicorp/cli/Makefile similarity index 100% rename from vendor/github.com/mitchellh/cli/Makefile rename to vendor/github.com/hashicorp/cli/Makefile diff --git a/vendor/github.com/mitchellh/cli/README.md b/vendor/github.com/hashicorp/cli/README.md similarity index 88% rename from vendor/github.com/mitchellh/cli/README.md rename to vendor/github.com/hashicorp/cli/README.md index d75ff863..440f69e6 100644 --- a/vendor/github.com/mitchellh/cli/README.md +++ b/vendor/github.com/hashicorp/cli/README.md @@ -1,8 +1,8 @@ -# Go CLI Library [![GoDoc](https://godoc.org/github.com/mitchellh/cli?status.png)](https://pkg.go.dev/github.com/mitchellh/cli) +# Go CLI Library [![GoDoc](https://godoc.org/github.com/hashicorp/cli?status.png)](https://pkg.go.dev/github.com/hashicorp/cli) cli is a library for implementing command-line interfaces in Go. cli is the library that powers the CLI for -[Packer](https://github.com/mitchellh/packer), +[Packer](https://github.com/hashicorp/packer), [Consul](https://github.com/hashicorp/consul), [Vault](https://github.com/hashicorp/vault), [Terraform](https://github.com/hashicorp/terraform), @@ -44,7 +44,7 @@ import ( "log" "os" - "github.com/mitchellh/cli" + "github.com/hashicorp/cli" ) func main() { diff --git a/vendor/github.com/mitchellh/cli/autocomplete.go b/vendor/github.com/hashicorp/cli/autocomplete.go similarity index 94% rename from vendor/github.com/mitchellh/cli/autocomplete.go rename to vendor/github.com/hashicorp/cli/autocomplete.go index 3bec6258..0671db7c 100644 --- a/vendor/github.com/mitchellh/cli/autocomplete.go +++ b/vendor/github.com/hashicorp/cli/autocomplete.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package cli import ( diff --git a/vendor/github.com/mitchellh/cli/cli.go b/vendor/github.com/hashicorp/cli/cli.go similarity index 99% rename from vendor/github.com/mitchellh/cli/cli.go rename to vendor/github.com/hashicorp/cli/cli.go index 95205328..0a479b86 100644 --- a/vendor/github.com/mitchellh/cli/cli.go +++ b/vendor/github.com/hashicorp/cli/cli.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package cli import ( diff --git a/vendor/github.com/mitchellh/cli/command.go b/vendor/github.com/hashicorp/cli/command.go similarity index 97% rename from vendor/github.com/mitchellh/cli/command.go rename to vendor/github.com/hashicorp/cli/command.go index bed11faf..717c0701 100644 --- a/vendor/github.com/mitchellh/cli/command.go +++ b/vendor/github.com/hashicorp/cli/command.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package cli import ( diff --git a/vendor/github.com/mitchellh/cli/command_mock.go b/vendor/github.com/hashicorp/cli/command_mock.go similarity index 94% rename from vendor/github.com/mitchellh/cli/command_mock.go rename to vendor/github.com/hashicorp/cli/command_mock.go index 7a584b7e..ee80c8f8 100644 --- a/vendor/github.com/mitchellh/cli/command_mock.go +++ b/vendor/github.com/hashicorp/cli/command_mock.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package cli import ( diff --git a/vendor/github.com/mitchellh/cli/help.go b/vendor/github.com/hashicorp/cli/help.go similarity index 96% rename from vendor/github.com/mitchellh/cli/help.go rename to vendor/github.com/hashicorp/cli/help.go index f5ca58f5..acbdc44b 100644 --- a/vendor/github.com/mitchellh/cli/help.go +++ b/vendor/github.com/hashicorp/cli/help.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package cli import ( diff --git a/vendor/github.com/hashicorp/cli/ui.go b/vendor/github.com/hashicorp/cli/ui.go new file mode 100644 index 00000000..4cb41f66 --- /dev/null +++ b/vendor/github.com/hashicorp/cli/ui.go @@ -0,0 +1,63 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +//go:build !js +// +build !js + +package cli + +import ( + "bufio" + "errors" + "fmt" + "os" + "os/signal" + "strings" + + "github.com/bgentry/speakeasy" + "github.com/mattn/go-isatty" +) + +func (u *BasicUi) ask(query string, secret bool) (string, error) { + if _, err := fmt.Fprint(u.Writer, query+" "); err != nil { + return "", err + } + + // Register for interrupts so that we can catch it and immediately + // return... + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt) + defer signal.Stop(sigCh) + + // Ask for input in a go-routine so that we can ignore it. + errCh := make(chan error, 1) + lineCh := make(chan string, 1) + go func() { + var line string + var err error + if secret && isatty.IsTerminal(os.Stdin.Fd()) { + line, err = speakeasy.Ask("") + } else { + r := bufio.NewReader(u.Reader) + line, err = r.ReadString('\n') + } + if err != nil { + errCh <- err + return + } + + lineCh <- strings.TrimRight(line, "\r\n") + }() + + select { + case err := <-errCh: + return "", err + case line := <-lineCh: + return line, nil + case <-sigCh: + // Print a newline so that any further output starts properly + // on a new line. + fmt.Fprintln(u.Writer) + + return "", errors.New("interrupted") + } +} diff --git a/vendor/github.com/mitchellh/cli/ui_colored.go b/vendor/github.com/hashicorp/cli/ui_colored.go similarity index 94% rename from vendor/github.com/mitchellh/cli/ui_colored.go rename to vendor/github.com/hashicorp/cli/ui_colored.go index b0ec4484..0c0bc27a 100644 --- a/vendor/github.com/mitchellh/cli/ui_colored.go +++ b/vendor/github.com/hashicorp/cli/ui_colored.go @@ -1,3 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +//go:build !js +// +build !js + package cli import ( diff --git a/vendor/github.com/mitchellh/cli/ui.go b/vendor/github.com/hashicorp/cli/ui_common.go similarity index 72% rename from vendor/github.com/mitchellh/cli/ui.go rename to vendor/github.com/hashicorp/cli/ui_common.go index a2d6f94f..9cd6b1b9 100644 --- a/vendor/github.com/mitchellh/cli/ui.go +++ b/vendor/github.com/hashicorp/cli/ui_common.go @@ -1,16 +1,8 @@ package cli import ( - "bufio" - "errors" "fmt" "io" - "os" - "os/signal" - "strings" - - "github.com/bgentry/speakeasy" - "github.com/mattn/go-isatty" ) // Ui is an interface for interacting with the terminal, or "interface" @@ -59,51 +51,6 @@ func (u *BasicUi) AskSecret(query string) (string, error) { return u.ask(query, true) } -func (u *BasicUi) ask(query string, secret bool) (string, error) { - if _, err := fmt.Fprint(u.Writer, query+" "); err != nil { - return "", err - } - - // Register for interrupts so that we can catch it and immediately - // return... - sigCh := make(chan os.Signal, 1) - signal.Notify(sigCh, os.Interrupt) - defer signal.Stop(sigCh) - - // Ask for input in a go-routine so that we can ignore it. - errCh := make(chan error, 1) - lineCh := make(chan string, 1) - go func() { - var line string - var err error - if secret && isatty.IsTerminal(os.Stdin.Fd()) { - line, err = speakeasy.Ask("") - } else { - r := bufio.NewReader(u.Reader) - line, err = r.ReadString('\n') - } - if err != nil { - errCh <- err - return - } - - lineCh <- strings.TrimRight(line, "\r\n") - }() - - select { - case err := <-errCh: - return "", err - case line := <-lineCh: - return line, nil - case <-sigCh: - // Print a newline so that any further output starts properly - // on a new line. - fmt.Fprintln(u.Writer) - - return "", errors.New("interrupted") - } -} - func (u *BasicUi) Error(message string) { w := u.Writer if u.ErrorWriter != nil { diff --git a/vendor/github.com/mitchellh/cli/ui_concurrent.go b/vendor/github.com/hashicorp/cli/ui_concurrent.go similarity index 92% rename from vendor/github.com/mitchellh/cli/ui_concurrent.go rename to vendor/github.com/hashicorp/cli/ui_concurrent.go index b4f4dbfa..3262a113 100644 --- a/vendor/github.com/mitchellh/cli/ui_concurrent.go +++ b/vendor/github.com/hashicorp/cli/ui_concurrent.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package cli import ( diff --git a/vendor/github.com/hashicorp/cli/ui_js.go b/vendor/github.com/hashicorp/cli/ui_js.go new file mode 100644 index 00000000..ac02693d --- /dev/null +++ b/vendor/github.com/hashicorp/cli/ui_js.go @@ -0,0 +1,10 @@ +package cli + +import ( + "syscall/js" +) + +func (u *BasicUi) ask(query string, secret bool) (string, error) { + line := js.Global().Call("prompt", query).String() + return line, nil +} diff --git a/vendor/github.com/mitchellh/cli/ui_mock.go b/vendor/github.com/hashicorp/cli/ui_mock.go similarity index 96% rename from vendor/github.com/mitchellh/cli/ui_mock.go rename to vendor/github.com/hashicorp/cli/ui_mock.go index 935f28a4..42d90e2c 100644 --- a/vendor/github.com/mitchellh/cli/ui_mock.go +++ b/vendor/github.com/hashicorp/cli/ui_mock.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package cli import ( diff --git a/vendor/github.com/mitchellh/cli/ui_writer.go b/vendor/github.com/hashicorp/cli/ui_writer.go similarity index 83% rename from vendor/github.com/mitchellh/cli/ui_writer.go rename to vendor/github.com/hashicorp/cli/ui_writer.go index 1e1db3cf..b0b4cdcc 100644 --- a/vendor/github.com/mitchellh/cli/ui_writer.go +++ b/vendor/github.com/hashicorp/cli/ui_writer.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package cli // UiWriter is an io.Writer implementation that can be used with diff --git a/vendor/github.com/hashicorp/hc-install/version/VERSION b/vendor/github.com/hashicorp/hc-install/version/VERSION index 844f6a91..d2b13eb6 100644 --- a/vendor/github.com/hashicorp/hc-install/version/VERSION +++ b/vendor/github.com/hashicorp/hc-install/version/VERSION @@ -1 +1 @@ -0.6.3 +0.6.4 diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/build/version.go b/vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/build/version.go new file mode 100644 index 00000000..01ded843 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/build/version.go @@ -0,0 +1,18 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package build + +var ( + // These vars will be set by goreleaser. + version string = `dev` + commit string = `` +) + +func GetVersion() string { + version := "tfplugindocs" + " Version " + version + if commit != "" { + version += " from commit " + commit + } + return version +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/main.go b/vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/main.go index df6e336a..8e3c25da 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/main.go +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/main.go @@ -6,24 +6,9 @@ package main import ( "os" - "github.com/mattn/go-colorable" - "github.com/hashicorp/terraform-plugin-docs/internal/cmd" ) func main() { - name := "tfplugindocs" - version := name + " Version " + version - if commit != "" { - version += " from commit " + commit - } - - os.Exit(cmd.Run( - name, - version, - os.Args[1:], - os.Stdin, - colorable.NewColorableStdout(), - colorable.NewColorableStderr(), - )) + os.Exit(cmd.Main()) } diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/version.go b/vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/version.go deleted file mode 100644 index 68dc6cee..00000000 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/version.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package main - -var ( - // These vars will be set by goreleaser. - version string = `dev` - commit string = `` -) diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/directory.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/directory.go new file mode 100644 index 00000000..3aefa6a1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/directory.go @@ -0,0 +1,210 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package check + +import ( + "fmt" + "log" + "path/filepath" +) + +const ( + CdktfIndexDirectory = `cdktf` + + LegacyIndexDirectory = `website/docs` + LegacyDataSourcesDirectory = `d` + LegacyGuidesDirectory = `guides` + LegacyResourcesDirectory = `r` + LegacyFunctionsDirectory = `functions` + + RegistryIndexDirectory = `docs` + RegistryDataSourcesDirectory = `data-sources` + RegistryGuidesDirectory = `guides` + RegistryResourcesDirectory = `resources` + RegistryFunctionsDirectory = `functions` + + // Terraform Registry Storage Limits + // https://www.terraform.io/docs/registry/providers/docs.html#storage-limits + RegistryMaximumNumberOfFiles = 2000 + RegistryMaximumSizeOfFile = 500000 // 500KB + +) + +var ValidLegacyDirectories = []string{ + LegacyIndexDirectory, + LegacyIndexDirectory + "/" + LegacyDataSourcesDirectory, + LegacyIndexDirectory + "/" + LegacyGuidesDirectory, + LegacyIndexDirectory + "/" + LegacyResourcesDirectory, + LegacyIndexDirectory + "/" + LegacyFunctionsDirectory, +} + +var ValidRegistryDirectories = []string{ + RegistryIndexDirectory, + RegistryIndexDirectory + "/" + RegistryDataSourcesDirectory, + RegistryIndexDirectory + "/" + RegistryGuidesDirectory, + RegistryIndexDirectory + "/" + RegistryResourcesDirectory, + RegistryIndexDirectory + "/" + RegistryFunctionsDirectory, +} + +var ValidCdktfLanguages = []string{ + "csharp", + "go", + "java", + "python", + "typescript", +} + +var ValidLegacySubdirectories = []string{ + LegacyIndexDirectory, + LegacyDataSourcesDirectory, + LegacyGuidesDirectory, + LegacyResourcesDirectory, +} + +var ValidRegistrySubdirectories = []string{ + RegistryIndexDirectory, + RegistryDataSourcesDirectory, + RegistryGuidesDirectory, + RegistryResourcesDirectory, +} + +func InvalidDirectoriesCheck(dirPath string) error { + if IsValidRegistryDirectory(dirPath) { + return nil + } + + if IsValidLegacyDirectory(dirPath) { + return nil + } + + if IsValidCdktfDirectory(dirPath) { + return nil + } + + return fmt.Errorf("invalid Terraform Provider documentation directory found: %s", dirPath) + +} + +func MixedDirectoriesCheck(docFiles []string) error { + var legacyDirectoryFound bool + var registryDirectoryFound bool + err := fmt.Errorf("mixed Terraform Provider documentation directory layouts found, must use only legacy or registry layout") + + for _, file := range docFiles { + directory := filepath.Dir(file) + log.Printf("[DEBUG] Found directory: %s", directory) + + // Allow docs/ with other files + if IsValidRegistryDirectory(directory) && directory != RegistryIndexDirectory { + registryDirectoryFound = true + + if legacyDirectoryFound { + log.Printf("[DEBUG] Found mixed directories") + return err + } + } + + if IsValidLegacyDirectory(directory) { + legacyDirectoryFound = true + + if registryDirectoryFound { + log.Printf("[DEBUG] Found mixed directories") + return err + } + } + } + + return nil +} + +// NumberOfFilesCheck verifies that documentation is below the Terraform Registry storage limit. +// This check presumes that all provided directories are valid, e.g. that directory checking +// for invalid or mixed directory structures was previously completed. +func NumberOfFilesCheck(docFiles []string) error { + var numberOfFiles int + + directoryCounts := make(map[string]int) + for _, file := range docFiles { + directory := filepath.Dir(file) + + // Ignore CDKTF files. The file limit is per-language and presumably there is one CDKTF file per source HCL file. + if IsValidCdktfDirectory(directory) { + continue + } + + if directory == RegistryIndexDirectory || directory == filepath.FromSlash(LegacyIndexDirectory) { + continue + } + + directoryCounts[directory]++ + } + + for directory, count := range directoryCounts { + + log.Printf("[TRACE] Found %d documentation files in directory: %s", count, directory) + numberOfFiles = numberOfFiles + count + } + + log.Printf("[DEBUG] Found %d documentation files with limit of %d", numberOfFiles, RegistryMaximumNumberOfFiles) + if numberOfFiles >= RegistryMaximumNumberOfFiles { + return fmt.Errorf("exceeded maximum (%d) number of documentation files for Terraform Registry: %d", RegistryMaximumNumberOfFiles, numberOfFiles) + } + + return nil +} + +func IsValidLegacyDirectory(directory string) bool { + for _, validLegacyDirectory := range ValidLegacyDirectories { + if directory == filepath.FromSlash(validLegacyDirectory) { + return true + } + } + + return false +} + +func IsValidRegistryDirectory(directory string) bool { + for _, validRegistryDirectory := range ValidRegistryDirectories { + if directory == filepath.FromSlash(validRegistryDirectory) { + return true + } + } + + return false +} + +func IsValidCdktfDirectory(directory string) bool { + if directory == filepath.FromSlash(fmt.Sprintf("%s/%s", LegacyIndexDirectory, CdktfIndexDirectory)) { + return true + } + + if directory == filepath.FromSlash(fmt.Sprintf("%s/%s", RegistryIndexDirectory, CdktfIndexDirectory)) { + return true + } + + for _, validCdktfLanguage := range ValidCdktfLanguages { + + if directory == filepath.FromSlash(fmt.Sprintf("%s/%s/%s", LegacyIndexDirectory, CdktfIndexDirectory, validCdktfLanguage)) { + return true + } + + if directory == filepath.FromSlash(fmt.Sprintf("%s/%s/%s", RegistryIndexDirectory, CdktfIndexDirectory, validCdktfLanguage)) { + return true + } + + for _, validLegacySubdirectory := range ValidLegacySubdirectories { + if directory == filepath.FromSlash(fmt.Sprintf("%s/%s/%s/%s", LegacyIndexDirectory, CdktfIndexDirectory, validCdktfLanguage, validLegacySubdirectory)) { + return true + } + } + + for _, validRegistrySubdirectory := range ValidRegistrySubdirectories { + if directory == filepath.FromSlash(fmt.Sprintf("%s/%s/%s/%s", RegistryIndexDirectory, CdktfIndexDirectory, validCdktfLanguage, validRegistrySubdirectory)) { + return true + } + } + } + + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file.go new file mode 100644 index 00000000..cb079b3a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file.go @@ -0,0 +1,39 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package check + +import ( + "fmt" + "log" + "os" + "path/filepath" +) + +type FileOptions struct { + BasePath string +} + +func (opts *FileOptions) FullPath(path string) string { + if opts.BasePath != "" { + return filepath.Join(opts.BasePath, path) + } + + return path +} + +// FileSizeCheck verifies that documentation file is below the Terraform Registry storage limit. +func FileSizeCheck(fullpath string) error { + fi, err := os.Stat(fullpath) + + if err != nil { + return err + } + + log.Printf("[DEBUG] File %s size: %d (limit: %d)", fullpath, fi.Size(), RegistryMaximumSizeOfFile) + if fi.Size() >= int64(RegistryMaximumSizeOfFile) { + return fmt.Errorf("exceeded maximum (%d) size of documentation file for Terraform Registry: %d", RegistryMaximumSizeOfFile, fi.Size()) + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file_extension.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file_extension.go new file mode 100644 index 00000000..dd5f37b6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file_extension.go @@ -0,0 +1,64 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package check + +import ( + "fmt" + "path/filepath" + "strings" +) + +const ( + FileExtensionHtmlMarkdown = `.html.markdown` + FileExtensionHtmlMd = `.html.md` + FileExtensionMarkdown = `.markdown` + FileExtensionMd = `.md` +) + +var ValidLegacyFileExtensions = []string{ + FileExtensionHtmlMarkdown, + FileExtensionHtmlMd, + FileExtensionMarkdown, + FileExtensionMd, +} + +var ValidRegistryFileExtensions = []string{ + FileExtensionMd, +} + +// FileExtensionCheck checks if the file extension of the given path is valid. +func FileExtensionCheck(path string, validExtensions []string) error { + if !FilePathEndsWithExtensionFrom(path, validExtensions) { + return fmt.Errorf("file does not end with a valid extension, valid extensions: %v", ValidLegacyFileExtensions) + } + + return nil +} + +func FilePathEndsWithExtensionFrom(path string, validExtensions []string) bool { + for _, validExtension := range validExtensions { + if strings.HasSuffix(path, validExtension) { + return true + } + } + + return false +} + +// TrimFileExtension removes file extensions including those with multiple periods. +func TrimFileExtension(path string) string { + filename := filepath.Base(path) + + if filename == "." { + return "" + } + + dotIndex := strings.IndexByte(filename, '.') + + if dotIndex > 0 { + return filename[:dotIndex] + } + + return filename +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file_mismatch.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file_mismatch.go new file mode 100644 index 00000000..d65989fd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/file_mismatch.go @@ -0,0 +1,284 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package check + +import ( + "errors" + "fmt" + "log" + "os" + "sort" + + tfjson "github.com/hashicorp/terraform-json" +) + +type FileMismatchOptions struct { + *FileOptions + + IgnoreFileMismatch []string + + IgnoreFileMissing []string + + ProviderShortName string + + DatasourceEntries []os.DirEntry + + ResourceEntries []os.DirEntry + + FunctionEntries []os.DirEntry + + Schema *tfjson.ProviderSchema +} + +type FileMismatchCheck struct { + Options *FileMismatchOptions +} + +func NewFileMismatchCheck(opts *FileMismatchOptions) *FileMismatchCheck { + check := &FileMismatchCheck{ + Options: opts, + } + + if check.Options == nil { + check.Options = &FileMismatchOptions{} + } + + if check.Options.FileOptions == nil { + check.Options.FileOptions = &FileOptions{} + } + + return check +} + +func (check *FileMismatchCheck) Run() error { + var result error + + if check.Options.Schema == nil { + log.Printf("[DEBUG] Skipping file mismatch checks due to missing provider schema") + return nil + } + + if check.Options.ResourceEntries != nil { + err := check.ResourceFileMismatchCheck(check.Options.ResourceEntries, "resource", check.Options.Schema.ResourceSchemas) + result = errors.Join(result, err) + } + + if check.Options.DatasourceEntries != nil { + err := check.ResourceFileMismatchCheck(check.Options.DatasourceEntries, "datasource", check.Options.Schema.DataSourceSchemas) + result = errors.Join(result, err) + } + + if check.Options.FunctionEntries != nil { + err := check.FunctionFileMismatchCheck(check.Options.FunctionEntries, check.Options.Schema.Functions) + result = errors.Join(result, err) + } + + return result +} + +// ResourceFileMismatchCheck checks for mismatched files, either missing or extraneous, against the resource/datasouce schema +func (check *FileMismatchCheck) ResourceFileMismatchCheck(files []os.DirEntry, resourceType string, schemas map[string]*tfjson.Schema) error { + if len(files) == 0 { + log.Printf("[DEBUG] Skipping %s file mismatch checks due to missing file list", resourceType) + return nil + } + + if len(schemas) == 0 { + log.Printf("[DEBUG] Skipping %s file mismatch checks due to missing schemas", resourceType) + return nil + } + + var extraFiles []string + var missingFiles []string + + for _, file := range files { + log.Printf("[DEBUG] Found file %s", file.Name()) + if fileHasResource(schemas, check.Options.ProviderShortName, file.Name()) { + continue + } + + if check.IgnoreFileMismatch(file.Name()) { + continue + } + + log.Printf("[DEBUG] Found extraneous file %s", file.Name()) + extraFiles = append(extraFiles, file.Name()) + } + + for _, resourceName := range resourceNames(schemas) { + log.Printf("[DEBUG] Found %s %s", resourceType, resourceName) + if resourceHasFile(files, check.Options.ProviderShortName, resourceName) { + continue + } + + if check.IgnoreFileMissing(resourceName) { + continue + } + + log.Printf("[DEBUG] Missing file for %s %s", resourceType, resourceName) + missingFiles = append(missingFiles, resourceName) + } + + var result error + + for _, extraFile := range extraFiles { + err := fmt.Errorf("matching %s for documentation file (%s) not found, file is extraneous or incorrectly named", resourceType, extraFile) + result = errors.Join(result, err) + } + + for _, missingFile := range missingFiles { + err := fmt.Errorf("missing documentation file for %s: %s", resourceType, missingFile) + result = errors.Join(result, err) + } + + return result + +} + +// FunctionFileMismatchCheck checks for mismatched files, either missing or extraneous, against the function signature +func (check *FileMismatchCheck) FunctionFileMismatchCheck(files []os.DirEntry, functions map[string]*tfjson.FunctionSignature) error { + if len(files) == 0 { + log.Printf("[DEBUG] Skipping function file mismatch checks due to missing file list") + return nil + } + + if len(functions) == 0 { + log.Printf("[DEBUG] Skipping function file mismatch checks due to missing schemas") + return nil + } + + var extraFiles []string + var missingFiles []string + + for _, file := range files { + if fileHasFunction(functions, file.Name()) { + continue + } + + if check.IgnoreFileMismatch(file.Name()) { + continue + } + + extraFiles = append(extraFiles, file.Name()) + } + + for _, functionName := range functionNames(functions) { + if functionHasFile(files, functionName) { + continue + } + + if check.IgnoreFileMissing(functionName) { + continue + } + + missingFiles = append(missingFiles, functionName) + } + + var result error + + for _, extraFile := range extraFiles { + err := fmt.Errorf("matching function for documentation file (%s) not found, file is extraneous or incorrectly named", extraFile) + result = errors.Join(result, err) + } + + for _, missingFile := range missingFiles { + err := fmt.Errorf("missing documentation file for function: %s", missingFile) + result = errors.Join(result, err) + } + + return result + +} + +func (check *FileMismatchCheck) IgnoreFileMismatch(file string) bool { + for _, ignoreResourceName := range check.Options.IgnoreFileMismatch { + if ignoreResourceName == fileResourceName(check.Options.ProviderShortName, file) { + return true + } + } + + return false +} + +func (check *FileMismatchCheck) IgnoreFileMissing(resourceName string) bool { + for _, ignoreResourceName := range check.Options.IgnoreFileMissing { + if ignoreResourceName == resourceName { + return true + } + } + + return false +} + +func fileHasResource(schemaResources map[string]*tfjson.Schema, providerName, file string) bool { + if _, ok := schemaResources[fileResourceName(providerName, file)]; ok { + return true + } + + return false +} + +func fileHasFunction(functions map[string]*tfjson.FunctionSignature, file string) bool { + if _, ok := functions[TrimFileExtension(file)]; ok { + return true + } + + return false +} + +func fileResourceName(providerName, fileName string) string { + resourceSuffix := TrimFileExtension(fileName) + + return fmt.Sprintf("%s_%s", providerName, resourceSuffix) +} + +func resourceHasFile(files []os.DirEntry, providerName, resourceName string) bool { + var found bool + + for _, file := range files { + if fileResourceName(providerName, file.Name()) == resourceName { + found = true + break + } + } + + return found +} + +func functionHasFile(files []os.DirEntry, functionName string) bool { + var found bool + + for _, file := range files { + if TrimFileExtension(file.Name()) == functionName { + found = true + break + } + } + + return found +} + +func resourceNames(resources map[string]*tfjson.Schema) []string { + names := make([]string, 0, len(resources)) + + for name := range resources { + names = append(names, name) + } + + sort.Strings(names) + + return names +} + +func functionNames(functions map[string]*tfjson.FunctionSignature) []string { + names := make([]string, 0, len(functions)) + + for name := range functions { + names = append(names, name) + } + + sort.Strings(names) + + return names +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/frontmatter.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/frontmatter.go new file mode 100644 index 00000000..65ac43aa --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/frontmatter.go @@ -0,0 +1,104 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package check + +import ( + "bytes" + "fmt" + + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/parser" + "go.abhg.dev/goldmark/frontmatter" +) + +type FrontMatterCheck struct { + Options *FrontMatterOptions +} + +// FrontMatterData represents the YAML frontmatter of Terraform Provider documentation. +type FrontMatterData struct { + Description *string `yaml:"description,omitempty"` + Layout *string `yaml:"layout,omitempty"` + PageTitle *string `yaml:"page_title,omitempty"` + SidebarCurrent *string `yaml:"sidebar_current,omitempty"` + Subcategory *string `yaml:"subcategory,omitempty"` +} + +// FrontMatterOptions represents configuration options for FrontMatter. +type FrontMatterOptions struct { + NoLayout bool + NoPageTitle bool + NoSidebarCurrent bool + NoSubcategory bool + RequireDescription bool + RequireLayout bool + RequirePageTitle bool +} + +func NewFrontMatterCheck(opts *FrontMatterOptions) *FrontMatterCheck { + check := &FrontMatterCheck{ + Options: opts, + } + + if check.Options == nil { + check.Options = &FrontMatterOptions{} + } + + return check +} + +func (check *FrontMatterCheck) Run(src []byte) error { + frontMatter := FrontMatterData{} + + md := goldmark.New( + goldmark.WithExtensions(&frontmatter.Extender{}), + ) + + ctx := parser.NewContext() + var buff bytes.Buffer + + err := md.Convert(src, &buff, parser.WithContext(ctx)) + if err != nil { + return err + } + d := frontmatter.Get(ctx) + if d == nil { + return fmt.Errorf("no frontmatter found") + } + + err = d.Decode(&frontMatter) + if err != nil { + return fmt.Errorf("error parsing YAML frontmatter: %w", err) + } + + if check.Options.NoLayout && frontMatter.Layout != nil { + return fmt.Errorf("YAML frontmatter should not contain layout") + } + + if check.Options.NoPageTitle && frontMatter.PageTitle != nil { + return fmt.Errorf("YAML frontmatter should not contain page_title") + } + + if check.Options.NoSidebarCurrent && frontMatter.SidebarCurrent != nil { + return fmt.Errorf("YAML frontmatter should not contain sidebar_current") + } + + if check.Options.NoSubcategory && frontMatter.Subcategory != nil { + return fmt.Errorf("YAML frontmatter should not contain subcategory") + } + + if check.Options.RequireDescription && frontMatter.Description == nil { + return fmt.Errorf("YAML frontmatter missing required description") + } + + if check.Options.RequireLayout && frontMatter.Layout == nil { + return fmt.Errorf("YAML frontmatter missing required layout") + } + + if check.Options.RequirePageTitle && frontMatter.PageTitle == nil { + return fmt.Errorf("YAML frontmatter missing required page_title") + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/provider_file.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/provider_file.go new file mode 100644 index 00000000..5358b669 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/check/provider_file.go @@ -0,0 +1,67 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package check + +import ( + "fmt" + "log" + "os" +) + +type ProviderFileOptions struct { + *FileOptions + + FrontMatter *FrontMatterOptions + ValidExtensions []string +} + +type ProviderFileCheck struct { + Options *ProviderFileOptions +} + +func NewProviderFileCheck(opts *ProviderFileOptions) *ProviderFileCheck { + check := &ProviderFileCheck{ + Options: opts, + } + + if check.Options == nil { + check.Options = &ProviderFileOptions{} + } + + if check.Options.FileOptions == nil { + check.Options.FileOptions = &FileOptions{} + } + + if check.Options.FrontMatter == nil { + check.Options.FrontMatter = &FrontMatterOptions{} + } + + return check +} + +func (check *ProviderFileCheck) Run(path string) error { + fullpath := check.Options.FullPath(path) + + log.Printf("[DEBUG] Checking file: %s", fullpath) + + if err := FileExtensionCheck(path, check.Options.ValidExtensions); err != nil { + return fmt.Errorf("%s: error checking file extension: %w", path, err) + } + + if err := FileSizeCheck(fullpath); err != nil { + return fmt.Errorf("%s: error checking file size: %w", path, err) + } + + content, err := os.ReadFile(fullpath) + + if err != nil { + return fmt.Errorf("%s: error reading file: %w", path, err) + } + + if err := NewFrontMatterCheck(check.Options.FrontMatter).Run(content); err != nil { + return fmt.Errorf("%s: error checking file frontmatter: %w", path, err) + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/generate.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/generate.go index 29b25ed5..1a0c7f15 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/generate.go +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/generate.go @@ -20,6 +20,7 @@ type generateCmd struct { flagRenderedProviderName string flagProviderDir string + flagProvidersSchema string flagRenderedWebsiteDir string flagExamplesDir string flagWebsiteTmpDir string @@ -73,12 +74,13 @@ func (cmd *generateCmd) Flags() *flag.FlagSet { fs := flag.NewFlagSet("generate", flag.ExitOnError) fs.StringVar(&cmd.flagProviderName, "provider-name", "", "provider name, as used in Terraform configurations") fs.StringVar(&cmd.flagProviderDir, "provider-dir", "", "relative or absolute path to the root provider code directory when running the command outside the root provider code directory") + fs.StringVar(&cmd.flagProvidersSchema, "providers-schema", "", "path to the providers schema JSON file, which contains the output of the terraform providers schema -json command. Setting this flag will skip building the provider and calling Terraform CLI") fs.StringVar(&cmd.flagRenderedProviderName, "rendered-provider-name", "", "provider name, as generated in documentation (ex. page titles, ...)") fs.StringVar(&cmd.flagRenderedWebsiteDir, "rendered-website-dir", "docs", "output directory based on provider-dir") fs.StringVar(&cmd.flagExamplesDir, "examples-dir", "examples", "examples directory based on provider-dir") fs.StringVar(&cmd.flagWebsiteTmpDir, "website-temp-dir", "", "temporary directory (used during generation)") fs.StringVar(&cmd.flagWebsiteSourceDir, "website-source-dir", "templates", "templates directory based on provider-dir") - fs.StringVar(&cmd.tfVersion, "tf-version", "", "terraform binary version to download") + fs.StringVar(&cmd.tfVersion, "tf-version", "", "terraform binary version to download. If not provided, will look for a terraform binary in the local environment. If not found in the environment, will download the latest version of Terraform") fs.BoolVar(&cmd.flagIgnoreDeprecated, "ignore-deprecated", false, "don't generate documentation for deprecated resources and data-sources") return fs } @@ -99,6 +101,7 @@ func (cmd *generateCmd) runInternal() error { cmd.ui, cmd.flagProviderDir, cmd.flagProviderName, + cmd.flagProvidersSchema, cmd.flagRenderedProviderName, cmd.flagRenderedWebsiteDir, cmd.flagExamplesDir, diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/migrate.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/migrate.go new file mode 100644 index 00000000..d0e9ca3a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/migrate.go @@ -0,0 +1,100 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package cmd + +import ( + "flag" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-docs/internal/provider" +) + +type migrateCmd struct { + commonCmd + + flagProviderDir string + flagTemplatesDir string + flagExamplesDir string + flagProviderName string +} + +func (cmd *migrateCmd) Synopsis() string { + return "migrates website files from either the legacy rendered website directory (`website/docs/r`) or the docs rendered website directory (`docs/resources`) to the tfplugindocs supported structure (`templates/`)." +} + +func (cmd *migrateCmd) Help() string { + strBuilder := &strings.Builder{} + + longestName := 0 + longestUsage := 0 + cmd.Flags().VisitAll(func(f *flag.Flag) { + if len(f.Name) > longestName { + longestName = len(f.Name) + } + if len(f.Usage) > longestUsage { + longestUsage = len(f.Usage) + } + }) + + strBuilder.WriteString("\nUsage: tfplugindocs migrate []\n\n") + cmd.Flags().VisitAll(func(f *flag.Flag) { + if f.DefValue != "" { + strBuilder.WriteString(fmt.Sprintf(" --%s %s%s%s (default: %q)\n", + f.Name, + strings.Repeat(" ", longestName-len(f.Name)+2), + f.Usage, + strings.Repeat(" ", longestUsage-len(f.Usage)+2), + f.DefValue, + )) + } else { + strBuilder.WriteString(fmt.Sprintf(" --%s %s%s%s\n", + f.Name, + strings.Repeat(" ", longestName-len(f.Name)+2), + f.Usage, + strings.Repeat(" ", longestUsage-len(f.Usage)+2), + )) + } + }) + strBuilder.WriteString("\n") + + return strBuilder.String() +} + +func (cmd *migrateCmd) Flags() *flag.FlagSet { + fs := flag.NewFlagSet("migrate", flag.ExitOnError) + + fs.StringVar(&cmd.flagProviderDir, "provider-dir", "", "relative or absolute path to the root provider code directory; this will default to the current working directory if not set") + fs.StringVar(&cmd.flagTemplatesDir, "templates-dir", "templates", "new website templates directory based on provider-dir; files will be migrated to this directory") + fs.StringVar(&cmd.flagExamplesDir, "examples-dir", "examples", "examples directory based on provider-dir; extracted code examples will be migrated to this directory") + fs.StringVar(&cmd.flagProviderName, "provider-name", "", "provider name, as used in Terraform configurations; this will default to provider-dir basename if not set") + + return fs +} + +func (cmd *migrateCmd) Run(args []string) int { + fs := cmd.Flags() + err := fs.Parse(args) + if err != nil { + cmd.ui.Error(fmt.Sprintf("unable to parse flags: %s", err)) + return 1 + } + + return cmd.run(cmd.runInternal) +} + +func (cmd *migrateCmd) runInternal() error { + err := provider.Migrate( + cmd.ui, + cmd.flagProviderDir, + cmd.flagTemplatesDir, + cmd.flagExamplesDir, + cmd.flagProviderName, + ) + if err != nil { + return fmt.Errorf("unable to migrate website: %w", err) + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/run.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/run.go index 82f47cde..471a76b8 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/run.go +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/run.go @@ -8,7 +8,10 @@ import ( "io" "os" - "github.com/mitchellh/cli" + "github.com/hashicorp/cli" + "github.com/mattn/go-colorable" + + "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs/build" ) type commonCmd struct { @@ -54,10 +57,19 @@ func initCommands(ui cli.Ui) map[string]cli.CommandFactory { }, nil } + migrateFactory := func() (cli.Command, error) { + return &migrateCmd{ + commonCmd: commonCmd{ + ui: ui, + }, + }, nil + } + return map[string]cli.CommandFactory{ "": defaultFactory, "generate": generateFactory, "validate": validateFactory, + "migrate": migrateFactory, //"serve": serveFactory, } } @@ -100,3 +112,16 @@ func Run(name, version string, args []string, stdin io.Reader, stdout, stderr io } return exitCode } + +// Main has the required function signature for use with testscript +func Main() int { + + return Run( + "tfplugindocs", + build.GetVersion(), + os.Args[1:], + os.Stdin, + colorable.NewColorableStdout(), + colorable.NewColorableStderr(), + ) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/validate.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/validate.go index c4a406cf..8999c4e8 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/validate.go +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/cmd/validate.go @@ -4,6 +4,7 @@ package cmd import ( + "errors" "flag" "fmt" "strings" @@ -13,10 +14,15 @@ import ( type validateCmd struct { commonCmd + + flagProviderName string + flagProviderDir string + flagProvidersSchema string + tfVersion string } func (cmd *validateCmd) Synopsis() string { - return "validates a plugin website for the current directory" + return "validates a plugin website" } func (cmd *validateCmd) Help() string { @@ -59,6 +65,10 @@ func (cmd *validateCmd) Help() string { func (cmd *validateCmd) Flags() *flag.FlagSet { fs := flag.NewFlagSet("validate", flag.ExitOnError) + fs.StringVar(&cmd.flagProviderName, "provider-name", "", "provider name, as used in Terraform configurations") + fs.StringVar(&cmd.flagProviderDir, "provider-dir", "", "relative or absolute path to the root provider code directory; this will default to the current working directory if not set") + fs.StringVar(&cmd.flagProvidersSchema, "providers-schema", "", "path to the providers schema JSON file, which contains the output of the terraform providers schema -json command. Setting this flag will skip building the provider and calling Terraform CLI") + fs.StringVar(&cmd.tfVersion, "tf-version", "", "terraform binary version to download. If not provided, will look for a terraform binary in the local environment. If not found in the environment, will download the latest version of Terraform") return fs } @@ -74,9 +84,14 @@ func (cmd *validateCmd) Run(args []string) int { } func (cmd *validateCmd) runInternal() error { - err := provider.Validate(cmd.ui) + err := provider.Validate(cmd.ui, + cmd.flagProviderDir, + cmd.flagProviderName, + cmd.flagProvidersSchema, + cmd.tfVersion, + ) if err != nil { - return fmt.Errorf("unable to validate website: %w", err) + return errors.Join(errors.New("validation errors found: "), err) } return nil diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/functionmd/render.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/functionmd/render.go new file mode 100644 index 00000000..7b4951b7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/functionmd/render.go @@ -0,0 +1,96 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package functionmd + +import ( + "bytes" + "fmt" + "strings" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-docs/internal/schemamd" +) + +// RenderArguments returns a Markdown formatted string of the function arguments. +func RenderArguments(signature *tfjson.FunctionSignature) (string, error) { + argBuffer := bytes.NewBuffer(nil) + for i, p := range signature.Parameters { + name := p.Name + desc := strings.TrimSpace(p.Description) + + typeBuffer := bytes.NewBuffer(nil) + err := schemamd.WriteType(typeBuffer, p.Type) + if err != nil { + return "", err + } + + if p.IsNullable { + argBuffer.WriteString(fmt.Sprintf("1. `%s` (%s, Nullable) %s", name, typeBuffer.String(), desc)) + } else { + argBuffer.WriteString(fmt.Sprintf("1. `%s` (%s) %s", name, typeBuffer.String(), desc)) + } + + if i != len(signature.Parameters)-1 { + argBuffer.WriteString("\n") + } + + } + return argBuffer.String(), nil + +} + +// RenderSignature returns a Markdown formatted string of the function signature. +func RenderSignature(funcName string, signature *tfjson.FunctionSignature) (string, error) { + + returnType := signature.ReturnType.FriendlyName() + + paramBuffer := bytes.NewBuffer(nil) + for i, p := range signature.Parameters { + if i != 0 { + paramBuffer.WriteString(", ") + } + + paramBuffer.WriteString(fmt.Sprintf("%s %s", p.Name, p.Type.FriendlyName())) + } + + if signature.VariadicParameter != nil { + if signature.Parameters != nil { + paramBuffer.WriteString(", ") + } + + paramBuffer.WriteString(fmt.Sprintf("%s %s...", signature.VariadicParameter.Name, + signature.VariadicParameter.Type.FriendlyName())) + + } + + return fmt.Sprintf("```text\n"+ + "%s(%s) %s\n"+ + "```", + funcName, paramBuffer.String(), returnType), nil +} + +// RenderVariadicArg returns a Markdown formatted string of the variadic argument if it exists, +// otherwise an empty string. +func RenderVariadicArg(signature *tfjson.FunctionSignature) (string, error) { + if signature.VariadicParameter == nil { + return "", nil + } + + name := signature.VariadicParameter.Name + desc := strings.TrimSpace(signature.VariadicParameter.Description) + + typeBuffer := bytes.NewBuffer(nil) + err := schemamd.WriteType(typeBuffer, signature.VariadicParameter.Type) + if err != nil { + return "", err + } + + if signature.VariadicParameter.IsNullable { + return fmt.Sprintf("1. `%s` (Variadic, %s, Nullable) %s", name, typeBuffer.String(), desc), nil + } else { + return fmt.Sprintf("1. `%s` (Variadic, %s) %s", name, typeBuffer.String(), desc), nil + } + +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/mdplain/mdplain.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/mdplain/mdplain.go index ded53b65..60a0ede9 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/mdplain/mdplain.go +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/mdplain/mdplain.go @@ -3,13 +3,25 @@ package mdplain -import "github.com/russross/blackfriday" +import ( + "bytes" -// Clean runs a VERY naive cleanup of markdown text to make it more palatable as plain text. -func PlainMarkdown(md string) (string, error) { - pt := &Text{} - - html := blackfriday.MarkdownOptions([]byte(md), pt, blackfriday.Options{}) + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/extension" +) - return string(html), nil +// Clean runs a VERY naive cleanup of markdown text to make it more palatable as plain text. +func PlainMarkdown(markdown string) (string, error) { + var buf bytes.Buffer + extensions := []goldmark.Extender{ + extension.Linkify, + } + md := goldmark.New( + goldmark.WithExtensions(extensions...), + goldmark.WithRenderer(NewTextRenderer()), + ) + if err := md.Convert([]byte(markdown), &buf); err != nil { + return "", err + } + return buf.String(), nil } diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/mdplain/renderer.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/mdplain/renderer.go index 660cdae5..93bd5ec7 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/mdplain/renderer.go +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/mdplain/renderer.go @@ -5,175 +5,101 @@ package mdplain import ( "bytes" + "io" - "github.com/russross/blackfriday" + "github.com/yuin/goldmark/ast" + extAST "github.com/yuin/goldmark/extension/ast" + "github.com/yuin/goldmark/renderer" ) -type Text struct{} - -func TextRenderer() blackfriday.Renderer { - return &Text{} -} - -func (options *Text) GetFlags() int { - return 0 -} - -func (options *Text) TitleBlock(out *bytes.Buffer, text []byte) { - text = bytes.TrimPrefix(text, []byte("% ")) - text = bytes.Replace(text, []byte("\n% "), []byte("\n"), -1) - out.Write(text) - out.WriteString("\n") -} - -func (options *Text) Header(out *bytes.Buffer, text func() bool, level int, id string) { - marker := out.Len() - doubleSpace(out) - - if !text() { - out.Truncate(marker) - return +type TextRender struct{} + +func NewTextRenderer() *TextRender { + return &TextRender{} +} + +func (r *TextRender) Render(w io.Writer, source []byte, n ast.Node) error { + out := bytes.NewBuffer([]byte{}) + err := ast.Walk(n, func(node ast.Node, entering bool) (ast.WalkStatus, error) { + if !entering || node.Type() == ast.TypeDocument { + return ast.WalkContinue, nil + } + + switch node := node.(type) { + case *ast.Blockquote, *ast.Heading: + doubleSpace(out) + out.Write(node.Text(source)) + return ast.WalkSkipChildren, nil + case *ast.ThematicBreak: + doubleSpace(out) + return ast.WalkSkipChildren, nil + case *ast.CodeBlock: + doubleSpace(out) + for i := 0; i < node.Lines().Len(); i++ { + line := node.Lines().At(i) + out.Write(line.Value(source)) + } + return ast.WalkSkipChildren, nil + case *ast.FencedCodeBlock: + doubleSpace(out) + doubleSpace(out) + for i := 0; i < node.Lines().Len(); i++ { + line := node.Lines().At(i) + _, _ = out.Write(line.Value(source)) + } + return ast.WalkSkipChildren, nil + case *ast.List: + doubleSpace(out) + return ast.WalkContinue, nil + case *ast.Paragraph: + doubleSpace(out) + if node.Text(source)[0] == '|' { // Write tables as-is. + for i := 0; i < node.Lines().Len(); i++ { + line := node.Lines().At(i) + out.Write(line.Value(source)) + } + return ast.WalkSkipChildren, nil + } + return ast.WalkContinue, nil + case *extAST.Strikethrough: + out.Write(node.Text(source)) + return ast.WalkContinue, nil + case *ast.AutoLink: + out.Write(node.URL(source)) + return ast.WalkSkipChildren, nil + case *ast.CodeSpan: + out.Write(node.Text(source)) + return ast.WalkSkipChildren, nil + case *ast.Link: + _, err := out.Write(node.Text(source)) + if !isRelativeLink(node.Destination) { + out.WriteString(" ") + out.Write(node.Destination) + } + return ast.WalkSkipChildren, err + case *ast.Text: + out.Write(node.Text(source)) + if node.SoftLineBreak() { + doubleSpace(out) + } + return ast.WalkContinue, nil + case *ast.Image: + return ast.WalkSkipChildren, nil + + } + return ast.WalkContinue, nil + }) + if err != nil { + return err } -} - -func (options *Text) BlockHtml(out *bytes.Buffer, text []byte) { - doubleSpace(out) - out.Write(text) - out.WriteByte('\n') -} - -func (options *Text) HRule(out *bytes.Buffer) { - doubleSpace(out) -} - -func (options *Text) BlockCode(out *bytes.Buffer, text []byte, lang string) { - options.BlockCodeNormal(out, text, lang) -} - -func (options *Text) BlockCodeNormal(out *bytes.Buffer, text []byte, lang string) { - doubleSpace(out) - out.Write(text) -} - -func (options *Text) BlockQuote(out *bytes.Buffer, text []byte) { - doubleSpace(out) - out.Write(text) -} - -func (options *Text) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) { - doubleSpace(out) - out.Write(header) - out.Write(body) -} - -func (options *Text) TableRow(out *bytes.Buffer, text []byte) { - doubleSpace(out) - out.Write(text) -} - -func (options *Text) TableHeaderCell(out *bytes.Buffer, text []byte, align int) { - doubleSpace(out) - out.Write(text) -} - -func (options *Text) TableCell(out *bytes.Buffer, text []byte, align int) { - doubleSpace(out) - out.Write(text) -} - -func (options *Text) Footnotes(out *bytes.Buffer, text func() bool) { - options.HRule(out) - options.List(out, text, 0) -} - -func (options *Text) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) { - out.Write(text) -} - -func (options *Text) List(out *bytes.Buffer, text func() bool, flags int) { - marker := out.Len() - doubleSpace(out) - - if !text() { - out.Truncate(marker) - return + _, err = w.Write(out.Bytes()) + if err != nil { + return err } + return nil } -func (options *Text) ListItem(out *bytes.Buffer, text []byte, flags int) { - out.Write(text) -} - -func (options *Text) Paragraph(out *bytes.Buffer, text func() bool) { - marker := out.Len() - doubleSpace(out) - - if !text() { - out.Truncate(marker) - return - } -} - -func (options *Text) AutoLink(out *bytes.Buffer, link []byte, kind int) { - out.Write(link) -} - -func (options *Text) CodeSpan(out *bytes.Buffer, text []byte) { - out.Write(text) -} - -func (options *Text) DoubleEmphasis(out *bytes.Buffer, text []byte) { - out.Write(text) -} - -func (options *Text) Emphasis(out *bytes.Buffer, text []byte) { - if len(text) == 0 { - return - } - out.Write(text) -} - -func (options *Text) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {} - -func (options *Text) LineBreak(out *bytes.Buffer) {} - -func (options *Text) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) { - out.Write(content) - if !isRelativeLink(link) { - out.WriteString(" ") - out.Write(link) - } -} - -func (options *Text) RawHtmlTag(out *bytes.Buffer, text []byte) {} - -func (options *Text) TripleEmphasis(out *bytes.Buffer, text []byte) { - out.Write(text) -} - -func (options *Text) StrikeThrough(out *bytes.Buffer, text []byte) { - out.Write(text) -} - -func (options *Text) FootnoteRef(out *bytes.Buffer, ref []byte, id int) {} - -func (options *Text) Entity(out *bytes.Buffer, entity []byte) { - out.Write(entity) -} - -func (options *Text) NormalText(out *bytes.Buffer, text []byte) { - out.Write(text) -} - -func (options *Text) Smartypants(out *bytes.Buffer, text []byte) {} - -func (options *Text) DocumentHeader(out *bytes.Buffer) {} - -func (options *Text) DocumentFooter(out *bytes.Buffer) {} - -func (options *Text) TocHeader(text []byte, level int) {} - -func (options *Text) TocFinalize() {} +func (r *TextRender) AddOptions(...renderer.Option) {} func doubleSpace(out *bytes.Buffer) { if out.Len() > 0 { diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/generate.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/generate.go index b4c3293f..d0c3c965 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/generate.go +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/generate.go @@ -8,11 +8,11 @@ import ( "fmt" "os" "os/exec" - "path" "path/filepath" "runtime" "strings" + "github.com/hashicorp/cli" "github.com/hashicorp/go-version" install "github.com/hashicorp/hc-install" "github.com/hashicorp/hc-install/checkpoint" @@ -22,54 +22,55 @@ import ( "github.com/hashicorp/hc-install/src" "github.com/hashicorp/terraform-exec/tfexec" tfjson "github.com/hashicorp/terraform-json" - "github.com/mitchellh/cli" "golang.org/x/exp/slices" ) var ( - examplesResourceFileTemplate = resourceFileTemplate("resources/{{.Name}}/resource.tf") - examplesResourceImportTemplate = resourceFileTemplate("resources/{{.Name}}/import.sh") - examplesDataSourceFileTemplate = resourceFileTemplate("data-sources/{{ .Name }}/data-source.tf") - examplesProviderFileTemplate = providerFileTemplate("provider/provider.tf") - - websiteResourceFileTemplate = resourceFileTemplate("resources/{{ .ShortName }}.md.tmpl") - websiteResourceFallbackFileTemplate = resourceFileTemplate("resources.md.tmpl") - websiteResourceFileStatic = []resourceFileTemplate{ - resourceFileTemplate("resources/{{ .ShortName }}.md"), - // TODO: warn for all of these, as they won't render? massage them to the proper output file name? - resourceFileTemplate("resources/{{ .ShortName }}.markdown"), - resourceFileTemplate("resources/{{ .ShortName }}.html.markdown"), - resourceFileTemplate("resources/{{ .ShortName }}.html.md"), - resourceFileTemplate("r/{{ .ShortName }}.markdown"), - resourceFileTemplate("r/{{ .ShortName }}.md"), - resourceFileTemplate("r/{{ .ShortName }}.html.markdown"), - resourceFileTemplate("r/{{ .ShortName }}.html.md"), - } - websiteDataSourceFileTemplate = resourceFileTemplate("data-sources/{{ .ShortName }}.md.tmpl") - websiteDataSourceFallbackFileTemplate = resourceFileTemplate("data-sources.md.tmpl") - websiteDataSourceFileStatic = []resourceFileTemplate{ - resourceFileTemplate("data-sources/{{ .ShortName }}.md"), - // TODO: warn for all of these, as they won't render? massage them to the proper output file name? - resourceFileTemplate("data-sources/{{ .ShortName }}.markdown"), - resourceFileTemplate("data-sources/{{ .ShortName }}.html.markdown"), - resourceFileTemplate("data-sources/{{ .ShortName }}.html.md"), - resourceFileTemplate("d/{{ .ShortName }}.markdown"), - resourceFileTemplate("d/{{ .ShortName }}.md"), - resourceFileTemplate("d/{{ .ShortName }}.html.markdown"), - resourceFileTemplate("d/{{ .ShortName }}.html.md"), - } - websiteProviderFileTemplate = providerFileTemplate("index.md.tmpl") - websiteProviderFileStatic = []providerFileTemplate{ - providerFileTemplate("index.markdown"), - providerFileTemplate("index.md"), - providerFileTemplate("index.html.markdown"), - providerFileTemplate("index.html.md"), + websiteResourceFile = "resources/%s.md.tmpl" + websiteResourceFallbackFile = "resources.md.tmpl" + websiteResourceFileStaticCandidates = []string{ + "resources/%s.md", + "resources/%s.markdown", + "resources/%s.html.markdown", + "resources/%s.html.md", + "r/%s.markdown", + "r/%s.md", + "r/%s.html.markdown", + "r/%s.html.md", + } + websiteDataSourceFile = "data-sources/%s.md.tmpl" + websiteDataSourceFallbackFile = "data-sources.md.tmpl" + websiteDataSourceFileStaticCandidates = []string{ + "data-sources/%s.md", + "data-sources/%s.markdown", + "data-sources/%s.html.markdown", + "data-sources/%s.html.md", + "d/%s.markdown", + "d/%s.md", + "d/%s.html.markdown", + "d/%s.html.md", + } + websiteFunctionFile = "functions/%s.md.tmpl" + websiteFunctionFallbackFile = "functions.md.tmpl" + websiteFunctionFileStaticCandidates = []string{ + "functions/%s.md", + "functions/%s.markdown", + "functions/%s.html.markdown", + "functions/%s.html.md", + } + websiteProviderFile = "index.md.tmpl" + websiteProviderFileStaticCandidates = []string{ + "index.markdown", + "index.md", + "index.html.markdown", + "index.html.md", } managedWebsiteSubDirectories = []string{ "data-sources", "guides", "resources", + "functions", } managedWebsiteFiles = []string{ @@ -85,6 +86,7 @@ type generator struct { providerDir string providerName string + providersSchemaPath string renderedProviderName string renderedWebsiteDir string examplesDir string @@ -102,7 +104,7 @@ func (g *generator) warnf(format string, a ...interface{}) { g.ui.Warn(fmt.Sprintf(format, a...)) } -func Generate(ui cli.Ui, providerDir, providerName, renderedProviderName, renderedWebsiteDir, examplesDir, websiteTmpDir, templatesDir, tfVersion string, ignoreDeprecated bool) error { +func Generate(ui cli.Ui, providerDir, providerName, providersSchemaPath, renderedProviderName, renderedWebsiteDir, examplesDir, websiteTmpDir, templatesDir, tfVersion string, ignoreDeprecated bool) error { // Ensure provider directory is resolved absolute path if providerDir == "" { wd, err := os.Getwd() @@ -139,6 +141,7 @@ func Generate(ui cli.Ui, providerDir, providerName, renderedProviderName, render providerDir: providerDir, providerName: providerName, + providersSchemaPath: providersSchemaPath, renderedProviderName: renderedProviderName, renderedWebsiteDir: renderedWebsiteDir, examplesDir: examplesDir, @@ -156,35 +159,34 @@ func Generate(ui cli.Ui, providerDir, providerName, renderedProviderName, render func (g *generator) Generate(ctx context.Context) error { var err error - providerName := g.providerName if g.providerName == "" { - providerName = filepath.Base(g.providerDir) + g.providerName = filepath.Base(g.providerDir) } if g.renderedProviderName == "" { - g.renderedProviderName = providerName + g.renderedProviderName = g.providerName } - g.infof("rendering website for provider %q (as %q)", providerName, g.renderedProviderName) + g.infof("rendering website for provider %q (as %q)", g.providerName, g.renderedProviderName) switch { case g.websiteTmpDir == "": g.websiteTmpDir, err = os.MkdirTemp("", "tfws") if err != nil { - return err + return fmt.Errorf("error creating temporary website directory: %w", err) } defer os.RemoveAll(g.websiteTmpDir) default: g.infof("cleaning tmp dir %q", g.websiteTmpDir) err = os.RemoveAll(g.websiteTmpDir) if err != nil { - return err + return fmt.Errorf("error removing temporary website directory %q: %w", g.websiteTmpDir, err) } g.infof("creating tmp dir %q", g.websiteTmpDir) err = os.MkdirAll(g.websiteTmpDir, 0755) if err != nil { - return err + return fmt.Errorf("error creating temporary website directory %q: %w", g.websiteTmpDir, err) } } @@ -193,7 +195,7 @@ func (g *generator) Generate(ctx context.Context) error { case os.IsNotExist(err): // do nothing, no template dir case err != nil: - return err + return fmt.Errorf("error getting information for provider templates directory %q: %w", g.ProviderTemplatesDir(), err) default: if !templatesDirInfo.IsDir() { return fmt.Errorf("template path is not a directory: %s", g.ProviderTemplatesDir()) @@ -202,26 +204,36 @@ func (g *generator) Generate(ctx context.Context) error { g.infof("copying any existing content to tmp dir") err = cp(g.ProviderTemplatesDir(), g.TempTemplatesDir()) if err != nil { - return err + return fmt.Errorf("error copying exiting content to temporary directory %q: %w", g.TempTemplatesDir(), err) } } - g.infof("exporting schema from Terraform") - providerSchema, err := g.terraformProviderSchema(ctx, providerName) - if err != nil { - return err + var providerSchema *tfjson.ProviderSchema + + if g.providersSchemaPath == "" { + g.infof("exporting schema from Terraform") + providerSchema, err = g.terraformProviderSchemaFromTerraform(ctx) + if err != nil { + return fmt.Errorf("error exporting provider schema from Terraform: %w", err) + } + } else { + g.infof("exporting schema from JSON file") + providerSchema, err = g.terraformProviderSchemaFromFile() + if err != nil { + return fmt.Errorf("error exporting provider schema from JSON file: %w", err) + } } - g.infof("rendering missing docs") - err = g.renderMissingDocs(providerName, providerSchema) + g.infof("generating missing templates") + err = g.generateMissingTemplates(providerSchema) if err != nil { - return err + return fmt.Errorf("error generating missing templates: %w", err) } g.infof("rendering static website") - err = g.renderStaticWebsite(providerName, providerSchema) + err = g.renderStaticWebsite(providerSchema) if err != nil { - return err + return fmt.Errorf("error rendering static website: %w", err) } return nil @@ -229,170 +241,171 @@ func (g *generator) Generate(ctx context.Context) error { // ProviderDocsDir returns the absolute path to the joined provider and // given website documentation directory, which defaults to "docs". -func (g generator) ProviderDocsDir() string { +func (g *generator) ProviderDocsDir() string { return filepath.Join(g.providerDir, g.renderedWebsiteDir) } // ProviderExamplesDir returns the absolute path to the joined provider and // given examples directory, which defaults to "examples". -func (g generator) ProviderExamplesDir() string { +func (g *generator) ProviderExamplesDir() string { return filepath.Join(g.providerDir, g.examplesDir) } // ProviderTemplatesDir returns the absolute path to the joined provider and // given templates directory, which defaults to "templates". -func (g generator) ProviderTemplatesDir() string { +func (g *generator) ProviderTemplatesDir() string { return filepath.Join(g.providerDir, g.templatesDir) } // TempTemplatesDir returns the absolute path to the joined temporary and -// hardcoded "templates" sub-directory, which is where provider templates are +// hardcoded "templates" subdirectory, which is where provider templates are // copied. -func (g generator) TempTemplatesDir() string { +func (g *generator) TempTemplatesDir() string { return filepath.Join(g.websiteTmpDir, "templates") } -func (g *generator) renderMissingResourceDoc(providerName, name, typeName string, schema *tfjson.Schema, websiteFileTemplate resourceFileTemplate, fallbackWebsiteFileTemplate resourceFileTemplate, websiteStaticCandidateTemplates []resourceFileTemplate, examplesFileTemplate resourceFileTemplate, examplesImportTemplate *resourceFileTemplate) error { - tmplPath, err := websiteFileTemplate.Render(g.providerDir, name, providerName) - if err != nil { - return fmt.Errorf("unable to render path for resource %q: %w", name, err) - } - tmplPath = filepath.Join(g.TempTemplatesDir(), tmplPath) - if fileExists(tmplPath) { - g.infof("resource %q template exists, skipping", name) +func (g *generator) generateMissingResourceTemplate(resourceName string) error { + templatePath := fmt.Sprintf(websiteResourceFile, resourceShortName(resourceName, g.providerName)) + templatePath = filepath.Join(g.TempTemplatesDir(), templatePath) + if fileExists(templatePath) { + g.infof("resource %q template exists, skipping", resourceName) return nil } - for _, candidate := range websiteStaticCandidateTemplates { - candidatePath, err := candidate.Render(g.providerDir, name, providerName) + fallbackTemplatePath := filepath.Join(g.TempTemplatesDir(), websiteResourceFallbackFile) + if fileExists(fallbackTemplatePath) { + g.infof("resource %q fallback template exists, creating template", resourceName) + err := cp(fallbackTemplatePath, templatePath) if err != nil { - return fmt.Errorf("unable to render path for resource %q: %w", name, err) + return fmt.Errorf("unable to copy fallback template for %q: %w", resourceName, err) } + return nil + } + + for _, candidate := range websiteResourceFileStaticCandidates { + candidatePath := fmt.Sprintf(candidate, resourceShortName(resourceName, g.providerName)) candidatePath = filepath.Join(g.TempTemplatesDir(), candidatePath) if fileExists(candidatePath) { - g.infof("resource %q static file exists, skipping", name) + g.infof("resource %q static file exists, skipping", resourceName) return nil } } - examplePath, err := examplesFileTemplate.Render(g.providerDir, name, providerName) + g.infof("generating new template for %q", resourceName) + err := writeFile(templatePath, string(defaultResourceTemplate)) if err != nil { - return fmt.Errorf("unable to render example file path for %q: %w", name, err) - } - if examplePath != "" { - examplePath = filepath.Join(g.ProviderExamplesDir(), examplePath) - } - if !fileExists(examplePath) { - examplePath = "" + return fmt.Errorf("unable to write template for %q: %w", resourceName, err) } - importPath := "" - if examplesImportTemplate != nil { - importPath, err = examplesImportTemplate.Render(g.providerDir, name, providerName) - if err != nil { - return fmt.Errorf("unable to render example import file path for %q: %w", name, err) - } - if importPath != "" { - importPath = filepath.Join(g.ProviderExamplesDir(), importPath) - } - if !fileExists(importPath) { - importPath = "" - } - } - - targetResourceTemplate := defaultResourceTemplate + return nil +} - fallbackTmplPath, err := fallbackWebsiteFileTemplate.Render(g.providerDir, name, providerName) - if err != nil { - return fmt.Errorf("unable to render path for resource %q: %w", name, err) +func (g *generator) generateMissingDataSourceTemplate(datasourceName string) error { + templatePath := fmt.Sprintf(websiteDataSourceFile, resourceShortName(datasourceName, g.providerName)) + templatePath = filepath.Join(g.TempTemplatesDir(), templatePath) + if fileExists(templatePath) { + g.infof("data-source %q template exists, skipping", datasourceName) + return nil } - fallbackTmplPath = filepath.Join(g.TempTemplatesDir(), fallbackTmplPath) - if fileExists(fallbackTmplPath) { - g.infof("resource %q fallback template exists", name) - tmplData, err := os.ReadFile(fallbackTmplPath) + + fallbackTemplatePath := filepath.Join(g.TempTemplatesDir(), websiteDataSourceFallbackFile) + if fileExists(fallbackTemplatePath) { + g.infof("data-source %q fallback template exists, creating template", datasourceName) + err := cp(fallbackTemplatePath, templatePath) if err != nil { - return fmt.Errorf("unable to read file %q: %w", fallbackTmplPath, err) + return fmt.Errorf("unable to copy fallback template for %q: %w", datasourceName, err) } - targetResourceTemplate = resourceTemplate(tmplData) + return nil } - g.infof("generating template for %q", name) - md, err := targetResourceTemplate.Render(g.providerDir, name, providerName, g.renderedProviderName, typeName, examplePath, importPath, schema) - if err != nil { - return fmt.Errorf("unable to render template for %q: %w", name, err) + for _, candidate := range websiteDataSourceFileStaticCandidates { + candidatePath := fmt.Sprintf(candidate, resourceShortName(datasourceName, g.providerName)) + candidatePath = filepath.Join(g.TempTemplatesDir(), candidatePath) + if fileExists(candidatePath) { + g.infof("data-source %q static file exists, skipping", datasourceName) + return nil + } } - err = writeFile(tmplPath, md) + g.infof("generating new template for data-source %q", datasourceName) + err := writeFile(templatePath, string(defaultResourceTemplate)) if err != nil { - return fmt.Errorf("unable to write file %q: %w", tmplPath, err) + return fmt.Errorf("unable to write template for %q: %w", datasourceName, err) } return nil } -func (g *generator) renderMissingProviderDoc(providerName string, schema *tfjson.Schema, websiteFileTemplate providerFileTemplate, websiteStaticCandidateTemplates []providerFileTemplate, examplesFileTemplate providerFileTemplate) error { - tmplPath, err := websiteFileTemplate.Render(g.providerDir, providerName) - if err != nil { - return fmt.Errorf("unable to render path for provider %q: %w", providerName, err) - } - tmplPath = filepath.Join(g.TempTemplatesDir(), tmplPath) - if fileExists(tmplPath) { - g.infof("provider %q template exists, skipping", providerName) +func (g *generator) generateMissingFunctionTemplate(functionName string) error { + templatePath := fmt.Sprintf(websiteFunctionFile, resourceShortName(functionName, g.providerName)) + templatePath = filepath.Join(g.TempTemplatesDir(), templatePath) + if fileExists(templatePath) { + g.infof("function %q template exists, skipping", functionName) return nil } - for _, candidate := range websiteStaticCandidateTemplates { - candidatePath, err := candidate.Render(g.providerDir, providerName) + fallbackTemplatePath := filepath.Join(g.TempTemplatesDir(), websiteFunctionFallbackFile) + if fileExists(fallbackTemplatePath) { + g.infof("function %q fallback template exists, creating template", functionName) + err := cp(fallbackTemplatePath, templatePath) if err != nil { - return fmt.Errorf("unable to render path for provider %q: %w", providerName, err) + return fmt.Errorf("unable to copy fallback template for %q: %w", functionName, err) } + return nil + } + + for _, candidate := range websiteFunctionFileStaticCandidates { + candidatePath := fmt.Sprintf(candidate, resourceShortName(functionName, g.providerName)) candidatePath = filepath.Join(g.TempTemplatesDir(), candidatePath) if fileExists(candidatePath) { - g.infof("provider %q static file exists, skipping", providerName) + g.infof("function %q static file exists, skipping", functionName) return nil } } - examplePath, err := examplesFileTemplate.Render(g.providerDir, providerName) + g.infof("generating new template for function %q", functionName) + err := writeFile(templatePath, string(defaultFunctionTemplate)) if err != nil { - return fmt.Errorf("unable to render example file path for %q: %w", providerName, err) - } - if examplePath != "" { - examplePath = filepath.Join(g.ProviderExamplesDir(), examplePath) + return fmt.Errorf("unable to write template for %q: %w", functionName, err) } - if !fileExists(examplePath) { - examplePath = "" + + return nil +} + +func (g *generator) generateMissingProviderTemplate() error { + templatePath := filepath.Join(g.TempTemplatesDir(), websiteProviderFile) + if fileExists(templatePath) { + g.infof("provider %q template exists, skipping", g.providerName) + return nil } - g.infof("generating template for %q", providerName) - md, err := defaultProviderTemplate.Render(g.providerDir, providerName, g.renderedProviderName, examplePath, schema) - if err != nil { - return fmt.Errorf("unable to render template for %q: %w", providerName, err) + for _, candidate := range websiteProviderFileStaticCandidates { + candidatePath := filepath.Join(g.TempTemplatesDir(), candidate) + if fileExists(candidatePath) { + g.infof("provider %q static file exists, skipping", g.providerName) + return nil + } } - err = writeFile(tmplPath, md) + g.infof("generating new template for %q", g.providerName) + err := writeFile(templatePath, string(defaultProviderTemplate)) if err != nil { - return fmt.Errorf("unable to write file %q: %w", tmplPath, err) + return fmt.Errorf("unable to write template for %q: %w", g.providerName, err) } return nil } -func (g *generator) renderMissingDocs(providerName string, providerSchema *tfjson.ProviderSchema) error { +func (g *generator) generateMissingTemplates(providerSchema *tfjson.ProviderSchema) error { g.infof("generating missing resource content") for name, schema := range providerSchema.ResourceSchemas { if g.ignoreDeprecated && schema.Block.Deprecated { continue } - err := g.renderMissingResourceDoc(providerName, name, "Resource", schema, - websiteResourceFileTemplate, - websiteResourceFallbackFileTemplate, - websiteResourceFileStatic, - examplesResourceFileTemplate, - &examplesResourceImportTemplate) + err := g.generateMissingResourceTemplate(name) if err != nil { - return fmt.Errorf("unable to render doc %q: %w", name, err) + return fmt.Errorf("unable to generate template for resource %q: %w", name, err) } } @@ -402,35 +415,38 @@ func (g *generator) renderMissingDocs(providerName string, providerSchema *tfjso continue } - err := g.renderMissingResourceDoc(providerName, name, "Data Source", schema, - websiteDataSourceFileTemplate, - websiteDataSourceFallbackFileTemplate, - websiteDataSourceFileStatic, - examplesDataSourceFileTemplate, - nil) + err := g.generateMissingDataSourceTemplate(name) if err != nil { - return fmt.Errorf("unable to render doc %q: %w", name, err) + return fmt.Errorf("unable to generate template for data-source %q: %w", name, err) + } + } + + g.infof("generating missing function content") + for name, signature := range providerSchema.Functions { + if g.ignoreDeprecated && signature.DeprecationMessage != "" { + continue + } + + err := g.generateMissingFunctionTemplate(name) + if err != nil { + return fmt.Errorf("unable to generate template for function %q: %w", name, err) } } g.infof("generating missing provider content") - err := g.renderMissingProviderDoc(providerName, providerSchema.ConfigSchema, - websiteProviderFileTemplate, - websiteProviderFileStatic, - examplesProviderFileTemplate, - ) + err := g.generateMissingProviderTemplate() if err != nil { - return fmt.Errorf("unable to render provider doc: %w", err) + return fmt.Errorf("unable to generate template for provider: %w", err) } return nil } -func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfjson.ProviderSchema) error { +func (g *generator) renderStaticWebsite(providerSchema *tfjson.ProviderSchema) error { g.infof("cleaning rendered website dir") dirEntry, err := os.ReadDir(g.ProviderDocsDir()) - if err != nil { - return err + if err != nil && !os.IsNotExist(err) { + return fmt.Errorf("unable to read rendered website directory %q: %w", g.ProviderDocsDir(), err) } for _, file := range dirEntry { @@ -438,9 +454,9 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj // Remove subdirectories managed by tfplugindocs if file.IsDir() && slices.Contains(managedWebsiteSubDirectories, file.Name()) { g.infof("removing directory: %q", file.Name()) - err = os.RemoveAll(path.Join(g.ProviderDocsDir(), file.Name())) + err = os.RemoveAll(filepath.Join(g.ProviderDocsDir(), file.Name())) if err != nil { - return err + return fmt.Errorf("unable to remove directory %q from rendered website directory: %w", file.Name(), err) } continue } @@ -448,41 +464,45 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj // Remove files managed by tfplugindocs if !file.IsDir() && slices.Contains(managedWebsiteFiles, file.Name()) { g.infof("removing file: %q", file.Name()) - err = os.RemoveAll(path.Join(g.ProviderDocsDir(), file.Name())) + err = os.RemoveAll(filepath.Join(g.ProviderDocsDir(), file.Name())) if err != nil { - return err + return fmt.Errorf("unable to remove file %q from rendered website directory: %w", file.Name(), err) } continue } } - shortName := providerShortName(providerName) + shortName := providerShortName(g.providerName) g.infof("rendering templated website to static markdown") - err = filepath.Walk(g.websiteTmpDir, func(path string, info os.FileInfo, _ error) error { - if info.IsDir() { + err = filepath.WalkDir(g.websiteTmpDir, func(path string, d os.DirEntry, err error) error { + if err != nil { + return fmt.Errorf("unable to walk path %q: %w", path, err) + } + if d.IsDir() { // skip directories return nil } rel, err := filepath.Rel(filepath.Join(g.TempTemplatesDir()), path) if err != nil { - return err + return fmt.Errorf("unable to retrieve the relative path of basepath %q and targetpath %q: %w", + filepath.Join(g.TempTemplatesDir()), path, err) } relDir, relFile := filepath.Split(rel) relDir = filepath.ToSlash(relDir) - // skip special top-level generic resource and data source templates - if relDir == "" && (relFile == "resources.md.tmpl" || relFile == "data-sources.md.tmpl") { + // skip special top-level generic resource, data source, and function templates + if relDir == "" && (relFile == "resources.md.tmpl" || relFile == "data-sources.md.tmpl" || relFile == "functions.md.tmpl") { return nil } renderedPath := filepath.Join(g.ProviderDocsDir(), rel) err = os.MkdirAll(filepath.Dir(renderedPath), 0755) if err != nil { - return err + return fmt.Errorf("unable to create rendered website subdirectory %q: %w", renderedPath, err) } ext := filepath.Ext(path) @@ -500,7 +520,7 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj out, err := os.Create(renderedPath) if err != nil { - return err + return fmt.Errorf("unable to create file %q: %w", renderedPath, err) } defer out.Close() @@ -512,7 +532,7 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj if resSchema != nil { tmpl := resourceTemplate(tmplData) - render, err := tmpl.Render(g.providerDir, resName, providerName, g.renderedProviderName, "Data Source", exampleFilePath, "", resSchema) + render, err := tmpl.Render(g.providerDir, resName, g.providerName, g.renderedProviderName, "Data Source", exampleFilePath, "", resSchema) if err != nil { return fmt.Errorf("unable to render data source template %q: %w", rel, err) } @@ -530,22 +550,40 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj if resSchema != nil { tmpl := resourceTemplate(tmplData) - render, err := tmpl.Render(g.providerDir, resName, providerName, g.renderedProviderName, "Resource", exampleFilePath, importFilePath, resSchema) + render, err := tmpl.Render(g.providerDir, resName, g.providerName, g.renderedProviderName, "Resource", exampleFilePath, importFilePath, resSchema) if err != nil { return fmt.Errorf("unable to render resource template %q: %w", rel, err) } _, err = out.WriteString(render) if err != nil { - return fmt.Errorf("unable to write regindered string: %w", err) + return fmt.Errorf("unable to write rendered string: %w", err) } return nil } g.warnf("resource entitled %q, or %q does not exist", shortName, resName) + case "functions/": + funcName := removeAllExt(relFile) + if signature, ok := providerSchema.Functions[funcName]; ok { + exampleFilePath := filepath.Join(g.ProviderExamplesDir(), "functions", funcName, "function.tf") + + tmpl := functionTemplate(tmplData) + render, err := tmpl.Render(g.providerDir, funcName, g.providerName, g.renderedProviderName, "function", exampleFilePath, signature) + if err != nil { + return fmt.Errorf("unable to render function template %q: %w", rel, err) + } + _, err = out.WriteString(render) + if err != nil { + return fmt.Errorf("unable to write rendered string: %w", err) + } + return nil + } + + g.warnf("function entitled %q does not exist", funcName) case "": // provider if relFile == "index.md.tmpl" { tmpl := providerTemplate(tmplData) exampleFilePath := filepath.Join(g.ProviderExamplesDir(), "provider", "provider.tf") - render, err := tmpl.Render(g.providerDir, providerName, g.renderedProviderName, exampleFilePath, providerSchema.ConfigSchema) + render, err := tmpl.Render(g.providerDir, g.providerName, g.renderedProviderName, exampleFilePath, providerSchema.ConfigSchema) if err != nil { return fmt.Errorf("unable to render provider template %q: %w", rel, err) } @@ -565,28 +603,23 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj return nil }) if err != nil { - return err + return fmt.Errorf("unable to render templated website to static markdown: %w", err) } return nil } -func (g *generator) terraformProviderSchema(ctx context.Context, providerName string) (*tfjson.ProviderSchema, error) { +func (g *generator) terraformProviderSchemaFromTerraform(ctx context.Context) (*tfjson.ProviderSchema, error) { var err error - shortName := providerShortName(providerName) + shortName := providerShortName(g.providerName) tmpDir, err := os.MkdirTemp("", "tfws") if err != nil { - return nil, err + return nil, fmt.Errorf("unable to create temporary provider install directory %q: %w", tmpDir, err) } defer os.RemoveAll(tmpDir) - // tmpDir := "/tmp/tftmp" - // os.RemoveAll(tmpDir) - // os.MkdirAll(tmpDir, 0755) - // fmt.Printf("[DEBUG] tmpdir %q\n", tmpDir) - g.infof("compiling provider %q", shortName) providerPath := fmt.Sprintf("plugins/registry.terraform.io/hashicorp/%s/0.0.1/%s_%s", shortName, runtime.GOOS, runtime.GOARCH) outFile := filepath.Join(tmpDir, providerPath, fmt.Sprintf("terraform-provider-%s", shortName)) @@ -599,7 +632,7 @@ func (g *generator) terraformProviderSchema(ctx context.Context, providerName st // TODO: constrain env here to make it a little safer? _, err = runCmd(buildCmd) if err != nil { - return nil, err + return nil, fmt.Errorf("unable to execute go build command: %w", err) } err = writeFile(filepath.Join(tmpDir, "provider.tf"), fmt.Sprintf(` @@ -607,7 +640,7 @@ provider %[1]q { } `, shortName)) if err != nil { - return nil, err + return nil, fmt.Errorf("unable to write provider.tf file: %w", err) } i := install.NewInstaller() @@ -636,24 +669,46 @@ provider %[1]q { tfBin, err := i.Ensure(context.Background(), sources) if err != nil { - return nil, err + return nil, fmt.Errorf("unable to download Terraform binary: %w", err) } tf, err := tfexec.NewTerraform(tmpDir, tfBin) if err != nil { - return nil, err + return nil, fmt.Errorf("unable to create new terraform exec instance: %w", err) } g.infof("running terraform init") err = tf.Init(ctx, tfexec.Get(false), tfexec.PluginDir("./plugins")) if err != nil { - return nil, err + return nil, fmt.Errorf("unable to run terraform init on provider: %w", err) } g.infof("getting provider schema") schemas, err := tf.ProvidersSchema(ctx) if err != nil { - return nil, err + return nil, fmt.Errorf("unable to retrieve provider schema from terraform exec: %w", err) + } + + if ps, ok := schemas.Schemas[shortName]; ok { + return ps, nil + } + + if ps, ok := schemas.Schemas["registry.terraform.io/hashicorp/"+shortName]; ok { + return ps, nil + } + + return nil, fmt.Errorf("unable to find schema in JSON for provider %q", shortName) +} + +func (g *generator) terraformProviderSchemaFromFile() (*tfjson.ProviderSchema, error) { + var err error + + shortName := providerShortName(g.providerName) + + g.infof("getting provider schema") + schemas, err := extractSchemaFromFile(g.providersSchemaPath) + if err != nil { + return nil, fmt.Errorf("unable to retrieve provider schema from JSON file: %w", err) } if ps, ok := schemas.Schemas[shortName]; ok { diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/logger.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/logger.go new file mode 100644 index 00000000..366812bc --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/logger.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package provider + +import ( + "fmt" + + "github.com/hashicorp/cli" +) + +type Logger struct { + ui cli.Ui +} + +func NewLogger(ui cli.Ui) *Logger { + return &Logger{ui} +} + +func (l *Logger) infof(format string, args ...interface{}) { + l.ui.Info(fmt.Sprintf(format, args...)) +} + +//nolint:unused +func (l *Logger) warnf(format string, args ...interface{}) { + l.ui.Warn(fmt.Sprintf(format, args...)) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/migrate.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/migrate.go new file mode 100644 index 00000000..babe2127 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/migrate.go @@ -0,0 +1,409 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package provider + +import ( + "bufio" + "bytes" + "fmt" + "io/fs" + "os" + "path/filepath" + "regexp" + "strconv" + "strings" + + "github.com/hashicorp/cli" + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" +) + +type migrator struct { + // providerDir is the absolute path to the root provider directory + providerDir string + + websiteDir string + templatesDir string + examplesDir string + + providerName string + + ui cli.Ui +} + +func (m *migrator) infof(format string, a ...interface{}) { + m.ui.Info(fmt.Sprintf(format, a...)) +} + +func (m *migrator) warnf(format string, a ...interface{}) { + m.ui.Warn(fmt.Sprintf(format, a...)) +} + +func Migrate(ui cli.Ui, providerDir string, templatesDir string, examplesDir string, providerName string) error { + // Ensure provider directory is resolved absolute path + if providerDir == "" { + wd, err := os.Getwd() + + if err != nil { + return fmt.Errorf("error getting working directory: %w", err) + } + + providerDir = wd + } else { + absProviderDir, err := filepath.Abs(providerDir) + + if err != nil { + return fmt.Errorf("error getting absolute path with provider directory %q: %w", providerDir, err) + } + + providerDir = absProviderDir + } + + // Verify provider directory + providerDirFileInfo, err := os.Stat(providerDir) + + if err != nil { + return fmt.Errorf("error getting information for provider directory %q: %w", providerDir, err) + } + + if !providerDirFileInfo.IsDir() { + return fmt.Errorf("expected %q to be a directory", providerDir) + } + + // Default providerName to provider directory name + if providerName == "" { + providerName = filepath.Base(providerDir) + } + + // Determine website directory + websiteDir, err := determineWebsiteDir(providerDir) + if err != nil { + return err + } + + m := &migrator{ + providerDir: providerDir, + templatesDir: templatesDir, + examplesDir: examplesDir, + websiteDir: websiteDir, + providerName: providerName, + ui: ui, + } + + return m.Migrate() +} + +func (m *migrator) Migrate() error { + m.infof("migrating website from %q to %q", m.ProviderWebsiteDir(), m.ProviderTemplatesDir()) + + err := filepath.WalkDir(m.ProviderWebsiteDir(), func(path string, d os.DirEntry, err error) error { + if err != nil { + return fmt.Errorf("unable to walk path %q: %w", path, err) + } + + if d.IsDir() { + switch d.Name() { + case "d", "data-sources": //data-sources + m.infof("migrating data-sources directory: %s", d.Name()) + err := filepath.WalkDir(path, m.MigrateTemplate("data-sources")) + if err != nil { + return err + } + return filepath.SkipDir + case "r", "resources": //resources + m.infof("migrating resources directory: %s", d.Name()) + err := filepath.WalkDir(path, m.MigrateTemplate("resources")) + if err != nil { + return err + } + return filepath.SkipDir + case "functions": + m.infof("migrating functons directory: %s", d.Name()) + err := filepath.WalkDir(path, m.MigrateTemplate("functions")) + if err != nil { + return err + } + return filepath.SkipDir + case "guides": + m.infof("copying guides directory: %s", d.Name()) + err := cp(path, filepath.Join(m.ProviderTemplatesDir(), "guides")) + if err != nil { + return fmt.Errorf("unable to copy guides directory %q: %w", path, err) + } + return filepath.SkipDir + } + } else { + switch { + case regexp.MustCompile(`index.*`).MatchString(d.Name()): //index file + m.infof("migrating provider index: %s", d.Name()) + err := filepath.WalkDir(path, m.MigrateTemplate("")) + if err != nil { + return err + } + return nil + default: + //skip non-index files + return nil + } + } + + return nil + }) + if err != nil { + return fmt.Errorf("unable to migrate website: %w", err) + } + + //remove legacy website directory + err = os.RemoveAll(filepath.Join(m.providerDir, "website")) + if err != nil { + return fmt.Errorf("unable to remove legacy website directory: %w", err) + } + + return nil +} + +func (m *migrator) MigrateTemplate(relDir string) fs.WalkDirFunc { + return func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() { + //skip processing directories + return nil + } + + m.infof("migrating file %q", d.Name()) + data, err := os.ReadFile(path) + if err != nil { + return fmt.Errorf("unable to read file %q: %w", d.Name(), err) + } + + baseName, _, _ := strings.Cut(d.Name(), ".") + shortName := providerShortName(m.providerName) + fileName := strings.TrimPrefix(baseName, shortName+"_") + + var exampleRelDir string + if fileName == "index" { + exampleRelDir = relDir + } else { + exampleRelDir = filepath.Join(relDir, fileName) + } + templateFilePath := filepath.Join(m.ProviderTemplatesDir(), relDir, fileName+".md.tmpl") + + err = os.MkdirAll(filepath.Dir(templateFilePath), 0755) + if err != nil { + return fmt.Errorf("unable to create directory %q: %w", templateFilePath, err) + } + + templateFile, err := os.OpenFile(templateFilePath, os.O_WRONLY|os.O_CREATE, 0600) + + if err != nil { + return fmt.Errorf("unable to open file %q: %w", templateFilePath, err) + } + + defer func(f *os.File) { + err := f.Close() + if err != nil { + m.warnf("unable to close file %q: %q", f.Name(), err) + } + }(templateFile) + + m.infof("extracting YAML frontmatter to %q", templateFilePath) + err = m.ExtractFrontMatter(data, relDir, templateFile) + if err != nil { + return fmt.Errorf("unable to extract front matter to %q: %w", templateFilePath, err) + } + + m.infof("extracting code examples from %q", d.Name()) + err = m.ExtractCodeExamples(data, exampleRelDir, templateFile) + if err != nil { + return fmt.Errorf("unable to extract code examples from %q: %w", templateFilePath, err) + } + + return nil + } + +} + +func (m *migrator) ExtractFrontMatter(content []byte, relDir string, templateFile *os.File) error { + fileScanner := bufio.NewScanner(bytes.NewReader(content)) + fileScanner.Split(bufio.ScanLines) + + hasFirstLine := fileScanner.Scan() + if !hasFirstLine || fileScanner.Text() != "---" { + m.warnf("no frontmatter found in %q", templateFile.Name()) + return nil + } + _, err := templateFile.WriteString(fileScanner.Text() + "\n") + if err != nil { + return fmt.Errorf("unable to append frontmatter to %q: %w", templateFile.Name(), err) + } + exited := false + for fileScanner.Scan() { + if strings.Contains(fileScanner.Text(), "layout:") { + // skip layout front matter + continue + } + _, err = templateFile.WriteString(fileScanner.Text() + "\n") + if err != nil { + return fmt.Errorf("unable to append frontmatter to %q: %w", templateFile.Name(), err) + } + if fileScanner.Text() == "---" { + exited = true + break + } + } + + if !exited { + return fmt.Errorf("cannot find ending of frontmatter block in %q", templateFile.Name()) + } + + // add comment to end of front matter briefly explaining template functionality + if relDir == "functions" { + _, err = templateFile.WriteString(migrateFunctionTemplateComment + "\n") + } else { + _, err = templateFile.WriteString(migrateProviderTemplateComment + "\n") + } + if err != nil { + return fmt.Errorf("unable to append template comment to %q: %w", templateFile.Name(), err) + } + + return nil +} + +func (m *migrator) ExtractCodeExamples(content []byte, newRelDir string, templateFile *os.File) error { + md := newMarkdownRenderer() + p := md.Parser() + root := p.Parse(text.NewReader(content)) + + exampleCount := 0 + importCount := 0 + + err := ast.Walk(root, func(node ast.Node, enter bool) (ast.WalkStatus, error) { + // skip the root node + if !enter || node.Type() == ast.TypeDocument { + return ast.WalkContinue, nil + } + + if fencedNode, isFenced := node.(*ast.FencedCodeBlock); isFenced && fencedNode.Info != nil { + var ext, exampleName, examplePath, template string + + lang := string(fencedNode.Info.Text(content)[:]) + switch lang { + case "hcl", "terraform": + exampleCount++ + ext = ".tf" + exampleName = "example_" + strconv.Itoa(exampleCount) + ext + examplePath = filepath.Join(m.examplesDir, newRelDir, exampleName) + template = fmt.Sprintf("{{tffile \"%s\"}}", examplePath) + m.infof("creating example file %q", filepath.Join(m.providerDir, examplePath)) + case "console": + importCount++ + ext = ".sh" + exampleName = "import_" + strconv.Itoa(importCount) + ext + examplePath = filepath.Join(m.examplesDir, newRelDir, exampleName) + template = fmt.Sprintf("{{codefile \"shell\" \"%s\"}}", examplePath) + m.infof("creating import file %q", filepath.Join(m.providerDir, examplePath)) + default: + // Render node as is + m.infof("skipping code block with unknown language %q", lang) + err := md.Renderer().Render(templateFile, content, node) + if err != nil { + return ast.WalkStop, fmt.Errorf("unable to render node: %w", err) + } + return ast.WalkSkipChildren, nil + } + + // add code block text to buffer + codeBuf := bytes.Buffer{} + for i := 0; i < node.Lines().Len(); i++ { + line := node.Lines().At(i) + _, _ = codeBuf.Write(line.Value(content)) + } + + // create example file from code block + err := writeFile(examplePath, codeBuf.String()) + if err != nil { + return ast.WalkStop, fmt.Errorf("unable to write file %q: %w", examplePath, err) + } + + // replace original code block with tfplugindocs template + _, err = templateFile.WriteString("\n\n" + template) + if err != nil { + return ast.WalkStop, fmt.Errorf("unable to write to template %q: %w", template, err) + } + + return ast.WalkSkipChildren, nil + } + + // Render non-code nodes as is + err := md.Renderer().Render(templateFile, content, node) + if err != nil { + return ast.WalkStop, fmt.Errorf("unable to render node: %w", err) + } + if node.HasChildren() { + return ast.WalkSkipChildren, nil + } + + return ast.WalkContinue, nil + }) + if err != nil { + return fmt.Errorf("unable to walk AST: %w", err) + } + + _, err = templateFile.WriteString("\n") + if err != nil { + return fmt.Errorf("unable to write to template %q: %w", templateFile.Name(), err) + } + m.infof("finished creating template %q", templateFile.Name()) + + return nil +} + +// ProviderWebsiteDir returns the absolute path to the joined provider and +// the website directory that templates will be migrated from, which defaults to either "website/docs/" or "docs". +func (m *migrator) ProviderWebsiteDir() string { + return filepath.Join(m.providerDir, m.websiteDir) +} + +// ProviderTemplatesDir returns the absolute path to the joined provider and +// given new templates directory, which defaults to "templates". +func (m *migrator) ProviderTemplatesDir() string { + return filepath.Join(m.providerDir, m.templatesDir) +} + +// ProviderExamplesDir returns the absolute path to the joined provider and +// given examples directory, which defaults to "examples". +func (m *migrator) ProviderExamplesDir() string { + return filepath.Join(m.providerDir, m.examplesDir) +} + +func determineWebsiteDir(providerDir string) (string, error) { + // Check for legacy website directory + providerWebsiteDirFileInfo, err := os.Stat(filepath.Join(providerDir, "website/docs")) + + if err != nil { + if os.IsNotExist(err) { + // Legacy website directory does not exist, check for docs directory + } else { + return "", fmt.Errorf("error getting information for provider website directory %q: %w", providerDir, err) + } + } else if providerWebsiteDirFileInfo.IsDir() { + return "website/docs", nil + } + + // Check for docs directory + providerDocsDirFileInfo, err := os.Stat(filepath.Join(providerDir, "docs")) + + if err != nil { + return "", fmt.Errorf("error getting information for provider docs directory %q: %w", providerDir, err) + } + + if providerDocsDirFileInfo.IsDir() { + return "docs", nil + } + + return "", fmt.Errorf("unable to determine website directory for provider %q", providerDir) + +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/schema.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/schema.go new file mode 100644 index 00000000..3338fe98 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/schema.go @@ -0,0 +1,136 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package provider + +import ( + "context" + "fmt" + "os" + "os/exec" + "path/filepath" + "runtime" + + "github.com/hashicorp/go-version" + install "github.com/hashicorp/hc-install" + "github.com/hashicorp/hc-install/checkpoint" + "github.com/hashicorp/hc-install/fs" + "github.com/hashicorp/hc-install/product" + "github.com/hashicorp/hc-install/releases" + "github.com/hashicorp/hc-install/src" + "github.com/hashicorp/terraform-exec/tfexec" + tfjson "github.com/hashicorp/terraform-json" +) + +func TerraformProviderSchemaFromTerraform(ctx context.Context, providerName, providerDir, tfVersion string, l *Logger) (*tfjson.ProviderSchema, error) { + var err error + + shortName := providerShortName(providerName) + + tmpDir, err := os.MkdirTemp("", "tfws") + if err != nil { + return nil, fmt.Errorf("unable to create temporary provider install directory %q: %w", tmpDir, err) + } + defer os.RemoveAll(tmpDir) + + l.infof("compiling provider %q", shortName) + providerPath := fmt.Sprintf("plugins/registry.terraform.io/hashicorp/%s/0.0.1/%s_%s", shortName, runtime.GOOS, runtime.GOARCH) + outFile := filepath.Join(tmpDir, providerPath, fmt.Sprintf("terraform-provider-%s", shortName)) + switch runtime.GOOS { + case "windows": + outFile = outFile + ".exe" + } + buildCmd := exec.Command("go", "build", "-o", outFile) + buildCmd.Dir = providerDir + // TODO: constrain env here to make it a little safer? + _, err = runCmd(buildCmd) + if err != nil { + return nil, fmt.Errorf("unable to execute go build command: %w", err) + } + + err = writeFile(filepath.Join(tmpDir, "provider.tf"), fmt.Sprintf(` +provider %[1]q { +} +`, shortName)) + if err != nil { + return nil, fmt.Errorf("unable to write provider.tf file: %w", err) + } + + i := install.NewInstaller() + var sources []src.Source + if tfVersion != "" { + l.infof("downloading Terraform CLI binary version from releases.hashicorp.com: %s", tfVersion) + sources = []src.Source{ + &releases.ExactVersion{ + Product: product.Terraform, + Version: version.Must(version.NewVersion(tfVersion)), + InstallDir: tmpDir, + }, + } + } else { + l.infof("using Terraform CLI binary from PATH if available, otherwise downloading latest Terraform CLI binary") + sources = []src.Source{ + &fs.AnyVersion{ + Product: &product.Terraform, + }, + &checkpoint.LatestVersion{ + InstallDir: tmpDir, + Product: product.Terraform, + }, + } + } + + tfBin, err := i.Ensure(context.Background(), sources) + if err != nil { + return nil, fmt.Errorf("unable to download Terraform binary: %w", err) + } + + tf, err := tfexec.NewTerraform(tmpDir, tfBin) + if err != nil { + return nil, fmt.Errorf("unable to create new terraform exec instance: %w", err) + } + + l.infof("running terraform init") + err = tf.Init(ctx, tfexec.Get(false), tfexec.PluginDir("./plugins")) + if err != nil { + return nil, fmt.Errorf("unable to run terraform init on provider: %w", err) + } + + l.infof("getting provider schema") + schemas, err := tf.ProvidersSchema(ctx) + if err != nil { + return nil, fmt.Errorf("unable to retrieve provider schema from terraform exec: %w", err) + } + + if ps, ok := schemas.Schemas[shortName]; ok { + return ps, nil + } + + if ps, ok := schemas.Schemas["registry.terraform.io/hashicorp/"+shortName]; ok { + return ps, nil + } + + return nil, fmt.Errorf("unable to find schema in JSON for provider %q", shortName) +} + +func TerraformProviderSchemaFromFile(providerName, providersSchemaPath string, l *Logger) (*tfjson.ProviderSchema, error) { + var err error + + shortName := providerShortName(providerName) + + l.infof("getting provider schema") + schemas, err := extractSchemaFromFile(providersSchemaPath) + if err != nil { + return nil, fmt.Errorf("unable to retrieve provider schema from JSON file: %w", err) + } + + if ps, ok := schemas.Schemas[shortName]; ok { + return ps, nil + } + + if ps, ok := schemas.Schemas["registry.terraform.io/hashicorp/"+shortName]; ok { + return ps, nil + } + + return nil, fmt.Errorf("unable to find schema in JSON for provider %q", shortName) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/template.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/template.go index 3d71b419..58766489 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/template.go +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/template.go @@ -16,23 +16,27 @@ import ( tfjson "github.com/hashicorp/terraform-json" + "github.com/hashicorp/terraform-plugin-docs/internal/schemamd" + + "github.com/hashicorp/terraform-plugin-docs/internal/functionmd" "github.com/hashicorp/terraform-plugin-docs/internal/mdplain" "github.com/hashicorp/terraform-plugin-docs/internal/tmplfuncs" - "github.com/hashicorp/terraform-plugin-docs/schemamd" ) const ( - schemaComment = "" + schemaComment = "" + signatureComment = "" + argumentComment = "" + variadicComment = "" + frontmatterComment = "# generated by https://github.com/hashicorp/terraform-plugin-docs" ) type ( resourceTemplate string + functionTemplate string providerTemplate string - resourceFileTemplate string - providerFileTemplate string - docTemplate string ) @@ -116,38 +120,45 @@ func (t docTemplate) Render(providerDir string, out io.Writer) error { return renderTemplate(providerDir, "docTemplate", s, out, nil) } -func (t resourceFileTemplate) Render(providerDir, name, providerName string) (string, error) { +func (t providerTemplate) Render(providerDir, providerName, renderedProviderName, exampleFile string, schema *tfjson.Schema) (string, error) { + schemaBuffer := bytes.NewBuffer(nil) + err := schemamd.Render(schema, schemaBuffer) + if err != nil { + return "", fmt.Errorf("unable to render schema: %w", err) + } + s := string(t) if s == "" { return "", nil } - return renderStringTemplate(providerDir, "resourceFileTemplate", s, struct { - Name string - ShortName string + + return renderStringTemplate(providerDir, "providerTemplate", s, struct { + Description string + + HasExample bool + ExampleFile string ProviderName string ProviderShortName string + SchemaMarkdown string + + RenderedProviderName string }{ - Name: name, - ShortName: resourceShortName(name, providerName), + Description: schema.Block.Description, + + HasExample: exampleFile != "" && fileExists(exampleFile), + ExampleFile: exampleFile, ProviderName: providerName, ProviderShortName: providerShortName(providerName), - }) -} -func (t providerFileTemplate) Render(providerDir, name string) (string, error) { - s := string(t) - if s == "" { - return "", nil - } - return renderStringTemplate(providerDir, "providerFileTemplate", s, struct { - Name string - ShortName string - }{name, providerShortName(name)}) + SchemaMarkdown: schemaComment + "\n" + schemaBuffer.String(), + + RenderedProviderName: renderedProviderName, + }) } -func (t providerTemplate) Render(providerDir, providerName, renderedProviderName, exampleFile string, schema *tfjson.Schema) (string, error) { +func (t resourceTemplate) Render(providerDir, name, providerName, renderedProviderName, typeName, exampleFile, importFile string, schema *tfjson.Schema) (string, error) { schemaBuffer := bytes.NewBuffer(nil) err := schemamd.Render(schema, schemaBuffer) if err != nil { @@ -159,12 +170,17 @@ func (t providerTemplate) Render(providerDir, providerName, renderedProviderName return "", nil } - return renderStringTemplate(providerDir, "providerTemplate", s, struct { + return renderStringTemplate(providerDir, "resourceTemplate", s, struct { + Type string + Name string Description string HasExample bool ExampleFile string + HasImport bool + ImportFile string + ProviderName string ProviderShortName string @@ -172,11 +188,16 @@ func (t providerTemplate) Render(providerDir, providerName, renderedProviderName RenderedProviderName string }{ + Type: typeName, + Name: name, Description: schema.Block.Description, HasExample: exampleFile != "" && fileExists(exampleFile), ExampleFile: exampleFile, + HasImport: importFile != "" && fileExists(importFile), + ImportFile: importFile, + ProviderName: providerName, ProviderShortName: providerShortName(providerName), @@ -186,11 +207,20 @@ func (t providerTemplate) Render(providerDir, providerName, renderedProviderName }) } -func (t resourceTemplate) Render(providerDir, name, providerName, renderedProviderName, typeName, exampleFile, importFile string, schema *tfjson.Schema) (string, error) { - schemaBuffer := bytes.NewBuffer(nil) - err := schemamd.Render(schema, schemaBuffer) +func (t functionTemplate) Render(providerDir, name, providerName, renderedProviderName, typeName, exampleFile string, signature *tfjson.FunctionSignature) (string, error) { + funcSig, err := functionmd.RenderSignature(name, signature) if err != nil { - return "", fmt.Errorf("unable to render schema: %w", err) + return "", fmt.Errorf("unable to render function signature: %w", err) + } + + funcArgs, err := functionmd.RenderArguments(signature) + if err != nil { + return "", fmt.Errorf("unable to render function arguments: %w", err) + } + + funcVarArg, err := functionmd.RenderVariadicArg(signature) + if err != nil { + return "", fmt.Errorf("unable to render variadic argument: %w", err) } s := string(t) @@ -202,34 +232,38 @@ func (t resourceTemplate) Render(providerDir, name, providerName, renderedProvid Type string Name string Description string + Summary string HasExample bool ExampleFile string - HasImport bool - ImportFile string - ProviderName string ProviderShortName string - SchemaMarkdown string + FunctionSignatureMarkdown string + FunctionArgumentsMarkdown string + + HasVariadic bool + FunctionVariadicArgumentMarkdown string RenderedProviderName string }{ Type: typeName, Name: name, - Description: schema.Block.Description, + Description: signature.Description, + Summary: signature.Summary, HasExample: exampleFile != "" && fileExists(exampleFile), ExampleFile: exampleFile, - HasImport: importFile != "" && fileExists(importFile), - ImportFile: importFile, - ProviderName: providerName, ProviderShortName: providerShortName(providerName), - SchemaMarkdown: schemaComment + "\n" + schemaBuffer.String(), + FunctionSignatureMarkdown: signatureComment + "\n" + funcSig, + FunctionArgumentsMarkdown: argumentComment + "\n" + funcArgs, + + HasVariadic: signature.VariadicParameter != nil, + FunctionVariadicArgumentMarkdown: variadicComment + "\n" + funcVarArg, RenderedProviderName: renderedProviderName, }) @@ -250,7 +284,7 @@ description: |- {{ if .HasExample -}} ## Example Usage -{{ printf "{{tffile %q}}" .ExampleFile }} +{{tffile .ExampleFile }} {{- end }} {{ .SchemaMarkdown | trimspace }} @@ -260,7 +294,37 @@ description: |- Import is supported using the following syntax: -{{ printf "{{codefile \"shell\" %q}}" .ImportFile }} +{{codefile "shell" .ImportFile }} +{{- end }} +` + +const defaultFunctionTemplate functionTemplate = `--- +` + frontmatterComment + ` +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "" +description: |- +{{ .Summary | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Type}}: {{.Name}} + +{{ .Description | trimspace }} + +{{ if .HasExample -}} +## Example Usage + +{{tffile .ExampleFile }} +{{- end }} + +## Signature + +{{ .FunctionSignatureMarkdown }} + +## Arguments + +{{ .FunctionArgumentsMarkdown }} +{{ if .HasVariadic -}} +{{ .FunctionVariadicArgumentMarkdown }} {{- end }} ` @@ -279,8 +343,20 @@ description: |- {{ if .HasExample -}} ## Example Usage -{{ printf "{{tffile %q}}" .ExampleFile }} +{{tffile .ExampleFile }} {{- end }} {{ .SchemaMarkdown | trimspace }} ` + +const migrateProviderTemplateComment string = ` +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} +` + +const migrateFunctionTemplateComment string = ` +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .FunctionArgumentsMarkdown }} template can be used to replace manual argument documentation if descriptions of function arguments are added in the provider source code. */ -}} +` diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/util.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/util.go index 06aee6b1..7a3ec336 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/util.go +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/util.go @@ -12,7 +12,12 @@ import ( "path/filepath" "strings" + "github.com/Kunde21/markdownfmt/v3/markdown" tfjson "github.com/hashicorp/terraform-json" + "github.com/yuin/goldmark" + meta "github.com/yuin/goldmark-meta" + "github.com/yuin/goldmark/extension" + "github.com/yuin/goldmark/parser" ) func providerShortName(n string) string { @@ -31,6 +36,12 @@ func copyFile(srcPath, dstPath string, mode os.FileMode) error { } defer srcFile.Close() + // Ensure destination path exists for file creation + err = os.MkdirAll(filepath.Dir(dstPath), 0755) + if err != nil { + return err + } + // If the destination file already exists, we shouldn't blow it away dstFile, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, mode) if err != nil { @@ -75,9 +86,13 @@ func resourceSchema(schemas map[string]*tfjson.Schema, providerShortName, templa func writeFile(path string, data string) error { dir, _ := filepath.Split(path) - err := os.MkdirAll(dir, 0755) - if err != nil { - return fmt.Errorf("unable to make dir %q: %w", dir, err) + + var err error + if dir != "" { + err = os.MkdirAll(dir, 0755) + if err != nil { + return fmt.Errorf("unable to make dir %q: %w", dir, err) + } } err = os.WriteFile(path, []byte(data), 0644) @@ -88,6 +103,7 @@ func writeFile(path string, data string) error { return nil } +//nolint:unparam func runCmd(cmd *exec.Cmd) ([]byte, error) { output, err := cmd.CombinedOutput() if err != nil { @@ -136,3 +152,39 @@ func fileExists(filename string) bool { } return !info.IsDir() } + +func extractSchemaFromFile(path string) (*tfjson.ProviderSchemas, error) { + schemajson, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("unable to read file %q: %w", path, err) + } + + schemas := &tfjson.ProviderSchemas{ + FormatVersion: "", + Schemas: nil, + } + err = schemas.UnmarshalJSON(schemajson) + if err != nil { + return nil, err + } + + return schemas, nil +} + +func newMarkdownRenderer() goldmark.Markdown { + mr := markdown.NewRenderer() + extensions := []goldmark.Extender{ + extension.GFM, + meta.Meta, // We need this to skip YAML frontmatter when parsing. + } + parserOptions := []parser.Option{ + parser.WithAttribute(), // We need this to enable # headers {#custom-ids}. + } + + gm := goldmark.New( + goldmark.WithExtensions(extensions...), + goldmark.WithParserOptions(parserOptions...), + goldmark.WithRenderer(mr), + ) + return gm +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/validate.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/validate.go index 329e05d1..6732091e 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/validate.go +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/provider/validate.go @@ -4,267 +4,363 @@ package provider import ( + "context" + "errors" "fmt" + "log" "os" "path/filepath" - "strings" - "github.com/mitchellh/cli" + "github.com/bmatcuk/doublestar/v4" + "github.com/hashicorp/cli" + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-docs/internal/check" ) -func Validate(ui cli.Ui) error { - dirExists := func(name string) bool { - if _, err := os.Stat(name); err != nil { - return false - } +const ( + FileExtensionHtmlMarkdown = `.html.markdown` + FileExtensionHtmlMd = `.html.md` + FileExtensionMarkdown = `.markdown` + FileExtensionMd = `.md` - return true - } + DocumentationGlobPattern = `{docs/index.md,docs/{,cdktf/}{data-sources,guides,resources,functions}/**/*,website/docs/**/*}` + DocumentationDirGlobPattern = `{docs/{,cdktf/}{data-sources,guides,resources,functions}{,/*},website/docs/**/*}` +) - switch { - default: - ui.Warn("no website detected, exiting") - case dirExists("templates"): - ui.Info("detected templates directory, running checks...") - err := validateTemplates(ui, "templates") - if err != nil { - return err - } - if dirExists("examples") { - ui.Info("detected examples directory for templates, running checks...") - err = validateExamples(ui, "examples") - if err != nil { - return err - } - } - return err - case dirExists("docs"): - ui.Info("detected static docs directory, running checks") - return validateStaticDocs(ui, "docs") - case dirExists("website"): - ui.Info("detected legacy website directory, running checks") - return validateLegacyWebsite(ui, "website") - } +var ValidLegacyFileExtensions = []string{ + FileExtensionHtmlMarkdown, + FileExtensionHtmlMd, + FileExtensionMarkdown, + FileExtensionMd, +} - return nil +var ValidRegistryFileExtensions = []string{ + FileExtensionMd, } -func validateExamples(ui cli.Ui, dir string) error { - return nil +var LegacyFrontMatterOptions = &check.FrontMatterOptions{ + NoSidebarCurrent: true, + RequireDescription: true, + RequireLayout: true, + RequirePageTitle: true, } -func validateTemplates(ui cli.Ui, dir string) error { - checks := []check{ - checkAllowedFiles( - "index.md", - "index.md.tmpl", - ), - checkAllowedDirs( - "data-sources", - "guides", - "resources", - ), - checkBlockedExtensions( - ".html.md.tmpl", - ), - checkAllowedExtensions( - ".md", - ".md.tmpl", - ), - } - issues := []issue{} - for _, c := range checks { - checkIssues, err := c(dir) +var LegacyIndexFrontMatterOptions = &check.FrontMatterOptions{ + NoSidebarCurrent: true, + NoSubcategory: true, + RequireDescription: true, + RequireLayout: true, + RequirePageTitle: true, +} + +var LegacyGuideFrontMatterOptions = &check.FrontMatterOptions{ + NoSidebarCurrent: true, + RequireDescription: true, + RequireLayout: true, + RequirePageTitle: true, +} + +var RegistryFrontMatterOptions = &check.FrontMatterOptions{ + NoLayout: true, + NoSidebarCurrent: true, +} + +var RegistryIndexFrontMatterOptions = &check.FrontMatterOptions{ + NoLayout: true, + NoSidebarCurrent: true, + NoSubcategory: true, +} + +var RegistryGuideFrontMatterOptions = &check.FrontMatterOptions{ + NoLayout: true, + NoSidebarCurrent: true, + RequirePageTitle: true, +} + +type validator struct { + providerName string + providerDir string + providersSchemaPath string + + tfVersion string + providerSchema *tfjson.ProviderSchema + + logger *Logger +} + +func Validate(ui cli.Ui, providerDir, providerName, providersSchemaPath, tfversion string) error { + // Ensure provider directory is resolved absolute path + if providerDir == "" { + wd, err := os.Getwd() + if err != nil { - return err + return fmt.Errorf("error getting working directory: %w", err) + } + + providerDir = wd + } else { + absProviderDir, err := filepath.Abs(providerDir) + + if err != nil { + return fmt.Errorf("error getting absolute path with provider directory %q: %w", providerDir, err) } - issues = append(issues, checkIssues...) + + providerDir = absProviderDir } - for _, issue := range issues { - ui.Warn(fmt.Sprintf("%s: %s", issue.file, issue.message)) + + // Verify provider directory + providerDirFileInfo, err := os.Stat(providerDir) + + if err != nil { + return fmt.Errorf("error getting information for provider directory %q: %w", providerDir, err) } - if len(issues) > 0 { - return fmt.Errorf("invalid templates directory") + + if !providerDirFileInfo.IsDir() { + return fmt.Errorf("expected %q to be a directory", providerDir) } - return nil -} -func validateStaticDocs(ui cli.Ui, dir string) error { - checks := []check{ - checkAllowedFiles( - "index.md", - ), - checkAllowedDirs( - "data-sources", - "guides", - "resources", - "cdktf", - ), - checkBlockedExtensions( - ".html.md.tmpl", - ".html.md", - ".md.tmpl", - ), - checkAllowedExtensions( - ".md", - ), + v := &validator{ + providerName: providerName, + providerDir: providerDir, + providersSchemaPath: providersSchemaPath, + tfVersion: tfversion, + + logger: NewLogger(ui), } - issues := []issue{} - for _, c := range checks { - checkIssues, err := c(dir) + + ctx := context.Background() + + return v.validate(ctx) +} + +func (v *validator) validate(ctx context.Context) error { + var result error + + var err error + + if v.providersSchemaPath == "" { + v.logger.infof("exporting schema from Terraform") + v.providerSchema, err = TerraformProviderSchemaFromTerraform(ctx, v.providerName, v.providerDir, v.tfVersion, v.logger) if err != nil { - return err + return fmt.Errorf("error exporting provider schema from Terraform: %w", err) + } + } else { + v.logger.infof("exporting schema from JSON file") + v.providerSchema, err = TerraformProviderSchemaFromFile(v.providerName, v.providersSchemaPath, v.logger) + if err != nil { + return fmt.Errorf("error exporting provider schema from JSON file: %w", err) } - issues = append(issues, checkIssues...) } - for _, issue := range issues { - ui.Warn(fmt.Sprintf("%s: %s", issue.file, issue.message)) + + providerFs := os.DirFS(v.providerDir) + + files, globErr := doublestar.Glob(providerFs, DocumentationGlobPattern) + if globErr != nil { + return fmt.Errorf("error finding documentation files: %w", err) } - if len(issues) > 0 { - return fmt.Errorf("invalid templates directory") + + log.Printf("[DEBUG] Found documentation files %v", files) + + v.logger.infof("running mixed directories check") + err = check.MixedDirectoriesCheck(files) + result = errors.Join(result, err) + + v.logger.infof("running number of files check") + err = check.NumberOfFilesCheck(files) + result = errors.Join(result, err) + + if dirExists(filepath.Join(v.providerDir, "docs")) { + v.logger.infof("detected static docs directory, running checks") + err = v.validateStaticDocs(filepath.Join(v.providerDir, "docs")) + result = errors.Join(result, err) + + } + if dirExists(filepath.Join(v.providerDir, filepath.Join("website", "docs"))) { + v.logger.infof("detected legacy website directory, running checks") + err = v.validateLegacyWebsite(filepath.Join(v.providerDir, "website/docs")) + result = errors.Join(result, err) } - return nil -} -func validateLegacyWebsite(ui cli.Ui, dir string) error { - panic("not implemented") + return result } -type issue struct { - file string - message string -} +func (v *validator) validateStaticDocs(dir string) error { -type check func(dir string) ([]issue, error) + var result error -func checkBlockedExtensions(exts ...string) check { - return func(dir string) ([]issue, error) { - issues := []issue{} - err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() { - return nil - } - for _, ext := range exts { - if strings.HasSuffix(path, ext) { - _, file := filepath.Split(path) - issues = append(issues, issue{ - file: path, - message: fmt.Sprintf("the extension for %q is not supported", file), - }) - break - } - } - return nil - }) + options := &check.ProviderFileOptions{ + FrontMatter: RegistryFrontMatterOptions, + ValidExtensions: ValidRegistryFileExtensions, + } + + var files []string + + err := filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error { if err != nil { - return nil, err + return fmt.Errorf("error walking directory %q: %w", dir, err) } - return issues, nil - } -} -func checkAllowedExtensions(exts ...string) check { - return func(dir string) ([]issue, error) { - issues := []issue{} - err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + rel, err := filepath.Rel(v.providerDir, path) + if err != nil { + return err + } + if d.IsDir() { + match, err := doublestar.PathMatch(filepath.FromSlash(DocumentationDirGlobPattern), rel) if err != nil { return err } - if info.IsDir() { - return nil - } - valid := false - for _, ext := range exts { - if strings.HasSuffix(path, ext) { - valid = true - break - } - } - if !valid { - _, file := filepath.Split(path) - issues = append(issues, issue{ - file: path, - message: fmt.Sprintf("the extension for %q is not expected", file), - }) + if !match { + return nil // skip valid non-documentation directories } + + v.logger.infof("running invalid directories check on %s", rel) + result = errors.Join(result, check.InvalidDirectoriesCheck(rel)) return nil - }) + } + match, err := doublestar.PathMatch(filepath.FromSlash(DocumentationGlobPattern), rel) if err != nil { - return nil, err + return err } - return issues, nil + if !match { + return nil // skip valid non-documentation files + } + + // Configure FrontMatterOptions based on file type + if d.Name() == "index.md" { + options.FrontMatter = RegistryIndexFrontMatterOptions + } else if _, relErr := filepath.Rel(rel, "guides"); relErr != nil { + options.FrontMatter = RegistryGuideFrontMatterOptions + } else { + options.FrontMatter = RegistryFrontMatterOptions + } + v.logger.infof("running file checks on %s", rel) + result = errors.Join(result, check.NewProviderFileCheck(options).Run(path)) + + files = append(files, path) + return nil + }) + if err != nil { + return fmt.Errorf("error walking directory %q: %w", dir, err) + } + + mismatchOpt := &check.FileMismatchOptions{ + ProviderShortName: providerShortName(v.providerName), + Schema: v.providerSchema, } -} -func checkAllowedDirs(dirs ...string) check { - allowedDirs := map[string]bool{} - for _, d := range dirs { - allowedDirs[d] = true + if dirExists(filepath.Join(dir, "data-sources")) { + dataSourceFiles, _ := os.ReadDir(filepath.Join(dir, "data-sources")) + mismatchOpt.DatasourceEntries = dataSourceFiles + } + if dirExists(filepath.Join(dir, "resources")) { + resourceFiles, _ := os.ReadDir(filepath.Join(dir, "resources")) + mismatchOpt.ResourceEntries = resourceFiles } + if dirExists(filepath.Join(dir, "functions")) { + functionFiles, _ := os.ReadDir(filepath.Join(dir, "functions")) + mismatchOpt.FunctionEntries = functionFiles + } + + v.logger.infof("running file mismatch check") + if err := check.NewFileMismatchCheck(mismatchOpt).Run(); err != nil { + result = errors.Join(result, err) + } + + return result +} + +func (v *validator) validateLegacyWebsite(dir string) error { + + var result error - return func(dir string) ([]issue, error) { - issues := []issue{} + options := &check.ProviderFileOptions{ + FrontMatter: LegacyFrontMatterOptions, + ValidExtensions: ValidLegacyFileExtensions, + } - f, err := os.Open(dir) + var files []string + err := filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error { if err != nil { - return nil, err + return fmt.Errorf("error walking directory %q: %w", dir, err) } - infos, err := f.Readdir(-1) + + rel, err := filepath.Rel(v.providerDir, path) if err != nil { - return nil, err + return err } - - for _, fi := range infos { - if !fi.IsDir() { - continue + if d.IsDir() { + match, err := doublestar.PathMatch(filepath.FromSlash(DocumentationDirGlobPattern), rel) + if err != nil { + return err } - - if !allowedDirs[fi.Name()] { - issues = append(issues, issue{ - file: filepath.Join(dir, fi.Name()), - message: fmt.Sprintf("directory %q is not allowed", fi.Name()), - }) + if !match { + return nil // skip valid non-documentation directories } + + v.logger.infof("running invalid directories check on %s", rel) + result = errors.Join(result, check.InvalidDirectoriesCheck(rel)) + return nil } - return issues, nil - } -} + match, err := doublestar.PathMatch(filepath.FromSlash(DocumentationGlobPattern), rel) + if err != nil { + return err + } + if !match { + return nil // skip non-documentation files + } -func checkAllowedFiles(dirs ...string) check { - allowedFiles := map[string]bool{} - for _, d := range dirs { - allowedFiles[d] = true + // Configure FrontMatterOptions based on file type + if d.Name() == "index.md" { + options.FrontMatter = LegacyIndexFrontMatterOptions + } else if _, relErr := filepath.Rel(rel, "guides"); relErr != nil { + options.FrontMatter = LegacyGuideFrontMatterOptions + } else { + options.FrontMatter = LegacyFrontMatterOptions + } + v.logger.infof("running file checks on %s", rel) + result = errors.Join(result, check.NewProviderFileCheck(options).Run(path)) + + files = append(files, path) + return nil + }) + if err != nil { + return fmt.Errorf("error walking directory %q: %w", dir, err) } - return func(dir string) ([]issue, error) { - issues := []issue{} + mismatchOpt := &check.FileMismatchOptions{ + ProviderShortName: providerShortName(v.providerName), + Schema: v.providerSchema, + } - f, err := os.Open(dir) - if err != nil { - return nil, err - } - infos, err := f.Readdir(-1) - if err != nil { - return nil, err - } + if dirExists(filepath.Join(dir, "d")) { + dataSourceFiles, _ := os.ReadDir(filepath.Join(dir, "d")) + mismatchOpt.DatasourceEntries = dataSourceFiles + } + if dirExists(filepath.Join(dir, "r")) { + resourceFiles, _ := os.ReadDir(filepath.Join(dir, "r")) + mismatchOpt.ResourceEntries = resourceFiles + } + if dirExists(filepath.Join(dir, "functions")) { + functionFiles, _ := os.ReadDir(filepath.Join(dir, "functions")) + mismatchOpt.FunctionEntries = functionFiles + } - for _, fi := range infos { - if fi.IsDir() { - continue - } + v.logger.infof("running file mismatch check") + if err := check.NewFileMismatchCheck(mismatchOpt).Run(); err != nil { + result = errors.Join(result, err) + } - if !allowedFiles[fi.Name()] { - issues = append(issues, issue{ - file: filepath.Join(dir, fi.Name()), - message: fmt.Sprintf("file %q is not allowed", fi.Name()), - }) - } - } + return result +} - return issues, nil +func dirExists(name string) bool { + if file, err := os.Stat(name); err != nil { + return false + } else if !file.IsDir() { + return false } + + return true } diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/behaviors.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/behaviors.go similarity index 100% rename from vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/behaviors.go rename to vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/behaviors.go diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/render.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/render.go similarity index 92% rename from vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/render.go rename to vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/render.go index 90617d86..210ede34 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/render.go +++ b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/render.go @@ -57,11 +57,12 @@ var ( ) type nestedType struct { - anchorID string - path []string - block *tfjson.SchemaBlock - object *cty.Type - attrs *tfjson.SchemaNestedAttributeType + anchorID string + pathTitle string + path []string + block *tfjson.SchemaBlock + object *cty.Type + attrs *tfjson.SchemaNestedAttributeType group groupFilter } @@ -87,6 +88,7 @@ func writeAttribute(w io.Writer, path []string, att *tfjson.SchemaAttribute, gro } anchorID := "nestedatt--" + strings.Join(path, "--") + pathTitle := strings.Join(path, ".") nestedTypes := []nestedType{} switch { case att.AttributeNestedType != nil: @@ -96,9 +98,10 @@ func writeAttribute(w io.Writer, path []string, att *tfjson.SchemaAttribute, gro } nestedTypes = append(nestedTypes, nestedType{ - anchorID: anchorID, - path: path, - attrs: att.AttributeNestedType, + anchorID: anchorID, + pathTitle: pathTitle, + path: path, + attrs: att.AttributeNestedType, group: group, }) @@ -109,9 +112,10 @@ func writeAttribute(w io.Writer, path []string, att *tfjson.SchemaAttribute, gro } nestedTypes = append(nestedTypes, nestedType{ - anchorID: anchorID, - path: path, - object: &att.AttributeType, + anchorID: anchorID, + pathTitle: pathTitle, + path: path, + object: &att.AttributeType, group: group, }) @@ -123,9 +127,10 @@ func writeAttribute(w io.Writer, path []string, att *tfjson.SchemaAttribute, gro nt := att.AttributeType.ElementType() nestedTypes = append(nestedTypes, nestedType{ - anchorID: anchorID, - path: path, - object: &nt, + anchorID: anchorID, + pathTitle: pathTitle, + path: path, + object: &nt, group: group, }) @@ -153,10 +158,12 @@ func writeBlockType(w io.Writer, path []string, block *tfjson.SchemaBlockType) ( } anchorID := "nestedblock--" + strings.Join(path, "--") + pathTitle := strings.Join(path, ".") nt := nestedType{ - anchorID: anchorID, - path: path, - block: block.Block, + anchorID: anchorID, + pathTitle: pathTitle, + path: path, + block: block.Block, } _, err = io.WriteString(w, " (see [below for nested schema](#"+anchorID+"))") @@ -231,7 +238,7 @@ nameLoop: // // If a `.Description` is provided instead, the behaviour will be the // same as for every other attribute. - if strings.ToLower(n) == "id" && childAtt.Description == "" { + if strings.ToLower(n) == "id" && len(parents) == 0 && childAtt.Description == "" { if strings.Contains(gf.topLevelTitle, "Read-Only") { childAtt.Description = "The ID of this resource." groups[i] = append(groups[i], n) @@ -344,7 +351,7 @@ func writeNestedTypes(w io.Writer, nestedTypes []nestedType) error { return err } - _, err = io.WriteString(w, "### Nested Schema for `"+strings.Join(nt.path, ".")+"`\n\n") + _, err = io.WriteString(w, "### Nested Schema for `"+nt.pathTitle+"`\n\n") if err != nil { return err } @@ -401,6 +408,7 @@ func writeObjectAttribute(w io.Writer, path []string, att cty.Type, group groupF } anchorID := "nestedobjatt--" + strings.Join(path, "--") + pathTitle := strings.Join(path, ".") nestedTypes := []nestedType{} switch { case att.IsObjectType(): @@ -410,9 +418,10 @@ func writeObjectAttribute(w io.Writer, path []string, att cty.Type, group groupF } nestedTypes = append(nestedTypes, nestedType{ - anchorID: anchorID, - path: path, - object: &att, + anchorID: anchorID, + pathTitle: pathTitle, + path: path, + object: &att, group: group, }) @@ -424,9 +433,10 @@ func writeObjectAttribute(w io.Writer, path []string, att cty.Type, group groupF nt := att.ElementType() nestedTypes = append(nestedTypes, nestedType{ - anchorID: anchorID, - path: path, - object: &nt, + anchorID: anchorID, + pathTitle: pathTitle, + path: path, + object: &nt, group: group, }) diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/write_attribute_description.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/write_attribute_description.go similarity index 100% rename from vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/write_attribute_description.go rename to vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/write_attribute_description.go diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/write_block_type_description.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/write_block_type_description.go similarity index 100% rename from vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/write_block_type_description.go rename to vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/write_block_type_description.go diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/write_nested_attribute_type_description.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/write_nested_attribute_type_description.go similarity index 100% rename from vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/write_nested_attribute_type_description.go rename to vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/write_nested_attribute_type_description.go diff --git a/vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/write_type.go b/vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/write_type.go similarity index 100% rename from vendor/github.com/hashicorp/terraform-plugin-docs/schemamd/write_type.go rename to vendor/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/write_type.go diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/LICENSE b/vendor/github.com/hashicorp/terraform-plugin-framework/LICENSE new file mode 100644 index 00000000..84cd0643 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/LICENSE @@ -0,0 +1,356 @@ +Copyright (c) 2021 HashiCorp, Inc. + +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. + diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/attr/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/doc.go new file mode 100644 index 00000000..9fc3b6fc --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/doc.go @@ -0,0 +1,7 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package attr contains type and value interfaces for core framework and +// provider-defined data types. The underlying xattr package contains +// additional interfaces for advanced type functionality. +package attr diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/attr/type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/type.go new file mode 100644 index 00000000..4542812e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/type.go @@ -0,0 +1,120 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package attr + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Type defines an interface for describing a kind of attribute. Types are +// collections of constraints and behaviors such that they can be reused on +// multiple attributes easily. +// +// Refer also to the xattr package, which contains additional extensions for +// Type, such as validation. +type Type interface { + // TerraformType returns the tftypes.Type that should be used to + // represent this type. This constrains what user input will be + // accepted and what kind of data can be set in state. The framework + // will use this to translate the Type to something Terraform can + // understand. + TerraformType(context.Context) tftypes.Type + + // ValueFromTerraform returns a Value given a tftypes.Value. This is + // meant to convert the tftypes.Value into a more convenient Go type + // for the provider to consume the data with. + ValueFromTerraform(context.Context, tftypes.Value) (Value, error) + + // ValueType should return the attr.Value type returned by + // ValueFromTerraform. The returned attr.Value can be any null, unknown, + // or known value for the type, as this is intended for type detection + // and improving error diagnostics. + ValueType(context.Context) Value + + // Equal should return true if the Type is considered equivalent to the + // Type passed as an argument. + // + // Most types should verify the associated Type is exactly equal to prevent + // potential data consistency issues. For example: + // + // - basetypes.Number is inequal to basetypes.Int64 or basetypes.Float64 + // - basetypes.String is inequal to a custom Go type that embeds it + // + Equal(Type) bool + + // String should return a human-friendly version of the Type. + String() string + + tftypes.AttributePathStepper +} + +// TypeWithAttributeTypes extends the Type interface to include information about +// attribute types. Attribute types are part of the definition of an object type. +type TypeWithAttributeTypes interface { + Type + + // WithAttributeTypes returns a new copy of the type with its + // attribute types set. + WithAttributeTypes(map[string]Type) TypeWithAttributeTypes + + // AttributeTypes returns the object's attribute types. + AttributeTypes() map[string]Type +} + +// TypeWithElementType extends the Type interface to include information about the type +// all elements will share. Element types are part of the definition of a list, +// set, or map type. +type TypeWithElementType interface { + Type + + // WithElementType returns a new copy of the type with its element type + // set. + WithElementType(Type) TypeWithElementType + + // ElementType returns the type's element type. + ElementType() Type +} + +// TypeWithElementTypes extends the Type interface to include information about the +// types of each element. Element types are part of the definition of a tuple +// type. +type TypeWithElementTypes interface { + Type + + // WithElementTypes returns a new copy of the type with its elements' + // types set. + WithElementTypes([]Type) TypeWithElementTypes + + // ElementTypes returns the type's elements' types. + ElementTypes() []Type +} + +// TypeWithPlaintextDescription extends the Type interface to include a +// Description method, used to bundle extra information to include in attribute +// descriptions with the Type. It expects the description to be written as +// plain text, with no special formatting. +type TypeWithPlaintextDescription interface { + Type + + // Description returns a practitioner-friendly explanation of the type + // and the constraints of the data it accepts and returns. It will be + // combined with the Description associated with the Attribute. + Description(context.Context) string +} + +// TypeWithMarkdownDescription extends the Type interface to include a +// MarkdownDescription method, used to bundle extra information to include in +// attribute descriptions with the Type. It expects the description to be +// formatted for display with Markdown. +type TypeWithMarkdownDescription interface { + Type + + // MarkdownDescription returns a practitioner-friendly explanation of + // the type and the constraints of the data it accepts and returns. It + // will be combined with the MarkdownDescription associated with the + // Attribute. + MarkdownDescription(context.Context) string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/attr/value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/value.go new file mode 100644 index 00000000..b34a3bb7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/value.go @@ -0,0 +1,71 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package attr + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +const ( + // UnknownValueString should be returned by Value.String() implementations, + // when Value.IsUnknown() returns true. + UnknownValueString = "" + + // NullValueString should be returned by Value.String() implementations + // when Value.IsNull() returns true. + NullValueString = "" + + // UnsetValueString should be returned by Value.String() implementations + // when Value does not contain sufficient information to display to users. + // + // This is primarily used for invalid Dynamic Value implementations. + UnsetValueString = "" +) + +// Value defines an interface for describing data associated with an attribute. +// Values allow provider developers to specify data in a convenient format, and +// have it transparently be converted to formats Terraform understands. +type Value interface { + // Type returns the Type that created the Value. + Type(context.Context) Type + + // ToTerraformValue returns the data contained in the Value as + // a tftypes.Value. + ToTerraformValue(context.Context) (tftypes.Value, error) + + // Equal should return true if the Value is considered type and data + // value equivalent to the Value passed as an argument. + // + // Most types should verify the associated Type is exactly equal to prevent + // potential data consistency issues. For example: + // + // - basetypes.Number is inequal to basetypes.Int64 or basetypes.Float64 + // - basetypes.String is inequal to a custom Go type that embeds it + // + // Additionally, most types should verify that known values are compared + // to comply with Terraform's data consistency rules. For example: + // + // - In a list, element order is significant + // - In a string, runes are compared byte-wise (e.g. whitespace is + // significant in JSON-encoded strings) + // + Equal(Value) bool + + // IsNull returns true if the Value is not set, or is explicitly set to null. + IsNull() bool + + // IsUnknown returns true if the value is not yet known. + IsUnknown() bool + + // String returns a summary representation of either the underlying Value, + // or UnknownValueString (``) when IsUnknown() returns true, + // or NullValueString (``) when IsNull() return true. + // + // This is an intentionally lossy representation, that are best suited for + // logging and error reporting, as they are not protected by + // compatibility guarantees within the framework. + String() string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/attr/value_state.go b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/value_state.go new file mode 100644 index 00000000..b75a3d19 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/value_state.go @@ -0,0 +1,34 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package attr + +import "fmt" + +const ( + // ValueStateNull represents a value which is null. + // + // This value is 0 so it is the zero-value for types implementations. + ValueStateNull ValueState = 0 + + // ValueStateUnknown represents a value which is unknown. + ValueStateUnknown ValueState = 1 + + // ValueStateKnown represents a value which is known (not null or unknown). + ValueStateKnown ValueState = 2 +) + +type ValueState uint8 + +func (s ValueState) String() string { + switch s { + case ValueStateKnown: + return "known" + case ValueStateNull: + return "null" + case ValueStateUnknown: + return "unknown" + default: + panic(fmt.Sprintf("unhandled ValueState in String: %d", s)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/attribute.go new file mode 100644 index 00000000..9b50e554 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/attribute.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package xattr + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// ValidateableAttribute defines an interface for validating an attribute value. +// The ValidateAttribute method is called implicitly by the framework when value +// types from Terraform are converted into framework types. +type ValidateableAttribute interface { + // ValidateAttribute returns any warnings or errors generated during validation + // of the attribute. It is generally used to check the data format and ensure + // that it complies with the requirements of the Value. + ValidateAttribute(context.Context, ValidateAttributeRequest, *ValidateAttributeResponse) +} + +// ValidateAttributeRequest represents a request for the Value to call its +// validation logic. An instance of this request struct is supplied as an +// argument to the ValidateAttribute method. +type ValidateAttributeRequest struct { + // Path is the path to the attribute being validated. + Path path.Path +} + +// ValidateAttributeResponse represents a response to a ValidateAttributeRequest. +// An instance of this response struct is supplied as an argument to the +// ValidateAttribute method. +type ValidateAttributeResponse struct { + // Diagnostics is a collection of warnings or errors generated during + // validation of the Value. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/doc.go new file mode 100644 index 00000000..6c5a453a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package xattr contains additional interfaces for attr types. This package +// is separate from the core attr package to prevent import cycles. +package xattr diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/type.go new file mode 100644 index 00000000..1dd534fa --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/attr/xattr/type.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package xattr + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// TypeWithValidate extends the attr.Type interface to include a Validate +// method, used to bundle consistent validation logic with the Type. +// +// Deprecated: Use the ValidateableAttribute interface instead for schema +// attribute validation. Use the function.ValidateableParameter interface +// for provider-defined function parameter validation. +type TypeWithValidate interface { + attr.Type + + // Validate returns any warnings or errors about the value that is + // being used to populate the Type. It is generally used to check the + // data format and ensure that it complies with the requirements of the + // Type. + Validate(context.Context, tftypes.Value, path.Path) diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/config_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/config_validator.go new file mode 100644 index 00000000..0a153da4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/config_validator.go @@ -0,0 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package datasource + +import "context" + +// ConfigValidator describes reusable data source configuration validation functionality. +type ConfigValidator interface { + // Description describes the validation in plain text formatting. + // + // This information may be automatically added to data source plain text + // descriptions by external tooling. + Description(context.Context) string + + // MarkdownDescription describes the validation in Markdown formatting. + // + // This information may be automatically added to data source Markdown + // descriptions by external tooling. + MarkdownDescription(context.Context) string + + // ValidateDataSource performs the validation. + // + // This method name is separate from the provider.ConfigValidator + // interface ValidateProvider method name and resource.ConfigValidator + // interface ValidateResource method name to allow generic validators. + ValidateDataSource(context.Context, ValidateConfigRequest, *ValidateConfigResponse) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/configure.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/configure.go new file mode 100644 index 00000000..9a569a91 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/configure.go @@ -0,0 +1,34 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package datasource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +// ConfigureRequest represents a request for the provider to configure a data +// source, i.e., set provider-level data or clients. An instance of this +// request struct is supplied as an argument to the DataSource type Configure +// method. +type ConfigureRequest struct { + // ProviderData is the data set in the + // [provider.ConfigureResponse.DataSourceData] field. This data is + // provider-specifc and therefore can contain any necessary remote system + // clients, custom provider data, or anything else pertinent to the + // functionality of the DataSource. + // + // This data is only set after the ConfigureProvider RPC has been called + // by Terraform. + ProviderData any +} + +// ConfigureResponse represents a response to a ConfigureRequest. An +// instance of this response struct is supplied as an argument to the +// DataSource type Configure method. +type ConfigureResponse struct { + // Diagnostics report errors or warnings related to configuring of the + // Datasource. An empty slice indicates a successful operation with no + // warnings or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/data_source.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/data_source.go new file mode 100644 index 00000000..97a6eaa2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/data_source.go @@ -0,0 +1,77 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package datasource + +import ( + "context" +) + +// DataSource represents an instance of a data source type. This is the core +// interface that all data sources must implement. +// +// Data sources can optionally implement these additional concepts: +// +// - Configure: Include provider-level data or clients. +// - Validation: Schema-based or entire configuration +// via DataSourceWithConfigValidators or DataSourceWithValidateConfig. +type DataSource interface { + // Metadata should return the full name of the data source, such as + // examplecloud_thing. + Metadata(context.Context, MetadataRequest, *MetadataResponse) + + // Schema should return the schema for this data source. + Schema(context.Context, SchemaRequest, *SchemaResponse) + + // Read is called when the provider must read data source values in + // order to update state. Config values should be read from the + // ReadRequest and new state values set on the ReadResponse. + Read(context.Context, ReadRequest, *ReadResponse) +} + +// DataSourceWithConfigure is an interface type that extends DataSource to +// include a method which the framework will automatically call so provider +// developers have the opportunity to setup any necessary provider-level data +// or clients in the DataSource type. +// +// This method is intended to replace the provider.DataSourceType type +// NewDataSource method in a future release. +type DataSourceWithConfigure interface { + DataSource + + // Configure enables provider-level data or clients to be set in the + // provider-defined DataSource type. It is separately executed for each + // ReadDataSource RPC. + Configure(context.Context, ConfigureRequest, *ConfigureResponse) +} + +// DataSourceWithConfigValidators is an interface type that extends DataSource to include declarative validations. +// +// Declaring validation using this methodology simplifies implmentation of +// reusable functionality. These also include descriptions, which can be used +// for automating documentation. +// +// Validation will include ConfigValidators and ValidateConfig, if both are +// implemented, in addition to any Attribute or Type validation. +type DataSourceWithConfigValidators interface { + DataSource + + // ConfigValidators returns a list of ConfigValidators. Each ConfigValidator's Validate method will be called when validating the data source. + ConfigValidators(context.Context) []ConfigValidator +} + +// DataSourceWithValidateConfig is an interface type that extends DataSource to include imperative validation. +// +// Declaring validation using this methodology simplifies one-off +// functionality that typically applies to a single data source. Any +// documentation of this functionality must be manually added into schema +// descriptions. +// +// Validation will include ConfigValidators and ValidateConfig, if both are +// implemented, in addition to any Attribute or Type validation. +type DataSourceWithValidateConfig interface { + DataSource + + // ValidateConfig performs the validation. + ValidateConfig(context.Context, ValidateConfigRequest, *ValidateConfigResponse) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/doc.go new file mode 100644 index 00000000..7770cd1f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/doc.go @@ -0,0 +1,19 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package datasource contains all interfaces, request types, and response +// types for a data source implementation. +// +// In Terraform, a data source is a concept which enables provider developers +// to offer practitioners a read-only source of information, which is saved +// into the Terraform state and can be referenced by other parts of a +// configuration. Data sources are defined by a data source type/name, such as +// "examplecloud_thing", a schema representing the structure and data types of +// configuration and state, and read logic. +// +// The main starting point for implementations in this package is the +// DataSource type which represents an instance of a data source type that has +// its own configuration, read logic, and state. The DataSource implementations +// are referenced by a [provider.Provider] type DataSources method, which +// enables the data source for practitioner and testing usage. +package datasource diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/metadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/metadata.go new file mode 100644 index 00000000..d00c0516 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/metadata.go @@ -0,0 +1,24 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package datasource + +// MetadataRequest represents a request for the DataSource to return metadata, +// such as its type name. An instance of this request struct is supplied as an +// argument to the DataSource type Metadata method. +type MetadataRequest struct { + // ProviderTypeName is the string returned from + // [provider.MetadataResponse.TypeName], if the Provider type implements + // the Metadata method. This string should prefix the DataSource type name + // with an underscore in the response. + ProviderTypeName string +} + +// MetadataResponse represents a response to a MetadataRequest. An +// instance of this response struct is supplied as an argument to the +// DataSource type Metadata method. +type MetadataResponse struct { + // TypeName should be the full data source type, including the provider + // type prefix and an underscore. For example, examplecloud_thing. + TypeName string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/read.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/read.go new file mode 100644 index 00000000..07e28cab --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/read.go @@ -0,0 +1,40 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package datasource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ReadRequest represents a request for the provider to read a data +// source, i.e., update values in state according to the real state of the +// data source. An instance of this request struct is supplied as an argument +// to the data source's Read function. +type ReadRequest struct { + // Config is the configuration the user supplied for the data source. + // + // This configuration may contain unknown values if a user uses + // interpolation or other functionality that would prevent Terraform + // from knowing the value at request time. + Config tfsdk.Config + + // ProviderMeta is metadata from the provider_meta block of the module. + ProviderMeta tfsdk.Config +} + +// ReadResponse represents a response to a ReadRequest. An +// instance of this response struct is supplied as an argument to the data +// source's Read function, in which the provider should set values on the +// ReadResponse as appropriate. +type ReadResponse struct { + // State is the state of the data source following the Read operation. + // This field should be set during the resource's Read operation. + State tfsdk.State + + // Diagnostics report errors or warnings related to reading the data + // source. An empty slice indicates a successful operation with no + // warnings or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema.go new file mode 100644 index 00000000..022f4f52 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package datasource + +import ( + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +// SchemaRequest represents a request for the DataSource to return its schema. +// An instance of this request struct is supplied as an argument to the +// DataSource type Schema method. +type SchemaRequest struct{} + +// SchemaResponse represents a response to a SchemaRequest. An instance of this +// response struct is supplied as an argument to the DataSource type Schema +// method. +type SchemaResponse struct { + // Schema is the schema of the data source. + Schema schema.Schema + + // Diagnostics report errors or warnings related to validating the data + // source configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/attribute.go new file mode 100644 index 00000000..4a0fecee --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/attribute.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Attribute define a value field inside the Schema. Implementations in this +// package include: +// - BoolAttribute +// - Float64Attribute +// - Int64Attribute +// - ListAttribute +// - MapAttribute +// - NumberAttribute +// - ObjectAttribute +// - SetAttribute +// - StringAttribute +// +// Additionally, the NestedAttribute interface extends Attribute with nested +// attributes. Only supported in protocol version 6. Implementations in this +// package include: +// - ListNestedAttribute +// - MapNestedAttribute +// - SetNestedAttribute +// - SingleNestedAttribute +// +// In practitioner configurations, an equals sign (=) is required to set +// the value. [Configuration Reference] +// +// [Configuration Reference]: https://developer.hashicorp.com/terraform/language/syntax/configuration +type Attribute interface { + fwschema.Attribute +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/block.go new file mode 100644 index 00000000..f741d8f8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/block.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Block defines a structural field inside a Schema. Implementations in this +// package include: +// - ListNestedBlock +// - SetNestedBlock +// - SingleNestedBlock +// +// In practitioner configurations, an equals sign (=) cannot be used to set the +// value. Blocks are instead repeated as necessary, or require the use of +// [Dynamic Block Expressions]. +// +// Prefer NestedAttribute over Block. Blocks should typically be used for +// configuration compatibility with previously existing schemas from an older +// Terraform Plugin SDK. Efforts should be made to convert from Block to +// NestedAttribute as a breaking change for practitioners. +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +// +// [Configuration Reference]: https://developer.hashicorp.com/terraform/language/syntax/configuration +type Block interface { + fwschema.Block +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/bool_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/bool_attribute.go new file mode 100644 index 00000000..b9f6e382 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/bool_attribute.go @@ -0,0 +1,187 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = BoolAttribute{} + _ fwxschema.AttributeWithBoolValidators = BoolAttribute{} +) + +// BoolAttribute represents a schema attribute that is a boolean. When +// retrieving the value for this attribute, use types.Bool as the value type +// unless the CustomType field is set. +// +// Terraform configurations configure this attribute using expressions that +// return a boolean or directly via the true/false keywords. +// +// example_attribute = true +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type BoolAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.BoolType. When retrieving data, the basetypes.BoolValuable + // associated with this custom type must be used in place of types.Bool. + CustomType basetypes.BoolTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Bool +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a BoolAttribute. +func (a BoolAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// BoolValidators returns the Validators field value. +func (a BoolAttribute) BoolValidators() []validator.Bool { + return a.Validators +} + +// Equal returns true if the given Attribute is a BoolAttribute +// and all fields are equal. +func (a BoolAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(BoolAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a BoolAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a BoolAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a BoolAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.StringType or the CustomType field value if defined. +func (a BoolAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.BoolType +} + +// IsComputed returns the Computed field value. +func (a BoolAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a BoolAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a BoolAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a BoolAttribute) IsSensitive() bool { + return a.Sensitive +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/doc.go new file mode 100644 index 00000000..64993307 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/doc.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package schema contains all available schema functionality for data sources. +// Data source schemas define the structure and value types for configuration +// and state data. Schemas are implemented via the datasource.DataSource type +// Schema method. +package schema diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/dynamic_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/dynamic_attribute.go new file mode 100644 index 00000000..6b1b6c83 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/dynamic_attribute.go @@ -0,0 +1,188 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = DynamicAttribute{} + _ fwxschema.AttributeWithDynamicValidators = DynamicAttribute{} +) + +// DynamicAttribute represents a schema attribute that is a dynamic, rather +// than a single static type. Static types are always preferable over dynamic +// types in Terraform as practitioners will receive less helpful configuration +// assistance from validation error diagnostics and editor integrations. When +// retrieving the value for this attribute, use types.Dynamic as the value type +// unless the CustomType field is set. +// +// The concrete value type for a dynamic is determined at runtime in this order: +// 1. By Terraform, if defined in the configuration (if Required or Optional). +// 2. By the provider (if Computed). +// +// Once the concrete value type has been determined, it must remain consistent between +// plan and apply or Terraform will return an error. +type DynamicAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.DynamicType. When retrieving data, the basetypes.DynamicValuable + // associated with this custom type must be used in place of types.Dynamic. + CustomType basetypes.DynamicTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Dynamic +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a DynamicAttribute. +func (a DynamicAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a DynamicAttribute +// and all fields are equal. +func (a DynamicAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(DynamicAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a DynamicAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a DynamicAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a DynamicAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.DynamicType or the CustomType field value if defined. +func (a DynamicAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.DynamicType +} + +// IsComputed returns the Computed field value. +func (a DynamicAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a DynamicAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a DynamicAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a DynamicAttribute) IsSensitive() bool { + return a.Sensitive +} + +// DynamicValidators returns the Validators field value. +func (a DynamicAttribute) DynamicValidators() []validator.Dynamic { + return a.Validators +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/float64_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/float64_attribute.go new file mode 100644 index 00000000..1313353e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/float64_attribute.go @@ -0,0 +1,190 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = Float64Attribute{} + _ fwxschema.AttributeWithFloat64Validators = Float64Attribute{} +) + +// Float64Attribute represents a schema attribute that is a 64-bit floating +// point number. When retrieving the value for this attribute, use +// types.Float64 as the value type unless the CustomType field is set. +// +// Use Int64Attribute for 64-bit integer attributes or NumberAttribute for +// 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via a floating point value. +// +// example_attribute = 123.45 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type Float64Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Float64Type. When retrieving data, the basetypes.Float64Valuable + // associated with this custom type must be used in place of types.Float64. + CustomType basetypes.Float64Typable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Float64 +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Float64Attribute. +func (a Float64Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Float64Attribute +// and all fields are equal. +func (a Float64Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Float64Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// Float64Validators returns the Validators field value. +func (a Float64Attribute) Float64Validators() []validator.Float64 { + return a.Validators +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a Float64Attribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a Float64Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a Float64Attribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.Float64Type or the CustomType field value if defined. +func (a Float64Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Float64Type +} + +// IsComputed returns the Computed field value. +func (a Float64Attribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a Float64Attribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a Float64Attribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a Float64Attribute) IsSensitive() bool { + return a.Sensitive +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/int64_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/int64_attribute.go new file mode 100644 index 00000000..ab9d5ca1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/int64_attribute.go @@ -0,0 +1,190 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = Int64Attribute{} + _ fwxschema.AttributeWithInt64Validators = Int64Attribute{} +) + +// Int64Attribute represents a schema attribute that is a 64-bit integer. +// When retrieving the value for this attribute, use types.Int64 as the value +// type unless the CustomType field is set. +// +// Use Float64Attribute for 64-bit floating point number attributes or +// NumberAttribute for 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via an integer value. +// +// example_attribute = 123 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type Int64Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Int64Type. When retrieving data, the basetypes.Int64Valuable + // associated with this custom type must be used in place of types.Int64. + CustomType basetypes.Int64Typable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Int64 +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Int64Attribute. +func (a Int64Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Int64Attribute +// and all fields are equal. +func (a Int64Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Int64Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a Int64Attribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a Int64Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a Int64Attribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.Int64Type or the CustomType field value if defined. +func (a Int64Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Int64Type +} + +// Int64Validators returns the Validators field value. +func (a Int64Attribute) Int64Validators() []validator.Int64 { + return a.Validators +} + +// IsComputed returns the Computed field value. +func (a Int64Attribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a Int64Attribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a Int64Attribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a Int64Attribute) IsSensitive() bool { + return a.Sensitive +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_attribute.go new file mode 100644 index 00000000..9d502067 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_attribute.go @@ -0,0 +1,222 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = ListAttribute{} + _ fwschema.AttributeWithValidateImplementation = ListAttribute{} + _ fwxschema.AttributeWithListValidators = ListAttribute{} +) + +// ListAttribute represents a schema attribute that is a list with a single +// element type. When retrieving the value for this attribute, use types.List +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use ListNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list or directly via square brace syntax. +// +// # list of strings +// example_attribute = ["first", "second"] +// +// Terraform configurations reference this attribute using expressions that +// accept a list or an element directly via square brace 0-based index syntax: +// +// # first known element +// .example_attribute[0] +type ListAttribute struct { + // ElementType is the type for all elements of the list. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ListType. When retrieving data, the basetypes.ListValuable + // associated with this custom type must be used in place of types.List. + CustomType basetypes.ListTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.List +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a list +// index or an error. +func (a ListAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a ListAttribute +// and all fields are equal. +func (a ListAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(ListAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a ListAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a ListAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ListAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.ListType or the CustomType field value if defined. +func (a ListAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ListType{ + ElemType: a.ElementType, + } +} + +// IsComputed returns the Computed field value. +func (a ListAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a ListAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ListAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a ListAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ListValidators returns the Validators field value. +func (a ListAttribute) ListValidators() []validator.List { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a ListAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_nested_attribute.go new file mode 100644 index 00000000..b9b70d6f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_nested_attribute.go @@ -0,0 +1,246 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = ListNestedAttribute{} + _ fwschema.AttributeWithValidateImplementation = ListNestedAttribute{} + _ fwxschema.AttributeWithListValidators = ListNestedAttribute{} +) + +// ListNestedAttribute represents an attribute that is a list of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.List +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use ListAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list of objects or directly via square and curly brace syntax. +// +// # list of objects +// example_attribute = [ +// { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a list of objects or an element directly via square brace 0-based +// index syntax: +// +// # first known object +// .example_attribute[0] +// # first known object nested_attribute value +// .example_attribute[0].nested_attribute +type ListNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.ListType of types.ObjectType. When retrieving data, the + // basetypes.ListValuable associated with this custom type must be used in + // place of types.List. + CustomType basetypes.ListTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.List +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyInt, otherwise returns an error. +func (a ListNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyInt) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to ListNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a ListNestedAttribute +// and all fields are equal. +func (a ListNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(ListNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a ListNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a ListNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ListNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a ListNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a ListNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeList +} + +// GetType returns ListType of ObjectType or CustomType. +func (a ListNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ListType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed returns the Computed field value. +func (a ListNestedAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a ListNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ListNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a ListNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ListValidators returns the Validators field value. +func (a ListNestedAttribute) ListValidators() []validator.List { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a ListNestedAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_nested_block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_nested_block.go new file mode 100644 index 00000000..4d098bc2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/list_nested_block.go @@ -0,0 +1,205 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Block = ListNestedBlock{} + _ fwschema.BlockWithValidateImplementation = ListNestedBlock{} + _ fwxschema.BlockWithListValidators = ListNestedBlock{} +) + +// ListNestedBlock represents a block that is a list of objects where +// the object attributes can be fully defined, including further attributes +// or blocks. When retrieving the value for this block, use types.List +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. +// +// Prefer ListNestedAttribute over ListNestedBlock if the provider is +// using protocol version 6. Nested attributes allow practitioners to configure +// values directly with expressions. +// +// Terraform configurations configure this block repeatedly using curly brace +// syntax without an equals (=) sign or [Dynamic Block Expressions]. +// +// # list of blocks with two elements +// example_block { +// nested_attribute = #... +// } +// example_block { +// nested_attribute = #... +// } +// +// Terraform configurations reference this block using expressions that +// accept a list of objects or an element directly via square brace 0-based +// index syntax: +// +// # first known object +// .example_block[0] +// # first known object nested_attribute value +// .example_block[0].nested_attribute +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +type ListNestedBlock struct { + // NestedObject is the underlying object that contains nested attributes or + // blocks. This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this block definition with + // a DynamicAttribute. + NestedObject NestedBlockObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.ListType of types.ObjectType. When retrieving data, the + // basetypes.ListValuable associated with this custom type must be used in + // place of types.List. + CustomType basetypes.ListTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.List +} + +// ApplyTerraform5AttributePathStep returns the NestedObject field value if step +// is ElementKeyInt, otherwise returns an error. +func (b ListNestedBlock) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyInt) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to ListNestedBlock", step) + } + + return b.NestedObject, nil +} + +// Equal returns true if the given Block is ListNestedBlock +// and all fields are equal. +func (b ListNestedBlock) Equal(o fwschema.Block) bool { + if _, ok := o.(ListNestedBlock); !ok { + return false + } + + return fwschema.BlocksEqual(b, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (b ListNestedBlock) GetDeprecationMessage() string { + return b.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (b ListNestedBlock) GetDescription() string { + return b.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (b ListNestedBlock) GetMarkdownDescription() string { + return b.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (b ListNestedBlock) GetNestedObject() fwschema.NestedBlockObject { + return b.NestedObject +} + +// GetNestingMode always returns BlockNestingModeList. +func (b ListNestedBlock) GetNestingMode() fwschema.BlockNestingMode { + return fwschema.BlockNestingModeList +} + +// ListValidators returns the Validators field value. +func (b ListNestedBlock) ListValidators() []validator.List { + return b.Validators +} + +// Type returns ListType of ObjectType or CustomType. +func (b ListNestedBlock) Type() attr.Type { + if b.CustomType != nil { + return b.CustomType + } + + return types.ListType{ + ElemType: b.NestedObject.Type(), + } +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the block to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (b ListNestedBlock) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if b.CustomType == nil && fwtype.ContainsCollectionWithDynamic(b.Type()) { + resp.Diagnostics.Append(fwtype.BlockCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/map_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/map_attribute.go new file mode 100644 index 00000000..d9b701f7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/map_attribute.go @@ -0,0 +1,225 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = MapAttribute{} + _ fwschema.AttributeWithValidateImplementation = MapAttribute{} + _ fwxschema.AttributeWithMapValidators = MapAttribute{} +) + +// MapAttribute represents a schema attribute that is a list with a single +// element type. When retrieving the value for this attribute, use types.Map +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use MapNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list or directly via curly brace syntax. +// +// # map of strings +// example_attribute = { +// key1 = "first", +// key2 = "second", +// } +// +// Terraform configurations reference this attribute using expressions that +// accept a map or an element directly via square brace string syntax: +// +// # key1 known element +// .example_attribute["key1"] +type MapAttribute struct { + // ElementType is the type for all elements of the map. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.MapType. When retrieving data, the basetypes.MapValuable + // associated with this custom type must be used in place of types.Map. + CustomType basetypes.MapTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Map +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a map +// index or an error. +func (a MapAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a MapAttribute +// and all fields are equal. +func (a MapAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(MapAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a MapAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a MapAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a MapAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.MapType or the CustomType field value if defined. +func (a MapAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.MapType{ + ElemType: a.ElementType, + } +} + +// IsComputed returns the Computed field value. +func (a MapAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a MapAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a MapAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a MapAttribute) IsSensitive() bool { + return a.Sensitive +} + +// MapValidators returns the Validators field value. +func (a MapAttribute) MapValidators() []validator.Map { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a MapAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/map_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/map_nested_attribute.go new file mode 100644 index 00000000..2f3a60ec --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/map_nested_attribute.go @@ -0,0 +1,247 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = MapNestedAttribute{} + _ fwschema.AttributeWithValidateImplementation = MapNestedAttribute{} + _ fwxschema.AttributeWithMapValidators = MapNestedAttribute{} +) + +// MapNestedAttribute represents an attribute that is a set of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Map +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use MapAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set of objects or directly via curly brace syntax. +// +// # map of objects +// example_attribute = { +// key = { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a map of objects or an element directly via square brace string +// syntax: +// +// # known object at key +// .example_attribute["key"] +// # known object nested_attribute value at key +// .example_attribute["key"].nested_attribute +type MapNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.MapType of types.ObjectType. When retrieving data, the + // basetypes.MapValuable associated with this custom type must be used in + // place of types.Map. + CustomType basetypes.MapTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Map +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyString, otherwise returns an error. +func (a MapNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyString) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to MapNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a MapNestedAttribute +// and all fields are equal. +func (a MapNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(MapNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a MapNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a MapNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a MapNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a MapNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a MapNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeMap +} + +// GetType returns MapType of ObjectType or CustomType. +func (a MapNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.MapType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed returns the Computed field value. +func (a MapNestedAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a MapNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a MapNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a MapNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// MapValidators returns the Validators field value. +func (a MapNestedAttribute) MapValidators() []validator.Map { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a MapNestedAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_attribute.go new file mode 100644 index 00000000..31d2ee15 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_attribute.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Nested attributes are only compatible with protocol version 6. +type NestedAttribute interface { + Attribute + fwschema.NestedAttribute +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_attribute_object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_attribute_object.go new file mode 100644 index 00000000..3719a239 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_attribute_object.go @@ -0,0 +1,82 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ fwxschema.NestedAttributeObjectWithValidators = NestedAttributeObject{} + +// NestedAttributeObject is the object containing the underlying attributes +// for a ListNestedAttribute, MapNestedAttribute, SetNestedAttribute, or +// SingleNestedAttribute (automatically generated). When retrieving the value +// for this attribute, use types.Object as the value type unless the CustomType +// field is set. The Attributes field must be set. Nested attributes are only +// compatible with protocol version 6. +// +// This object enables customizing and simplifying details within its parent +// NestedAttribute, therefore it cannot have Terraform schema fields such as +// Required, Description, etc. +type NestedAttributeObject struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. This field must be set. + Attributes map[string]Attribute + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object +} + +// ApplyTerraform5AttributePathStep performs an AttributeName step on the +// underlying attributes or returns an error. +func (o NestedAttributeObject) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.NestedAttributeObjectApplyTerraform5AttributePathStep(o, step) +} + +// Equal returns true if the given NestedAttributeObject is equivalent. +func (o NestedAttributeObject) Equal(other fwschema.NestedAttributeObject) bool { + if _, ok := other.(NestedAttributeObject); !ok { + return false + } + + return fwschema.NestedAttributeObjectEqual(o, other) +} + +// GetAttributes returns the Attributes field value. +func (o NestedAttributeObject) GetAttributes() fwschema.UnderlyingAttributes { + return schemaAttributes(o.Attributes) +} + +// ObjectValidators returns the Validators field value. +func (o NestedAttributeObject) ObjectValidators() []validator.Object { + return o.Validators +} + +// Type returns the framework type of the NestedAttributeObject. +func (o NestedAttributeObject) Type() basetypes.ObjectTypable { + if o.CustomType != nil { + return o.CustomType + } + + return fwschema.NestedAttributeObjectType(o) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_block_object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_block_object.go new file mode 100644 index 00000000..2b560b60 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/nested_block_object.go @@ -0,0 +1,94 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ fwxschema.NestedBlockObjectWithValidators = NestedBlockObject{} + +// NestedBlockObject is the object containing the underlying attributes and +// blocks for a ListNestedBlock or SetNestedBlock. When retrieving the value +// for this attribute, use types.Object as the value type unless the CustomType +// field is set. +// +// This object enables customizing and simplifying details within its parent +// Block, therefore it cannot have Terraform schema fields such as Description, +// etc. +type NestedBlockObject struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Blocks names. + Attributes map[string]Attribute + + // Blocks is the mapping of underlying block names to block definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Attributes names. + Blocks map[string]Block + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object +} + +// ApplyTerraform5AttributePathStep performs an AttributeName step on the +// underlying attributes or returns an error. +func (o NestedBlockObject) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.NestedBlockObjectApplyTerraform5AttributePathStep(o, step) +} + +// Equal returns true if the given NestedBlockObject is equivalent. +func (o NestedBlockObject) Equal(other fwschema.NestedBlockObject) bool { + if _, ok := other.(NestedBlockObject); !ok { + return false + } + + return fwschema.NestedBlockObjectEqual(o, other) +} + +// GetAttributes returns the Attributes field value. +func (o NestedBlockObject) GetAttributes() fwschema.UnderlyingAttributes { + return schemaAttributes(o.Attributes) +} + +// GetAttributes returns the Blocks field value. +func (o NestedBlockObject) GetBlocks() map[string]fwschema.Block { + return schemaBlocks(o.Blocks) +} + +// ObjectValidators returns the Validators field value. +func (o NestedBlockObject) ObjectValidators() []validator.Object { + return o.Validators +} + +// Type returns the framework type of the NestedBlockObject. +func (o NestedBlockObject) Type() basetypes.ObjectTypable { + if o.CustomType != nil { + return o.CustomType + } + + return fwschema.NestedBlockObjectType(o) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/number_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/number_attribute.go new file mode 100644 index 00000000..ffe4e083 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/number_attribute.go @@ -0,0 +1,191 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = NumberAttribute{} + _ fwxschema.AttributeWithNumberValidators = NumberAttribute{} +) + +// NumberAttribute represents a schema attribute that is a generic number with +// up to 512 bits of floating point or integer precision. When retrieving the +// value for this attribute, use types.Number as the value type unless the +// CustomType field is set. +// +// Use Float64Attribute for 64-bit floating point number attributes or +// Int64Attribute for 64-bit integer number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via a floating point or integer value. +// +// example_attribute = 123 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type NumberAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.NumberType. When retrieving data, the basetypes.NumberValuable + // associated with this custom type must be used in place of types.Number. + CustomType basetypes.NumberTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Number +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a NumberAttribute. +func (a NumberAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a NumberAttribute +// and all fields are equal. +func (a NumberAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(NumberAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a NumberAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a NumberAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a NumberAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.NumberType or the CustomType field value if defined. +func (a NumberAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.NumberType +} + +// IsComputed returns the Computed field value. +func (a NumberAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a NumberAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a NumberAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a NumberAttribute) IsSensitive() bool { + return a.Sensitive +} + +// NumberValidators returns the Validators field value. +func (a NumberAttribute) NumberValidators() []validator.Number { + return a.Validators +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/object_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/object_attribute.go new file mode 100644 index 00000000..eafa40c6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/object_attribute.go @@ -0,0 +1,224 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = ObjectAttribute{} + _ fwschema.AttributeWithValidateImplementation = ObjectAttribute{} + _ fwxschema.AttributeWithObjectValidators = ObjectAttribute{} +) + +// ObjectAttribute represents a schema attribute that is an object with only +// type information for underlying attributes. When retrieving the value for +// this attribute, use types.Object as the value type unless the CustomType +// field is set. The AttributeTypes field must be set. +// +// Prefer SingleNestedAttribute over ObjectAttribute if the provider is +// using protocol version 6 and full attribute functionality is needed. +// +// Terraform configurations configure this attribute using expressions that +// return an object or directly via curly brace syntax. +// +// # object with one attribute +// example_attribute = { +// underlying_attribute = #... +// } +// +// Terraform configurations reference this attribute using expressions that +// accept an object or an attribute directly via period syntax: +// +// # underlying attribute +// .example_attribute.underlying_attribute +type ObjectAttribute struct { + // AttributeTypes is the mapping of underlying attribute names to attribute + // types. This field must be set. + // + // Attribute types that contain a collection with a nested dynamic type (i.e. types.List[types.Dynamic]) are not supported. + // If underlying dynamic collection values are required, replace this attribute definition with + // DynamicAttribute instead. + AttributeTypes map[string]attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into an +// attribute name or an error. +func (a ObjectAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a ObjectAttribute +// and all fields are equal. +func (a ObjectAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(ObjectAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a ObjectAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a ObjectAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ObjectAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.ObjectType or the CustomType field value if defined. +func (a ObjectAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ObjectType{ + AttrTypes: a.AttributeTypes, + } +} + +// IsComputed returns the Computed field value. +func (a ObjectAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a ObjectAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ObjectAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a ObjectAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ObjectValidators returns the Validators field value. +func (a ObjectAttribute) ObjectValidators() []validator.Object { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a ObjectAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.AttributeTypes == nil && a.CustomType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingAttributeTypesDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/schema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/schema.go new file mode 100644 index 00000000..90d1096c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/schema.go @@ -0,0 +1,187 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Schema must satify the fwschema.Schema interface. +var _ fwschema.Schema = Schema{} + +// Schema defines the structure and value types of data source data. This type +// is used as the datasource.SchemaResponse type Schema field, which is +// implemented by the datasource.DataSource type Schema method. +type Schema struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Blocks names. + Attributes map[string]Attribute + + // Blocks is the mapping of underlying block names to block definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Attributes names. + Blocks map[string]Block + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this data source is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this data source is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this data source. The warning diagnostic + // summary is automatically set to "Data Source Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Use examplecloud_other data source instead. This data source + // will be removed in the next major version of the provider." + // - "Remove this data source as it no longer is valid and + // will be removed in the next major version of the provider." + // + DeprecationMessage string +} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// schema. +func (s Schema) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.SchemaApplyTerraform5AttributePathStep(s, step) +} + +// AttributeAtPath returns the Attribute at the passed path. If the path points +// to an element or attribute of a complex type, rather than to an Attribute, +// it will return an ErrPathInsideAtomicAttribute error. +func (s Schema) AttributeAtPath(ctx context.Context, p path.Path) (fwschema.Attribute, diag.Diagnostics) { + return fwschema.SchemaAttributeAtPath(ctx, s, p) +} + +// AttributeAtPath returns the Attribute at the passed path. If the path points +// to an element or attribute of a complex type, rather than to an Attribute, +// it will return an ErrPathInsideAtomicAttribute error. +func (s Schema) AttributeAtTerraformPath(ctx context.Context, p *tftypes.AttributePath) (fwschema.Attribute, error) { + return fwschema.SchemaAttributeAtTerraformPath(ctx, s, p) +} + +// GetAttributes returns the Attributes field value. +func (s Schema) GetAttributes() map[string]fwschema.Attribute { + return schemaAttributes(s.Attributes) +} + +// GetBlocks returns the Blocks field value. +func (s Schema) GetBlocks() map[string]fwschema.Block { + return schemaBlocks(s.Blocks) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (s Schema) GetDeprecationMessage() string { + return s.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (s Schema) GetDescription() string { + return s.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (s Schema) GetMarkdownDescription() string { + return s.MarkdownDescription +} + +// GetVersion always returns 0 as data source schemas cannot be versioned. +func (s Schema) GetVersion() int64 { + return 0 +} + +// Type returns the framework type of the schema. +func (s Schema) Type() attr.Type { + return fwschema.SchemaType(s) +} + +// TypeAtPath returns the framework type at the given schema path. +func (s Schema) TypeAtPath(ctx context.Context, p path.Path) (attr.Type, diag.Diagnostics) { + return fwschema.SchemaTypeAtPath(ctx, s, p) +} + +// TypeAtTerraformPath returns the framework type at the given tftypes path. +func (s Schema) TypeAtTerraformPath(ctx context.Context, p *tftypes.AttributePath) (attr.Type, error) { + return fwschema.SchemaTypeAtTerraformPath(ctx, s, p) +} + +// Validate verifies that the schema is not using a reserved field name for a top-level attribute. +// +// Deprecated: Use the ValidateImplementation method instead. +func (s Schema) Validate() diag.Diagnostics { + return s.ValidateImplementation(context.Background()) +} + +// ValidateImplementation contains logic for validating the provider-defined +// implementation of the schema and underlying attributes and blocks to prevent +// unexpected errors or panics. This logic runs during the GetProviderSchema +// RPC, or via provider-defined unit testing, and should never include false +// positives. +func (s Schema) ValidateImplementation(ctx context.Context) diag.Diagnostics { + var diags diag.Diagnostics + + for attributeName, attribute := range s.GetAttributes() { + req := fwschema.ValidateImplementationRequest{ + Name: attributeName, + Path: path.Root(attributeName), + } + + diags.Append(fwschema.IsReservedResourceAttributeName(req.Name, req.Path)...) + diags.Append(fwschema.ValidateAttributeImplementation(ctx, attribute, req)...) + } + + for blockName, block := range s.GetBlocks() { + req := fwschema.ValidateImplementationRequest{ + Name: blockName, + Path: path.Root(blockName), + } + + diags.Append(fwschema.IsReservedResourceAttributeName(req.Name, req.Path)...) + diags.Append(fwschema.ValidateBlockImplementation(ctx, block, req)...) + } + + return diags +} + +// schemaAttributes is a datasource to fwschema type conversion function. +func schemaAttributes(attributes map[string]Attribute) map[string]fwschema.Attribute { + result := make(map[string]fwschema.Attribute, len(attributes)) + + for name, attribute := range attributes { + result[name] = attribute + } + + return result +} + +// schemaBlocks is a datasource to fwschema type conversion function. +func schemaBlocks(blocks map[string]Block) map[string]fwschema.Block { + result := make(map[string]fwschema.Block, len(blocks)) + + for name, block := range blocks { + result[name] = block + } + + return result +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_attribute.go new file mode 100644 index 00000000..261b0242 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_attribute.go @@ -0,0 +1,220 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = SetAttribute{} + _ fwschema.AttributeWithValidateImplementation = SetAttribute{} + _ fwxschema.AttributeWithSetValidators = SetAttribute{} +) + +// SetAttribute represents a schema attribute that is a set with a single +// element type. When retrieving the value for this attribute, use types.Set +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use SetNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set or directly via square brace syntax. +// +// # set of strings +// example_attribute = ["first", "second"] +// +// Terraform configurations reference this attribute using expressions that +// accept a set. Sets cannot be indexed in Terraform, therefore an expression +// is required to access an explicit element. +type SetAttribute struct { + // ElementType is the type for all elements of the set. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.SetType. When retrieving data, the basetypes.SetValuable + // associated with this custom type must be used in place of types.Set. + CustomType basetypes.SetTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Set +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a set +// index or an error. +func (a SetAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a SetAttribute +// and all fields are equal. +func (a SetAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(SetAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a SetAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a SetAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SetAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.SetType or the CustomType field value if defined. +func (a SetAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.SetType{ + ElemType: a.ElementType, + } +} + +// IsComputed returns the Computed field value. +func (a SetAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a SetAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SetAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a SetAttribute) IsSensitive() bool { + return a.Sensitive +} + +// SetValidators returns the Validators field value. +func (a SetAttribute) SetValidators() []validator.Set { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a SetAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_nested_attribute.go new file mode 100644 index 00000000..860ab4c9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_nested_attribute.go @@ -0,0 +1,242 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = SetNestedAttribute{} + _ fwschema.AttributeWithValidateImplementation = SetNestedAttribute{} + _ fwxschema.AttributeWithSetValidators = SetNestedAttribute{} +) + +// SetNestedAttribute represents an attribute that is a set of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Set +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use SetAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set of objects or directly via square and curly brace syntax. +// +// # set of objects +// example_attribute = [ +// { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a set of objects. Sets cannot be indexed in Terraform, therefore +// an expression is required to access an explicit element. +type SetNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.SetType of types.ObjectType. When retrieving data, the + // basetypes.SetValuable associated with this custom type must be used in + // place of types.Set. + CustomType basetypes.SetTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Set +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyValue, otherwise returns an error. +func (a SetNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyValue) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SetNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a SetNestedAttribute +// and all fields are equal. +func (a SetNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(SetNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a SetNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a SetNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SetNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a SetNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a SetNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeSet +} + +// GetType returns SetType of ObjectType or CustomType. +func (a SetNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.SetType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed returns the Computed field value. +func (a SetNestedAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a SetNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SetNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a SetNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// SetValidators returns the Validators field value. +func (a SetNestedAttribute) SetValidators() []validator.Set { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a SetNestedAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_nested_block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_nested_block.go new file mode 100644 index 00000000..085163f3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/set_nested_block.go @@ -0,0 +1,205 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Block = SetNestedBlock{} + _ fwschema.BlockWithValidateImplementation = SetNestedBlock{} + _ fwxschema.BlockWithSetValidators = SetNestedBlock{} +) + +// SetNestedBlock represents a block that is a set of objects where +// the object attributes can be fully defined, including further attributes +// or blocks. When retrieving the value for this block, use types.Set +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. +// +// Prefer SetNestedAttribute over SetNestedBlock if the provider is +// using protocol version 6. Nested attributes allow practitioners to configure +// values directly with expressions. +// +// Terraform configurations configure this block repeatedly using curly brace +// syntax without an equals (=) sign or [Dynamic Block Expressions]. +// +// # set of blocks with two elements +// example_block { +// nested_attribute = #... +// } +// example_block { +// nested_attribute = #... +// } +// +// Terraform configurations reference this block using expressions that +// accept a set of objects or an element directly via square brace 0-based +// index syntax: +// +// # first known object +// .example_block[0] +// # first known object nested_attribute value +// .example_block[0].nested_attribute +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +type SetNestedBlock struct { + // NestedObject is the underlying object that contains nested attributes or + // blocks. This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this block definition with + // a DynamicAttribute. + NestedObject NestedBlockObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.SetType of types.ObjectType. When retrieving data, the + // basetypes.SetValuable associated with this custom type must be used in + // place of types.Set. + CustomType basetypes.SetTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Set +} + +// ApplyTerraform5AttributePathStep returns the NestedObject field value if step +// is ElementKeyValue, otherwise returns an error. +func (b SetNestedBlock) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyValue) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SetNestedBlock", step) + } + + return b.NestedObject, nil +} + +// Equal returns true if the given Block is SetNestedBlock +// and all fields are equal. +func (b SetNestedBlock) Equal(o fwschema.Block) bool { + if _, ok := o.(SetNestedBlock); !ok { + return false + } + + return fwschema.BlocksEqual(b, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (b SetNestedBlock) GetDeprecationMessage() string { + return b.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (b SetNestedBlock) GetDescription() string { + return b.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (b SetNestedBlock) GetMarkdownDescription() string { + return b.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (b SetNestedBlock) GetNestedObject() fwschema.NestedBlockObject { + return b.NestedObject +} + +// GetNestingMode always returns BlockNestingModeSet. +func (b SetNestedBlock) GetNestingMode() fwschema.BlockNestingMode { + return fwschema.BlockNestingModeSet +} + +// SetValidators returns the Validators field value. +func (b SetNestedBlock) SetValidators() []validator.Set { + return b.Validators +} + +// Type returns SetType of ObjectType or CustomType. +func (b SetNestedBlock) Type() attr.Type { + if b.CustomType != nil { + return b.CustomType + } + + return types.SetType{ + ElemType: b.NestedObject.Type(), + } +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the block to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (b SetNestedBlock) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if b.CustomType == nil && fwtype.ContainsCollectionWithDynamic(b.Type()) { + resp.Diagnostics.Append(fwtype.BlockCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/single_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/single_nested_attribute.go new file mode 100644 index 00000000..21c9f323 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/single_nested_attribute.go @@ -0,0 +1,246 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = SingleNestedAttribute{} + _ fwxschema.AttributeWithObjectValidators = SingleNestedAttribute{} +) + +// SingleNestedAttribute represents an attribute that is a single object where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Object +// as the value type unless the CustomType field is set. The Attributes field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use ObjectAttribute if the underlying attributes do not require definition +// beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return an object or directly via curly brace syntax. +// +// # single object +// example_attribute = { +// nested_attribute = #... +// } +// +// Terraform configurations reference this attribute using expressions that +// accept an object or an attribute name directly via period syntax: +// +// # object nested_attribute value +// .example_attribute.nested_attribute +type SingleNestedAttribute struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. This field must be set. + Attributes map[string]Attribute + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is AttributeName, otherwise returns an error. +func (a SingleNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + name, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SingleNestedAttribute", step) + } + + attribute, ok := a.Attributes[string(name)] + + if !ok { + return nil, fmt.Errorf("no attribute %q on SingleNestedAttribute", name) + } + + return attribute, nil +} + +// Equal returns true if the given Attribute is a SingleNestedAttribute +// and all fields are equal. +func (a SingleNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(SingleNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetAttributes returns the Attributes field value. +func (a SingleNestedAttribute) GetAttributes() fwschema.UnderlyingAttributes { + return schemaAttributes(a.Attributes) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a SingleNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a SingleNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SingleNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns a generated NestedAttributeObject from the +// Attributes, CustomType, and Validators field values. +func (a SingleNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return NestedAttributeObject{ + Attributes: a.Attributes, + CustomType: a.CustomType, + Validators: a.Validators, + } +} + +// GetNestingMode always returns NestingModeList. +func (a SingleNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeSingle +} + +// GetType returns ListType of ObjectType or CustomType. +func (a SingleNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + attrTypes := make(map[string]attr.Type, len(a.Attributes)) + + for name, attribute := range a.Attributes { + attrTypes[name] = attribute.GetType() + } + + return types.ObjectType{ + AttrTypes: attrTypes, + } +} + +// IsComputed returns the Computed field value. +func (a SingleNestedAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a SingleNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SingleNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a SingleNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ObjectValidators returns the Validators field value. +func (a SingleNestedAttribute) ObjectValidators() []validator.Object { + return a.Validators +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/single_nested_block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/single_nested_block.go new file mode 100644 index 00000000..926825a0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/single_nested_block.go @@ -0,0 +1,213 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Block = SingleNestedBlock{} + _ fwxschema.BlockWithObjectValidators = SingleNestedBlock{} +) + +// SingleNestedBlock represents a block that is a single object where +// the object attributes can be fully defined, including further attributes +// or blocks. When retrieving the value for this block, use types.Object +// as the value type unless the CustomType field is set. +// +// Prefer SingleNestedAttribute over SingleNestedBlock if the provider is +// using protocol version 6. Nested attributes allow practitioners to configure +// values directly with expressions. +// +// Terraform configurations configure this block only once using curly brace +// syntax without an equals (=) sign or [Dynamic Block Expressions]. +// +// # single block +// example_block { +// nested_attribute = #... +// } +// +// Terraform configurations reference this block using expressions that +// accept an object or an attribute name directly via period syntax: +// +// # object nested_attribute value +// .example_block.nested_attribute +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +type SingleNestedBlock struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Blocks names. + Attributes map[string]Attribute + + // Blocks is the mapping of underlying block names to block definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Attributes names. + Blocks map[string]Block + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is AttributeName, otherwise returns an error. +func (b SingleNestedBlock) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + name, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SingleNestedBlock", step) + } + + if attribute, ok := b.Attributes[string(name)]; ok { + return attribute, nil + } + + if block, ok := b.Blocks[string(name)]; ok { + return block, nil + } + + return nil, fmt.Errorf("no attribute or block %q on SingleNestedBlock", name) +} + +// Equal returns true if the given Attribute is b SingleNestedBlock +// and all fields are equal. +func (b SingleNestedBlock) Equal(o fwschema.Block) bool { + if _, ok := o.(SingleNestedBlock); !ok { + return false + } + + return fwschema.BlocksEqual(b, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (b SingleNestedBlock) GetDeprecationMessage() string { + return b.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (b SingleNestedBlock) GetDescription() string { + return b.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (b SingleNestedBlock) GetMarkdownDescription() string { + return b.MarkdownDescription +} + +// GetNestedObject returns a generated NestedBlockObject from the +// Attributes, CustomType, and Validators field values. +func (b SingleNestedBlock) GetNestedObject() fwschema.NestedBlockObject { + return NestedBlockObject{ + Attributes: b.Attributes, + Blocks: b.Blocks, + CustomType: b.CustomType, + Validators: b.Validators, + } +} + +// GetNestingMode always returns BlockNestingModeSingle. +func (b SingleNestedBlock) GetNestingMode() fwschema.BlockNestingMode { + return fwschema.BlockNestingModeSingle +} + +// ObjectValidators returns the Validators field value. +func (b SingleNestedBlock) ObjectValidators() []validator.Object { + return b.Validators +} + +// Type returns ObjectType or CustomType. +func (b SingleNestedBlock) Type() attr.Type { + if b.CustomType != nil { + return b.CustomType + } + + attrTypes := make(map[string]attr.Type, len(b.Attributes)+len(b.Blocks)) + + for name, attribute := range b.Attributes { + attrTypes[name] = attribute.GetType() + } + + for name, block := range b.Blocks { + attrTypes[name] = block.Type() + } + + return types.ObjectType{ + AttrTypes: attrTypes, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/string_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/string_attribute.go new file mode 100644 index 00000000..0c2dd9ab --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/schema/string_attribute.go @@ -0,0 +1,187 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = StringAttribute{} + _ fwxschema.AttributeWithStringValidators = StringAttribute{} +) + +// StringAttribute represents a schema attribute that is a string. When +// retrieving the value for this attribute, use types.String as the value type +// unless the CustomType field is set. +// +// Terraform configurations configure this attribute using expressions that +// return a string or directly via double quote syntax. +// +// example_attribute = "value" +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type StringAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.StringType. When retrieving data, the basetypes.StringValuable + // associated with this custom type must be used in place of types.String. + CustomType basetypes.StringTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.String +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a StringAttribute. +func (a StringAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a StringAttribute +// and all fields are equal. +func (a StringAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(StringAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a StringAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a StringAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a StringAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.StringType or the CustomType field value if defined. +func (a StringAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.StringType +} + +// IsComputed returns the Computed field value. +func (a StringAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a StringAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a StringAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a StringAttribute) IsSensitive() bool { + return a.Sensitive +} + +// StringValidators returns the Validators field value. +func (a StringAttribute) StringValidators() []validator.String { + return a.Validators +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/validate_config.go b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/validate_config.go new file mode 100644 index 00000000..048facd5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/datasource/validate_config.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package datasource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ValidateConfigRequest represents a request to validate the +// configuration of a data source. An instance of this request struct is +// supplied as an argument to the DataSource ValidateConfig receiver method +// or automatically passed through to each ConfigValidator. +type ValidateConfigRequest struct { + // Config is the configuration the user supplied for the data source. + // + // This configuration may contain unknown values if a user uses + // interpolation or other functionality that would prevent Terraform + // from knowing the value at request time. + Config tfsdk.Config +} + +// ValidateConfigResponse represents a response to a +// ValidateConfigRequest. An instance of this response struct is +// supplied as an argument to the DataSource ValidateConfig receiver method +// or automatically passed through to each ConfigValidator. +type ValidateConfigResponse struct { + // Diagnostics report errors or warnings related to validating the data + // source configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/diag/attribute_error_diagnostic.go b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/attribute_error_diagnostic.go new file mode 100644 index 00000000..9ae92e75 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/attribute_error_diagnostic.go @@ -0,0 +1,16 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package diag + +import ( + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// NewAttributeErrorDiagnostic returns a new error severity diagnostic with the given summary, detail, and path. +func NewAttributeErrorDiagnostic(path path.Path, summary string, detail string) DiagnosticWithPath { + return withPath{ + Diagnostic: NewErrorDiagnostic(summary, detail), + path: path, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/diag/attribute_warning_diagnostic.go b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/attribute_warning_diagnostic.go new file mode 100644 index 00000000..bb8c2f16 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/attribute_warning_diagnostic.go @@ -0,0 +1,16 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package diag + +import ( + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// NewAttributeWarningDiagnostic returns a new warning severity diagnostic with the given summary, detail, and path. +func NewAttributeWarningDiagnostic(path path.Path, summary string, detail string) DiagnosticWithPath { + return withPath{ + Diagnostic: NewWarningDiagnostic(summary, detail), + path: path, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/diag/diagnostic.go b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/diagnostic.go new file mode 100644 index 00000000..74af0143 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/diagnostic.go @@ -0,0 +1,53 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package diag + +import "github.com/hashicorp/terraform-plugin-framework/path" + +// Diagnostic is an interface for providing enhanced feedback. +// +// These are typically practitioner facing, however it is possible for +// functionality, such as validation, to use these to change behaviors or +// otherwise have these be manipulated or removed before being presented. +// +// See the ErrorDiagnostic and WarningDiagnostic concrete types for generic +// implementations. +// +// To add path information to an existing diagnostic, see the WithPath() +// function. +type Diagnostic interface { + // Severity returns the desired level of feedback for the diagnostic. + Severity() Severity + + // Summary is a short description for the diagnostic. + // + // Typically this is implemented as a title, such as "Invalid Resource Name", + // or single line sentence. + Summary() string + + // Detail is a long description for the diagnostic. + // + // This should contain all relevant information about why the diagnostic + // was generated and if applicable, ways to prevent the diagnostic. It + // should generally be written and formatted for human consumption by + // practitioners or provider developers. + Detail() string + + // Equal returns true if the other diagnostic is wholly equivalent. + Equal(Diagnostic) bool +} + +// DiagnosticWithPath is a diagnostic associated with an attribute path. +// +// This attribute information is used to display contextual source configuration +// to practitioners. +type DiagnosticWithPath interface { + Diagnostic + + // Path points to a specific value within an aggregate value. + // + // If present, this enables the display of source configuration context for + // supporting implementations such as Terraform CLI commands. + Path() path.Path +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/diag/diagnostics.go b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/diagnostics.go new file mode 100644 index 00000000..5b842cb2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/diagnostics.go @@ -0,0 +1,122 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package diag + +import ( + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Diagnostics represents a collection of diagnostics. +// +// While this collection is ordered, the order is not guaranteed as reliable +// or consistent. +type Diagnostics []Diagnostic + +// AddAttributeError adds a generic attribute error diagnostic to the collection. +func (diags *Diagnostics) AddAttributeError(path path.Path, summary string, detail string) { + diags.Append(NewAttributeErrorDiagnostic(path, summary, detail)) +} + +// AddAttributeWarning adds a generic attribute warning diagnostic to the collection. +func (diags *Diagnostics) AddAttributeWarning(path path.Path, summary string, detail string) { + diags.Append(NewAttributeWarningDiagnostic(path, summary, detail)) +} + +// AddError adds a generic error diagnostic to the collection. +func (diags *Diagnostics) AddError(summary string, detail string) { + diags.Append(NewErrorDiagnostic(summary, detail)) +} + +// AddWarning adds a generic warning diagnostic to the collection. +func (diags *Diagnostics) AddWarning(summary string, detail string) { + diags.Append(NewWarningDiagnostic(summary, detail)) +} + +// Append adds non-empty and non-duplicate diagnostics to the collection. +func (diags *Diagnostics) Append(in ...Diagnostic) { + for _, diag := range in { + if diag == nil { + continue + } + + if diags.Contains(diag) { + continue + } + *diags = append(*diags, diag) + } +} + +// Contains returns true if the collection contains an equal Diagnostic. +func (diags Diagnostics) Contains(in Diagnostic) bool { + for _, diag := range diags { + if diag.Equal(in) { + return true + } + } + + return false +} + +// Equal returns true if all given diagnostics are equivalent in order and +// content, based on the underlying (Diagnostic).Equal() method of each. +func (diags Diagnostics) Equal(other Diagnostics) bool { + if len(diags) != len(other) { + return false + } + + for diagIndex, diag := range diags { + if !diag.Equal(other[diagIndex]) { + return false + } + } + + return true +} + +// HasError returns true if the collection has an error severity Diagnostic. +func (diags Diagnostics) HasError() bool { + for _, diag := range diags { + if diag.Severity() == SeverityError { + return true + } + } + + return false +} + +// ErrorsCount returns the number of Diagnostic in Diagnostics that are SeverityError. +func (diags Diagnostics) ErrorsCount() int { + return len(diags.Errors()) +} + +// WarningsCount returns the number of Diagnostic in Diagnostics that are SeverityWarning. +func (diags Diagnostics) WarningsCount() int { + return len(diags.Warnings()) +} + +// Errors returns all the Diagnostic in Diagnostics that are SeverityError. +func (diags Diagnostics) Errors() Diagnostics { + dd := Diagnostics{} + + for _, d := range diags { + if SeverityError == d.Severity() { + dd = append(dd, d) + } + } + + return dd +} + +// Warnings returns all the Diagnostic in Diagnostics that are SeverityWarning. +func (diags Diagnostics) Warnings() Diagnostics { + dd := Diagnostics{} + + for _, d := range diags { + if SeverityWarning == d.Severity() { + dd = append(dd, d) + } + } + + return dd +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/diag/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/doc.go new file mode 100644 index 00000000..95e332d6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/doc.go @@ -0,0 +1,11 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package diag implements diagnostic functionality, which is a practitioner +// feedback mechanism for providers. It is designed for display in Terraform +// user interfaces, rather than logging based feedback, which is generally +// saved to a file for later inspection and troubleshooting. +// +// Practitioner feedback for provider defined functions is provided by the +// [function.FuncError] type, rather than the [diag.Diagnostic] type. +package diag diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/diag/error_diagnostic.go b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/error_diagnostic.go new file mode 100644 index 00000000..9edf5999 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/error_diagnostic.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package diag + +var _ Diagnostic = ErrorDiagnostic{} + +// ErrorDiagnostic is a generic diagnostic with error severity. +type ErrorDiagnostic struct { + detail string + summary string +} + +// Detail returns the diagnostic detail. +func (d ErrorDiagnostic) Detail() string { + return d.detail +} + +// Equal returns true if the other diagnostic is wholly equivalent. +func (d ErrorDiagnostic) Equal(other Diagnostic) bool { + ed, ok := other.(ErrorDiagnostic) + + if !ok { + return false + } + + return ed.Summary() == d.Summary() && ed.Detail() == d.Detail() +} + +// Severity returns the diagnostic severity. +func (d ErrorDiagnostic) Severity() Severity { + return SeverityError +} + +// Summary returns the diagnostic summary. +func (d ErrorDiagnostic) Summary() string { + return d.summary +} + +// NewErrorDiagnostic returns a new error severity diagnostic with the given summary and detail. +func NewErrorDiagnostic(summary string, detail string) ErrorDiagnostic { + return ErrorDiagnostic{ + detail: detail, + summary: summary, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/diag/severity.go b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/severity.go new file mode 100644 index 00000000..a145191c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/severity.go @@ -0,0 +1,41 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package diag + +// Severity represents the level of feedback for a diagnostic. +// +// Each severity implies behavior changes for the feedback and potentially the +// further execution of logic. +type Severity int + +const ( + // SeverityInvalid represents an undefined severity. + // + // It should not be used directly in implementations. + SeverityInvalid Severity = 0 + + // SeverityError represents a terminating condition. + // + // This can cause a failing status code for command line programs. + // + // Most implementations should return early when encountering an error. + SeverityError Severity = 1 + + // SeverityWarning represents a condition with explicit feedback. + // + // Most implementations should continue when encountering a warning. + SeverityWarning Severity = 2 +) + +// String returns a textual representation of the severity. +func (s Severity) String() string { + switch s { + case SeverityError: + return "Error" + case SeverityWarning: + return "Warning" + default: + return "Invalid" + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/diag/warning_diagnostic.go b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/warning_diagnostic.go new file mode 100644 index 00000000..27013e4f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/warning_diagnostic.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package diag + +var _ Diagnostic = WarningDiagnostic{} + +// WarningDiagnostic is a generic diagnostic with warning severity. +type WarningDiagnostic struct { + detail string + summary string +} + +// Detail returns the diagnostic detail. +func (d WarningDiagnostic) Detail() string { + return d.detail +} + +// Equal returns true if the other diagnostic is wholly equivalent. +func (d WarningDiagnostic) Equal(other Diagnostic) bool { + wd, ok := other.(WarningDiagnostic) + + if !ok { + return false + } + + return wd.Summary() == d.Summary() && wd.Detail() == d.Detail() +} + +// Severity returns the diagnostic severity. +func (d WarningDiagnostic) Severity() Severity { + return SeverityWarning +} + +// Summary returns the diagnostic summary. +func (d WarningDiagnostic) Summary() string { + return d.summary +} + +// NewErrorDiagnostic returns a new warning severity diagnostic with the given summary and detail. +func NewWarningDiagnostic(summary string, detail string) WarningDiagnostic { + return WarningDiagnostic{ + detail: detail, + summary: summary, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/diag/with_path.go b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/with_path.go new file mode 100644 index 00000000..f4292aa9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/diag/with_path.go @@ -0,0 +1,57 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package diag + +import ( + "github.com/hashicorp/terraform-plugin-framework/path" +) + +var _ DiagnosticWithPath = withPath{} + +// withPath wraps a diagnostic with path information. +type withPath struct { + Diagnostic + + path path.Path +} + +// Equal returns true if the other diagnostic is wholly equivalent. +func (d withPath) Equal(other Diagnostic) bool { + o, ok := other.(withPath) + + if !ok { + return false + } + + if !d.Path().Equal(o.Path()) { + return false + } + + if d.Diagnostic == nil { + return d.Diagnostic == o.Diagnostic + } + + return d.Diagnostic.Equal(o.Diagnostic) +} + +// Path returns the diagnostic path. +func (d withPath) Path() path.Path { + return d.path +} + +// WithPath wraps a diagnostic with path information or overwrites the path. +func WithPath(path path.Path, d Diagnostic) DiagnosticWithPath { + wp, ok := d.(withPath) + + if !ok { + return withPath{ + Diagnostic: d, + path: path, + } + } + + wp.path = path + + return wp +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/arguments_data.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/arguments_data.go new file mode 100644 index 00000000..40b4e00d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/arguments_data.go @@ -0,0 +1,173 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + fwreflect "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// ArgumentsData is the zero-based positional argument data sent by Terraform +// for a single function call. Use the Get method or GetArgument method in the +// Function type Run method to fetch the data. +// +// This data is automatically populated by the framework based on the function +// definition. For unit testing, use the NewArgumentsData function to manually +// create the data. +type ArgumentsData struct { + values []attr.Value +} + +// Equal returns true if all the underlying values are equivalent. +func (d ArgumentsData) Equal(o ArgumentsData) bool { + if len(d.values) != len(o.values) { + return false + } + + for index, value := range d.values { + if !value.Equal(o.values[index]) { + return false + } + } + + return true +} + +// Get retrieves all argument data and populates the targets with the values. +// All arguments must be present in the targets, including all parameters and an +// optional variadic parameter, otherwise an error diagnostic will be raised. +// Each target type must be acceptable for the data type in the parameter +// definition. +// +// Variadic parameter argument data must be consumed by a types.Tuple or Go slice +// type with an element type appropriate for the parameter definition ([]T). The +// framework automatically populates this tuple with elements matching the zero, +// one, or more arguments passed. +func (d ArgumentsData) Get(ctx context.Context, targets ...any) *FuncError { + var funcErr *FuncError + + if len(d.values) == 0 { + errMsg := "Invalid Argument Data Usage: When attempting to fetch argument data during the function call, the provider code incorrectly attempted to read argument data. " + + "This is always an issue in the provider code and should be reported to the provider developers.\n\n" + + "Function does not have argument data." + + funcErr = ConcatFuncErrors(funcErr, NewFuncError(errMsg)) + + return funcErr + } + + if len(targets) != len(d.values) { + errMsg := "Invalid Argument Data Usage: When attempting to fetch argument data during the function call, the provider code incorrectly attempted to read argument data. " + + "The Get call requires all parameters and the final variadic parameter, if implemented, to be in the targets. " + + "This is always an error in the provider code and should be reported to the provider developers.\n\n" + + fmt.Sprintf("Given targets count: %d, expected targets count: %d", len(targets), len(d.values)) + + funcErr = ConcatFuncErrors(funcErr, NewFuncError(errMsg)) + + return funcErr + } + + for position, attrValue := range d.values { + target := targets[position] + + if fwreflect.IsGenericAttrValue(ctx, target) { + //nolint:forcetypeassert // Type assertion is guaranteed by the above `reflect.IsGenericAttrValue` function + *(target.(*attr.Value)) = attrValue + + continue + } + + tfValue, tfValueErr := attrValue.ToTerraformValue(ctx) + + if tfValueErr != nil { + errMsg := fmt.Sprintf("Argument Value Conversion Error: An unexpected error was encountered converting a %T to its equivalent Terraform representation. "+ + "This is always an error in the provider code and should be reported to the provider developers.\n\n"+ + "Position: %d\n"+ + "Error: %s", + attrValue, position, tfValueErr) + + funcErr = ConcatFuncErrors(funcErr, NewArgumentFuncError(int64(position), errMsg)) + + continue + } + + reflectDiags := fwreflect.Into(ctx, attrValue.Type(ctx), tfValue, target, fwreflect.Options{}, path.Empty()) + + funcErr = ConcatFuncErrors(funcErr, FuncErrorFromDiags(ctx, reflectDiags)) + } + + return funcErr +} + +// GetArgument retrieves the argument data found at the given zero-based +// position and populates the target with the value. The target type must be +// acceptable for the data type in the parameter definition. +// +// Variadic parameter argument data must be consumed by a types.Tuple or Go slice +// type with an element type appropriate for the parameter definition ([]T) at +// the position after all parameters. The framework automatically populates this +// tuple with elements matching the zero, one, or more arguments passed. +func (d ArgumentsData) GetArgument(ctx context.Context, position int, target any) *FuncError { + var funcErr *FuncError + + if len(d.values) == 0 { + errMsg := "Invalid Argument Data Usage: When attempting to fetch argument data during the function call, the provider code incorrectly attempted to read argument data. " + + "This is always an issue in the provider code and should be reported to the provider developers.\n\n" + + "Function does not have argument data." + + funcErr = ConcatFuncErrors(funcErr, NewArgumentFuncError(int64(position), errMsg)) + + return funcErr + } + + if position >= len(d.values) { + errMsg := "Invalid Argument Data Position: When attempting to fetch argument data during the function call, the provider code attempted to read a non-existent argument position. " + + "Function argument positions are 0-based and any final variadic parameter is represented as one argument position with a tuple where each element " + + "type matches the parameter data type. This is always an error in the provider code and should be reported to the provider developers.\n\n" + + fmt.Sprintf("Given argument position: %d, last argument position: %d", position, len(d.values)-1) + + funcErr = ConcatFuncErrors(funcErr, NewArgumentFuncError(int64(position), errMsg)) + + return funcErr + } + + attrValue := d.values[position] + + if fwreflect.IsGenericAttrValue(ctx, target) { + //nolint:forcetypeassert // Type assertion is guaranteed by the above `reflect.IsGenericAttrValue` function + *(target.(*attr.Value)) = attrValue + + return nil + } + + tfValue, err := attrValue.ToTerraformValue(ctx) + + if err != nil { + errMsg := fmt.Sprintf("Argument Value Conversion Error: An unexpected error was encountered converting a %T to its equivalent Terraform representation. "+ + "This is always an error in the provider code and should be reported to the provider developers.\n\n"+ + "Error: %s", attrValue, err) + + funcErr = ConcatFuncErrors(funcErr, NewArgumentFuncError(int64(position), errMsg)) + + return funcErr + } + + reflectDiags := fwreflect.Into(ctx, attrValue.Type(ctx), tfValue, target, fwreflect.Options{}, path.Empty()) + + funcErr = ConcatFuncErrors(funcErr, FuncErrorFromDiags(ctx, reflectDiags)) + + return funcErr +} + +// NewArgumentsData creates an ArgumentsData. This is only necessary for unit +// testing as the framework automatically creates this data. +func NewArgumentsData(values []attr.Value) ArgumentsData { + return ArgumentsData{ + values: values, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_parameter.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_parameter.go new file mode 100644 index 00000000..67929c31 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_parameter.go @@ -0,0 +1,117 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Parameter = BoolParameter{} +var _ ParameterWithBoolValidators = BoolParameter{} + +// BoolParameter represents a function parameter that is a boolean. +// +// When retrieving the argument value for this parameter: +// +// - If CustomType is set, use its associated value type. +// - If AllowUnknownValues is enabled, you must use the [types.Bool] value +// type. +// - If AllowNullValue is enabled, you must use [types.Bool] or *bool +// value types. +// - Otherwise, use [types.Bool] or *bool, or bool value types. +// +// Terraform configurations set this parameter's argument data using expressions +// that return a bool or directly via true/false keywords. +type BoolParameter struct { + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the function. When disabled, Terraform returns an error if the + // argument value is null. + // + // Enabling this requires reading argument values as *bool or [types.Bool]. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that an unknown argument value + // can be passed to the function. When disabled, Terraform skips the + // function call entirely and assumes an unknown value result from the + // function. + // + // Enabling this requires reading argument values as [types.Bool]. + AllowUnknownValues bool + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.BoolType]. When retrieving data, the + // [basetypes.BoolValuable] implementation associated with this custom + // type must be used in place of [types.Bool]. + CustomType basetypes.BoolTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this parameter is, + // what it is for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this parameter is, what it is for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // Name is a short usage name for the parameter, such as "data". This name + // is used in documentation, such as generating a function signature, + // however its usage may be extended in the future. + // + // If no name is provided, this will default to "param" with a suffix of the + // position the parameter is in the function definition. ("param1", "param2", etc.) + // If the parameter is variadic, the default name will be "varparam". + // + // This must be a valid Terraform identifier, such as starting with an + // alphabetical character and followed by alphanumeric or underscore + // characters. + Name string + + // Validators is a list of bool validators that should be applied to the + // parameter. + Validators []BoolParameterValidator +} + +// GetValidators returns the list of validators for the parameter. +func (p BoolParameter) GetValidators() []BoolParameterValidator { + return p.Validators +} + +// GetAllowNullValue returns if the parameter accepts a null value. +func (p BoolParameter) GetAllowNullValue() bool { + return p.AllowNullValue +} + +// GetAllowUnknownValues returns if the parameter accepts an unknown value. +func (p BoolParameter) GetAllowUnknownValues() bool { + return p.AllowUnknownValues +} + +// GetDescription returns the parameter plaintext description. +func (p BoolParameter) GetDescription() string { + return p.Description +} + +// GetMarkdownDescription returns the parameter Markdown description. +func (p BoolParameter) GetMarkdownDescription() string { + return p.MarkdownDescription +} + +// GetName returns the parameter name. +func (p BoolParameter) GetName() string { + return p.Name +} + +// GetType returns the parameter data type. +func (p BoolParameter) GetType() attr.Type { + if p.CustomType != nil { + return p.CustomType + } + + return basetypes.BoolType{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_parameter_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_parameter_validator.go new file mode 100644 index 00000000..145519af --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_parameter_validator.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// BoolParameterValidator is a function validator for types.Bool parameters. +type BoolParameterValidator interface { + + // ValidateParameterBool performs the validation. + ValidateParameterBool(context.Context, BoolParameterValidatorRequest, *BoolParameterValidatorResponse) +} + +// BoolParameterValidatorRequest is a request for types.Bool schema validation. +type BoolParameterValidatorRequest struct { + // ArgumentPosition contains the position of the argument for validation. + // Use this position for any response diagnostics. + ArgumentPosition int64 + + // Value contains the value of the argument for validation. + Value types.Bool +} + +// BoolParameterValidatorResponse is a response to a BoolParameterValidatorRequest. +type BoolParameterValidatorResponse struct { + // Error is a function error generated during validation of the Value. + Error *FuncError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_return.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_return.go new file mode 100644 index 00000000..0410b38e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/bool_return.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Return = BoolReturn{} + +// BoolReturn represents a function return that is a boolean. +// +// When setting the value for this return: +// +// - If CustomType is set, use its associated value type. +// - Otherwise, use [types.Bool], *bool, or bool. +type BoolReturn struct { + // CustomType enables the use of a custom data type in place of the + // default [basetypes.BoolType]. When setting data, the + // [basetypes.BoolValuable] implementation associated with this custom + // type must be used in place of [types.Bool]. + CustomType basetypes.BoolTypable +} + +// GetType returns the return data type. +func (r BoolReturn) GetType() attr.Type { + if r.CustomType != nil { + return r.CustomType + } + + return basetypes.BoolType{} +} + +// NewResultData returns a new result data based on the type. +func (r BoolReturn) NewResultData(ctx context.Context) (ResultData, *FuncError) { + value := basetypes.NewBoolUnknown() + + if r.CustomType == nil { + return NewResultData(value), nil + } + + valuable, diags := r.CustomType.ValueFromBool(ctx, value) + + return NewResultData(valuable), FuncErrorFromDiags(ctx, diags) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/definition.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/definition.go new file mode 100644 index 00000000..aafb8d02 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/definition.go @@ -0,0 +1,194 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwfunction" +) + +// Definition is a function definition. Always set at least the Result field. +type Definition struct { + // Parameters is the ordered list of function parameters and their + // associated data types. + Parameters []Parameter + + // VariadicParameter is an optional final parameter which can accept zero or + // more arguments when the function is called. The argument data is sent as + // a tuple, where all elements are of the same associated data type. + VariadicParameter Parameter + + // Return is the function call response data type. + Return Return + + // Summary is a short description of the function, preferably a single + // sentence. Use the Description field for longer documentation about the + // function and its implementation. + Summary string + + // Description is the longer documentation for usage, such as editor + // integrations, to give practitioners more information about the purpose of + // the function and how its logic is implemented. It should be plaintext + // formatted. + Description string + + // MarkdownDescription is the longer documentation for usage, such as a + // registry, to give practitioners more information about the purpose of the + // function and how its logic is implemented. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this function. The warning diagnostic + // summary is automatically set to "Function Deprecated" along with + // configuration source file and line information. + DeprecationMessage string +} + +// ValidateImplementation contains logic for validating the provider-defined +// implementation of the definition to prevent unexpected errors or panics. This +// logic runs during the GetProviderSchema RPC, or via provider-defined unit +// testing, and should never include false positives. +func (d Definition) ValidateImplementation(ctx context.Context, req DefinitionValidateRequest, resp *DefinitionValidateResponse) { + var diags diag.Diagnostics + + if d.Return == nil { + diags.AddError( + "Invalid Function Definition", + "When validating the function definition, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Function %q - Definition Return field is undefined", req.FuncName), + ) + } else if d.Return.GetType() == nil { + diags.AddError( + "Invalid Function Definition", + "When validating the function definition, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Function %q - Definition return data type is undefined", req.FuncName), + ) + } else if returnWithValidateImplementation, ok := d.Return.(fwfunction.ReturnWithValidateImplementation); ok { + req := fwfunction.ValidateReturnImplementationRequest{} + resp := &fwfunction.ValidateReturnImplementationResponse{} + + returnWithValidateImplementation.ValidateImplementation(ctx, req, resp) + + diags.Append(resp.Diagnostics...) + } + + paramNames := make(map[string]int, len(d.Parameters)) + for pos, param := range d.Parameters { + parameterPosition := int64(pos) + name := param.GetName() + // If name is not set, add an error diagnostic, parameter names are mandatory. + if name == "" { + diags.AddError( + "Invalid Function Definition", + "When validating the function definition, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Function %q - Parameter at position %d does not have a name", req.FuncName, pos), + ) + } + + if paramWithValidateImplementation, ok := param.(fwfunction.ParameterWithValidateImplementation); ok { + req := fwfunction.ValidateParameterImplementationRequest{ + Name: name, + ParameterPosition: ¶meterPosition, + } + resp := &fwfunction.ValidateParameterImplementationResponse{} + + paramWithValidateImplementation.ValidateImplementation(ctx, req, resp) + + diags.Append(resp.Diagnostics...) + } + + conflictPos, exists := paramNames[name] + if exists && name != "" { + diags.AddError( + "Invalid Function Definition", + "When validating the function definition, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + "Parameter names must be unique. "+ + fmt.Sprintf("Function %q - Parameters at position %d and %d have the same name %q", req.FuncName, conflictPos, pos, name), + ) + continue + } + + paramNames[name] = pos + } + + if d.VariadicParameter != nil { + name := d.VariadicParameter.GetName() + // If name is not set, add an error diagnostic, parameter names are mandatory. + if name == "" { + diags.AddError( + "Invalid Function Definition", + "When validating the function definition, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Function %q - The variadic parameter does not have a name", req.FuncName), + ) + } + + if paramWithValidateImplementation, ok := d.VariadicParameter.(fwfunction.ParameterWithValidateImplementation); ok { + req := fwfunction.ValidateParameterImplementationRequest{ + Name: name, + } + resp := &fwfunction.ValidateParameterImplementationResponse{} + + paramWithValidateImplementation.ValidateImplementation(ctx, req, resp) + + diags.Append(resp.Diagnostics...) + } + + conflictPos, exists := paramNames[name] + if exists && name != "" { + diags.AddError( + "Invalid Function Definition", + "When validating the function definition, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + "Parameter names must be unique. "+ + fmt.Sprintf("Function %q - Parameter at position %d and the variadic parameter have the same name %q", req.FuncName, conflictPos, name), + ) + } + } + + resp.Diagnostics.Append(diags...) +} + +// DefinitionRequest represents a request for the Function to return its +// definition, such as its ordered parameters and result. An instance of this +// request struct is supplied as an argument to the Function type Definition +// method. +type DefinitionRequest struct{} + +// DefinitionResponse represents a response to a DefinitionRequest. An instance +// of this response struct is supplied as an argument to the Function type +// Definition method. Always set at least the Definition field. +type DefinitionResponse struct { + // Definition is the function definition. + Definition Definition + + // Diagnostics report errors or warnings related to defining the function. + // An empty slice indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics +} + +// DefinitionValidateRequest represents a request for the Function to validate its +// definition. An instance of this request struct is supplied as an argument to +// the Definition type ValidateImplementation method. +type DefinitionValidateRequest struct { + // FuncName is the name of the function definition being validated. + FuncName string +} + +// DefinitionValidateResponse represents a response to a DefinitionValidateRequest. +// An instance of this response struct is supplied as an argument to the Definition +// type ValidateImplementation method. +type DefinitionValidateResponse struct { + // Diagnostics report errors or warnings related to validation of a function + // definition. An empty slice indicates success, with no warnings or errors + // generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/doc.go new file mode 100644 index 00000000..2c71069b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/doc.go @@ -0,0 +1,21 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package function contains all interfaces, request types, and response +// types for a Terraform Provider function implementation. +// +// In Terraform, a function is a concept which enables provider developers +// to offer practitioners a pure function call in their configuration. Functions +// are defined by a function name, such as "parse_xyz", a definition +// representing the ordered list of parameters with associated data types and +// a result data type, and the function logic. +// +// The main starting point for implementations in this package is the +// [Function] type which represents an instance of a function that has its own +// argument data when called. The [Function] implementations are referenced by a +// [provider.Provider] type Functions method, which enables the function for +// practitioner and testing usage. +// +// Practitioner feedback is provided by the [FuncError] type, rather than +// the [diag.Diagnostic] type. +package function diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_parameter.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_parameter.go new file mode 100644 index 00000000..cbf2ea33 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_parameter.go @@ -0,0 +1,112 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Parameter = DynamicParameter{} +var _ ParameterWithDynamicValidators = DynamicParameter{} + +// DynamicParameter represents a function parameter that is a dynamic, rather +// than a static type. Static types are always preferable over dynamic +// types in Terraform as practitioners will receive less helpful configuration +// assistance from validation error diagnostics and editor integrations. +// +// When retrieving the argument value for this parameter: +// +// - If CustomType is set, use its associated value type. +// - Otherwise, use the [types.Dynamic] value type. +// +// The concrete value type for a dynamic is determined at runtime by Terraform, +// if defined in the configuration. +type DynamicParameter struct { + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the function. When disabled, Terraform returns an error if the + // argument value is null. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that an unknown argument value + // can be passed to the function. When disabled, Terraform skips the + // function call entirely and assumes an unknown value result from the + // function. + AllowUnknownValues bool + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.DynamicType]. When retrieving data, the + // [basetypes.DynamicValuable] implementation associated with this custom + // type must be used in place of [types.Dynamic]. + CustomType basetypes.DynamicTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this parameter is, + // what it is for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this parameter is, what it is for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // Name is a short usage name for the parameter, such as "data". This name + // is used in documentation, such as generating a function signature, + // however its usage may be extended in the future. + // + // If no name is provided, this will default to "param" with a suffix of the + // position the parameter is in the function definition. ("param1", "param2", etc.) + // If the parameter is variadic, the default name will be "varparam". + // + // This must be a valid Terraform identifier, such as starting with an + // alphabetical character and followed by alphanumeric or underscore + // characters. + Name string + + // Validators is a list of dynamic validators that should be applied to the + // parameter. + Validators []DynamicParameterValidator +} + +// GetValidators returns the list of validators for the parameter. +func (p DynamicParameter) GetValidators() []DynamicParameterValidator { + return p.Validators +} + +// GetAllowNullValue returns if the parameter accepts a null value. +func (p DynamicParameter) GetAllowNullValue() bool { + return p.AllowNullValue +} + +// GetAllowUnknownValues returns if the parameter accepts an unknown value. +func (p DynamicParameter) GetAllowUnknownValues() bool { + return p.AllowUnknownValues +} + +// GetDescription returns the parameter plaintext description. +func (p DynamicParameter) GetDescription() string { + return p.Description +} + +// GetMarkdownDescription returns the parameter Markdown description. +func (p DynamicParameter) GetMarkdownDescription() string { + return p.MarkdownDescription +} + +// GetName returns the parameter name. +func (p DynamicParameter) GetName() string { + return p.Name +} + +// GetType returns the parameter data type. +func (p DynamicParameter) GetType() attr.Type { + if p.CustomType != nil { + return p.CustomType + } + + return basetypes.DynamicType{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_parameter_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_parameter_validator.go new file mode 100644 index 00000000..43c6e1a4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_parameter_validator.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// DynamicParameterValidator is a function validator for types.Dynamic parameters. +type DynamicParameterValidator interface { + + // ValidateParameterDynamic performs the validation. + ValidateParameterDynamic(context.Context, DynamicParameterValidatorRequest, *DynamicParameterValidatorResponse) +} + +// DynamicParameterValidatorRequest is a request for types.Dynamic schema validation. +type DynamicParameterValidatorRequest struct { + // ArgumentPosition contains the position of the argument for validation. + // Use this position for any response diagnostics. + ArgumentPosition int64 + + // Value contains the value of the argument for validation. + Value types.Dynamic +} + +// DynamicParameterValidatorResponse is a response to a DynamicParameterValidatorRequest. +type DynamicParameterValidatorResponse struct { + // Error is a function error generated during validation of the Value. + Error *FuncError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_return.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_return.go new file mode 100644 index 00000000..bab38f85 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/dynamic_return.go @@ -0,0 +1,53 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Return = DynamicReturn{} + +// DynamicReturn represents a function return that is a dynamic, rather +// than a static type. Static types are always preferable over dynamic +// types in Terraform as practitioners will receive less helpful configuration +// assistance from validation error diagnostics and editor integrations. +// +// When setting the value for this return: +// +// - If CustomType is set, use its associated value type. +// - Otherwise, use the [types.Dynamic] value type. +type DynamicReturn struct { + // CustomType enables the use of a custom data type in place of the + // default [basetypes.DynamicType]. When setting data, the + // [basetypes.DynamicValuable] implementation associated with this custom + // type must be used in place of [types.Dynamic]. + CustomType basetypes.DynamicTypable +} + +// GetType returns the return data type. +func (r DynamicReturn) GetType() attr.Type { + if r.CustomType != nil { + return r.CustomType + } + + return basetypes.DynamicType{} +} + +// NewResultData returns a new result data based on the type. +func (r DynamicReturn) NewResultData(ctx context.Context) (ResultData, *FuncError) { + value := basetypes.NewDynamicUnknown() + + if r.CustomType == nil { + return NewResultData(value), nil + } + + valuable, diags := r.CustomType.ValueFromDynamic(ctx, value) + + return NewResultData(valuable), FuncErrorFromDiags(ctx, diags) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_parameter.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_parameter.go new file mode 100644 index 00000000..11e31c7e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_parameter.go @@ -0,0 +1,114 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Parameter = Float64Parameter{} +var _ ParameterWithFloat64Validators = Float64Parameter{} + +// Float64Parameter represents a function parameter that is a 64-bit floating +// point number. +// +// When retrieving the argument value for this parameter: +// +// - If CustomType is set, use its associated value type. +// - If AllowUnknownValues is enabled, you must use the [types.Float64] value +// type. +// - If AllowNullValue is enabled, you must use [types.Float64] or *float64 +// value types. +// - Otherwise, use [types.Float64] or *float64, or float64 value types. +// +// Terraform configurations set this parameter's argument data using expressions +// that return a number or directly via numeric syntax. +type Float64Parameter struct { + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the function. When disabled, Terraform returns an error if the + // argument value is null. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that an unknown argument value + // can be passed to the function. When disabled, Terraform skips the + // function call entirely and assumes an unknown value result from the + // function. + AllowUnknownValues bool + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.Float64Type]. When retrieving data, the + // [basetypes.Float64Valuable] implementation associated with this custom + // type must be used in place of [types.Float64]. + CustomType basetypes.Float64Typable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this parameter is, + // what it is for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this parameter is, what it is for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // Name is a short usage name for the parameter, such as "data". This name + // is used in documentation, such as generating a function signature, + // however its usage may be extended in the future. + // + // If no name is provided, this will default to "param" with a suffix of the + // position the parameter is in the function definition. ("param1", "param2", etc.) + // If the parameter is variadic, the default name will be "varparam". + // + // This must be a valid Terraform identifier, such as starting with an + // alphabetical character and followed by alphanumeric or underscore + // characters. + Name string + + // Validators is a list of float64 validators that should be applied to the + // parameter. + Validators []Float64ParameterValidator +} + +// GetValidators returns the list of validators for the parameter. +func (p Float64Parameter) GetValidators() []Float64ParameterValidator { + return p.Validators +} + +// GetAllowNullValue returns if the parameter accepts a null value. +func (p Float64Parameter) GetAllowNullValue() bool { + return p.AllowNullValue +} + +// GetAllowUnknownValues returns if the parameter accepts an unknown value. +func (p Float64Parameter) GetAllowUnknownValues() bool { + return p.AllowUnknownValues +} + +// GetDescription returns the parameter plaintext description. +func (p Float64Parameter) GetDescription() string { + return p.Description +} + +// GetMarkdownDescription returns the parameter Markdown description. +func (p Float64Parameter) GetMarkdownDescription() string { + return p.MarkdownDescription +} + +// GetName returns the parameter name. +func (p Float64Parameter) GetName() string { + return p.Name +} + +// GetType returns the parameter data type. +func (p Float64Parameter) GetType() attr.Type { + if p.CustomType != nil { + return p.CustomType + } + + return basetypes.Float64Type{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_parameter_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_parameter_validator.go new file mode 100644 index 00000000..07612888 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_parameter_validator.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Float64ParameterValidator is a function validator for types.Float64 parameters. +type Float64ParameterValidator interface { + + // ValidateParameterFloat64 performs the validation. + ValidateParameterFloat64(context.Context, Float64ParameterValidatorRequest, *Float64ParameterValidatorResponse) +} + +// Float64ParameterValidatorRequest is a request for types.Float64 schema validation. +type Float64ParameterValidatorRequest struct { + // ArgumentPosition contains the position of the argument for validation. + // Use this position for any response diagnostics. + ArgumentPosition int64 + + // Value contains the value of the argument for validation. + Value types.Float64 +} + +// Float64ParameterValidatorResponse is a response to a Float64ParameterValidatorRequest. +type Float64ParameterValidatorResponse struct { + // Error is a function error generated during validation of the Value. + Error *FuncError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_return.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_return.go new file mode 100644 index 00000000..e653c2d3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/float64_return.go @@ -0,0 +1,51 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Return = Float64Return{} + +// Float64Return represents a function return that is a 64-bit floating point +// number. +// +// When setting the value for this return: +// +// - If CustomType is set, use its associated value type. +// - Otherwise, use [types.Float64], *float64, or float64. +type Float64Return struct { + // CustomType enables the use of a custom data type in place of the + // default [basetypes.Float64Type]. When setting data, the + // [basetypes.Float64Valuable] implementation associated with this custom + // type must be used in place of [types.Float64]. + CustomType basetypes.Float64Typable +} + +// GetType returns the return data type. +func (r Float64Return) GetType() attr.Type { + if r.CustomType != nil { + return r.CustomType + } + + return basetypes.Float64Type{} +} + +// NewResultData returns a new result data based on the type. +func (r Float64Return) NewResultData(ctx context.Context) (ResultData, *FuncError) { + value := basetypes.NewFloat64Unknown() + + if r.CustomType == nil { + return NewResultData(value), nil + } + + valuable, diags := r.CustomType.ValueFromFloat64(ctx, value) + + return NewResultData(valuable), FuncErrorFromDiags(ctx, diags) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/func_error.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/func_error.go new file mode 100644 index 00000000..4ce870a2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/func_error.go @@ -0,0 +1,129 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-log/tflog" + + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +// NewFuncError returns a new function error with the +// given message. +func NewFuncError(text string) *FuncError { + return &FuncError{ + Text: text, + } +} + +// NewArgumentFuncError returns a new function error with the +// given message and function argument. +func NewArgumentFuncError(functionArgument int64, text string) *FuncError { + return &FuncError{ + Text: text, + FunctionArgument: &functionArgument, + } +} + +// FuncError is an error type specifically for function errors. +type FuncError struct { + // Text is a practitioner-oriented description of the problem. This should + // contain sufficient detail to provide both general and more specific information + // regarding the issue. For example "Error executing function: foo can only contain + // letters, numbers, and digits." + Text string + // FunctionArgument is a zero-based, int64 value that identifies the specific + // function argument position that caused the error. Only errors that pertain + // to a function argument will include this information. + FunctionArgument *int64 +} + +// Equal returns true if the other function error is wholly equivalent. +func (fe *FuncError) Equal(other *FuncError) bool { + if fe == nil && other == nil { + return true + } + + if fe == nil || other == nil { + return false + } + + if fe.Text != other.Text { + return false + } + + if fe.FunctionArgument == nil && other.FunctionArgument == nil { + return true + } + + if fe.FunctionArgument == nil || other.FunctionArgument == nil { + return false + } + + return *fe.FunctionArgument == *other.FunctionArgument +} + +// Error returns the error text. +func (fe *FuncError) Error() string { + if fe == nil { + return "" + } + + return fe.Text +} + +// ConcatFuncErrors returns a new function error with the text from all supplied +// function errors concatenated together. If any of the function errors have a +// function argument, the first one encountered will be used. +func ConcatFuncErrors(funcErrs ...*FuncError) *FuncError { + var text string + var functionArgument *int64 + + for _, f := range funcErrs { + if f == nil { + continue + } + + if text != "" && f.Text != "" { + text += "\n" + } + + text += f.Text + + if functionArgument == nil { + functionArgument = f.FunctionArgument + } + } + + if text != "" || functionArgument != nil { + return &FuncError{ + Text: text, + FunctionArgument: functionArgument, + } + } + + return nil +} + +// FuncErrorFromDiags iterates over the given diagnostics and returns a new function error +// with the summary and detail text from all error diagnostics concatenated together. +// Diagnostics with a severity of warning are logged but are not included in the returned +// function error. +func FuncErrorFromDiags(ctx context.Context, diags diag.Diagnostics) *FuncError { + var funcErr *FuncError + + for _, d := range diags { + switch d.Severity() { + case diag.SeverityError: + funcErr = ConcatFuncErrors(funcErr, NewFuncError(fmt.Sprintf("%s: %s", d.Summary(), d.Detail()))) + case diag.SeverityWarning: + tflog.Warn(ctx, "warning: call function", map[string]interface{}{"summary": d.Summary(), "detail": d.Detail()}) + } + } + + return funcErr +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/function.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/function.go new file mode 100644 index 00000000..87a83043 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/function.go @@ -0,0 +1,26 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" +) + +// Function represents an instance of a function. This is the core interface +// that all functions must implement. +// +// Provider-defined functions are supported in Terraform version 1.8 and later. +type Function interface { + // Metadata should return the name of the function, such as parse_xyz. + Metadata(context.Context, MetadataRequest, *MetadataResponse) + + // Definition should return the definition for the function. + Definition(context.Context, DefinitionRequest, *DefinitionResponse) + + // Run should return the result of the function logic. It is called when + // Terraform reaches a function call in the configuration. Argument data + // values should be read from the [RunRequest] and the result value set in + // the [RunResponse]. + Run(context.Context, RunRequest, *RunResponse) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_parameter.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_parameter.go new file mode 100644 index 00000000..15a9700a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_parameter.go @@ -0,0 +1,113 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Parameter = Int64Parameter{} +var _ ParameterWithInt64Validators = Int64Parameter{} + +// Int64Parameter represents a function parameter that is a 64-bit integer. +// +// When retrieving the argument value for this parameter: +// +// - If CustomType is set, use its associated value type. +// - If AllowUnknownValues is enabled, you must use the [types.Int64] value +// type. +// - If AllowNullValue is enabled, you must use [types.Int64] or *int64 +// value types. +// - Otherwise, use [types.Int64] or *int64, or int64 value types. +// +// Terraform configurations set this parameter's argument data using expressions +// that return a number or directly via numeric syntax. +type Int64Parameter struct { + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the function. When disabled, Terraform returns an error if the + // argument value is null. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that an unknown argument value + // can be passed to the function. When disabled, Terraform skips the + // function call entirely and assumes an unknown value result from the + // function. + AllowUnknownValues bool + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.Int64Type]. When retrieving data, the + // [basetypes.Int64Valuable] implementation associated with this custom + // type must be used in place of [types.Int64]. + CustomType basetypes.Int64Typable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this parameter is, + // what it is for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this parameter is, what it is for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // Name is a short usage name for the parameter, such as "data". This name + // is used in documentation, such as generating a function signature, + // however its usage may be extended in the future. + // + // If no name is provided, this will default to "param" with a suffix of the + // position the parameter is in the function definition. ("param1", "param2", etc.) + // If the parameter is variadic, the default name will be "varparam". + // + // This must be a valid Terraform identifier, such as starting with an + // alphabetical character and followed by alphanumeric or underscore + // characters. + Name string + + // Validators is a list of int64 validators that should be applied to the + // parameter. + Validators []Int64ParameterValidator +} + +// GetValidators returns the list of validators for the parameter. +func (p Int64Parameter) GetValidators() []Int64ParameterValidator { + return p.Validators +} + +// GetAllowNullValue returns if the parameter accepts a null value. +func (p Int64Parameter) GetAllowNullValue() bool { + return p.AllowNullValue +} + +// GetAllowUnknownValues returns if the parameter accepts an unknown value. +func (p Int64Parameter) GetAllowUnknownValues() bool { + return p.AllowUnknownValues +} + +// GetDescription returns the parameter plaintext description. +func (p Int64Parameter) GetDescription() string { + return p.Description +} + +// GetMarkdownDescription returns the parameter Markdown description. +func (p Int64Parameter) GetMarkdownDescription() string { + return p.MarkdownDescription +} + +// GetName returns the parameter name. +func (p Int64Parameter) GetName() string { + return p.Name +} + +// GetType returns the parameter data type. +func (p Int64Parameter) GetType() attr.Type { + if p.CustomType != nil { + return p.CustomType + } + + return basetypes.Int64Type{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_parameter_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_parameter_validator.go new file mode 100644 index 00000000..d938c4b9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_parameter_validator.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Int64ParameterValidator is a function validator for types.Int64 parameters. +type Int64ParameterValidator interface { + + // ValidateParameterInt64 performs the validation. + ValidateParameterInt64(context.Context, Int64ParameterValidatorRequest, *Int64ParameterValidatorResponse) +} + +// Int64ParameterValidatorRequest is a request for types.Int64 schema validation. +type Int64ParameterValidatorRequest struct { + // ArgumentPosition contains the position of the argument for validation. + // Use this position for any response diagnostics. + ArgumentPosition int64 + + // Value contains the value of the argument for validation. + Value types.Int64 +} + +// Int64ParameterValidatorResponse is a response to a Int64ParameterValidatorRequest. +type Int64ParameterValidatorResponse struct { + // Error is a function error generated during validation of the Value. + Error *FuncError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_return.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_return.go new file mode 100644 index 00000000..b7345b65 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/int64_return.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Return = Int64Return{} + +// Int64Return represents a function return that is a 64-bit integer number. +// +// When setting the value for this return: +// +// - If CustomType is set, use its associated value type. +// - Otherwise, use [types.Int64], *int64, or int64. +type Int64Return struct { + // CustomType enables the use of a custom data type in place of the + // default [basetypes.Int64Type]. When setting data, the + // [basetypes.Int64Valuable] implementation associated with this custom + // type must be used in place of [types.Int64]. + CustomType basetypes.Int64Typable +} + +// GetType returns the return data type. +func (r Int64Return) GetType() attr.Type { + if r.CustomType != nil { + return r.CustomType + } + + return basetypes.Int64Type{} +} + +// NewResultData returns a new result data based on the type. +func (r Int64Return) NewResultData(ctx context.Context) (ResultData, *FuncError) { + value := basetypes.NewInt64Unknown() + + if r.CustomType == nil { + return NewResultData(value), nil + } + + valuable, diags := r.CustomType.ValueFromInt64(ctx, value) + + return NewResultData(valuable), FuncErrorFromDiags(ctx, diags) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/list_parameter.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/list_parameter.go new file mode 100644 index 00000000..cdca5a28 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/list_parameter.go @@ -0,0 +1,148 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwfunction" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Parameter = ListParameter{} + _ fwfunction.ParameterWithValidateImplementation = ListParameter{} + _ ParameterWithListValidators = ListParameter{} +) + +// ListParameter represents a function parameter that is an ordered list of a +// single element type. Either the ElementType or CustomType field must be set. +// +// When retrieving the argument value for this parameter: +// +// - If CustomType is set, use its associated value type. +// - If AllowUnknownValues is enabled, you must use the [types.List] value +// type. +// - Otherwise, use [types.List] or any Go slice value types compatible with +// the element type. +// +// Terraform configurations set this parameter's argument data using expressions +// that return a list or directly via list ("[...]") syntax. +type ListParameter struct { + // ElementType is the type for all elements of the list. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this parameter definition with + // DynamicParameter instead. + ElementType attr.Type + + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the function. When disabled, Terraform returns an error if the + // argument value is null. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that an unknown argument value + // can be passed to the function. When disabled, Terraform skips the + // function call entirely and assumes an unknown value result from the + // function. + AllowUnknownValues bool + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.ListType]. When retrieving data, the + // [basetypes.ListValuable] implementation associated with this custom + // type must be used in place of [types.List]. + CustomType basetypes.ListTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this parameter is, + // what it is for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this parameter is, what it is for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // Name is a short usage name for the parameter, such as "data". This name + // is used in documentation, such as generating a function signature, + // however its usage may be extended in the future. + // + // If no name is provided, this will default to "param" with a suffix of the + // position the parameter is in the function definition. ("param1", "param2", etc.) + // If the parameter is variadic, the default name will be "varparam". + // + // This must be a valid Terraform identifier, such as starting with an + // alphabetical character and followed by alphanumeric or underscore + // characters. + Name string + + // Validators is a list of list validators that should be applied to the + // parameter. + Validators []ListParameterValidator +} + +// GetValidators returns the list of validators for the parameter. +func (p ListParameter) GetValidators() []ListParameterValidator { + return p.Validators +} + +// GetAllowNullValue returns if the parameter accepts a null value. +func (p ListParameter) GetAllowNullValue() bool { + return p.AllowNullValue +} + +// GetAllowUnknownValues returns if the parameter accepts an unknown value. +func (p ListParameter) GetAllowUnknownValues() bool { + return p.AllowUnknownValues +} + +// GetDescription returns the parameter plaintext description. +func (p ListParameter) GetDescription() string { + return p.Description +} + +// GetMarkdownDescription returns the parameter Markdown description. +func (p ListParameter) GetMarkdownDescription() string { + return p.MarkdownDescription +} + +// GetName returns the parameter name. +func (p ListParameter) GetName() string { + return p.Name +} + +// GetType returns the parameter data type. +func (p ListParameter) GetType() attr.Type { + if p.CustomType != nil { + return p.CustomType + } + + return basetypes.ListType{ + ElemType: p.ElementType, + } +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the parameter to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (p ListParameter) ValidateImplementation(ctx context.Context, req fwfunction.ValidateParameterImplementationRequest, resp *fwfunction.ValidateParameterImplementationResponse) { + if p.CustomType == nil && fwtype.ContainsCollectionWithDynamic(p.GetType()) { + var diag diag.Diagnostic + if req.ParameterPosition != nil { + diag = fwtype.ParameterCollectionWithDynamicTypeDiag(*req.ParameterPosition, req.Name) + } else { + diag = fwtype.VariadicParameterCollectionWithDynamicTypeDiag(req.Name) + } + + resp.Diagnostics.Append(diag) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/list_parameter_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/list_parameter_validator.go new file mode 100644 index 00000000..3ab9a776 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/list_parameter_validator.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// ListParameterValidator is a function validator for types.List parameters. +type ListParameterValidator interface { + + // ValidateParameterList performs the validation. + ValidateParameterList(context.Context, ListParameterValidatorRequest, *ListParameterValidatorResponse) +} + +// ListParameterValidatorRequest is a request for types.List schema validation. +type ListParameterValidatorRequest struct { + // ArgumentPosition contains the position of the argument for validation. + // Use this position for any response diagnostics. + ArgumentPosition int64 + + // Value contains the value of the argument for validation. + Value types.List +} + +// ListParameterValidatorResponse is a response to a ListParameterValidatorRequest. +type ListParameterValidatorResponse struct { + // Error is a function error generated during validation of the Value. + Error *FuncError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/list_return.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/list_return.go new file mode 100644 index 00000000..07eac8ad --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/list_return.go @@ -0,0 +1,77 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwfunction" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Return = ListReturn{} + _ fwfunction.ReturnWithValidateImplementation = ListReturn{} +) + +// ListReturn represents a function return that is an ordered collection of a +// single element type. Either the ElementType or CustomType field must be set. +// +// When setting the value for this return: +// +// - If CustomType is set, use its associated value type. +// - Otherwise, use [types.List] or a Go slice value type compatible with the +// element type. +type ListReturn struct { + // ElementType is the type for all elements of the list. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this return definition with + // DynamicReturn instead. + ElementType attr.Type + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.ListType]. When setting data, the + // [basetypes.ListValuable] implementation associated with this custom + // type must be used in place of [types.List]. + CustomType basetypes.ListTypable +} + +// GetType returns the return data type. +func (r ListReturn) GetType() attr.Type { + if r.CustomType != nil { + return r.CustomType + } + + return basetypes.ListType{ + ElemType: r.ElementType, + } +} + +// NewResultData returns a new result data based on the type. +func (r ListReturn) NewResultData(ctx context.Context) (ResultData, *FuncError) { + value := basetypes.NewListUnknown(r.ElementType) + + if r.CustomType == nil { + return NewResultData(value), nil + } + + valuable, diags := r.CustomType.ValueFromList(ctx, value) + + return NewResultData(valuable), FuncErrorFromDiags(ctx, diags) +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the Return to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (p ListReturn) ValidateImplementation(ctx context.Context, req fwfunction.ValidateReturnImplementationRequest, resp *fwfunction.ValidateReturnImplementationResponse) { + if p.CustomType == nil && fwtype.ContainsCollectionWithDynamic(p.GetType()) { + resp.Diagnostics.Append(fwtype.ReturnCollectionWithDynamicTypeDiag()) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/map_parameter.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/map_parameter.go new file mode 100644 index 00000000..62678135 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/map_parameter.go @@ -0,0 +1,148 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwfunction" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Parameter = MapParameter{} + _ fwfunction.ParameterWithValidateImplementation = MapParameter{} + _ ParameterWithMapValidators = MapParameter{} +) + +// MapParameter represents a function parameter that is a mapping of a single +// element type. Either the ElementType or CustomType field must be set. +// +// When retrieving the argument value for this parameter: +// +// - If CustomType is set, use its associated value type. +// - If AllowUnknownValues is enabled, you must use the [types.Map] value +// type. +// - Otherwise, use [types.Map] or any Go map value types compatible with +// the element type. +// +// Terraform configurations set this parameter's argument data using expressions +// that return a map or directly via map ("{...}") syntax. +type MapParameter struct { + // ElementType is the type for all elements of the map. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this parameter definition with + // DynamicParameter instead. + ElementType attr.Type + + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the function. When disabled, Terraform returns an error if the + // argument value is null. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that an unknown argument value + // can be passed to the function. When disabled, Terraform skips the + // function call entirely and assumes an unknown value result from the + // function. + AllowUnknownValues bool + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.MapType]. When retrieving data, the + // [basetypes.MapValuable] implementation associated with this custom + // type must be used in place of [types.Map]. + CustomType basetypes.MapTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this parameter is, + // what it is for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this parameter is, what it is for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // Name is a short usage name for the parameter, such as "data". This name + // is used in documentation, such as generating a function signature, + // however its usage may be extended in the future. + // + // If no name is provided, this will default to "param" with a suffix of the + // position the parameter is in the function definition. ("param1", "param2", etc.) + // If the parameter is variadic, the default name will be "varparam". + // + // This must be a valid Terraform identifier, such as starting with an + // alphabetical character and followed by alphanumeric or underscore + // characters. + Name string + + // Validators is a list of map validators that should be applied to the + // parameter. + Validators []MapParameterValidator +} + +// GetValidators returns the list of validators for the parameter. +func (p MapParameter) GetValidators() []MapParameterValidator { + return p.Validators +} + +// GetAllowNullValue returns if the parameter accepts a null value. +func (p MapParameter) GetAllowNullValue() bool { + return p.AllowNullValue +} + +// GetAllowUnknownValues returns if the parameter accepts an unknown value. +func (p MapParameter) GetAllowUnknownValues() bool { + return p.AllowUnknownValues +} + +// GetDescription returns the parameter plaintext description. +func (p MapParameter) GetDescription() string { + return p.Description +} + +// GetMarkdownDescription returns the parameter Markdown description. +func (p MapParameter) GetMarkdownDescription() string { + return p.MarkdownDescription +} + +// GetName returns the parameter name. +func (p MapParameter) GetName() string { + return p.Name +} + +// GetType returns the parameter data type. +func (p MapParameter) GetType() attr.Type { + if p.CustomType != nil { + return p.CustomType + } + + return basetypes.MapType{ + ElemType: p.ElementType, + } +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the parameter to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (p MapParameter) ValidateImplementation(ctx context.Context, req fwfunction.ValidateParameterImplementationRequest, resp *fwfunction.ValidateParameterImplementationResponse) { + if p.CustomType == nil && fwtype.ContainsCollectionWithDynamic(p.GetType()) { + var diag diag.Diagnostic + if req.ParameterPosition != nil { + diag = fwtype.ParameterCollectionWithDynamicTypeDiag(*req.ParameterPosition, req.Name) + } else { + diag = fwtype.VariadicParameterCollectionWithDynamicTypeDiag(req.Name) + } + + resp.Diagnostics.Append(diag) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/map_parameter_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/map_parameter_validator.go new file mode 100644 index 00000000..97c13c5c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/map_parameter_validator.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// MapParameterValidator is a function validator for types.Map parameters. +type MapParameterValidator interface { + + // ValidateParameterMap performs the validation. + ValidateParameterMap(context.Context, MapParameterValidatorRequest, *MapParameterValidatorResponse) +} + +// MapParameterValidatorRequest is a request for types.Map schema validation. +type MapParameterValidatorRequest struct { + // ArgumentPosition contains the position of the argument for validation. + // Use this position for any response diagnostics. + ArgumentPosition int64 + + // Value contains the value of the argument for validation. + Value types.Map +} + +// MapParameterValidatorResponse is a response to a MapParameterValidatorRequest. +type MapParameterValidatorResponse struct { + // Error is a function error generated during validation of the Value. + Error *FuncError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/map_return.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/map_return.go new file mode 100644 index 00000000..5f83c69c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/map_return.go @@ -0,0 +1,77 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwfunction" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Return = MapReturn{} + _ fwfunction.ReturnWithValidateImplementation = MapReturn{} +) + +// MapReturn represents a function return that is an ordered collect of a +// single element type. Either the ElementType or CustomType field must be set. +// +// When setting the value for this return: +// +// - If CustomType is set, use its associated value type. +// - Otherwise, use [types.Map] or a Go map value type compatible with the +// element type. +type MapReturn struct { + // ElementType is the type for all elements of the map. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this return definition with + // DynamicReturn instead. + ElementType attr.Type + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.MapType]. When setting data, the + // [basetypes.MapValuable] implementation associated with this custom + // type must be used in place of [types.Map]. + CustomType basetypes.MapTypable +} + +// GetType returns the return data type. +func (r MapReturn) GetType() attr.Type { + if r.CustomType != nil { + return r.CustomType + } + + return basetypes.MapType{ + ElemType: r.ElementType, + } +} + +// NewResultData returns a new result data based on the type. +func (r MapReturn) NewResultData(ctx context.Context) (ResultData, *FuncError) { + value := basetypes.NewMapUnknown(r.ElementType) + + if r.CustomType == nil { + return NewResultData(value), nil + } + + valuable, diags := r.CustomType.ValueFromMap(ctx, value) + + return NewResultData(valuable), FuncErrorFromDiags(ctx, diags) +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the Return to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (p MapReturn) ValidateImplementation(ctx context.Context, req fwfunction.ValidateReturnImplementationRequest, resp *fwfunction.ValidateReturnImplementationResponse) { + if p.CustomType == nil && fwtype.ContainsCollectionWithDynamic(p.GetType()) { + resp.Diagnostics.Append(fwtype.ReturnCollectionWithDynamicTypeDiag()) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/metadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/metadata.go new file mode 100644 index 00000000..a0f277af --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/metadata.go @@ -0,0 +1,20 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +// MetadataRequest represents a request for the Function to return metadata, +// such as its name. An instance of this request struct is supplied as an +// argument to the Function type Metadata method. +type MetadataRequest struct{} + +// MetadataResponse represents a response to a MetadataRequest. An +// instance of this response struct is supplied as an argument to the +// Function type Metadata method. +type MetadataResponse struct { + // Name should be the function name, such as parse_xyz. Unlike data sources + // and managed resources, the provider name and an underscore should not be + // included as the Terraform configuration syntax for provider function + // calls already include the provider name. + Name string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/number_parameter.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/number_parameter.go new file mode 100644 index 00000000..1114f235 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/number_parameter.go @@ -0,0 +1,112 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Parameter = NumberParameter{} +var _ ParameterWithNumberValidators = NumberParameter{} + +// NumberParameter represents a function parameter that is a 512-bit arbitrary +// precision number. +// +// When retrieving the argument value for this parameter: +// +// - If CustomType is set, use its associated value type. +// - If AllowUnknownValues is enabled, you must use the [types.Number] value +// type. +// - Otherwise, use [types.Number] or *big.Float value types. +// +// Terraform configurations set this parameter's argument data using expressions +// that return a number or directly via numeric syntax. +type NumberParameter struct { + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the function. When disabled, Terraform returns an error if the + // argument value is null. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that an unknown argument value + // can be passed to the function. When disabled, Terraform skips the + // function call entirely and assumes an unknown value result from the + // function. + AllowUnknownValues bool + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.NumberType]. When retrieving data, the + // [basetypes.NumberValuable] implementation associated with this custom + // type must be used in place of [types.Number]. + CustomType basetypes.NumberTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this parameter is, + // what it is for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this parameter is, what it is for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // Name is a short usage name for the parameter, such as "data". This name + // is used in documentation, such as generating a function signature, + // however its usage may be extended in the future. + // + // If no name is provided, this will default to "param" with a suffix of the + // position the parameter is in the function definition. ("param1", "param2", etc.) + // If the parameter is variadic, the default name will be "varparam". + // + // This must be a valid Terraform identifier, such as starting with an + // alphabetical character and followed by alphanumeric or underscore + // characters. + Name string + + // Validators is a list of validators that can be used to validate the + // parameter. + Validators []NumberParameterValidator +} + +// GetValidators returns the list of validators for the parameter. +func (p NumberParameter) GetValidators() []NumberParameterValidator { + return p.Validators +} + +// GetAllowNullValue returns if the parameter accepts a null value. +func (p NumberParameter) GetAllowNullValue() bool { + return p.AllowNullValue +} + +// GetAllowUnknownValues returns if the parameter accepts an unknown value. +func (p NumberParameter) GetAllowUnknownValues() bool { + return p.AllowUnknownValues +} + +// GetDescription returns the parameter plaintext description. +func (p NumberParameter) GetDescription() string { + return p.Description +} + +// GetMarkdownDescription returns the parameter Markdown description. +func (p NumberParameter) GetMarkdownDescription() string { + return p.MarkdownDescription +} + +// GetName returns the parameter name. +func (p NumberParameter) GetName() string { + return p.Name +} + +// GetType returns the parameter data type. +func (p NumberParameter) GetType() attr.Type { + if p.CustomType != nil { + return p.CustomType + } + + return basetypes.NumberType{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/number_parameter_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/number_parameter_validator.go new file mode 100644 index 00000000..d6ea27e3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/number_parameter_validator.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// NumberParameterValidator is a function validator for types.Number parameters. +type NumberParameterValidator interface { + + // ValidateParameterNumber performs the validation. + ValidateParameterNumber(context.Context, NumberParameterValidatorRequest, *NumberParameterValidatorResponse) +} + +// NumberParameterValidatorRequest is a request for types.Number schema validation. +type NumberParameterValidatorRequest struct { + // ArgumentPosition contains the position of the argument for validation. + // Use this position for any response diagnostics. + ArgumentPosition int64 + + // Value contains the value of the argument for validation. + Value types.Number +} + +// NumberParameterValidatorResponse is a response to a NumberParameterValidatorRequest. +type NumberParameterValidatorResponse struct { + // Error is a function error generated during validation of the Value. + Error *FuncError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/number_return.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/number_return.go new file mode 100644 index 00000000..ad94cfea --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/number_return.go @@ -0,0 +1,51 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Return = NumberReturn{} + +// NumberReturn represents a function return that is a 512-bit arbitrary +// precision number. +// +// When setting the value for this return: +// +// - If CustomType is set, use its associated value type. +// - Otherwise, use [types.Number] or *big.Float. +type NumberReturn struct { + // CustomType enables the use of a custom data type in place of the + // default [basetypes.NumberType]. When setting data, the + // [basetypes.NumberValuable] implementation associated with this custom + // type must be used in place of [types.Number]. + CustomType basetypes.NumberTypable +} + +// GetType returns the return data type. +func (r NumberReturn) GetType() attr.Type { + if r.CustomType != nil { + return r.CustomType + } + + return basetypes.NumberType{} +} + +// NewResultData returns a new result data based on the type. +func (r NumberReturn) NewResultData(ctx context.Context) (ResultData, *FuncError) { + value := basetypes.NewNumberUnknown() + + if r.CustomType == nil { + return NewResultData(value), nil + } + + valuable, diags := r.CustomType.ValueFromNumber(ctx, value) + + return NewResultData(valuable), FuncErrorFromDiags(ctx, diags) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/object_parameter.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/object_parameter.go new file mode 100644 index 00000000..13120c14 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/object_parameter.go @@ -0,0 +1,150 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwfunction" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Parameter = ObjectParameter{} + _ fwfunction.ParameterWithValidateImplementation = ObjectParameter{} + _ ParameterWithObjectValidators = ObjectParameter{} +) + +// ObjectParameter represents a function parameter that is a mapping of +// defined attribute names to values. Either the AttributeTypes or CustomType +// field must be set. +// +// When retrieving the argument value for this parameter: +// +// - If CustomType is set, use its associated value type. +// - If AllowUnknownValues is enabled, you must use the [types.Object] value +// type. +// - If AllowNullValue is enabled, you must use the [types.Object] or a +// compatible Go *struct value type. +// - Otherwise, use [types.Object] or compatible *struct/struct value types. +// +// Terraform configurations set this parameter's argument data using expressions +// that return an object or directly via object ("{...}") syntax. +type ObjectParameter struct { + // AttributeTypes is the mapping of underlying attribute names to attribute + // types. This field must be set. + // + // Attribute types that contain a collection with a nested dynamic type (i.e. types.List[types.Dynamic]) are not supported. + // If underlying dynamic collection values are required, replace this parameter definition with + // DynamicParameter instead. + AttributeTypes map[string]attr.Type + + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the function. When disabled, Terraform returns an error if the + // argument value is null. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that an unknown argument value + // can be passed to the function. When disabled, Terraform skips the + // function call entirely and assumes an unknown value result from the + // function. + AllowUnknownValues bool + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.ObjectType]. When retrieving data, the + // [basetypes.ObjectValuable] implementation associated with this custom + // type must be used in place of [types.Object]. + CustomType basetypes.ObjectTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this parameter is, + // what it is for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this parameter is, what it is for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // Name is a short usage name for the parameter, such as "data". This name + // is used in documentation, such as generating a function signature, + // however its usage may be extended in the future. + // + // If no name is provided, this will default to "param" with a suffix of the + // position the parameter is in the function definition. ("param1", "param2", etc.) + // If the parameter is variadic, the default name will be "varparam". + // + // This must be a valid Terraform identifier, such as starting with an + // alphabetical character and followed by alphanumeric or underscore + // characters. + Name string + + // Validators is a list of object validators that should be applied to the + // parameter. + Validators []ObjectParameterValidator +} + +// GetValidators returns the list of validators for the parameter. +func (p ObjectParameter) GetValidators() []ObjectParameterValidator { + return p.Validators +} + +// GetAllowNullValue returns if the parameter accepts a null value. +func (p ObjectParameter) GetAllowNullValue() bool { + return p.AllowNullValue +} + +// GetAllowUnknownValues returns if the parameter accepts an unknown value. +func (p ObjectParameter) GetAllowUnknownValues() bool { + return p.AllowUnknownValues +} + +// GetDescription returns the parameter plaintext description. +func (p ObjectParameter) GetDescription() string { + return p.Description +} + +// GetMarkdownDescription returns the parameter Markdown description. +func (p ObjectParameter) GetMarkdownDescription() string { + return p.MarkdownDescription +} + +// GetName returns the parameter name. +func (p ObjectParameter) GetName() string { + return p.Name +} + +// GetType returns the parameter data type. +func (p ObjectParameter) GetType() attr.Type { + if p.CustomType != nil { + return p.CustomType + } + + return basetypes.ObjectType{ + AttrTypes: p.AttributeTypes, + } +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the parameter to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (p ObjectParameter) ValidateImplementation(ctx context.Context, req fwfunction.ValidateParameterImplementationRequest, resp *fwfunction.ValidateParameterImplementationResponse) { + if p.CustomType == nil && fwtype.ContainsCollectionWithDynamic(p.GetType()) { + var diag diag.Diagnostic + if req.ParameterPosition != nil { + diag = fwtype.ParameterCollectionWithDynamicTypeDiag(*req.ParameterPosition, req.Name) + } else { + diag = fwtype.VariadicParameterCollectionWithDynamicTypeDiag(req.Name) + } + + resp.Diagnostics.Append(diag) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/object_parameter_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/object_parameter_validator.go new file mode 100644 index 00000000..b1143da2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/object_parameter_validator.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// ObjectParameterValidator is a function validator for types.Object parameters. +type ObjectParameterValidator interface { + + // ValidateParameterObject ValidateParameterSet performs the validation. + ValidateParameterObject(context.Context, ObjectParameterValidatorRequest, *ObjectParameterValidatorResponse) +} + +// ObjectParameterValidatorRequest is a request for types.Object schema validation. +type ObjectParameterValidatorRequest struct { + // ArgumentPosition contains the position of the argument for validation. + // Use this position for any response diagnostics. + ArgumentPosition int64 + + // Value contains the value of the argument for validation. + Value types.Object +} + +// ObjectParameterValidatorResponse is a response to a ObjectParameterValidatorRequest. +type ObjectParameterValidatorResponse struct { + // Error is a function error generated during validation of the Value. + Error *FuncError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/object_return.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/object_return.go new file mode 100644 index 00000000..201960f9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/object_return.go @@ -0,0 +1,73 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwfunction" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Return = ObjectReturn{} + _ fwfunction.ReturnWithValidateImplementation = ObjectReturn{} +) + +// ObjectReturn represents a function return that is mapping of defined +// attribute names to values. When setting the value for this return, use +// [types.Object] or a compatible Go struct as the value type unless the +// CustomType field is set. The AttributeTypes field must be set. +type ObjectReturn struct { + // AttributeTypes is the mapping of underlying attribute names to attribute + // types. This field must be set. + // + // Attribute types that contain a collection with a nested dynamic type (i.e. types.List[types.Dynamic]) are not supported. + // If underlying dynamic collection values are required, replace this return definition with + // DynamicReturn instead. + AttributeTypes map[string]attr.Type + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.ObjectType]. When setting data, the + // [basetypes.ObjectValuable] implementation associated with this custom + // type must be used in place of [types.Object]. + CustomType basetypes.ObjectTypable +} + +// GetType returns the return data type. +func (r ObjectReturn) GetType() attr.Type { + if r.CustomType != nil { + return r.CustomType + } + + return basetypes.ObjectType{ + AttrTypes: r.AttributeTypes, + } +} + +// NewResultData returns a new result data based on the type. +func (r ObjectReturn) NewResultData(ctx context.Context) (ResultData, *FuncError) { + value := basetypes.NewObjectUnknown(r.AttributeTypes) + + if r.CustomType == nil { + return NewResultData(value), nil + } + + valuable, diags := r.CustomType.ValueFromObject(ctx, value) + + return NewResultData(valuable), FuncErrorFromDiags(ctx, diags) +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the Return to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (p ObjectReturn) ValidateImplementation(ctx context.Context, req fwfunction.ValidateReturnImplementationRequest, resp *fwfunction.ValidateReturnImplementationResponse) { + if p.CustomType == nil && fwtype.ContainsCollectionWithDynamic(p.GetType()) { + resp.Diagnostics.Append(fwtype.ReturnCollectionWithDynamicTypeDiag()) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/parameter.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/parameter.go new file mode 100644 index 00000000..791711f9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/parameter.go @@ -0,0 +1,66 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" +) + +// Parameter is the interface for defining function parameters. +type Parameter interface { + // GetAllowNullValue should return if the parameter accepts a null value. + GetAllowNullValue() bool + + // GetAllowUnknownValues should return if the parameter accepts an unknown + // value. + GetAllowUnknownValues() bool + + // GetDescription should return the plaintext documentation for the + // parameter. + GetDescription() string + + // GetMarkdownDescription should return the Markdown documentation for the + // parameter. + GetMarkdownDescription() string + + // GetName should return a usage name for the parameter. Parameters are + // positional, so this name has no meaning except documentation. + // + // If the name is returned as an empty string, a default name will be used to prevent Terraform errors for missing names. + // The default name will be the prefix "param" with a suffix of the position the parameter is in the function definition. (`param1`, `param2`, etc.) + // If the parameter is variadic, the default name will be `varparam`. + GetName() string + + // GetType should return the data type for the parameter, which determines + // what data type Terraform requires for configurations setting the argument + // during a function call and the argument data type received by the + // Function type Run method. + GetType() attr.Type +} + +// ValidateableParameter defines an interface for validating a parameter value. +type ValidateableParameter interface { + // ValidateParameter returns any error generated during validation + // of the parameter. It is generally used to check the data format and ensure + // that it complies with the requirements of the attr.Value. + ValidateParameter(context.Context, ValidateParameterRequest, *ValidateParameterResponse) +} + +// ValidateParameterRequest represents a request for the attr.Value to call its +// validation logic. An instance of this request struct is supplied as an +// argument to the attr.Value type ValidateParameter method. +type ValidateParameterRequest struct { + // Position is the zero-ordered position of the parameter being validated. + Position int64 +} + +// ValidateParameterResponse represents a response to a ValidateParameterRequest. +// An instance of this response struct is supplied as an argument to the +// ValidateParameter method. +type ValidateParameterResponse struct { + // Error is a function error generated during validation of the attr.Value. + Error *FuncError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/parameter_validation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/parameter_validation.go new file mode 100644 index 00000000..df595760 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/parameter_validation.go @@ -0,0 +1,94 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +// ParameterWithBoolValidators is an optional interface on Parameter which +// enables Bool validation support. +type ParameterWithBoolValidators interface { + Parameter + + // GetValidators should return a list of Bool validators. + GetValidators() []BoolParameterValidator +} + +// ParameterWithInt64Validators is an optional interface on Parameter which +// enables Int64 validation support. +type ParameterWithInt64Validators interface { + Parameter + + // GetValidators should return a list of Int64 validators. + GetValidators() []Int64ParameterValidator +} + +// ParameterWithFloat64Validators is an optional interface on Parameter which +// enables Float64 validation support. +type ParameterWithFloat64Validators interface { + Parameter + + // GetValidators should return a list of Float64 validators. + GetValidators() []Float64ParameterValidator +} + +// ParameterWithDynamicValidators is an optional interface on Parameter which +// enables Dynamic validation support. +type ParameterWithDynamicValidators interface { + Parameter + + // GetValidators should return a list of Dynamic validators. + GetValidators() []DynamicParameterValidator +} + +// ParameterWithListValidators is an optional interface on Parameter which +// enables List validation support. +type ParameterWithListValidators interface { + Parameter + + // GetValidators should return a list of List validators. + GetValidators() []ListParameterValidator +} + +// ParameterWithMapValidators is an optional interface on Parameter which +// enables Map validation support. +type ParameterWithMapValidators interface { + Parameter + + // GetValidators should return a list of Map validators. + GetValidators() []MapParameterValidator +} + +// ParameterWithNumberValidators is an optional interface on Parameter which +// enables Number validation support. +type ParameterWithNumberValidators interface { + Parameter + + // GetValidators should return a list of Map validators. + GetValidators() []NumberParameterValidator +} + +// ParameterWithObjectValidators is an optional interface on Parameter which +// enables Object validation support. +type ParameterWithObjectValidators interface { + Parameter + + // GetValidators should return a list of Object validators. + GetValidators() []ObjectParameterValidator +} + +// ParameterWithSetValidators is an optional interface on Parameter which +// enables Set validation support. +type ParameterWithSetValidators interface { + Parameter + + // GetValidators should return a list of Set validators. + GetValidators() []SetParameterValidator +} + +// ParameterWithStringValidators is an optional interface on Parameter which +// enables String validation support. +type ParameterWithStringValidators interface { + Parameter + + // GetValidators should return a list of String validators. + GetValidators() []StringParameterValidator +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/result_data.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/result_data.go new file mode 100644 index 00000000..ef8400ab --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/result_data.go @@ -0,0 +1,60 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + fwreflect "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// ResultData is the response data sent to Terraform for a single function call. +// Use the Set method in the Function type Run method to set the result data. +// +// For unit testing, use the NewResultData function to manually create the data +// for comparison. +type ResultData struct { + value attr.Value +} + +// Equal returns true if the value is equivalent. +func (d ResultData) Equal(o ResultData) bool { + if d.value == nil { + return o.value == nil + } + + return d.value.Equal(o.value) +} + +// Set saves the result data. The value type must be acceptable for the data +// type in the result definition. +func (d *ResultData) Set(ctx context.Context, value any) *FuncError { + reflectValue, reflectDiags := fwreflect.FromValue(ctx, d.value.Type(ctx), value, path.Empty()) + + funcErr := FuncErrorFromDiags(ctx, reflectDiags) + + if funcErr != nil { + return funcErr + } + + d.value = reflectValue + + return nil +} + +// Value returns the saved value. +func (d ResultData) Value() attr.Value { + return d.value +} + +// NewResultData creates a ResultData. This is only necessary for unit testing +// as the framework automatically creates this data for the Function type Run +// method. +func NewResultData(value attr.Value) ResultData { + return ResultData{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/return.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/return.go new file mode 100644 index 00000000..87c26a08 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/return.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" +) + +// Return is the interface for defining function return data. +type Return interface { + // GetType should return the data type for the return, which determines + // what data type Terraform requires for configurations receiving the + // response of a function call and the return data type required from the + // Function type Run method. + GetType() attr.Type + + // NewResultData should return a new ResultData with an unknown value (or + // best approximation of an invalid value) of the corresponding data type. + // The Function type Run method is expected to overwrite the value before + // returning. + NewResultData(context.Context) (ResultData, *FuncError) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/run.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/run.go new file mode 100644 index 00000000..05108a75 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/run.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +// RunRequest represents a request for the Function to call its implementation +// logic. An instance of this request struct is supplied as an argument to the +// Function type Run method. +type RunRequest struct { + // Arguments is the data sent from Terraform. Use the ArgumentsData type + // GetArgument method to retrieve each positional argument. + Arguments ArgumentsData +} + +// RunResponse represents a response to a RunRequest. An instance of this +// response struct is supplied as an argument to the Function type Run method. +type RunResponse struct { + // Error contains errors related to running the function. + // A nil error indicates success, with no errors generated. + // [ConcatFuncErrors] can be used to combine multiple errors into a single error. + Error *FuncError + + // Result is the data to be returned to Terraform matching the function + // result definition. This must be set or an error diagnostic is raised. Use + // the ResultData type Set method to save the data. + Result ResultData +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/set_parameter.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/set_parameter.go new file mode 100644 index 00000000..16a0c312 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/set_parameter.go @@ -0,0 +1,148 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwfunction" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Parameter = SetParameter{} + _ fwfunction.ParameterWithValidateImplementation = SetParameter{} + _ ParameterWithSetValidators = SetParameter{} +) + +// SetParameter represents a function parameter that is an unordered set of a +// single element type. Either the ElementType or CustomType field must be set. +// +// When retrieving the argument value for this parameter: +// +// - If CustomType is set, use its associated value type. +// - If AllowUnknownValues is enabled, you must use the [types.Set] value +// type. +// - Otherwise, use [types.Set] or any Go slice value types compatible with +// the element type. +// +// Terraform configurations set this parameter's argument data using expressions +// that return a set or directly via set ("[...]") syntax. +type SetParameter struct { + // ElementType is the type for all elements of the set. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this parameter definition with + // DynamicParameter instead. + ElementType attr.Type + + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the function. When disabled, Terraform returns an error if the + // argument value is null. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that an unknown argument value + // can be passed to the function. When disabled, Terraform skips the + // function call entirely and assumes an unknown value result from the + // function. + AllowUnknownValues bool + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.SetType]. When retrieving data, the + // [basetypes.SetValuable] implementation associated with this custom + // type must be used in place of [types.Set]. + CustomType basetypes.SetTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this parameter is, + // what it is for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this parameter is, what it is for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // Name is a short usage name for the parameter, such as "data". This name + // is used in documentation, such as generating a function signature, + // however its usage may be extended in the future. + // + // If no name is provided, this will default to "param" with a suffix of the + // position the parameter is in the function definition. ("param1", "param2", etc.) + // If the parameter is variadic, the default name will be "varparam". + // + // This must be a valid Terraform identifier, such as starting with an + // alphabetical character and followed by alphanumeric or underscore + // characters. + Name string + + // Validators is a list of set validators that should be applied to the + // parameter. + Validators []SetParameterValidator +} + +// GetValidators returns the list of validators for the parameter. +func (p SetParameter) GetValidators() []SetParameterValidator { + return p.Validators +} + +// GetAllowNullValue returns if the parameter accepts a null value. +func (p SetParameter) GetAllowNullValue() bool { + return p.AllowNullValue +} + +// GetAllowUnknownValues returns if the parameter accepts an unknown value. +func (p SetParameter) GetAllowUnknownValues() bool { + return p.AllowUnknownValues +} + +// GetDescription returns the parameter plaintext description. +func (p SetParameter) GetDescription() string { + return p.Description +} + +// GetMarkdownDescription returns the parameter Markdown description. +func (p SetParameter) GetMarkdownDescription() string { + return p.MarkdownDescription +} + +// GetName returns the parameter name. +func (p SetParameter) GetName() string { + return p.Name +} + +// GetType returns the parameter data type. +func (p SetParameter) GetType() attr.Type { + if p.CustomType != nil { + return p.CustomType + } + + return basetypes.SetType{ + ElemType: p.ElementType, + } +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the parameter to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (p SetParameter) ValidateImplementation(ctx context.Context, req fwfunction.ValidateParameterImplementationRequest, resp *fwfunction.ValidateParameterImplementationResponse) { + if p.CustomType == nil && fwtype.ContainsCollectionWithDynamic(p.GetType()) { + var diag diag.Diagnostic + if req.ParameterPosition != nil { + diag = fwtype.ParameterCollectionWithDynamicTypeDiag(*req.ParameterPosition, req.Name) + } else { + diag = fwtype.VariadicParameterCollectionWithDynamicTypeDiag(req.Name) + } + + resp.Diagnostics.Append(diag) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/set_parameter_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/set_parameter_validator.go new file mode 100644 index 00000000..7dcd12c9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/set_parameter_validator.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// SetParameterValidator is a function validator for types.Set parameters. +type SetParameterValidator interface { + + // ValidateParameterSet performs the validation. + ValidateParameterSet(context.Context, SetParameterValidatorRequest, *SetParameterValidatorResponse) +} + +// SetParameterValidatorRequest is a request for types.Set schema validation. +type SetParameterValidatorRequest struct { + // ArgumentPosition contains the position of the argument for validation. + // Use this position for any response diagnostics. + ArgumentPosition int64 + + // Value contains the value of the argument for validation. + Value types.Set +} + +// SetParameterValidatorResponse is a response to a SetParameterValidatorRequest. +type SetParameterValidatorResponse struct { + // Error is a function error generated during validation of the Value. + Error *FuncError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/set_return.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/set_return.go new file mode 100644 index 00000000..2999a406 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/set_return.go @@ -0,0 +1,77 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwfunction" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Return = SetReturn{} + _ fwfunction.ReturnWithValidateImplementation = SetReturn{} +) + +// SetReturn represents a function return that is an unordered collection of a +// single element type. Either the ElementType or CustomType field must be set. +// +// When setting the value for this return: +// +// - If CustomType is set, use its associated value type. +// - Otherwise, use [types.Set] or a Go slice value type compatible with the +// element type. +type SetReturn struct { + // ElementType is the type for all elements of the set. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this return definition with + // DynamicReturn instead. + ElementType attr.Type + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.SetType]. When setting data, the + // [basetypes.SetValuable] implementation associated with this custom + // type must be used in place of [types.Set]. + CustomType basetypes.SetTypable +} + +// GetType returns the return data type. +func (r SetReturn) GetType() attr.Type { + if r.CustomType != nil { + return r.CustomType + } + + return basetypes.SetType{ + ElemType: r.ElementType, + } +} + +// NewResultData returns a new result data based on the type. +func (r SetReturn) NewResultData(ctx context.Context) (ResultData, *FuncError) { + value := basetypes.NewSetUnknown(r.ElementType) + + if r.CustomType == nil { + return NewResultData(value), nil + } + + valuable, diags := r.CustomType.ValueFromSet(ctx, value) + + return NewResultData(valuable), FuncErrorFromDiags(ctx, diags) +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the Return to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (p SetReturn) ValidateImplementation(ctx context.Context, req fwfunction.ValidateReturnImplementationRequest, resp *fwfunction.ValidateReturnImplementationResponse) { + if p.CustomType == nil && fwtype.ContainsCollectionWithDynamic(p.GetType()) { + resp.Diagnostics.Append(fwtype.ReturnCollectionWithDynamicTypeDiag()) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/string_parameter.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/string_parameter.go new file mode 100644 index 00000000..6e6bfe10 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/string_parameter.go @@ -0,0 +1,113 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Parameter = StringParameter{} +var _ ParameterWithStringValidators = StringParameter{} + +// StringParameter represents a function parameter that is a string. +// +// When retrieving the argument value for this parameter: +// +// - If CustomType is set, use its associated value type. +// - If AllowUnknownValues is enabled, you must use the [types.String] value +// type. +// - If AllowNullValue is enabled, you must use [types.String] or *string +// value types. +// - Otherwise, use [types.String] or *string, or string value types. +// +// Terraform configurations set this parameter's argument data using expressions +// that return a string or directly via double quote ("value") syntax. +type StringParameter struct { + // AllowNullValue when enabled denotes that a null argument value can be + // passed to the function. When disabled, Terraform returns an error if the + // argument value is null. + AllowNullValue bool + + // AllowUnknownValues when enabled denotes that an unknown argument value + // can be passed to the function. When disabled, Terraform skips the + // function call entirely and assumes an unknown value result from the + // function. + AllowUnknownValues bool + + // CustomType enables the use of a custom data type in place of the + // default [basetypes.StringType]. When retrieving data, the + // [basetypes.StringValuable] implementation associated with this custom + // type must be used in place of [types.String]. + CustomType basetypes.StringTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this parameter is, + // what it is for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this parameter is, what it is for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // Name is a short usage name for the parameter, such as "data". This name + // is used in documentation, such as generating a function signature, + // however its usage may be extended in the future. + // + // If no name is provided, this will default to "param" with a suffix of the + // position the parameter is in the function definition. ("param1", "param2", etc.) + // If the parameter is variadic, the default name will be "varparam". + // + // This must be a valid Terraform identifier, such as starting with an + // alphabetical character and followed by alphanumeric or underscore + // characters. + Name string + + // Validators is a list of string validators that should be applied to the + // parameter. + Validators []StringParameterValidator +} + +// GetValidators returns the string validators for the parameter. +func (p StringParameter) GetValidators() []StringParameterValidator { + return p.Validators +} + +// GetAllowNullValue returns if the parameter accepts a null value. +func (p StringParameter) GetAllowNullValue() bool { + return p.AllowNullValue +} + +// GetAllowUnknownValues returns if the parameter accepts an unknown value. +func (p StringParameter) GetAllowUnknownValues() bool { + return p.AllowUnknownValues +} + +// GetDescription returns the parameter plaintext description. +func (p StringParameter) GetDescription() string { + return p.Description +} + +// GetMarkdownDescription returns the parameter Markdown description. +func (p StringParameter) GetMarkdownDescription() string { + return p.MarkdownDescription +} + +// GetName returns the parameter name. +func (p StringParameter) GetName() string { + return p.Name +} + +// GetType returns the parameter data type. +func (p StringParameter) GetType() attr.Type { + if p.CustomType != nil { + return p.CustomType + } + + return basetypes.StringType{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/string_parameter_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/string_parameter_validator.go new file mode 100644 index 00000000..f7b51600 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/string_parameter_validator.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// StringParameterValidator is a function validator for types.String parameters. +type StringParameterValidator interface { + + // ValidateParameterString performs the validation. + ValidateParameterString(context.Context, StringParameterValidatorRequest, *StringParameterValidatorResponse) +} + +// StringParameterValidatorRequest is a request for types.String schema validation. +type StringParameterValidatorRequest struct { + // ArgumentPosition contains the position of the argument for validation. + // Use this position for any response diagnostics. + ArgumentPosition int64 + + // Value contains the value of the argument for validation. + Value types.String +} + +// StringParameterValidatorResponse is a response to a StringParameterValidatorRequest. +type StringParameterValidatorResponse struct { + // Error is a function error generated during validation of the Value. + Error *FuncError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/function/string_return.go b/vendor/github.com/hashicorp/terraform-plugin-framework/function/string_return.go new file mode 100644 index 00000000..73894b58 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/function/string_return.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package function + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ Return = StringReturn{} + +// StringReturn represents a function return that is a string. +// +// When setting the value for this return: +// +// - If CustomType is set, use its associated value type. +// - Otherwise, use [types.String], *string, or string. +type StringReturn struct { + // CustomType enables the use of a custom data type in place of the + // default [basetypes.StringType]. When setting data, the + // [basetypes.StringValuable] implementation associated with this custom + // type must be used in place of [types.String]. + CustomType basetypes.StringTypable +} + +// GetType returns the return data type. +func (r StringReturn) GetType() attr.Type { + if r.CustomType != nil { + return r.CustomType + } + + return basetypes.StringType{} +} + +// NewResultData returns a new result data based on the type. +func (r StringReturn) NewResultData(ctx context.Context) (ResultData, *FuncError) { + value := basetypes.NewStringUnknown() + + if r.CustomType == nil { + return NewResultData(value), nil + } + + valuable, diags := r.CustomType.ValueFromString(ctx, value) + + return NewResultData(valuable), FuncErrorFromDiags(ctx, diags) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/applyresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/applyresourcechange.go new file mode 100644 index 00000000..08d04d4a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/applyresourcechange.go @@ -0,0 +1,77 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +// ApplyResourceChangeRequest returns the *fwserver.ApplyResourceChangeRequest +// equivalent of a *tfprotov5.ApplyResourceChangeRequest. +func ApplyResourceChangeRequest(ctx context.Context, proto5 *tfprotov5.ApplyResourceChangeRequest, resource resource.Resource, resourceSchema fwschema.Schema, providerMetaSchema fwschema.Schema) (*fwserver.ApplyResourceChangeRequest, diag.Diagnostics) { + if proto5 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if resourceSchema == nil { + diags.AddError( + "Missing Resource Schema", + "An unexpected error was encountered when handling the request. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + fw := &fwserver.ApplyResourceChangeRequest{ + ResourceSchema: resourceSchema, + Resource: resource, + } + + config, configDiags := Config(ctx, proto5.Config, resourceSchema) + + diags.Append(configDiags...) + + fw.Config = config + + plannedState, plannedStateDiags := Plan(ctx, proto5.PlannedState, resourceSchema) + + diags.Append(plannedStateDiags...) + + fw.PlannedState = plannedState + + priorState, priorStateDiags := State(ctx, proto5.PriorState, resourceSchema) + + diags.Append(priorStateDiags...) + + fw.PriorState = priorState + + providerMeta, providerMetaDiags := ProviderMeta(ctx, proto5.ProviderMeta, providerMetaSchema) + + diags.Append(providerMetaDiags...) + + fw.ProviderMeta = providerMeta + + privateData, privateDataDiags := privatestate.NewData(ctx, proto5.PlannedPrivate) + + diags.Append(privateDataDiags...) + + fw.PlannedPrivate = privateData + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/arguments_data.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/arguments_data.go new file mode 100644 index 00000000..fefd8a19 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/arguments_data.go @@ -0,0 +1,542 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ArgumentsData returns the ArgumentsData for a given []*tfprotov5.DynamicValue +// and function.Definition. +func ArgumentsData(ctx context.Context, arguments []*tfprotov5.DynamicValue, definition function.Definition) (function.ArgumentsData, *function.FuncError) { + if definition.VariadicParameter == nil && len(arguments) != len(definition.Parameters) { + return function.NewArgumentsData(nil), function.NewFuncError( + "Unexpected Function Arguments Data: " + + "The provider received an unexpected number of function arguments from Terraform for the given function definition. " + + "This is always an issue in terraform-plugin-framework or Terraform itself and should be reported to the provider developers.\n\n" + + fmt.Sprintf("Expected function arguments: %d\n", len(definition.Parameters)) + + fmt.Sprintf("Given function arguments: %d", len(arguments)), + ) + } + + // Expect at least all parameters to have corresponding arguments. Variadic + // parameter might have 0 to n arguments, which is why it is not checked in + // this case. + if len(arguments) < len(definition.Parameters) { + return function.NewArgumentsData(nil), function.NewFuncError( + "Unexpected Function Arguments Data: " + + "The provider received an unexpected number of function arguments from Terraform for the given function definition. " + + "This is always an issue in terraform-plugin-framework or Terraform itself and should be reported to the provider developers.\n\n" + + fmt.Sprintf("Expected minimum function arguments: %d\n", len(definition.Parameters)) + + fmt.Sprintf("Given function arguments: %d", len(arguments)), + ) + } + + if definition.VariadicParameter == nil && len(arguments) == 0 { + return function.NewArgumentsData(nil), nil + } + + // Variadic values are collected as a separate tuple to ease developer usage. + argumentValues := make([]attr.Value, 0, len(definition.Parameters)) + variadicValues := make([]attr.Value, 0, len(arguments)-len(definition.Parameters)) + var funcError *function.FuncError + + for position, argument := range arguments { + var parameter function.Parameter + pos := int64(position) + + switch { + case definition.VariadicParameter != nil && position >= len(definition.Parameters): + parameter = definition.VariadicParameter + default: + parameter = definition.Parameters[position] + } + + parameterType := parameter.GetType() + + if parameterType == nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Unable to Convert Function Argument: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Parameter type missing at position %d", position), + )) + + return function.NewArgumentsData(nil), funcError + } + + tfValue, err := argument.Unmarshal(parameterType.TerraformType(ctx)) + + if err != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Unable to Convert Function Argument: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Unable to unmarshal DynamicValue at position %d: %s", position, err), + )) + + return function.NewArgumentsData(nil), funcError + } + + attrValue, err := parameterType.ValueFromTerraform(ctx, tfValue) + + if err != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Unable to Convert Function Argument"+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Unable to convert tftypes to framework type at position %d: %s", position, err), + )) + + return function.NewArgumentsData(nil), funcError + } + + // This is intentionally below the conversion of tftypes.Value to attr.Value + // so it can be updated for any new type system validation interfaces. Note that the + // original xattr.TypeWithValidate interface must set a path.Path, + // which will always be incorrect in the context of functions. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/589 + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/893 + switch t := attrValue.(type) { + case function.ValidateableParameter: + resp := function.ValidateParameterResponse{} + + logging.FrameworkTrace(ctx, "Parameter value implements ValidateableParameter") + logging.FrameworkTrace(ctx, "Calling provider defined Value ValidateParameter") + + t.ValidateParameter(ctx, + function.ValidateParameterRequest{ + Position: pos, + }, + &resp, + ) + + logging.FrameworkTrace(ctx, "Called provider defined Value ValidateParameter") + + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + + continue + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if t, ok := parameterType.(xattr.TypeWithValidate); ok { + logging.FrameworkTrace(ctx, "Parameter type implements TypeWithValidate") + logging.FrameworkTrace(ctx, "Calling provider defined Type Validate") + + diags := t.Validate(ctx, tfValue, path.Empty()) + + logging.FrameworkTrace(ctx, "Called provider defined Type Validate") + + funcErrFromDiags := function.FuncErrorFromDiags(ctx, diags) + + if funcErrFromDiags != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + funcErrFromDiags.Error())) + + continue + } + } + } + + switch parameterWithValidators := parameter.(type) { + case function.ParameterWithBoolValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + boolValuable, ok := attrValue.(basetypes.BoolValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.BoolValuable at position %d", pos), + )) + + continue + } + boolVal, diags := boolValuable.ToBoolValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.BoolParameterValidatorRequest{ + ArgumentPosition: pos, + Value: boolVal, + } + resp := &function.BoolParameterValidatorResponse{} + functionValidator.ValidateParameterBool(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithDynamicValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + dynamicValuable, ok := attrValue.(basetypes.DynamicValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.DynamicValuable at position %d", pos), + )) + + continue + } + dynamicVal, diags := dynamicValuable.ToDynamicValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.DynamicParameterValidatorRequest{ + ArgumentPosition: pos, + Value: dynamicVal, + } + resp := &function.DynamicParameterValidatorResponse{} + functionValidator.ValidateParameterDynamic(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithFloat64Validators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + float64Valuable, ok := attrValue.(basetypes.Float64Valuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.Float64Valuable at position %d", pos), + )) + + continue + } + float64Val, diags := float64Valuable.ToFloat64Value(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.Float64ParameterValidatorRequest{ + ArgumentPosition: pos, + Value: float64Val, + } + resp := &function.Float64ParameterValidatorResponse{} + functionValidator.ValidateParameterFloat64(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithInt64Validators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + int64Valuable, ok := attrValue.(basetypes.Int64Valuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.Int64Valuable at position %d", pos), + )) + + continue + } + int64Val, diags := int64Valuable.ToInt64Value(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.Int64ParameterValidatorRequest{ + ArgumentPosition: pos, + Value: int64Val, + } + resp := &function.Int64ParameterValidatorResponse{} + functionValidator.ValidateParameterInt64(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithListValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + listValue, ok := attrValue.(basetypes.ListValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.ListValuable at position %d", pos), + )) + + continue + } + listVal, diags := listValue.ToListValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.ListParameterValidatorRequest{ + ArgumentPosition: pos, + Value: listVal, + } + resp := &function.ListParameterValidatorResponse{} + functionValidator.ValidateParameterList(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithMapValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + mapValuable, ok := attrValue.(basetypes.MapValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.MapValuable at position %d", pos), + )) + + continue + } + mapVal, diags := mapValuable.ToMapValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.MapParameterValidatorRequest{ + ArgumentPosition: pos, + Value: mapVal, + } + resp := &function.MapParameterValidatorResponse{} + functionValidator.ValidateParameterMap(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithNumberValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + numberValuable, ok := attrValue.(basetypes.NumberValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.NumberValuable at position %d", pos), + )) + + continue + } + numberVal, diags := numberValuable.ToNumberValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.NumberParameterValidatorRequest{ + ArgumentPosition: pos, + Value: numberVal, + } + resp := &function.NumberParameterValidatorResponse{} + functionValidator.ValidateParameterNumber(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithObjectValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + objectValuable, ok := attrValue.(basetypes.ObjectValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.ObjectValuable at position %d", pos), + )) + + continue + } + objectVal, diags := objectValuable.ToObjectValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.ObjectParameterValidatorRequest{ + ArgumentPosition: pos, + Value: objectVal, + } + resp := &function.ObjectParameterValidatorResponse{} + functionValidator.ValidateParameterObject(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithSetValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + setValuable, ok := attrValue.(basetypes.SetValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.SetValuable at position %d", pos), + )) + + continue + } + setVal, diags := setValuable.ToSetValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.SetParameterValidatorRequest{ + ArgumentPosition: pos, + Value: setVal, + } + resp := &function.SetParameterValidatorResponse{} + functionValidator.ValidateParameterSet(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithStringValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + stringValuable, ok := attrValue.(basetypes.StringValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.StringValuable at position %d", pos), + )) + + continue + } + stringVal, diags := stringValuable.ToStringValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.StringParameterValidatorRequest{ + ArgumentPosition: pos, + Value: stringVal, + } + resp := &function.StringParameterValidatorResponse{} + functionValidator.ValidateParameterString(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + } + + if definition.VariadicParameter != nil && position >= len(definition.Parameters) { + variadicValues = append(variadicValues, attrValue) + + continue + } + + // Skip appending argument values if parameter validation raises an error. + if funcError != nil { + continue + } + + argumentValues = append(argumentValues, attrValue) + } + + if definition.VariadicParameter != nil { + // MAINTAINER NOTE: Variadic parameters are represented as individual arguments in the CallFunction RPC and Terraform core applies the variadic parameter + // type constraint to each argument individually. For developer convenience, the framework logic below, groups the variadic arguments into a + // framework Tuple where each element type of the tuple matches the variadic parameter type. + // + // Previously, this logic utilized a framework List with an element type that matched the variadic parameter type. Using a List presented an issue with dynamic + // variadic parameters, as each argument was allowed to be any type "individually", rather than having a single type constraint applied to all dynamic elements, + // like a cty.List in Terraform. This eventually results in an error attempting to create a tftypes.List with multiple element types (when unwrapping from a framework + // dynamic to a tftypes concrete value). + // + // While a framework List type can handle multiple dynamic values of different types (due to it's wrapping of dynamic values), `terraform-plugin-go` and `tftypes.List` cannot. + // Currently, the logic for retrieving argument data is dependent on the tftypes package to utilize the framework reflection logic, requiring us to apply a type constraint + // that is valid in Terraform core and `terraform-plugin-go`, which we are doing here with a Tuple. + variadicType := definition.VariadicParameter.GetType() + tupleTypes := make([]attr.Type, len(variadicValues)) + tupleValues := make([]attr.Value, len(variadicValues)) + for i, val := range variadicValues { + tupleTypes[i] = variadicType + tupleValues[i] = val + } + + variadicValue, variadicValueDiags := basetypes.NewTupleValue(tupleTypes, tupleValues) + + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, variadicValueDiags)) + + if funcError != nil { + return function.NewArgumentsData(argumentValues), funcError + } + + argumentValues = append(argumentValues, variadicValue) + } + + return function.NewArgumentsData(argumentValues), funcError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/callfunction.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/callfunction.go new file mode 100644 index 00000000..ee122519 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/callfunction.go @@ -0,0 +1,32 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// CallFunctionRequest returns the *fwserver.CallFunctionRequest +// equivalent of a *tfprotov5.CallFunctionRequest. +func CallFunctionRequest(ctx context.Context, proto *tfprotov5.CallFunctionRequest, function function.Function, functionDefinition function.Definition) (*fwserver.CallFunctionRequest, *function.FuncError) { + if proto == nil { + return nil, nil + } + + fw := &fwserver.CallFunctionRequest{ + Function: function, + FunctionDefinition: functionDefinition, + } + + arguments, funcError := ArgumentsData(ctx, proto.Arguments, functionDefinition) + + fw.Arguments = arguments + + return fw, funcError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/config.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/config.go new file mode 100644 index 00000000..09096556 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/config.go @@ -0,0 +1,53 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// Config returns the *tfsdk.Config for a *tfprotov5.DynamicValue and +// fwschema.Schema. +func Config(ctx context.Context, proto5DynamicValue *tfprotov5.DynamicValue, schema fwschema.Schema) (*tfsdk.Config, diag.Diagnostics) { + if proto5DynamicValue == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if schema == nil { + diags.AddError( + "Unable to Convert Configuration", + "An unexpected error was encountered when converting the configuration from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + data, dynamicValueDiags := DynamicValue(ctx, proto5DynamicValue, schema, fwschemadata.DataDescriptionConfiguration) + + diags.Append(dynamicValueDiags...) + + if diags.HasError() { + return nil, diags + } + + fw := &tfsdk.Config{ + Raw: data.TerraformValue, + Schema: schema, + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/configureprovider.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/configureprovider.go new file mode 100644 index 00000000..9dc0f111 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/configureprovider.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ConfigureProviderRequest returns the *fwserver.ConfigureProviderRequest +// equivalent of a *tfprotov5.ConfigureProviderRequest. +func ConfigureProviderRequest(ctx context.Context, proto5 *tfprotov5.ConfigureProviderRequest, providerSchema fwschema.Schema) (*provider.ConfigureRequest, diag.Diagnostics) { + if proto5 == nil { + return nil, nil + } + + fw := &provider.ConfigureRequest{ + TerraformVersion: proto5.TerraformVersion, + } + + config, diags := Config(ctx, proto5.Config, providerSchema) + + if config != nil { + fw.Config = *config + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/doc.go new file mode 100644 index 00000000..41f1120d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package fromproto5 contains functions to convert from protocol version 5 +// (tfprotov5) types to framework types. +package fromproto5 diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/dynamic_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/dynamic_value.go new file mode 100644 index 00000000..6b6d5975 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/dynamic_value.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// DynamicValue returns the fwschemadata.Data for a given +// *tfprotov5.DynamicValue. +// +// If necessary, the underlying data is modified to convert list and set block +// values from an empty collection to a null collection. This is to prevent +// developers from needing to understand Terraform's differences between +// block and attribute values where blocks are technically never null, but from +// a developer perspective this distinction introduces unnecessary complexity. +func DynamicValue(ctx context.Context, proto5 *tfprotov5.DynamicValue, schema fwschema.Schema, description fwschemadata.DataDescription) (fwschemadata.Data, diag.Diagnostics) { + var diags diag.Diagnostics + + data := &fwschemadata.Data{ + Description: description, + Schema: schema, + } + + if proto5 == nil { + return *data, diags + } + + proto5Value, err := proto5.Unmarshal(schema.Type().TerraformType(ctx)) + + if err != nil { + diags.AddError( + "Unable to Convert "+description.Title(), + "An unexpected error was encountered when converting the "+description.String()+" from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Unable to unmarshal DynamicValue: "+err.Error(), + ) + + return *data, diags + } + + data.TerraformValue = proto5Value + + diags.Append(data.NullifyCollectionBlocks(ctx)...) + + return *data, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getfunctions.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getfunctions.go new file mode 100644 index 00000000..45adedab --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getfunctions.go @@ -0,0 +1,23 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetFunctionsRequest returns the *fwserver.GetFunctionsRequest +// equivalent of a *tfprotov5.GetFunctionsRequest. +func GetFunctionsRequest(ctx context.Context, proto *tfprotov5.GetFunctionsRequest) *fwserver.GetFunctionsRequest { + if proto == nil { + return nil + } + + fw := &fwserver.GetFunctionsRequest{} + + return fw +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getmetadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getmetadata.go new file mode 100644 index 00000000..c80ad2b8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getmetadata.go @@ -0,0 +1,23 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetMetadataRequest returns the *fwserver.GetMetadataRequest +// equivalent of a *tfprotov5.GetMetadataRequest. +func GetMetadataRequest(ctx context.Context, proto5 *tfprotov5.GetMetadataRequest) *fwserver.GetMetadataRequest { + if proto5 == nil { + return nil + } + + fw := &fwserver.GetMetadataRequest{} + + return fw +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getproviderschema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getproviderschema.go new file mode 100644 index 00000000..d6060e60 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/getproviderschema.go @@ -0,0 +1,23 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetProviderSchemaRequest returns the *fwserver.GetProviderSchemaRequest +// equivalent of a *tfprotov5.GetProviderSchemaRequest. +func GetProviderSchemaRequest(ctx context.Context, proto5 *tfprotov5.GetProviderSchemaRequest) *fwserver.GetProviderSchemaRequest { + if proto5 == nil { + return nil + } + + fw := &fwserver.GetProviderSchemaRequest{} + + return fw +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/importresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/importresourcestate.go new file mode 100644 index 00000000..4a10174b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/importresourcestate.go @@ -0,0 +1,52 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// ImportResourceStateRequest returns the *fwserver.ImportResourceStateRequest +// equivalent of a *tfprotov5.ImportResourceStateRequest. +func ImportResourceStateRequest(ctx context.Context, proto5 *tfprotov5.ImportResourceStateRequest, resource resource.Resource, resourceSchema fwschema.Schema) (*fwserver.ImportResourceStateRequest, diag.Diagnostics) { + if proto5 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if resourceSchema == nil { + diags.AddError( + "Unable to Create Empty State", + "An unexpected error was encountered when creating the empty state. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + fw := &fwserver.ImportResourceStateRequest{ + EmptyState: tfsdk.State{ + Raw: tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), nil), + Schema: resourceSchema, + }, + ID: proto5.ID, + Resource: resource, + TypeName: proto5.TypeName, + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/moveresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/moveresourcestate.go new file mode 100644 index 00000000..f5e836b7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/moveresourcestate.go @@ -0,0 +1,57 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// MoveResourceStateRequest returns the *fwserver.MoveResourceStateRequest +// equivalent of a *tfprotov5.MoveResourceStateRequest. +func MoveResourceStateRequest(ctx context.Context, proto5 *tfprotov5.MoveResourceStateRequest, resource resource.Resource, resourceSchema fwschema.Schema) (*fwserver.MoveResourceStateRequest, diag.Diagnostics) { + if proto5 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if resourceSchema == nil { + diags.AddError( + "Framework Implementation Error", + "An unexpected issue was encountered when converting the MoveResourceState RPC request information from the protocol type to the framework type. "+ + "The resource schema was missing. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.", + ) + + return nil, diags + } + + fw := &fwserver.MoveResourceStateRequest{ + SourceProviderAddress: proto5.SourceProviderAddress, + SourceRawState: (*tfprotov6.RawState)(proto5.SourceState), + SourceSchemaVersion: proto5.SourceSchemaVersion, + SourceTypeName: proto5.SourceTypeName, + TargetResource: resource, + TargetResourceSchema: resourceSchema, + TargetTypeName: proto5.TargetTypeName, + } + + sourcePrivate, sourcePrivateDiags := privatestate.NewData(ctx, proto5.SourcePrivate) + + diags.Append(sourcePrivateDiags...) + + fw.SourcePrivate = sourcePrivate + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/plan.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/plan.go new file mode 100644 index 00000000..f20a1a50 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/plan.go @@ -0,0 +1,53 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// Plan returns the *tfsdk.Plan for a *tfprotov5.DynamicValue and +// fwschema.Schema. +func Plan(ctx context.Context, proto5DynamicValue *tfprotov5.DynamicValue, schema fwschema.Schema) (*tfsdk.Plan, diag.Diagnostics) { + if proto5DynamicValue == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if schema == nil { + diags.AddError( + "Unable to Convert Plan", + "An unexpected error was encountered when converting the plan from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + data, dynamicValueDiags := DynamicValue(ctx, proto5DynamicValue, schema, fwschemadata.DataDescriptionPlan) + + diags.Append(dynamicValueDiags...) + + if diags.HasError() { + return nil, diags + } + + fw := &tfsdk.Plan{ + Raw: data.TerraformValue, + Schema: schema, + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/planresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/planresourcechange.go new file mode 100644 index 00000000..67cced27 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/planresourcechange.go @@ -0,0 +1,77 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +// PlanResourceChangeRequest returns the *fwserver.PlanResourceChangeRequest +// equivalent of a *tfprotov5.PlanResourceChangeRequest. +func PlanResourceChangeRequest(ctx context.Context, proto5 *tfprotov5.PlanResourceChangeRequest, resource resource.Resource, resourceSchema fwschema.Schema, providerMetaSchema fwschema.Schema) (*fwserver.PlanResourceChangeRequest, diag.Diagnostics) { + if proto5 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if resourceSchema == nil { + diags.AddError( + "Missing Resource Schema", + "An unexpected error was encountered when handling the request. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + fw := &fwserver.PlanResourceChangeRequest{ + ResourceSchema: resourceSchema, + Resource: resource, + } + + config, configDiags := Config(ctx, proto5.Config, resourceSchema) + + diags.Append(configDiags...) + + fw.Config = config + + priorState, priorStateDiags := State(ctx, proto5.PriorState, resourceSchema) + + diags.Append(priorStateDiags...) + + fw.PriorState = priorState + + proposedNewState, proposedNewStateDiags := Plan(ctx, proto5.ProposedNewState, resourceSchema) + + diags.Append(proposedNewStateDiags...) + + fw.ProposedNewState = proposedNewState + + providerMeta, providerMetaDiags := ProviderMeta(ctx, proto5.ProviderMeta, providerMetaSchema) + + diags.Append(providerMetaDiags...) + + fw.ProviderMeta = providerMeta + + privateData, privateDataDiags := privatestate.NewData(ctx, proto5.PriorPrivate) + + diags.Append(privateDataDiags...) + + fw.PriorPrivate = privateData + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/prepareproviderconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/prepareproviderconfig.go new file mode 100644 index 00000000..6fe2dd58 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/prepareproviderconfig.go @@ -0,0 +1,29 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// PrepareProviderConfigRequest returns the *fwserver.ValidateProviderConfigRequest +// equivalent of a *tfprotov5.PrepareProviderConfigRequest. +func PrepareProviderConfigRequest(ctx context.Context, proto5 *tfprotov5.PrepareProviderConfigRequest, providerSchema fwschema.Schema) (*fwserver.ValidateProviderConfigRequest, diag.Diagnostics) { + if proto5 == nil { + return nil, nil + } + + fw := &fwserver.ValidateProviderConfigRequest{} + + config, diags := Config(ctx, proto5.Config, providerSchema) + + fw.Config = config + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/providermeta.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/providermeta.go new file mode 100644 index 00000000..d7c30cc8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/providermeta.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// ProviderMeta returns the *tfsdk.Config for a *tfprotov5.DynamicValue and +// fwschema.Schema. This data handling is different than Config to simplify +// implementors, in that: +// +// - Missing Schema will return nil, rather than an error +// - Missing DynamicValue will return nil typed Value, rather than an error +func ProviderMeta(ctx context.Context, proto5DynamicValue *tfprotov5.DynamicValue, schema fwschema.Schema) (*tfsdk.Config, diag.Diagnostics) { + if schema == nil { + return nil, nil + } + + var diags diag.Diagnostics + + fw := &tfsdk.Config{ + Raw: tftypes.NewValue(schema.Type().TerraformType(ctx), nil), + Schema: schema, + } + + if proto5DynamicValue == nil { + return fw, nil + } + + proto5Value, err := proto5DynamicValue.Unmarshal(schema.Type().TerraformType(ctx)) + + if err != nil { + diags.AddError( + "Unable to Convert Provider Meta Configuration", + "An unexpected error was encountered when converting the provider meta configuration from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+err.Error(), + ) + + return nil, diags + } + + fw.Raw = proto5Value + + return fw, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/readdatasource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/readdatasource.go new file mode 100644 index 00000000..53ac543a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/readdatasource.go @@ -0,0 +1,57 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ReadDataSourceRequest returns the *fwserver.ReadDataSourceRequest +// equivalent of a *tfprotov5.ReadDataSourceRequest. +func ReadDataSourceRequest(ctx context.Context, proto5 *tfprotov5.ReadDataSourceRequest, dataSource datasource.DataSource, dataSourceSchema fwschema.Schema, providerMetaSchema fwschema.Schema) (*fwserver.ReadDataSourceRequest, diag.Diagnostics) { + if proto5 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if dataSourceSchema == nil { + diags.AddError( + "Missing DataSource Schema", + "An unexpected error was encountered when handling the request. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + fw := &fwserver.ReadDataSourceRequest{ + DataSource: dataSource, + DataSourceSchema: dataSourceSchema, + } + + config, configDiags := Config(ctx, proto5.Config, dataSourceSchema) + + diags.Append(configDiags...) + + fw.Config = config + + providerMeta, providerMetaDiags := ProviderMeta(ctx, proto5.ProviderMeta, providerMetaSchema) + + diags.Append(providerMetaDiags...) + + fw.ProviderMeta = providerMeta + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/readresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/readresource.go new file mode 100644 index 00000000..94164a2c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/readresource.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +// ReadResourceRequest returns the *fwserver.ReadResourceRequest +// equivalent of a *tfprotov5.ReadResourceRequest. +func ReadResourceRequest(ctx context.Context, proto5 *tfprotov5.ReadResourceRequest, resource resource.Resource, resourceSchema fwschema.Schema, providerMetaSchema fwschema.Schema) (*fwserver.ReadResourceRequest, diag.Diagnostics) { + if proto5 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + fw := &fwserver.ReadResourceRequest{ + Resource: resource, + } + + currentState, currentStateDiags := State(ctx, proto5.CurrentState, resourceSchema) + + diags.Append(currentStateDiags...) + + fw.CurrentState = currentState + + providerMeta, providerMetaDiags := ProviderMeta(ctx, proto5.ProviderMeta, providerMetaSchema) + + diags.Append(providerMetaDiags...) + + fw.ProviderMeta = providerMeta + + privateData, privateDataDiags := privatestate.NewData(ctx, proto5.Private) + + diags.Append(privateDataDiags...) + + fw.Private = privateData + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/state.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/state.go new file mode 100644 index 00000000..54a6ce08 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/state.go @@ -0,0 +1,53 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// State returns the *tfsdk.State for a *tfprotov5.DynamicValue and +// fwschema.Schema. +func State(ctx context.Context, proto5DynamicValue *tfprotov5.DynamicValue, schema fwschema.Schema) (*tfsdk.State, diag.Diagnostics) { + if proto5DynamicValue == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if schema == nil { + diags.AddError( + "Unable to Convert State", + "An unexpected error was encountered when converting the state from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + data, dynamicValueDiags := DynamicValue(ctx, proto5DynamicValue, schema, fwschemadata.DataDescriptionState) + + diags.Append(dynamicValueDiags...) + + if diags.HasError() { + return nil, diags + } + + fw := &tfsdk.State{ + Raw: data.TerraformValue, + Schema: schema, + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/upgraderesourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/upgraderesourcestate.go new file mode 100644 index 00000000..8b1330cf --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/upgraderesourcestate.go @@ -0,0 +1,48 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// UpgradeResourceStateRequest returns the *fwserver.UpgradeResourceStateRequest +// equivalent of a *tfprotov5.UpgradeResourceStateRequest. +func UpgradeResourceStateRequest(ctx context.Context, proto5 *tfprotov5.UpgradeResourceStateRequest, resource resource.Resource, resourceSchema fwschema.Schema) (*fwserver.UpgradeResourceStateRequest, diag.Diagnostics) { + if proto5 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if resourceSchema == nil { + diags.AddError( + "Unable to Create Empty State", + "An unexpected error was encountered when creating the empty state. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + fw := &fwserver.UpgradeResourceStateRequest{ + RawState: (*tfprotov6.RawState)(proto5.RawState), + ResourceSchema: resourceSchema, + Resource: resource, + Version: proto5.Version, + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/validatedatasourceconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/validatedatasourceconfig.go new file mode 100644 index 00000000..8e937897 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/validatedatasourceconfig.go @@ -0,0 +1,31 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ValidateDataSourceConfigRequest returns the *fwserver.ValidateDataSourceConfigRequest +// equivalent of a *tfprotov5.ValidateDataSourceConfigRequest. +func ValidateDataSourceConfigRequest(ctx context.Context, proto5 *tfprotov5.ValidateDataSourceConfigRequest, dataSource datasource.DataSource, dataSourceSchema fwschema.Schema) (*fwserver.ValidateDataSourceConfigRequest, diag.Diagnostics) { + if proto5 == nil { + return nil, nil + } + + fw := &fwserver.ValidateDataSourceConfigRequest{} + + config, diags := Config(ctx, proto5.Config, dataSourceSchema) + + fw.Config = config + fw.DataSource = dataSource + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/validateresourcetypeconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/validateresourcetypeconfig.go new file mode 100644 index 00000000..ae6e4129 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto5/validateresourcetypeconfig.go @@ -0,0 +1,31 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ValidateResourceTypeConfigRequest returns the *fwserver.ValidateResourceConfigRequest +// equivalent of a *tfprotov5.ValidateResourceTypeConfigRequest. +func ValidateResourceTypeConfigRequest(ctx context.Context, proto5 *tfprotov5.ValidateResourceTypeConfigRequest, resource resource.Resource, resourceSchema fwschema.Schema) (*fwserver.ValidateResourceConfigRequest, diag.Diagnostics) { + if proto5 == nil { + return nil, nil + } + + fw := &fwserver.ValidateResourceConfigRequest{} + + config, diags := Config(ctx, proto5.Config, resourceSchema) + + fw.Config = config + fw.Resource = resource + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/applyresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/applyresourcechange.go new file mode 100644 index 00000000..f48eb856 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/applyresourcechange.go @@ -0,0 +1,77 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +// ApplyResourceChangeRequest returns the *fwserver.ApplyResourceChangeRequest +// equivalent of a *tfprotov6.ApplyResourceChangeRequest. +func ApplyResourceChangeRequest(ctx context.Context, proto6 *tfprotov6.ApplyResourceChangeRequest, resource resource.Resource, resourceSchema fwschema.Schema, providerMetaSchema fwschema.Schema) (*fwserver.ApplyResourceChangeRequest, diag.Diagnostics) { + if proto6 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if resourceSchema == nil { + diags.AddError( + "Missing Resource Schema", + "An unexpected error was encountered when handling the request. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + fw := &fwserver.ApplyResourceChangeRequest{ + ResourceSchema: resourceSchema, + Resource: resource, + } + + config, configDiags := Config(ctx, proto6.Config, resourceSchema) + + diags.Append(configDiags...) + + fw.Config = config + + plannedState, plannedStateDiags := Plan(ctx, proto6.PlannedState, resourceSchema) + + diags.Append(plannedStateDiags...) + + fw.PlannedState = plannedState + + priorState, priorStateDiags := State(ctx, proto6.PriorState, resourceSchema) + + diags.Append(priorStateDiags...) + + fw.PriorState = priorState + + providerMeta, providerMetaDiags := ProviderMeta(ctx, proto6.ProviderMeta, providerMetaSchema) + + diags.Append(providerMetaDiags...) + + fw.ProviderMeta = providerMeta + + privateData, privateDataDiags := privatestate.NewData(ctx, proto6.PlannedPrivate) + + diags.Append(privateDataDiags...) + + fw.PlannedPrivate = privateData + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/arguments_data.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/arguments_data.go new file mode 100644 index 00000000..1fcf3922 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/arguments_data.go @@ -0,0 +1,542 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ArgumentsData returns the ArgumentsData for a given []*tfprotov6.DynamicValue +// and function.Definition. +func ArgumentsData(ctx context.Context, arguments []*tfprotov6.DynamicValue, definition function.Definition) (function.ArgumentsData, *function.FuncError) { + if definition.VariadicParameter == nil && len(arguments) != len(definition.Parameters) { + return function.NewArgumentsData(nil), function.NewFuncError( + "Unexpected Function Arguments Data: " + + "The provider received an unexpected number of function arguments from Terraform for the given function definition. " + + "This is always an issue in terraform-plugin-framework or Terraform itself and should be reported to the provider developers.\n\n" + + fmt.Sprintf("Expected function arguments: %d\n", len(definition.Parameters)) + + fmt.Sprintf("Given function arguments: %d", len(arguments)), + ) + } + + // Expect at least all parameters to have corresponding arguments. Variadic + // parameter might have 0 to n arguments, which is why it is not checked in + // this case. + if len(arguments) < len(definition.Parameters) { + return function.NewArgumentsData(nil), function.NewFuncError( + "Unexpected Function Arguments Data: " + + "The provider received an unexpected number of function arguments from Terraform for the given function definition. " + + "This is always an issue in terraform-plugin-framework or Terraform itself and should be reported to the provider developers.\n\n" + + fmt.Sprintf("Expected minimum function arguments: %d\n", len(definition.Parameters)) + + fmt.Sprintf("Given function arguments: %d", len(arguments)), + ) + } + + if definition.VariadicParameter == nil && len(arguments) == 0 { + return function.NewArgumentsData(nil), nil + } + + // Variadic values are collected as a separate tuple to ease developer usage. + argumentValues := make([]attr.Value, 0, len(definition.Parameters)) + variadicValues := make([]attr.Value, 0, len(arguments)-len(definition.Parameters)) + var funcError *function.FuncError + + for position, argument := range arguments { + var parameter function.Parameter + pos := int64(position) + + switch { + case definition.VariadicParameter != nil && position >= len(definition.Parameters): + parameter = definition.VariadicParameter + default: + parameter = definition.Parameters[position] + } + + parameterType := parameter.GetType() + + if parameterType == nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Unable to Convert Function Argument: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Parameter type missing at position %d", position), + )) + + return function.NewArgumentsData(nil), funcError + } + + tfValue, err := argument.Unmarshal(parameterType.TerraformType(ctx)) + + if err != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Unable to Convert Function Argument: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Unable to unmarshal DynamicValue at position %d: %s", position, err), + )) + + return function.NewArgumentsData(nil), funcError + } + + attrValue, err := parameterType.ValueFromTerraform(ctx, tfValue) + + if err != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Unable to Convert Function Argument"+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Unable to convert tftypes to framework type at position %d: %s", position, err), + )) + + return function.NewArgumentsData(nil), funcError + } + + // This is intentionally below the conversion of tftypes.Value to attr.Value + // so it can be updated for any new type system validation interfaces. Note that the + // original xattr.TypeWithValidate interface must set a path.Path, + // which will always be incorrect in the context of functions. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/589 + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/893 + switch t := attrValue.(type) { + case function.ValidateableParameter: + resp := function.ValidateParameterResponse{} + + logging.FrameworkTrace(ctx, "Parameter value implements ValidateableParameter") + logging.FrameworkTrace(ctx, "Calling provider defined Value ValidateParameter") + + t.ValidateParameter(ctx, + function.ValidateParameterRequest{ + Position: pos, + }, + &resp, + ) + + logging.FrameworkTrace(ctx, "Called provider defined Value ValidateParameter") + + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + + continue + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if t, ok := parameterType.(xattr.TypeWithValidate); ok { + logging.FrameworkTrace(ctx, "Parameter type implements TypeWithValidate") + logging.FrameworkTrace(ctx, "Calling provider defined Type Validate") + + diags := t.Validate(ctx, tfValue, path.Empty()) + + logging.FrameworkTrace(ctx, "Called provider defined Type Validate") + + funcErrFromDiags := function.FuncErrorFromDiags(ctx, diags) + + if funcErrFromDiags != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + funcErrFromDiags.Error())) + + continue + } + } + } + + switch parameterWithValidators := parameter.(type) { + case function.ParameterWithBoolValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + boolValuable, ok := attrValue.(basetypes.BoolValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.BoolValuable at position %d", pos), + )) + + continue + } + boolVal, diags := boolValuable.ToBoolValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.BoolParameterValidatorRequest{ + ArgumentPosition: pos, + Value: boolVal, + } + resp := &function.BoolParameterValidatorResponse{} + functionValidator.ValidateParameterBool(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithDynamicValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + dynamicValuable, ok := attrValue.(basetypes.DynamicValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.DynamicValuable at position %d", pos), + )) + + continue + } + dynamicVal, diags := dynamicValuable.ToDynamicValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.DynamicParameterValidatorRequest{ + ArgumentPosition: pos, + Value: dynamicVal, + } + resp := &function.DynamicParameterValidatorResponse{} + functionValidator.ValidateParameterDynamic(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithFloat64Validators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + float64Valuable, ok := attrValue.(basetypes.Float64Valuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.Float64Valuable at position %d", pos), + )) + + continue + } + float64Val, diags := float64Valuable.ToFloat64Value(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.Float64ParameterValidatorRequest{ + ArgumentPosition: pos, + Value: float64Val, + } + resp := &function.Float64ParameterValidatorResponse{} + functionValidator.ValidateParameterFloat64(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithInt64Validators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + int64Valuable, ok := attrValue.(basetypes.Int64Valuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.Int64Valuable at position %d", pos), + )) + + continue + } + int64Val, diags := int64Valuable.ToInt64Value(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.Int64ParameterValidatorRequest{ + ArgumentPosition: pos, + Value: int64Val, + } + resp := &function.Int64ParameterValidatorResponse{} + functionValidator.ValidateParameterInt64(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithListValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + listValue, ok := attrValue.(basetypes.ListValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.ListValuable at position %d", pos), + )) + + continue + } + listVal, diags := listValue.ToListValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.ListParameterValidatorRequest{ + ArgumentPosition: pos, + Value: listVal, + } + resp := &function.ListParameterValidatorResponse{} + functionValidator.ValidateParameterList(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithMapValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + mapValuable, ok := attrValue.(basetypes.MapValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.MapValuable at position %d", pos), + )) + + continue + } + mapVal, diags := mapValuable.ToMapValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.MapParameterValidatorRequest{ + ArgumentPosition: pos, + Value: mapVal, + } + resp := &function.MapParameterValidatorResponse{} + functionValidator.ValidateParameterMap(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithNumberValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + numberValuable, ok := attrValue.(basetypes.NumberValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.NumberValuable at position %d", pos), + )) + + continue + } + numberVal, diags := numberValuable.ToNumberValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.NumberParameterValidatorRequest{ + ArgumentPosition: pos, + Value: numberVal, + } + resp := &function.NumberParameterValidatorResponse{} + functionValidator.ValidateParameterNumber(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithObjectValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + objectValuable, ok := attrValue.(basetypes.ObjectValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.ObjectValuable at position %d", pos), + )) + + continue + } + objectVal, diags := objectValuable.ToObjectValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.ObjectParameterValidatorRequest{ + ArgumentPosition: pos, + Value: objectVal, + } + resp := &function.ObjectParameterValidatorResponse{} + functionValidator.ValidateParameterObject(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithSetValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + setValuable, ok := attrValue.(basetypes.SetValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.SetValuable at position %d", pos), + )) + + continue + } + setVal, diags := setValuable.ToSetValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.SetParameterValidatorRequest{ + ArgumentPosition: pos, + Value: setVal, + } + resp := &function.SetParameterValidatorResponse{} + functionValidator.ValidateParameterSet(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + case function.ParameterWithStringValidators: + for _, functionValidator := range parameterWithValidators.GetValidators() { + stringValuable, ok := attrValue.(basetypes.StringValuable) + if !ok { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + "Invalid Argument Type: "+ + "An unexpected error was encountered when converting the function argument from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + fmt.Sprintf("Expected basetypes.StringValuable at position %d", pos), + )) + + continue + } + stringVal, diags := stringValuable.ToStringValue(ctx) + if diags.HasError() { + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, diags)) + continue + } + req := function.StringParameterValidatorRequest{ + ArgumentPosition: pos, + Value: stringVal, + } + resp := &function.StringParameterValidatorResponse{} + functionValidator.ValidateParameterString(ctx, req, resp) + if resp.Error != nil { + funcError = function.ConcatFuncErrors(funcError, function.NewArgumentFuncError( + pos, + resp.Error.Error(), + )) + } + } + } + + if definition.VariadicParameter != nil && position >= len(definition.Parameters) { + variadicValues = append(variadicValues, attrValue) + + continue + } + + // Skip appending argument values if parameter validation raises an error. + if funcError != nil { + continue + } + + argumentValues = append(argumentValues, attrValue) + } + + if definition.VariadicParameter != nil { + // MAINTAINER NOTE: Variadic parameters are represented as individual arguments in the CallFunction RPC and Terraform core applies the variadic parameter + // type constraint to each argument individually. For developer convenience, the framework logic below, groups the variadic arguments into a + // framework Tuple where each element type of the tuple matches the variadic parameter type. + // + // Previously, this logic utilized a framework List with an element type that matched the variadic parameter type. Using a List presented an issue with dynamic + // variadic parameters, as each argument was allowed to be any type "individually", rather than having a single type constraint applied to all dynamic elements, + // like a cty.List in Terraform. This eventually results in an error attempting to create a tftypes.List with multiple element types (when unwrapping from a framework + // dynamic to a tftypes concrete value). + // + // While a framework List type can handle multiple dynamic values of different types (due to it's wrapping of dynamic values), `terraform-plugin-go` and `tftypes.List` cannot. + // Currently, the logic for retrieving argument data is dependent on the tftypes package to utilize the framework reflection logic, requiring us to apply a type constraint + // that is valid in Terraform core and `terraform-plugin-go`, which we are doing here with a Tuple. + variadicType := definition.VariadicParameter.GetType() + tupleTypes := make([]attr.Type, len(variadicValues)) + tupleValues := make([]attr.Value, len(variadicValues)) + for i, val := range variadicValues { + tupleTypes[i] = variadicType + tupleValues[i] = val + } + + variadicValue, variadicValueDiags := basetypes.NewTupleValue(tupleTypes, tupleValues) + + funcError = function.ConcatFuncErrors(funcError, function.FuncErrorFromDiags(ctx, variadicValueDiags)) + + if funcError != nil { + return function.NewArgumentsData(argumentValues), funcError + } + + argumentValues = append(argumentValues, variadicValue) + } + + return function.NewArgumentsData(argumentValues), funcError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/callfunction.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/callfunction.go new file mode 100644 index 00000000..9fb3cb13 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/callfunction.go @@ -0,0 +1,32 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// CallFunctionRequest returns the *fwserver.CallFunctionRequest +// equivalent of a *tfprotov6.CallFunctionRequest. +func CallFunctionRequest(ctx context.Context, proto *tfprotov6.CallFunctionRequest, function function.Function, functionDefinition function.Definition) (*fwserver.CallFunctionRequest, *function.FuncError) { + if proto == nil { + return nil, nil + } + + fw := &fwserver.CallFunctionRequest{ + Function: function, + FunctionDefinition: functionDefinition, + } + + arguments, funcError := ArgumentsData(ctx, proto.Arguments, functionDefinition) + + fw.Arguments = arguments + + return fw, funcError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/config.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/config.go new file mode 100644 index 00000000..72a2a453 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/config.go @@ -0,0 +1,53 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// Config returns the *tfsdk.Config for a *tfprotov6.DynamicValue and +// fwschema.Schema. +func Config(ctx context.Context, proto6DynamicValue *tfprotov6.DynamicValue, schema fwschema.Schema) (*tfsdk.Config, diag.Diagnostics) { + if proto6DynamicValue == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if schema == nil { + diags.AddError( + "Unable to Convert Configuration", + "An unexpected error was encountered when converting the configuration from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + data, dynamicValueDiags := DynamicValue(ctx, proto6DynamicValue, schema, fwschemadata.DataDescriptionConfiguration) + + diags.Append(dynamicValueDiags...) + + if diags.HasError() { + return nil, diags + } + + fw := &tfsdk.Config{ + Raw: data.TerraformValue, + Schema: schema, + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/configureprovider.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/configureprovider.go new file mode 100644 index 00000000..733b76ca --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/configureprovider.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ConfigureProviderRequest returns the *fwserver.ConfigureProviderRequest +// equivalent of a *tfprotov6.ConfigureProviderRequest. +func ConfigureProviderRequest(ctx context.Context, proto6 *tfprotov6.ConfigureProviderRequest, providerSchema fwschema.Schema) (*provider.ConfigureRequest, diag.Diagnostics) { + if proto6 == nil { + return nil, nil + } + + fw := &provider.ConfigureRequest{ + TerraformVersion: proto6.TerraformVersion, + } + + config, diags := Config(ctx, proto6.Config, providerSchema) + + if config != nil { + fw.Config = *config + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/doc.go new file mode 100644 index 00000000..2692f35f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package fromproto6 contains functions to convert from protocol version 6 +// (tfprotov6) types to framework types. +package fromproto6 diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/dynamic_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/dynamic_value.go new file mode 100644 index 00000000..645c23a9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/dynamic_value.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// DynamicValue returns the fwschemadata.Data for a given +// *tfprotov6.DynamicValue. +// +// If necessary, the underlying data is modified to convert list and set block +// values from an empty collection to a null collection. This is to prevent +// developers from needing to understand Terraform's differences between +// block and attribute values where blocks are technically never null, but from +// a developer perspective this distinction introduces unnecessary complexity. +func DynamicValue(ctx context.Context, proto6 *tfprotov6.DynamicValue, schema fwschema.Schema, description fwschemadata.DataDescription) (fwschemadata.Data, diag.Diagnostics) { + var diags diag.Diagnostics + + data := &fwschemadata.Data{ + Description: description, + Schema: schema, + } + + if proto6 == nil { + return *data, diags + } + + proto6Value, err := proto6.Unmarshal(schema.Type().TerraformType(ctx)) + + if err != nil { + diags.AddError( + "Unable to Convert "+description.Title(), + "An unexpected error was encountered when converting the "+description.String()+" from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Unable to unmarshal DynamicValue: "+err.Error(), + ) + + return *data, diags + } + + data.TerraformValue = proto6Value + + diags.Append(data.NullifyCollectionBlocks(ctx)...) + + return *data, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getfunctions.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getfunctions.go new file mode 100644 index 00000000..40c22535 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getfunctions.go @@ -0,0 +1,23 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetFunctionsRequest returns the *fwserver.GetFunctionsRequest +// equivalent of a *tfprotov6.GetFunctionsRequest. +func GetFunctionsRequest(ctx context.Context, proto *tfprotov6.GetFunctionsRequest) *fwserver.GetFunctionsRequest { + if proto == nil { + return nil + } + + fw := &fwserver.GetFunctionsRequest{} + + return fw +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getmetadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getmetadata.go new file mode 100644 index 00000000..a9eedc56 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getmetadata.go @@ -0,0 +1,23 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetMetadataRequest returns the *fwserver.GetMetadataRequest +// equivalent of a *tfprotov6.GetMetadataRequest. +func GetMetadataRequest(ctx context.Context, proto6 *tfprotov6.GetMetadataRequest) *fwserver.GetMetadataRequest { + if proto6 == nil { + return nil + } + + fw := &fwserver.GetMetadataRequest{} + + return fw +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getproviderschema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getproviderschema.go new file mode 100644 index 00000000..daea7c82 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/getproviderschema.go @@ -0,0 +1,23 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetProviderSchemaRequest returns the *fwserver.GetProviderSchemaRequest +// equivalent of a *tfprotov6.GetProviderSchemaRequest. +func GetProviderSchemaRequest(ctx context.Context, proto6 *tfprotov6.GetProviderSchemaRequest) *fwserver.GetProviderSchemaRequest { + if proto6 == nil { + return nil + } + + fw := &fwserver.GetProviderSchemaRequest{} + + return fw +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/importresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/importresourcestate.go new file mode 100644 index 00000000..11018c41 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/importresourcestate.go @@ -0,0 +1,52 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// ImportResourceStateRequest returns the *fwserver.ImportResourceStateRequest +// equivalent of a *tfprotov6.ImportResourceStateRequest. +func ImportResourceStateRequest(ctx context.Context, proto6 *tfprotov6.ImportResourceStateRequest, resource resource.Resource, resourceSchema fwschema.Schema) (*fwserver.ImportResourceStateRequest, diag.Diagnostics) { + if proto6 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if resourceSchema == nil { + diags.AddError( + "Unable to Create Empty State", + "An unexpected error was encountered when creating the empty state. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + fw := &fwserver.ImportResourceStateRequest{ + EmptyState: tfsdk.State{ + Raw: tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), nil), + Schema: resourceSchema, + }, + ID: proto6.ID, + Resource: resource, + TypeName: proto6.TypeName, + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/moveresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/moveresourcestate.go new file mode 100644 index 00000000..6b31a2cc --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/moveresourcestate.go @@ -0,0 +1,56 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// MoveResourceStateRequest returns the *fwserver.MoveResourceStateRequest +// equivalent of a *tfprotov6.MoveResourceStateRequest. +func MoveResourceStateRequest(ctx context.Context, proto6 *tfprotov6.MoveResourceStateRequest, resource resource.Resource, resourceSchema fwschema.Schema) (*fwserver.MoveResourceStateRequest, diag.Diagnostics) { + if proto6 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if resourceSchema == nil { + diags.AddError( + "Framework Implementation Error", + "An unexpected issue was encountered when converting the MoveResourceState RPC request information from the protocol type to the framework type. "+ + "The resource schema was missing. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.", + ) + + return nil, diags + } + + fw := &fwserver.MoveResourceStateRequest{ + SourceProviderAddress: proto6.SourceProviderAddress, + SourceRawState: proto6.SourceState, + SourceSchemaVersion: proto6.SourceSchemaVersion, + SourceTypeName: proto6.SourceTypeName, + TargetResource: resource, + TargetResourceSchema: resourceSchema, + TargetTypeName: proto6.TargetTypeName, + } + + sourcePrivate, sourcePrivateDiags := privatestate.NewData(ctx, proto6.SourcePrivate) + + diags.Append(sourcePrivateDiags...) + + fw.SourcePrivate = sourcePrivate + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/plan.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/plan.go new file mode 100644 index 00000000..4ebb0137 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/plan.go @@ -0,0 +1,53 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// Plan returns the *tfsdk.Plan for a *tfprotov6.DynamicValue and +// fwschema.Schema. +func Plan(ctx context.Context, proto6DynamicValue *tfprotov6.DynamicValue, schema fwschema.Schema) (*tfsdk.Plan, diag.Diagnostics) { + if proto6DynamicValue == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if schema == nil { + diags.AddError( + "Unable to Convert Plan", + "An unexpected error was encountered when converting the plan from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + data, dynamicValueDiags := DynamicValue(ctx, proto6DynamicValue, schema, fwschemadata.DataDescriptionPlan) + + diags.Append(dynamicValueDiags...) + + if diags.HasError() { + return nil, diags + } + + fw := &tfsdk.Plan{ + Raw: data.TerraformValue, + Schema: schema, + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/planresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/planresourcechange.go new file mode 100644 index 00000000..3c2bb3e9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/planresourcechange.go @@ -0,0 +1,77 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +// PlanResourceChangeRequest returns the *fwserver.PlanResourceChangeRequest +// equivalent of a *tfprotov6.PlanResourceChangeRequest. +func PlanResourceChangeRequest(ctx context.Context, proto6 *tfprotov6.PlanResourceChangeRequest, resource resource.Resource, resourceSchema fwschema.Schema, providerMetaSchema fwschema.Schema) (*fwserver.PlanResourceChangeRequest, diag.Diagnostics) { + if proto6 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if resourceSchema == nil { + diags.AddError( + "Missing Resource Schema", + "An unexpected error was encountered when handling the request. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + fw := &fwserver.PlanResourceChangeRequest{ + ResourceSchema: resourceSchema, + Resource: resource, + } + + config, configDiags := Config(ctx, proto6.Config, resourceSchema) + + diags.Append(configDiags...) + + fw.Config = config + + priorState, priorStateDiags := State(ctx, proto6.PriorState, resourceSchema) + + diags.Append(priorStateDiags...) + + fw.PriorState = priorState + + proposedNewState, proposedNewStateDiags := Plan(ctx, proto6.ProposedNewState, resourceSchema) + + diags.Append(proposedNewStateDiags...) + + fw.ProposedNewState = proposedNewState + + providerMeta, providerMetaDiags := ProviderMeta(ctx, proto6.ProviderMeta, providerMetaSchema) + + diags.Append(providerMetaDiags...) + + fw.ProviderMeta = providerMeta + + privateData, privateDataDiags := privatestate.NewData(ctx, proto6.PriorPrivate) + + diags.Append(privateDataDiags...) + + fw.PriorPrivate = privateData + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/providermeta.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/providermeta.go new file mode 100644 index 00000000..8b846460 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/providermeta.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// ProviderMeta returns the *tfsdk.Config for a *tfprotov6.DynamicValue and +// fwschema.Schema. This data handling is different than Config to simplify +// implementors, in that: +// +// - Missing Schema will return nil, rather than an error +// - Missing DynamicValue will return nil typed Value, rather than an error +func ProviderMeta(ctx context.Context, proto6DynamicValue *tfprotov6.DynamicValue, schema fwschema.Schema) (*tfsdk.Config, diag.Diagnostics) { + if schema == nil { + return nil, nil + } + + var diags diag.Diagnostics + + fw := &tfsdk.Config{ + Raw: tftypes.NewValue(schema.Type().TerraformType(ctx), nil), + Schema: schema, + } + + if proto6DynamicValue == nil { + return fw, nil + } + + proto6Value, err := proto6DynamicValue.Unmarshal(schema.Type().TerraformType(ctx)) + + if err != nil { + diags.AddError( + "Unable to Convert Provider Meta Configuration", + "An unexpected error was encountered when converting the provider meta configuration from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+err.Error(), + ) + + return nil, diags + } + + fw.Raw = proto6Value + + return fw, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/readdatasource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/readdatasource.go new file mode 100644 index 00000000..83c264cd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/readdatasource.go @@ -0,0 +1,57 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ReadDataSourceRequest returns the *fwserver.ReadDataSourceRequest +// equivalent of a *tfprotov6.ReadDataSourceRequest. +func ReadDataSourceRequest(ctx context.Context, proto6 *tfprotov6.ReadDataSourceRequest, dataSource datasource.DataSource, dataSourceSchema fwschema.Schema, providerMetaSchema fwschema.Schema) (*fwserver.ReadDataSourceRequest, diag.Diagnostics) { + if proto6 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if dataSourceSchema == nil { + diags.AddError( + "Missing DataSource Schema", + "An unexpected error was encountered when handling the request. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + fw := &fwserver.ReadDataSourceRequest{ + DataSourceSchema: dataSourceSchema, + DataSource: dataSource, + } + + config, configDiags := Config(ctx, proto6.Config, dataSourceSchema) + + diags.Append(configDiags...) + + fw.Config = config + + providerMeta, providerMetaDiags := ProviderMeta(ctx, proto6.ProviderMeta, providerMetaSchema) + + diags.Append(providerMetaDiags...) + + fw.ProviderMeta = providerMeta + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/readresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/readresource.go new file mode 100644 index 00000000..4e48e565 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/readresource.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +// ReadResourceRequest returns the *fwserver.ReadResourceRequest +// equivalent of a *tfprotov6.ReadResourceRequest. +func ReadResourceRequest(ctx context.Context, proto6 *tfprotov6.ReadResourceRequest, resource resource.Resource, resourceSchema fwschema.Schema, providerMetaSchema fwschema.Schema) (*fwserver.ReadResourceRequest, diag.Diagnostics) { + if proto6 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + fw := &fwserver.ReadResourceRequest{ + Resource: resource, + } + + currentState, currentStateDiags := State(ctx, proto6.CurrentState, resourceSchema) + + diags.Append(currentStateDiags...) + + fw.CurrentState = currentState + + providerMeta, providerMetaDiags := ProviderMeta(ctx, proto6.ProviderMeta, providerMetaSchema) + + diags.Append(providerMetaDiags...) + + fw.ProviderMeta = providerMeta + + privateData, privateDataDiags := privatestate.NewData(ctx, proto6.Private) + + diags.Append(privateDataDiags...) + + fw.Private = privateData + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/state.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/state.go new file mode 100644 index 00000000..f33d637a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/state.go @@ -0,0 +1,53 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// State returns the *tfsdk.State for a *tfprotov6.DynamicValue and +// fwschema.Schema. +func State(ctx context.Context, proto6DynamicValue *tfprotov6.DynamicValue, schema fwschema.Schema) (*tfsdk.State, diag.Diagnostics) { + if proto6DynamicValue == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if schema == nil { + diags.AddError( + "Unable to Convert State", + "An unexpected error was encountered when converting the state from the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + data, dynamicValueDiags := DynamicValue(ctx, proto6DynamicValue, schema, fwschemadata.DataDescriptionState) + + diags.Append(dynamicValueDiags...) + + if diags.HasError() { + return nil, diags + } + + fw := &tfsdk.State{ + Raw: data.TerraformValue, + Schema: schema, + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/upgraderesourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/upgraderesourcestate.go new file mode 100644 index 00000000..f3820a20 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/upgraderesourcestate.go @@ -0,0 +1,47 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// UpgradeResourceStateRequest returns the *fwserver.UpgradeResourceStateRequest +// equivalent of a *tfprotov6.UpgradeResourceStateRequest. +func UpgradeResourceStateRequest(ctx context.Context, proto6 *tfprotov6.UpgradeResourceStateRequest, resource resource.Resource, resourceSchema fwschema.Schema) (*fwserver.UpgradeResourceStateRequest, diag.Diagnostics) { + if proto6 == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Panic prevention here to simplify the calling implementations. + // This should not happen, but just in case. + if resourceSchema == nil { + diags.AddError( + "Unable to Create Empty State", + "An unexpected error was encountered when creating the empty state. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Missing schema.", + ) + + return nil, diags + } + + fw := &fwserver.UpgradeResourceStateRequest{ + RawState: proto6.RawState, + ResourceSchema: resourceSchema, + Resource: resource, + Version: proto6.Version, + } + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validatedatasourceconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validatedatasourceconfig.go new file mode 100644 index 00000000..cd4fa6ea --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validatedatasourceconfig.go @@ -0,0 +1,31 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ValidateDataSourceConfigRequest returns the *fwserver.ValidateDataSourceConfigRequest +// equivalent of a *tfprotov6.ValidateDataSourceConfigRequest. +func ValidateDataSourceConfigRequest(ctx context.Context, proto6 *tfprotov6.ValidateDataResourceConfigRequest, dataSource datasource.DataSource, dataSourceSchema fwschema.Schema) (*fwserver.ValidateDataSourceConfigRequest, diag.Diagnostics) { + if proto6 == nil { + return nil, nil + } + + fw := &fwserver.ValidateDataSourceConfigRequest{} + + config, diags := Config(ctx, proto6.Config, dataSourceSchema) + + fw.Config = config + fw.DataSource = dataSource + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validateproviderconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validateproviderconfig.go new file mode 100644 index 00000000..8d36aa0c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validateproviderconfig.go @@ -0,0 +1,29 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ValidateProviderConfigRequest returns the *fwserver.ValidateProviderConfigRequest +// equivalent of a *tfprotov6.ValidateProviderConfigRequest. +func ValidateProviderConfigRequest(ctx context.Context, proto6 *tfprotov6.ValidateProviderConfigRequest, providerSchema fwschema.Schema) (*fwserver.ValidateProviderConfigRequest, diag.Diagnostics) { + if proto6 == nil { + return nil, nil + } + + fw := &fwserver.ValidateProviderConfigRequest{} + + config, diags := Config(ctx, proto6.Config, providerSchema) + + fw.Config = config + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validateresourceconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validateresourceconfig.go new file mode 100644 index 00000000..1eb65aa8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromproto6/validateresourceconfig.go @@ -0,0 +1,31 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ValidateResourceConfigRequest returns the *fwserver.ValidateResourceConfigRequest +// equivalent of a *tfprotov6.ValidateResourceConfigRequest. +func ValidateResourceConfigRequest(ctx context.Context, proto6 *tfprotov6.ValidateResourceConfigRequest, resource resource.Resource, resourceSchema fwschema.Schema) (*fwserver.ValidateResourceConfigRequest, diag.Diagnostics) { + if proto6 == nil { + return nil, nil + } + + fw := &fwserver.ValidateResourceConfigRequest{} + + config, diags := Config(ctx, proto6.Config, resourceSchema) + + fw.Config = config + fw.Resource = resource + + return fw, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/attribute_path.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/attribute_path.go new file mode 100644 index 00000000..ce19178f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/attribute_path.go @@ -0,0 +1,91 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromtftypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// AttributePath returns the path.Path equivalent of a *tftypes.AttributePath. +func AttributePath(ctx context.Context, tfType *tftypes.AttributePath, schema fwschema.Schema) (path.Path, diag.Diagnostics) { + fwPath := path.Empty() + + for tfTypeStepIndex, tfTypeStep := range tfType.Steps() { + currentTfTypeSteps := tfType.Steps()[:tfTypeStepIndex+1] + currentTfTypePath := tftypes.NewAttributePathWithSteps(currentTfTypeSteps) + attrType, err := schema.TypeAtTerraformPath(ctx, currentTfTypePath) + + if err != nil { + return path.Empty(), diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Unable to Convert Attribute Path", + "An unexpected error occurred while trying to convert an attribute path. "+ + "This is an error in terraform-plugin-framework used by the provider. "+ + "Please report the following to the provider developers.\n\n"+ + // Since this is an error with the attribute path + // conversion, we cannot return a protocol path-based + // diagnostic. Returning a framework human-readable + // representation seems like the next best thing to do. + fmt.Sprintf("Attribute Path: %s\n", currentTfTypePath.String())+ + fmt.Sprintf("Original Error: %s", err), + ), + } + } + + fwStep, err := AttributePathStep(ctx, tfTypeStep, attrType) + + if err != nil { + return path.Empty(), diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Unable to Convert Attribute Path", + "An unexpected error occurred while trying to convert an attribute path. "+ + "This is either an error in terraform-plugin-framework or a custom attribute type used by the provider. "+ + "Please report the following to the provider developers.\n\n"+ + // Since this is an error with the attribute path + // conversion, we cannot return a protocol path-based + // diagnostic. Returning a framework human-readable + // representation seems like the next best thing to do. + fmt.Sprintf("Attribute Path: %s\n", currentTfTypePath.String())+ + fmt.Sprintf("Original Error: %s", err), + ), + } + } + + // In lieu of creating a path.NewPathFromSteps function, this path + // building logic is inlined to not expand the path package API. + switch fwStep := fwStep.(type) { + case path.PathStepAttributeName: + fwPath = fwPath.AtName(string(fwStep)) + case path.PathStepElementKeyInt: + fwPath = fwPath.AtListIndex(int(fwStep)) + case path.PathStepElementKeyString: + fwPath = fwPath.AtMapKey(string(fwStep)) + case path.PathStepElementKeyValue: + fwPath = fwPath.AtSetValue(fwStep.Value) + default: + return fwPath, diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Unable to Convert Attribute Path", + "An unexpected error occurred while trying to convert an attribute path. "+ + "This is an error in terraform-plugin-framework used by the provider. "+ + "Please report the following to the provider developers.\n\n"+ + // Since this is an error with the attribute path + // conversion, we cannot return a protocol path-based + // diagnostic. Returning a framework human-readable + // representation seems like the next best thing to do. + fmt.Sprintf("Attribute Path: %s\n", currentTfTypePath.String())+ + fmt.Sprintf("Original Error: unknown path.PathStep type: %#v", fwStep), + ), + } + } + } + + return fwPath, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/attribute_path_step.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/attribute_path_step.go new file mode 100644 index 00000000..c61e9f85 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/attribute_path_step.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromtftypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// AttributePathStep returns the path.PathStep equivalent of a +// tftypes.AttributePathStep. An error is returned instead of diag.Diagnostics +// so callers can include appropriate logical context about when the error +// occurred. +func AttributePathStep(ctx context.Context, tfType tftypes.AttributePathStep, attrType attr.Type) (path.PathStep, error) { + switch tfType := tfType.(type) { + case tftypes.AttributeName: + return path.PathStepAttributeName(string(tfType)), nil + case tftypes.ElementKeyInt: + return path.PathStepElementKeyInt(int64(tfType)), nil + case tftypes.ElementKeyString: + return path.PathStepElementKeyString(string(tfType)), nil + case tftypes.ElementKeyValue: + attrValue, err := Value(ctx, tftypes.Value(tfType), attrType) + + if err != nil { + return nil, fmt.Errorf("unable to create PathStepElementKeyValue from tftypes.Value: %w", err) + } + + return path.PathStepElementKeyValue{Value: attrValue}, nil + default: + return nil, fmt.Errorf("unknown tftypes.AttributePathStep: %#v", tfType) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/doc.go new file mode 100644 index 00000000..e902d1aa --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package fromtftypes contains functions to convert from terraform-plugin-go +// tftypes types to framework types. +package fromtftypes diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/value.go new file mode 100644 index 00000000..1eded1f7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes/value.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromtftypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Value returns the attr.Value equivalent to the tftypes.Value. +func Value(ctx context.Context, tfType tftypes.Value, attrType attr.Type) (attr.Value, error) { + if attrType == nil { + return nil, fmt.Errorf("unable to convert tftypes.Value (%s) to attr.Value: missing attr.Type", tfType.String()) + } + + attrValue, err := attrType.ValueFromTerraform(ctx, tfType) + + if err != nil { + return nil, fmt.Errorf("unable to convert tftypes.Value (%s) to attr.Value: %w", tfType.String(), err) + } + + return attrValue, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/doc.go new file mode 100644 index 00000000..8acc6b88 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package fwfunction contains shared interfaces and structures for implementing behaviors +// in Terraform Provider function implementations. +package fwfunction diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/parameter_validate_implementation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/parameter_validate_implementation.go new file mode 100644 index 00000000..1e171f01 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/parameter_validate_implementation.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwfunction + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +// MAINTAINER NOTE: This interface doesn't need to be internal but we're initially keeping them +// private until we determine if they would be useful to expose as a public interface. + +// ParameterWithValidateImplementation is an optional interface on +// function.Parameter which enables validation of the provider-defined implementation +// for the function.Parameter. This logic runs during the GetProviderSchema RPC, or via +// provider-defined unit testing, to ensure the provider's definition is valid +// before further usage could cause other unexpected errors or panics. +type ParameterWithValidateImplementation interface { + // ValidateImplementation should contain the logic which validates + // the function.Parameter implementation. Since this logic can prevent the provider + // from being usable, it should be very targeted and defensive against + // false positives. + ValidateImplementation(context.Context, ValidateParameterImplementationRequest, *ValidateParameterImplementationResponse) +} + +// ValidateParameterImplementationRequest contains the information available +// during a ValidateImplementation call to validate the function.Parameter +// definition. ValidateParameterImplementationResponse is the type used for +// responses. +type ValidateParameterImplementationRequest struct { + // ParameterPosition is the position of the parameter in the function definition for reporting diagnostics. + // A parameter without a position (i.e. `nil`) is the variadic parameter. + ParameterPosition *int64 + + // Name is the provider-defined parameter name or the default parameter name for reporting diagnostics. + // + // MAINTAINER NOTE: Since parameter names are not required currently and can be defaulted by internal framework logic, + // we accept the Name in this validate request, rather than using `(function.Parameter).GetName()` for diagnostics, which + // could be empty. + Name string +} + +// ValidateParameterImplementationResponse contains the returned data from a +// ValidateImplementation method call to validate the function.Parameter +// implementation. ValidateParameterImplementationRequest is the type used for +// requests. +type ValidateParameterImplementationResponse struct { + // Diagnostics report errors or warnings related to validating the + // definition of the function.Parameter. An empty slice indicates success, with no + // warnings or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/return_validate_implementation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/return_validate_implementation.go new file mode 100644 index 00000000..17de03cf --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwfunction/return_validate_implementation.go @@ -0,0 +1,43 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwfunction + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +// MAINTAINER NOTE: This interface doesn't need to be internal but we're initially keeping them +// private until we determine if they would be useful to expose as a public interface. + +// ReturnWithValidateImplementation is an optional interface on +// function.Return which enables validation of the provider-defined implementation +// for the function.Return. This logic runs during the GetProviderSchema RPC, or via +// provider-defined unit testing, to ensure the provider's definition is valid +// before further usage could cause other unexpected errors or panics. +type ReturnWithValidateImplementation interface { + // ValidateImplementation should contain the logic which validates + // the function.Return implementation. Since this logic can prevent the provider + // from being usable, it should be very targeted and defensive against + // false positives. + ValidateImplementation(context.Context, ValidateReturnImplementationRequest, *ValidateReturnImplementationResponse) +} + +// ValidateReturnImplementationRequest contains the information available +// during a ValidateImplementation call to validate the function.Return +// definition. ValidateReturnImplementationResponse is the type used for +// responses. +type ValidateReturnImplementationRequest struct{} + +// ValidateReturnImplementationResponse contains the returned data from a +// ValidateImplementation method call to validate the function.Return +// implementation. ValidateReturnImplementationRequest is the type used for +// requests. +type ValidateReturnImplementationResponse struct { + // Diagnostics report errors or warnings related to validating the + // definition of the function.Return. An empty slice indicates success, with no + // warnings or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute.go new file mode 100644 index 00000000..4face5a9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute.go @@ -0,0 +1,105 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Attribute is the core interface required for implementing Terraform +// schema functionality that can accept a value. Refer to NestedAttribute for +// the additional interface that defines nested attributes. +// +// Refer to the internal/fwschema/fwxschema package for optional interfaces +// that define framework-specific functionality, such a plan modification and +// validation. +type Attribute interface { + // Implementations should include the tftypes.AttributePathStepper + // interface methods for proper path and data handling. + tftypes.AttributePathStepper + + // Equal should return true if the other attribute is exactly equivalent. + Equal(o Attribute) bool + + // GetDeprecationMessage should return a non-empty string if an attribute + // is deprecated. This is named differently than DeprecationMessage to + // prevent a conflict with the tfsdk.Attribute field name. + GetDeprecationMessage() string + + // GetDescription should return a non-empty string if an attribute + // has a plaintext description. This is named differently than Description + // to prevent a conflict with the tfsdk.Attribute field name. + GetDescription() string + + // GetMarkdownDescription should return a non-empty string if an attribute + // has a Markdown description. This is named differently than + // MarkdownDescription to prevent a conflict with the tfsdk.Attribute field + // name. + GetMarkdownDescription() string + + // GetType should return the framework type of an attribute. This is named + // differently than Type to prevent a conflict with the tfsdk.Attribute + // field name. + GetType() attr.Type + + // IsComputed should return true if the attribute configuration value is + // computed. This is named differently than Computed to prevent a conflict + // with the tfsdk.Attribute field name. + IsComputed() bool + + // IsOptional should return true if the attribute configuration value is + // optional. This is named differently than Optional to prevent a conflict + // with the tfsdk.Attribute field name. + IsOptional() bool + + // IsRequired should return true if the attribute configuration value is + // required. This is named differently than Required to prevent a conflict + // with the tfsdk.Attribute field name. + IsRequired() bool + + // IsSensitive should return true if the attribute configuration value is + // sensitive. This is named differently than Sensitive to prevent a + // conflict with the tfsdk.Attribute field name. + IsSensitive() bool +} + +// AttributesEqual is a helper function to perform equality testing on two +// Attribute. Attribute Equal implementations should still compare the concrete +// types in addition to using this helper. +func AttributesEqual(a, b Attribute) bool { + if !a.GetType().Equal(b.GetType()) { + return false + } + + if a.GetDeprecationMessage() != b.GetDeprecationMessage() { + return false + } + + if a.GetDescription() != b.GetDescription() { + return false + } + + if a.GetMarkdownDescription() != b.GetMarkdownDescription() { + return false + } + + if a.IsRequired() != b.IsRequired() { + return false + } + + if a.IsOptional() != b.IsOptional() { + return false + } + + if a.IsComputed() != b.IsComputed() { + return false + } + + if a.IsSensitive() != b.IsSensitive() { + return false + } + + return true +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_default.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_default.go new file mode 100644 index 00000000..29e63a7b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_default.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" +) + +// AttributeWithBoolDefaultValue is an optional interface on Attribute which +// enables Bool default value support. +type AttributeWithBoolDefaultValue interface { + Attribute + + BoolDefaultValue() defaults.Bool +} + +// AttributeWithFloat64DefaultValue is an optional interface on Attribute which +// enables Float64 default value support. +type AttributeWithFloat64DefaultValue interface { + Attribute + + Float64DefaultValue() defaults.Float64 +} + +// AttributeWithInt64DefaultValue is an optional interface on Attribute which +// enables Int64 default value support. +type AttributeWithInt64DefaultValue interface { + Attribute + + Int64DefaultValue() defaults.Int64 +} + +// AttributeWithListDefaultValue is an optional interface on Attribute which +// enables List default value support. +type AttributeWithListDefaultValue interface { + Attribute + + ListDefaultValue() defaults.List +} + +// AttributeWithMapDefaultValue is an optional interface on Attribute which +// enables Map default value support. +type AttributeWithMapDefaultValue interface { + Attribute + + MapDefaultValue() defaults.Map +} + +// AttributeWithNumberDefaultValue is an optional interface on Attribute which +// enables Number default value support. +type AttributeWithNumberDefaultValue interface { + Attribute + + NumberDefaultValue() defaults.Number +} + +// AttributeWithObjectDefaultValue is an optional interface on Attribute which +// enables Object default value support. +type AttributeWithObjectDefaultValue interface { + Attribute + + ObjectDefaultValue() defaults.Object +} + +// AttributeWithSetDefaultValue is an optional interface on Attribute which +// enables Set default value support. +type AttributeWithSetDefaultValue interface { + Attribute + + SetDefaultValue() defaults.Set +} + +// AttributeWithStringDefaultValue is an optional interface on Attribute which +// enables String default value support. +type AttributeWithStringDefaultValue interface { + Attribute + + StringDefaultValue() defaults.String +} + +// AttributeWithDynamicDefaultValue is an optional interface on Attribute which +// enables Dynamic default value support. +type AttributeWithDynamicDefaultValue interface { + Attribute + + DynamicDefaultValue() defaults.Dynamic +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_name_validation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_name_validation.go new file mode 100644 index 00000000..3d742955 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_name_validation.go @@ -0,0 +1,162 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "fmt" + "regexp" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// NumericPrefixRegex is a regular expression which matches whether a string +// begins with a numeric (0-9). +var NumericPrefixRegex = regexp.MustCompile(`^[0-9]`) + +// ReservedProviderAttributeNames contains the list of root attribute names +// which should not be included in provider-defined provider schemas since +// they require practitioners to implement special syntax in their +// configurations to be usable by the provider. +var ReservedProviderAttributeNames = []string{ + // Reference: https://developer.hashicorp.com/terraform/language/providers/configuration#alias-multiple-provider-configurations + "alias", + // Reference: https://developer.hashicorp.com/terraform/language/providers/configuration#version-deprecated + "version", +} + +// ReservedResourceAttributeNames contains the list of root attribute names +// which should not be included in provider-defined managed resource and +// data source schemas since they require practitioners to implement special +// syntax in their configurations to be usable by the provider resource. +var ReservedResourceAttributeNames = []string{ + // Reference: https://developer.hashicorp.com/terraform/language/resources/provisioners/connection + "connection", + // Reference: https://developer.hashicorp.com/terraform/language/meta-arguments/count + "count", + // Reference: https://developer.hashicorp.com/terraform/language/meta-arguments/depends_on + "depends_on", + // Reference: https://developer.hashicorp.com/terraform/language/meta-arguments/for_each + "for_each", + // Reference: https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle + "lifecycle", + // Reference: https://developer.hashicorp.com/terraform/language/meta-arguments/resource-provider + "provider", + // Reference: https://developer.hashicorp.com/terraform/language/resources/provisioners/syntax + "provisioner", +} + +// ValidAttributeNameRegex contains the regular expression to validate +// attribute names, which are considered [identifiers] in the Terraform +// configuration language. +// +// Hyphen characters (-) are technically valid in identifiers, however they are +// explicitly not validated due to the provider ecosystem conventionally never +// including them in attribute names. Introducing them could cause practitioner +// confusion. +// +// [identifiers]: https://developer.hashicorp.com/terraform/language/syntax/configuration#identifiers +var ValidAttributeNameRegex = regexp.MustCompile("^[a-z_][a-z0-9_]*$") + +// IsReservedProviderAttributeName returns an error diagnostic if the given +// attribute path represents a root attribute name in +// ReservedProviderAttributeNames. Other paths are automatically skipped +// without error. +func IsReservedProviderAttributeName(name string, attributePath path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + // Check that given path is root attribute name. This simplifies calling + // logic to not worry about conditionalizing this check. + if len(attributePath.Steps()) != 1 { + return diags + } + + for _, reservedName := range ReservedProviderAttributeNames { + if name == reservedName { + // The diagnostic path is intentionally omitted as it is invalid + // in this context. Diagnostic paths are intended to be mapped to + // actual data, while this path information must be synthesized. + diags.AddError( + "Reserved Root Attribute/Block Name", + "When validating the provider schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("%q is a reserved root attribute/block name. ", name)+ + "This is to prevent practitioners from needing special Terraform configuration syntax.", + ) + + break + } + } + + return diags +} + +// IsReservedResourceAttributeName returns an error diagnostic if the given +// attribute path represents a root attribute name in +// ReservedResourceAttributeNames. Other paths are automatically skipped +// without error. +func IsReservedResourceAttributeName(name string, attributePath path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + // Check that given path is root attribute name. This simplifies calling + // logic to not worry about conditionalizing this check. + if len(attributePath.Steps()) != 1 { + return diags + } + + for _, reservedName := range ReservedResourceAttributeNames { + if name == reservedName { + // The diagnostic path is intentionally omitted as it is invalid + // in this context. Diagnostic paths are intended to be mapped to + // actual data, while this path information must be synthesized. + diags.AddError( + "Reserved Root Attribute/Block Name", + "When validating the resource or data source schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("%q is a reserved root attribute/block name. ", name)+ + "This is to prevent practitioners from needing special Terraform configuration syntax.", + ) + + break + } + } + + return diags +} + +// IsValidAttributeName returns an error diagnostic if the given +// attribute path has an invalid attribute name according to +// ValidAttributeNameRegex. Non-AttributeName paths are automatically skipped +// without error. +func IsValidAttributeName(name string, attributePath path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + if ValidAttributeNameRegex.MatchString(name) { + return diags + } + + var message strings.Builder + + message.WriteString("Names must ") + + if NumericPrefixRegex.MatchString(name) { + message.WriteString("begin with a lowercase alphabet character (a-z) or underscore (_) and must ") + } + + message.WriteString("only contain lowercase alphanumeric characters (a-z, 0-9) and underscores (_).") + + // The diagnostic path is intentionally omitted as it is invalid in this + // context. Diagnostic paths are intended to be mapped to actual data, + // while this path information must be synthesized. + diags.AddError( + "Invalid Attribute/Block Name", + "When validating the schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("%q at schema path %q is an invalid attribute/block name. ", name, attributePath)+ + message.String(), + ) + + return diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_nesting_mode.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_nesting_mode.go new file mode 100644 index 00000000..612c2c5c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_nesting_mode.go @@ -0,0 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +// NestingMode is an enum type of the ways nested attributes can be nested in +// an attribute. They can be a list, a set, a map (with string +// keys), or they can be nested directly, like an object. +type NestingMode uint8 + +const ( + // NestingModeUnknown is an invalid nesting mode, used to catch when a + // nesting mode is expected and not set. + NestingModeUnknown NestingMode = 0 + + // NestingModeSingle is for attributes that represent a struct or + // object, a single instance of those attributes directly nested under + // another attribute. + NestingModeSingle NestingMode = 1 + + // NestingModeList is for attributes that represent a list of objects, + // with multiple instances of those attributes nested inside a list + // under another attribute. + NestingModeList NestingMode = 2 + + // NestingModeSet is for attributes that represent a set of objects, + // with multiple, unique instances of those attributes nested inside a + // set under another attribute. + NestingModeSet NestingMode = 3 + + // NestingModeMap is for attributes that represent a map of objects, + // with multiple instances of those attributes, each associated with a + // unique string key, nested inside a map under another attribute. + NestingModeMap NestingMode = 4 +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_validate_implementation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_validate_implementation.go new file mode 100644 index 00000000..a0159a09 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/attribute_validate_implementation.go @@ -0,0 +1,100 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// AttributeWithValidateImplementation is an optional interface on +// Attribute which enables validation of the provider-defined implementation +// for the Attribute. This logic runs during Validate* RPCs, or via +// provider-defined unit testing, to ensure the provider's definition is valid +// before further usage could cause other unexpected errors or panics. +type AttributeWithValidateImplementation interface { + Attribute + + // ValidateImplementation should contain the logic which validates + // the Attribute implementation. Since this logic can prevent the provider + // from being usable, it should be very targeted and defensive against + // false positives. + ValidateImplementation(context.Context, ValidateImplementationRequest, *ValidateImplementationResponse) +} + +// ValidateImplementation contains the generic Attribute +// implementation validation logic for all types. +// +// This logic currently: +// - Checks whether the given AttributeName in the path is a valid identifier +// - If the given Attribute implements the +// AttributeWithValidateImplementation interface, calls the method +// - If the given Attribute implements the NestedAttribute interface, +// recursively calls this function on nested attributes +func ValidateAttributeImplementation(ctx context.Context, attribute Attribute, req ValidateImplementationRequest) diag.Diagnostics { + var diags diag.Diagnostics + + diags.Append(IsValidAttributeName(req.Name, req.Path)...) + + if attributeWithValidateImplementation, ok := attribute.(AttributeWithValidateImplementation); ok { + resp := &ValidateImplementationResponse{} + + attributeWithValidateImplementation.ValidateImplementation(ctx, req, resp) + + diags.Append(resp.Diagnostics...) + } + + nestedAttribute, ok := attribute.(NestedAttribute) + + if !ok { + return diags + } + + nestedObject := nestedAttribute.GetNestedObject() + + if nestedObject == nil { + return diags + } + + nestingMode := nestedAttribute.GetNestingMode() + + for nestedAttributeName, nestedAttribute := range nestedObject.GetAttributes() { + var nestedAttributePath path.Path + + // TODO: path.Path and path.PathExpression are intended to map onto + // actual data implementations, however we need some representation + // for schema paths without data. It may make sense to introduce an + // internal "schema path" to simplify outputting specialized + // strings for these types of diagnostics. + // + // The below choices of AtListIndex(0), etc. are arbitrary in this + // situation. + // + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/574 + switch nestingMode { + // case NestingModeList: + // nestedAttributePath = req.Path.AtListIndex(0).AtName(nestedAttributeName) + // case NestingModeMap: + // nestedAttributePath = req.Path.AtMapKey("*").AtName(nestedAttributeName) + // case NestingModeSet: + // nestedAttributePath = req.Path.AtSetValue(types.StringValue("*")).AtName(nestedAttributeName) + // case NestingModeSingle: + // nestedAttributePath = req.Path.AtName(nestedAttributeName) + default: + // This is purely to preserve the prior logic. Refer to above comment. + nestedAttributePath = req.Path.AtName(nestedAttributeName) + } + + nestedReq := ValidateImplementationRequest{ + Name: nestedAttributeName, + Path: nestedAttributePath, + } + + diags.Append(ValidateAttributeImplementation(ctx, nestedAttribute, nestedReq)...) + } + + return diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block.go new file mode 100644 index 00000000..d37798d5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block.go @@ -0,0 +1,116 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Block is the core interface required for implementing Terraform schema +// functionality that structurally holds attributes and blocks. This is +// intended to be the first abstraction of tfsdk.Block functionality into +// data source, provider, and resource specific functionality. +// +// Refer to the internal/fwschema/fwxschema package for optional interfaces +// that define framework-specific functionality, such a plan modification and +// validation. +// +// Note that MaxItems and MinItems support, while defined in the Terraform +// protocol, is intentially not present. Terraform can only perform limited +// static analysis of blocks and errors generated occur before the provider +// is called for configuration validation, which means that practitioners do +// not get all configuration errors at the same time. Provider developers can +// implement validators to achieve the same validation functionality. +type Block interface { + // Implementations should include the tftypes.AttributePathStepper + // interface methods for proper path and data handling. + tftypes.AttributePathStepper + + // Equal should return true if the other block is exactly equivalent. + Equal(o Block) bool + + // GetDeprecationMessage should return a non-empty string if an attribute + // is deprecated. This is named differently than DeprecationMessage to + // prevent a conflict with the tfsdk.Attribute field name. + GetDeprecationMessage() string + + // GetDescription should return a non-empty string if an attribute + // has a plaintext description. This is named differently than Description + // to prevent a conflict with the tfsdk.Attribute field name. + GetDescription() string + + // GetMarkdownDescription should return a non-empty string if an attribute + // has a Markdown description. This is named differently than + // MarkdownDescription to prevent a conflict with the tfsdk.Attribute field + // name. + GetMarkdownDescription() string + + // GetNestedObject should return the object underneath the block. + // For single nesting mode, the NestedBlockObject can be generated from + // the Block. + GetNestedObject() NestedBlockObject + + // GetNestingMode should return the nesting mode of a block. This is named + // differently than NestingMode to prevent a conflict with the tfsdk.Block + // field name. + GetNestingMode() BlockNestingMode + + // Type should return the framework type of a block. + Type() attr.Type +} + +// BlocksEqual is a helper function to perform equality testing on two +// Block. Attribute Equal implementations should still compare the concrete +// types in addition to using this helper. +func BlocksEqual(a, b Block) bool { + if !a.Type().Equal(b.Type()) { + return false + } + + if a.GetDeprecationMessage() != b.GetDeprecationMessage() { + return false + } + + if a.GetDescription() != b.GetDescription() { + return false + } + + if a.GetMarkdownDescription() != b.GetMarkdownDescription() { + return false + } + + if a.GetNestingMode() != b.GetNestingMode() { + return false + } + + return a.GetNestedObject().Equal(b.GetNestedObject()) +} + +// BlockPathExpressions recursively returns a slice of the current path +// expression and all underlying path expressions which represent a Block. +func BlockPathExpressions(ctx context.Context, block Block, pathExpression path.Expression) path.Expressions { + result := path.Expressions{pathExpression} + + for name, nestedBlock := range block.GetNestedObject().GetBlocks() { + nestingMode := block.GetNestingMode() + + switch nestingMode { + case BlockNestingModeList: + result = append(result, BlockPathExpressions(ctx, nestedBlock, pathExpression.AtAnyListIndex().AtName(name))...) + case BlockNestingModeSet: + result = append(result, BlockPathExpressions(ctx, nestedBlock, pathExpression.AtAnySetValue().AtName(name))...) + case BlockNestingModeSingle: + result = append(result, BlockPathExpressions(ctx, nestedBlock, pathExpression.AtName(name))...) + default: + panic(fmt.Sprintf("unhandled BlockNestingMode: %T", nestingMode)) + } + } + + return result +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block_nested_mode.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block_nested_mode.go new file mode 100644 index 00000000..a5f2e1e7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block_nested_mode.go @@ -0,0 +1,39 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +// BlockNestingMode is an enum type of the ways attributes and blocks can be +// nested in a block. They can be a list or a set. +// +// While the protocol and theoretically Terraform itself support map and group +// nesting modes, this framework intentionally only supports list, set, and +// single blocks as those other modes were not typically implemented or +// tested with Terraform since the older Terraform Plugin SDK did not support +// them. +type BlockNestingMode uint8 + +const ( + // BlockNestingModeUnknown is an invalid nesting mode, used to catch when a + // nesting mode is expected and not set. + BlockNestingModeUnknown BlockNestingMode = 0 + + // BlockNestingModeList is for attributes that represent a list of objects, + // with multiple instances of those attributes nested inside a list + // under another attribute. + BlockNestingModeList BlockNestingMode = 1 + + // BlockNestingModeSet is for attributes that represent a set of objects, + // with multiple, unique instances of those attributes nested inside a + // set under another attribute. + BlockNestingModeSet BlockNestingMode = 2 + + // BlockNestingModeSingle is for attributes that represent a single object. + // The object cannot be repeated in the practitioner configuration. + // + // While the framework implements support for this block nesting mode, it + // is not thoroughly tested in production Terraform environments beyond the + // resource timeouts block from the older Terraform Plugin SDK. Use single + // nested attributes for new implementations instead. + BlockNestingModeSingle BlockNestingMode = 3 +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block_validate_implementation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block_validate_implementation.go new file mode 100644 index 00000000..ea1c1530 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/block_validate_implementation.go @@ -0,0 +1,125 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// BlockWithValidateImplementation is an optional interface on +// Block which enables validation of the provider-defined implementation +// for the Block. This logic runs during Validate* RPCs, or via +// provider-defined unit testing, to ensure the provider's definition is valid +// before further usage could cause other unexpected errors or panics. +type BlockWithValidateImplementation interface { + Block + + // ValidateImplementation should contain the logic which validates + // the Block implementation. Since this logic can prevent the provider + // from being usable, it should be very targeted and defensive against + // false positives. + ValidateImplementation(context.Context, ValidateImplementationRequest, *ValidateImplementationResponse) +} + +// ValidateBlockImplementation contains the generic Block implementation +// validation logic for all types. +// +// This logic currently: +// - Checks whether the given AttributeName in the path is a valid identifier +// - If the given Block implements the BlockWithValidateImplementation +// interface, calls the method +// - Recursively calls this function on nested attributes and blocks +func ValidateBlockImplementation(ctx context.Context, block Block, req ValidateImplementationRequest) diag.Diagnostics { + var diags diag.Diagnostics + + diags.Append(IsReservedResourceAttributeName(req.Name, req.Path)...) + diags.Append(IsValidAttributeName(req.Name, req.Path)...) + + if blockWithValidateImplementation, ok := block.(BlockWithValidateImplementation); ok { + resp := &ValidateImplementationResponse{} + + blockWithValidateImplementation.ValidateImplementation(ctx, req, resp) + + diags.Append(resp.Diagnostics...) + } + + nestedObject := block.GetNestedObject() + + if nestedObject == nil { + return diags + } + + nestingMode := block.GetNestingMode() + + for nestedAttributeName, nestedAttribute := range nestedObject.GetAttributes() { + var nestedAttributePath path.Path + + // TODO: path.Path and path.PathExpression are intended to map onto + // actual data implementations, however we need some representation + // for schema paths without data. It may make sense to introduce an + // internal "schema path" to simplify outputting specialized + // strings for these types of diagnostics. + // + // The below choices of AtListIndex(0), etc. are arbitrary in this + // situation. + // + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/574 + switch nestingMode { + // case BlockNestingModeList: + // nestedAttributePath = req.Path.AtListIndex(0).AtName(nestedAttributeName) + // case BlockNestingModeSet: + // nestedAttributePath = req.Path.AtSetValue(types.StringValue("*")).AtName(nestedAttributeName) + // case BlockNestingModeSingle: + // nestedAttributePath = req.Path.AtName(nestedAttributeName) + default: + // This is purely to preserve the prior logic. Refer to above comment. + nestedAttributePath = req.Path.AtName(nestedAttributeName) + } + + nestedReq := ValidateImplementationRequest{ + Name: nestedAttributeName, + Path: nestedAttributePath, + } + + diags.Append(ValidateAttributeImplementation(ctx, nestedAttribute, nestedReq)...) + } + + for nestedBlockName, nestedBlock := range nestedObject.GetBlocks() { + var nestedBlockPath path.Path + + // TODO: path.Path and path.PathExpression are intended to map onto + // actual data implementations, however we need some representation + // for schema paths without data. It may make sense to introduce an + // internal "schema path" to simplify outputting specialized + // strings for these types of diagnostics. + // + // The below choices of AtListIndex(0), etc. are arbitrary in this + // situation. + // + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/574 + switch nestingMode { + // case BlockNestingModeList: + // nestedBlockPath = req.Path.AtListIndex(0).AtName(nestedBlockName) + // case BlockNestingModeSet: + // nestedBlockPath = req.Path.AtSetValue(types.StringValue("*")).AtName(nestedBlockName) + // case BlockNestingModeSingle: + // nestedBlockPath = req.Path.AtName(nestedBlockName) + default: + // This is purely to preserve the prior logic. Refer to above comment. + nestedBlockPath = req.Path.AtName(nestedBlockName) + } + + nestedReq := ValidateImplementationRequest{ + Name: nestedBlockName, + Path: nestedBlockPath, + } + + diags.Append(ValidateBlockImplementation(ctx, nestedBlock, nestedReq)...) + } + + return diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/diagnostics.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/diagnostics.go new file mode 100644 index 00000000..c7953132 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/diagnostics.go @@ -0,0 +1,66 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// AttributeMissingAttributeTypesDiag returns an error diagnostic to provider +// developers about missing the AttributeTypes field on an Attribute +// implementation. This can cause unexpected errors or panics. +// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/699 +func AttributeMissingAttributeTypesDiag(attributePath path.Path) diag.Diagnostic { + // The diagnostic path is intentionally omitted as it is invalid in this + // context. Diagnostic paths are intended to be mapped to actual data, + // while this path information must be synthesized. + return diag.NewErrorDiagnostic( + "Invalid Attribute Implementation", + "When validating the schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("%q is missing the AttributeTypes or CustomType field on an object Attribute. ", attributePath)+ + "One of these fields is required to prevent other unexpected errors or panics.", + ) +} + +// AttributeMissingElementTypeDiag returns an error diagnostic to provider +// developers about missing the ElementType field on an Attribute +// implementation. This can cause unexpected errors or panics. +// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/699 +func AttributeMissingElementTypeDiag(attributePath path.Path) diag.Diagnostic { + // The diagnostic path is intentionally omitted as it is invalid in this + // context. Diagnostic paths are intended to be mapped to actual data, + // while this path information must be synthesized. + return diag.NewErrorDiagnostic( + "Invalid Attribute Implementation", + "When validating the schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("%q is missing the CustomType or ElementType field on a collection Attribute. ", attributePath)+ + "One of these fields is required to prevent other unexpected errors or panics.", + ) +} + +func AttributeDefaultElementTypeMismatchDiag(attributePath path.Path, expectedElementType attr.Type, actualElementType attr.Type) diag.Diagnostic { + return diag.NewErrorDiagnostic( + "Invalid Attribute Implementation", + "When validating the schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("%q has a default value of element type %q, but the schema expects a type of %q. ", attributePath, actualElementType, expectedElementType)+ + "The default value must match the type of the schema.", + ) +} + +func AttributeDefaultTypeMismatchDiag(attributePath path.Path, expectedType attr.Type, actualType attr.Type) diag.Diagnostic { + return diag.NewErrorDiagnostic( + "Invalid Attribute Implementation", + "When validating the schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("%q has a default value of type %q, but the schema expects a type of %q. ", attributePath, actualType, expectedType)+ + "The default value must match the type of the schema.", + ) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/doc.go new file mode 100644 index 00000000..16f01731 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/doc.go @@ -0,0 +1,10 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package fwschema implements shared logic for describing the structure, +// data types, and behaviors of framework data for data sources, providers, +// and resources. +// +// Refer to the internal/fwschemadata package for logic built on values based +// on this schema information. +package fwschema diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/errors.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/errors.go new file mode 100644 index 00000000..21e7b065 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/errors.go @@ -0,0 +1,22 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import "errors" + +var ( + // ErrPathInsideAtomicAttribute is used when AttributeAtPath is called + // on a path that doesn't have a schema associated with it, because + // it's an element, attribute, or block of a complex type, not a nested + // attribute. + ErrPathInsideAtomicAttribute = errors.New("path leads to element, attribute, or block of a schema.Attribute that has no schema associated with it") + + // ErrPathIsBlock is used when AttributeAtPath is called on a path is a + // block, not an attribute. Use blockAtPath on the path instead. + ErrPathIsBlock = errors.New("path leads to block, not an attribute") + + // ErrPathInsideDynamicAttribute is used when AttributeAtPath is called on a path that doesn't + // have a schema associated with it because it's nested in a dynamic attribute. + ErrPathInsideDynamicAttribute = errors.New("path leads to element or attribute nested in a schema.DynamicAttribute") +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/attribute_plan_modification.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/attribute_plan_modification.go new file mode 100644 index 00000000..f4cb841d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/attribute_plan_modification.go @@ -0,0 +1,99 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwxschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// AttributeWithBoolPlanModifiers is an optional interface on Attribute which +// enables Bool plan modifier support. +type AttributeWithBoolPlanModifiers interface { + fwschema.Attribute + + // BoolPlanModifiers should return a list of Bool plan modifiers. + BoolPlanModifiers() []planmodifier.Bool +} + +// AttributeWithFloat64PlanModifiers is an optional interface on Attribute which +// enables Float64 plan modifier support. +type AttributeWithFloat64PlanModifiers interface { + fwschema.Attribute + + // Float64PlanModifiers should return a list of Float64 plan modifiers. + Float64PlanModifiers() []planmodifier.Float64 +} + +// AttributeWithInt64PlanModifiers is an optional interface on Attribute which +// enables Int64 plan modifier support. +type AttributeWithInt64PlanModifiers interface { + fwschema.Attribute + + // Int64PlanModifiers should return a list of Int64 plan modifiers. + Int64PlanModifiers() []planmodifier.Int64 +} + +// AttributeWithListPlanModifiers is an optional interface on Attribute which +// enables List plan modifier support. +type AttributeWithListPlanModifiers interface { + fwschema.Attribute + + // ListPlanModifiers should return a list of List plan modifiers. + ListPlanModifiers() []planmodifier.List +} + +// AttributeWithMapPlanModifiers is an optional interface on Attribute which +// enables Map plan modifier support. +type AttributeWithMapPlanModifiers interface { + fwschema.Attribute + + // MapPlanModifiers should return a list of Map plan modifiers. + MapPlanModifiers() []planmodifier.Map +} + +// AttributeWithNumberPlanModifiers is an optional interface on Attribute which +// enables Number plan modifier support. +type AttributeWithNumberPlanModifiers interface { + fwschema.Attribute + + // NumberPlanModifiers should return a list of Number plan modifiers. + NumberPlanModifiers() []planmodifier.Number +} + +// AttributeWithObjectPlanModifiers is an optional interface on Attribute which +// enables Object plan modifier support. +type AttributeWithObjectPlanModifiers interface { + fwschema.Attribute + + // ObjectPlanModifiers should return a list of Object plan modifiers. + ObjectPlanModifiers() []planmodifier.Object +} + +// AttributeWithSetPlanModifiers is an optional interface on Attribute which +// enables Set plan modifier support. +type AttributeWithSetPlanModifiers interface { + fwschema.Attribute + + // SetPlanModifiers should return a list of Set plan modifiers. + SetPlanModifiers() []planmodifier.Set +} + +// AttributeWithStringPlanModifiers is an optional interface on Attribute which +// enables String plan modifier support. +type AttributeWithStringPlanModifiers interface { + fwschema.Attribute + + // StringPlanModifiers should return a list of String plan modifiers. + StringPlanModifiers() []planmodifier.String +} + +// AttributeWithDynamicPlanModifiers is an optional interface on Attribute which +// enables Dynamic plan modifier support. +type AttributeWithDynamicPlanModifiers interface { + fwschema.Attribute + + // DynamicPlanModifiers should return a list of Dynamic plan modifiers. + DynamicPlanModifiers() []planmodifier.Dynamic +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/attribute_validation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/attribute_validation.go new file mode 100644 index 00000000..e8274de4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/attribute_validation.go @@ -0,0 +1,99 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwxschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// AttributeWithBoolValidators is an optional interface on Attribute which +// enables Bool validation support. +type AttributeWithBoolValidators interface { + fwschema.Attribute + + // BoolValidators should return a list of Bool validators. + BoolValidators() []validator.Bool +} + +// AttributeWithFloat64Validators is an optional interface on Attribute which +// enables Float64 validation support. +type AttributeWithFloat64Validators interface { + fwschema.Attribute + + // Float64Validators should return a list of Float64 validators. + Float64Validators() []validator.Float64 +} + +// AttributeWithInt64Validators is an optional interface on Attribute which +// enables Int64 validation support. +type AttributeWithInt64Validators interface { + fwschema.Attribute + + // Int64Validators should return a list of Int64 validators. + Int64Validators() []validator.Int64 +} + +// AttributeWithListValidators is an optional interface on Attribute which +// enables List validation support. +type AttributeWithListValidators interface { + fwschema.Attribute + + // ListValidators should return a list of List validators. + ListValidators() []validator.List +} + +// AttributeWithMapValidators is an optional interface on Attribute which +// enables Map validation support. +type AttributeWithMapValidators interface { + fwschema.Attribute + + // MapValidators should return a list of Map validators. + MapValidators() []validator.Map +} + +// AttributeWithNumberValidators is an optional interface on Attribute which +// enables Number validation support. +type AttributeWithNumberValidators interface { + fwschema.Attribute + + // NumberValidators should return a list of Number validators. + NumberValidators() []validator.Number +} + +// AttributeWithObjectValidators is an optional interface on Attribute which +// enables Object validation support. +type AttributeWithObjectValidators interface { + fwschema.Attribute + + // ObjectValidators should return a list of Object validators. + ObjectValidators() []validator.Object +} + +// AttributeWithSetValidators is an optional interface on Attribute which +// enables Set validation support. +type AttributeWithSetValidators interface { + fwschema.Attribute + + // SetValidators should return a list of Set validators. + SetValidators() []validator.Set +} + +// AttributeWithStringValidators is an optional interface on Attribute which +// enables String validation support. +type AttributeWithStringValidators interface { + fwschema.Attribute + + // StringValidators should return a list of String validators. + StringValidators() []validator.String +} + +// AttributeWithDynamicValidators is an optional interface on Attribute which +// enables Dynamic validation support. +type AttributeWithDynamicValidators interface { + fwschema.Attribute + + // DynamicValidators should return a list of Dynamic validators. + DynamicValidators() []validator.Dynamic +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/block_plan_modification.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/block_plan_modification.go new file mode 100644 index 00000000..745a8fd2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/block_plan_modification.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwxschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// BlockWithListPlanModifiers is an optional interface on Block which +// enables List plan modifier support. +type BlockWithListPlanModifiers interface { + fwschema.Block + + // ListPlanModifiers should return a list of List plan modifiers. + ListPlanModifiers() []planmodifier.List +} + +// BlockWithObjectPlanModifiers is an optional interface on Block which +// enables Object plan modifier support. +type BlockWithObjectPlanModifiers interface { + fwschema.Block + + // ObjectPlanModifiers should return a list of Object plan modifiers. + ObjectPlanModifiers() []planmodifier.Object +} + +// BlockWithSetPlanModifiers is an optional interface on Block which +// enables Set plan modifier support. +type BlockWithSetPlanModifiers interface { + fwschema.Block + + // SetPlanModifiers should return a list of Set plan modifiers. + SetPlanModifiers() []planmodifier.Set +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/block_validation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/block_validation.go new file mode 100644 index 00000000..95c637ab --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/block_validation.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwxschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// BlockWithListValidators is an optional interface on Block which +// enables List validation support. +type BlockWithListValidators interface { + fwschema.Block + + // ListValidators should return a list of List validators. + ListValidators() []validator.List +} + +// BlockWithObjectValidators is an optional interface on Block which +// enables Object validation support. +type BlockWithObjectValidators interface { + fwschema.Block + + // ObjectValidators should return a list of Object validators. + ObjectValidators() []validator.Object +} + +// BlockWithSetValidators is an optional interface on Block which +// enables Set validation support. +type BlockWithSetValidators interface { + fwschema.Block + + // SetValidators should return a list of Set validators. + SetValidators() []validator.Set +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/doc.go new file mode 100644 index 00000000..45da2e9d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/doc.go @@ -0,0 +1,9 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package fwxschema implements extra framework-based schema +// functionality on top of base Terraform attribute functionality. +// +// This package is separated from fwschema to prevent import cycles +// with existing tfsdk functionality. +package fwxschema diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_attribute_object_plan_modification.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_attribute_object_plan_modification.go new file mode 100644 index 00000000..6909704f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_attribute_object_plan_modification.go @@ -0,0 +1,18 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwxschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// NestedAttributeObjectWithPlanModifiers is an optional interface on +// NestedAttributeObject which enables Object plan modification support. +type NestedAttributeObjectWithPlanModifiers interface { + fwschema.NestedAttributeObject + + // ObjectPlanModifiers should return a list of Object plan modifiers. + ObjectPlanModifiers() []planmodifier.Object +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_attribute_object_validation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_attribute_object_validation.go new file mode 100644 index 00000000..f2a88ef1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_attribute_object_validation.go @@ -0,0 +1,18 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwxschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// NestedAttributeObjectWithValidators is an optional interface on +// NestedAttributeObject which enables Object validation support. +type NestedAttributeObjectWithValidators interface { + fwschema.NestedAttributeObject + + // ObjectValidators should return a list of Object validators. + ObjectValidators() []validator.Object +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_block_object_plan_modification.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_block_object_plan_modification.go new file mode 100644 index 00000000..09a0e67a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_block_object_plan_modification.go @@ -0,0 +1,18 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwxschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// NestedBlockObjectWithPlanModifiers is an optional interface on +// NestedBlockObject which enables Object plan modification support. +type NestedBlockObjectWithPlanModifiers interface { + fwschema.NestedBlockObject + + // ObjectPlanModifiers should return a list of Object plan modifiers. + ObjectPlanModifiers() []planmodifier.Object +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_block_object_validators.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_block_object_validators.go new file mode 100644 index 00000000..8eeb3b96 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema/nested_block_object_validators.go @@ -0,0 +1,18 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwxschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// NestedBlockObjectWithValidators is an optional interface on +// NestedBlockObject which enables Object validation support. +type NestedBlockObjectWithValidators interface { + fwschema.NestedBlockObject + + // ObjectValidators should return a list of Object validators. + ObjectValidators() []validator.Object +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_attribute.go new file mode 100644 index 00000000..192fa023 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_attribute.go @@ -0,0 +1,34 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +// NestedAttribute defines a schema attribute that contains nested attributes. +type NestedAttribute interface { + Attribute + + // GetNestedObject should return the object underneath the nested + // attribute. For single nesting mode, the NestedAttributeObject can be + // generated from the Attribute. + GetNestedObject() NestedAttributeObject + + // GetNestingMode should return the nesting mode (list, map, set, or + // single) of the nested attributes or left unset if this Attribute + // does not represent nested attributes. + GetNestingMode() NestingMode +} + +// NestedAttributesEqual is a helper function to perform equality testing on two +// NestedAttribute. NestedAttribute Equal implementations should still compare +// the concrete types in addition to using this helper. +func NestedAttributesEqual(a, b NestedAttribute) bool { + if !AttributesEqual(a, b) { + return false + } + + if a.GetNestingMode() != b.GetNestingMode() { + return false + } + + return a.GetNestedObject().Equal(b.GetNestedObject()) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_attribute_object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_attribute_object.go new file mode 100644 index 00000000..49cfbd84 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_attribute_object.go @@ -0,0 +1,93 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// NestedAttributeObject represents the Object inside a NestedAttribute. +// Refer to the fwxschema package for validation and plan modification +// extensions to this interface. +type NestedAttributeObject interface { + tftypes.AttributePathStepper + + // Equal should return true if given NestedAttributeObject is equivalent. + Equal(NestedAttributeObject) bool + + // GetAttributes should return the nested attributes of an attribute. + GetAttributes() UnderlyingAttributes + + // Type should return the framework type of the object. + Type() basetypes.ObjectTypable +} + +// NestedAttributeObjectApplyTerraform5AttributePathStep is a helper function +// to perform base tftypes.AttributePathStepper handling using the +// GetAttributes method. NestedAttributeObject implementations should still +// include custom type functionality in addition to using this helper. +func NestedAttributeObjectApplyTerraform5AttributePathStep(o NestedAttributeObject, step tftypes.AttributePathStep) (any, error) { + name, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to NestedAttributeObject", step) + } + + attribute, ok := o.GetAttributes()[string(name)] + + if ok { + return attribute, nil + } + + return nil, fmt.Errorf("no attribute %q on NestedAttributeObject", name) +} + +// NestedAttributeObjectEqual is a helper function to perform base equality testing +// on two NestedAttributeObject. NestedAttributeObject implementations should still +// compare the concrete types and other custom functionality in addition to +// using this helper. +func NestedAttributeObjectEqual(a, b NestedAttributeObject) bool { + if !a.Type().Equal(b.Type()) { + return false + } + + if len(a.GetAttributes()) != len(b.GetAttributes()) { + return false + } + + for name, aAttribute := range a.GetAttributes() { + bAttribute, ok := b.GetAttributes()[name] + + if !ok { + return false + } + + if !aAttribute.Equal(bAttribute) { + return false + } + } + + return true +} + +// NestedAttributeObjectType is a helper function to perform base type handling +// using the GetAttributes and GetBlocks methods. NestedAttributeObject +// implementations should still include custom type functionality in addition +// to using this helper. +func NestedAttributeObjectType(o NestedAttributeObject) basetypes.ObjectTypable { + attrTypes := make(map[string]attr.Type, len(o.GetAttributes())) + + for name, attribute := range o.GetAttributes() { + attrTypes[name] = attribute.GetType() + } + + return types.ObjectType{ + AttrTypes: attrTypes, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_block_object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_block_object.go new file mode 100644 index 00000000..bc93a099 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/nested_block_object.go @@ -0,0 +1,122 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// NestedBlockObject represents the Object inside a Block. +// Refer to the fwxschema package for validation and plan modification +// extensions to this interface. +type NestedBlockObject interface { + tftypes.AttributePathStepper + + // Equal should return true if given NestedBlockObject is equivalent. + Equal(NestedBlockObject) bool + + // GetAttributes should return the nested attributes of the object. + GetAttributes() UnderlyingAttributes + + // GetBlocks should return the nested attributes of the object. + GetBlocks() map[string]Block + + // Type should return the framework type of the object. + Type() basetypes.ObjectTypable +} + +// NestedBlockObjectApplyTerraform5AttributePathStep is a helper function to +// perform base tftypes.AttributePathStepper handling using the GetAttributes +// and GetBlocks methods. NestedBlockObject implementations should still +// include custom type functionality in addition to using this helper. +func NestedBlockObjectApplyTerraform5AttributePathStep(o NestedBlockObject, step tftypes.AttributePathStep) (any, error) { + name, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to NestedBlockObject", step) + } + + attribute, ok := o.GetAttributes()[string(name)] + + if ok { + return attribute, nil + } + + block, ok := o.GetBlocks()[string(name)] + + if ok { + return block, nil + } + + return nil, fmt.Errorf("no attribute or block %q on NestedBlockObject", name) +} + +// NestedBlockObjectEqual is a helper function to perform base equality testing +// on two NestedBlockObject. NestedBlockObject implementations should still +// compare the concrete types and other custom functionality in addition to +// using this helper. +func NestedBlockObjectEqual(a, b NestedBlockObject) bool { + if !a.Type().Equal(b.Type()) { + return false + } + + if len(a.GetAttributes()) != len(b.GetAttributes()) { + return false + } + + for name, aAttribute := range a.GetAttributes() { + bAttribute, ok := b.GetAttributes()[name] + + if !ok { + return false + } + + if !aAttribute.Equal(bAttribute) { + return false + } + } + + if len(a.GetBlocks()) != len(b.GetBlocks()) { + return false + } + + for name, aBlock := range a.GetBlocks() { + bBlock, ok := b.GetBlocks()[name] + + if !ok { + return false + } + + if !aBlock.Equal(bBlock) { + return false + } + } + + return true +} + +// NestedBlockObjectType is a helper function to perform base type handling +// using the GetAttributes and GetBlocks methods. NestedBlockObject +// implementations should still include custom type functionality in addition +// to using this helper. +func NestedBlockObjectType(o NestedBlockObject) basetypes.ObjectTypable { + attrTypes := make(map[string]attr.Type, len(o.GetAttributes())+len(o.GetBlocks())) + + for name, attribute := range o.GetAttributes() { + attrTypes[name] = attribute.GetType() + } + + for name, block := range o.GetBlocks() { + attrTypes[name] = block.Type() + } + + return types.ObjectType{ + AttrTypes: attrTypes, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/schema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/schema.go new file mode 100644 index 00000000..cc51acd8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/schema.go @@ -0,0 +1,270 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/totftypes" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Schema is the core interface required for data sources, providers, and +// resources. +type Schema interface { + // Implementations should include the tftypes.AttributePathStepper + // interface methods for proper path and data handling. + tftypes.AttributePathStepper + + // AttributeAtPath should return the Attribute at the given path or return + // an error. + AttributeAtPath(context.Context, path.Path) (Attribute, diag.Diagnostics) + + // AttributeAtTerraformPath should return the Attribute at the given + // Terraform path or return an error. + AttributeAtTerraformPath(context.Context, *tftypes.AttributePath) (Attribute, error) + + // GetAttributes should return the attributes of a schema. This is named + // differently than Attributes to prevent a conflict with the tfsdk.Schema + // field name. + GetAttributes() map[string]Attribute + + // GetBlocks should return the blocks of a schema. This is named + // differently than Blocks to prevent a conflict with the tfsdk.Schema + // field name. + GetBlocks() map[string]Block + + // GetDeprecationMessage should return a non-empty string if a schema + // is deprecated. This is named differently than DeprecationMessage to + // prevent a conflict with the tfsdk.Schema field name. + GetDeprecationMessage() string + + // GetDescription should return a non-empty string if a schema has a + // plaintext description. This is named differently than Description + // to prevent a conflict with the tfsdk.Schema field name. + GetDescription() string + + // GetMarkdownDescription should return a non-empty string if a schema has + // a Markdown description. This is named differently than + // MarkdownDescription to prevent a conflict with the tfsdk.Schema field + // name. + GetMarkdownDescription() string + + // GetVersion should return the version of a schema. This is named + // differently than Version to prevent a conflict with the tfsdk.Schema + // field name. + GetVersion() int64 + + // Type should return the framework type of the schema. + Type() attr.Type + + // TypeAtPath should return the framework type of the Attribute at the + // the given path or return an error. + TypeAtPath(context.Context, path.Path) (attr.Type, diag.Diagnostics) + + // AttributeTypeAtPath should return the framework type of the Attribute at + // the given Terraform path or return an error. + TypeAtTerraformPath(context.Context, *tftypes.AttributePath) (attr.Type, error) +} + +// SchemaApplyTerraform5AttributePathStep is a helper function to perform base +// tftypes.AttributePathStepper handling using the GetAttributes and GetBlocks +// methods. +func SchemaApplyTerraform5AttributePathStep(s Schema, step tftypes.AttributePathStep) (any, error) { + name, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to schema", step) + } + + if attr, ok := s.GetAttributes()[string(name)]; ok { + return attr, nil + } + + if block, ok := s.GetBlocks()[string(name)]; ok { + return block, nil + } + + return nil, fmt.Errorf("could not find attribute or block %q in schema", name) +} + +// SchemaAttributeAtPath is a helper function to perform base type handling using +// the AttributeAtTerraformPath method. +func SchemaAttributeAtPath(ctx context.Context, s Schema, p path.Path) (Attribute, diag.Diagnostics) { + var diags diag.Diagnostics + + tftypesPath, tftypesDiags := totftypes.AttributePath(ctx, p) + + diags.Append(tftypesDiags...) + + if diags.HasError() { + return nil, diags + } + + attribute, err := s.AttributeAtTerraformPath(ctx, tftypesPath) + + if err != nil { + diags.AddAttributeError( + p, + "Invalid Schema Path", + "When attempting to get the framework attribute associated with a schema path, an unexpected error was returned. "+ + "This is always an issue with the provider. Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Path: %s\n", p)+ + fmt.Sprintf("Original Error: %s", err), + ) + return nil, diags + } + + return attribute, diags +} + +// SchemaAttributeAtTerraformPath is a helper function to perform base type +// handling using the tftypes.AttributePathStepper interface. +func SchemaAttributeAtTerraformPath(ctx context.Context, s Schema, p *tftypes.AttributePath) (Attribute, error) { + rawType, remaining, err := tftypes.WalkAttributePath(s, p) + + if err != nil { + return nil, checkErrForDynamic(rawType, remaining, err) + } + + switch typ := rawType.(type) { + case attr.Type: + return nil, ErrPathInsideAtomicAttribute + case Attribute: + return typ, nil + case Block: + return nil, ErrPathIsBlock + case NestedAttributeObject: + return nil, ErrPathInsideAtomicAttribute + case NestedBlockObject: + return nil, ErrPathInsideAtomicAttribute + case UnderlyingAttributes: + return nil, ErrPathInsideAtomicAttribute + default: + return nil, fmt.Errorf("got unexpected type %T", rawType) + } +} + +// SchemaBlockPathExpressions returns a slice of all path expressions which +// represent a Block according to the Schema. +func SchemaBlockPathExpressions(ctx context.Context, s Schema) path.Expressions { + result := path.Expressions{} + + for name, block := range s.GetBlocks() { + result = append(result, BlockPathExpressions(ctx, block, path.MatchRoot(name))...) + } + + return result +} + +// SchemaTypeAtPath is a helper function to perform base type handling using +// the TypeAtTerraformPath method. +func SchemaTypeAtPath(ctx context.Context, s Schema, p path.Path) (attr.Type, diag.Diagnostics) { + var diags diag.Diagnostics + + tftypesPath, tftypesDiags := totftypes.AttributePath(ctx, p) + + diags.Append(tftypesDiags...) + + if diags.HasError() { + return nil, diags + } + + attrType, err := s.TypeAtTerraformPath(ctx, tftypesPath) + + if err != nil { + diags.AddAttributeError( + p, + "Invalid Schema Path", + "When attempting to get the framework type associated with a schema path, an unexpected error was returned. "+ + "This is always an issue with the provider. Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Path: %s\n", p)+ + fmt.Sprintf("Original Error: %s", err), + ) + return nil, diags + } + + return attrType, diags +} + +// SchemaTypeAtTerraformPath is a helper function to perform base type handling +// using the tftypes.AttributePathStepper interface. +func SchemaTypeAtTerraformPath(ctx context.Context, s Schema, p *tftypes.AttributePath) (attr.Type, error) { + rawType, remaining, err := tftypes.WalkAttributePath(s, p) + + if err != nil { + return nil, checkErrForDynamic(rawType, remaining, err) + } + + switch typ := rawType.(type) { + case attr.Type: + return typ, nil + case Attribute: + return typ.GetType(), nil + case Block: + return typ.Type(), nil + case NestedAttributeObject: + return typ.Type(), nil + case NestedBlockObject: + return typ.Type(), nil + case Schema: + return typ.Type(), nil + case UnderlyingAttributes: + return typ.Type(), nil + default: + return nil, fmt.Errorf("got unexpected type %T", rawType) + } +} + +// SchemaType is a helper function to perform base type handling using the +// GetAttributes and GetBlocks methods. +func SchemaType(s Schema) attr.Type { + attrTypes := map[string]attr.Type{} + + for name, attr := range s.GetAttributes() { + attrTypes[name] = attr.GetType() + } + + for name, block := range s.GetBlocks() { + attrTypes[name] = block.Type() + } + + return types.ObjectType{AttrTypes: attrTypes} +} + +// checkErrForDynamic is a helper function that will always return an error. It will return +// an `ErrPathInsideDynamicAttribute` error if rawType: +// - Is a dynamic type +// - Is an attribute that has a dynamic type +func checkErrForDynamic(rawType any, remaining *tftypes.AttributePath, err error) error { + if rawType == nil { + return fmt.Errorf("%v still remains in the path: %w", remaining, err) + } + + // Check to see if we tried walking into a dynamic type (types.DynamicType) + _, isDynamic := rawType.(basetypes.DynamicTypable) + if isDynamic { + // If the type is dynamic there is no schema information underneath it, return an error to allow calling logic to safely skip + return ErrPathInsideDynamicAttribute + } + + // Check to see if we tried walking into an attribute with a dynamic type (schema.DynamicAttribute) + attr, ok := rawType.(Attribute) + if ok { + _, isDynamic := attr.GetType().(basetypes.DynamicTypable) + if isDynamic { + // If the attribute is dynamic there are no nested attributes underneath it, return an error to allow calling logic to safely skip + return ErrPathInsideDynamicAttribute + } + } + + return fmt.Errorf("%v still remains in the path: %w", remaining, err) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/underlying_attributes.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/underlying_attributes.go new file mode 100644 index 00000000..22b7178e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/underlying_attributes.go @@ -0,0 +1,70 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure UnderlyingAttributes satisfies the expected interfaces. +var _ tftypes.AttributePathStepper = UnderlyingAttributes{} + +// UnderlyingAttributes represents attributes under a nested attribute. +type UnderlyingAttributes map[string]Attribute + +// ApplyTerraform5AttributePathStep performs an AttributeName step on the +// underlying attributes or returns an error. +func (u UnderlyingAttributes) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + name, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("can't apply %T to Attributes", step) + } + + attribute, ok := u[string(name)] + + if !ok { + return nil, fmt.Errorf("no attribute %q on Attributes", name) + } + + return attribute, nil +} + +// Equal returns true if all underlying attributes are equal. +func (u UnderlyingAttributes) Equal(o UnderlyingAttributes) bool { + if len(u) != len(o) { + return false + } + + for name, uAttribute := range u { + oAttribute, ok := o[name] + + if !ok { + return false + } + + if !uAttribute.Equal(oAttribute) { + return false + } + } + + return true +} + +// Type returns the framework type of the underlying attributes. +func (u UnderlyingAttributes) Type() basetypes.ObjectTypable { + attrTypes := make(map[string]attr.Type, len(u)) + + for name, attr := range u { + attrTypes[name] = attr.GetType() + } + + return basetypes.ObjectType{ + AttrTypes: attrTypes, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/validate_implementation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/validate_implementation.go new file mode 100644 index 00000000..6b9f1a66 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschema/validate_implementation.go @@ -0,0 +1,37 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// ValidateImplementationRequest contains the information available +// during a ValidateImplementation call to validate the Attribute +// definition. ValidateImplementationResponse is the type used for +// responses. +type ValidateImplementationRequest struct { + // Name contains the current Attribute name. + Name string + + // Path contains the current Attribute path. This path information is + // synthesized for any Attribute which is nested below other Attribute or + // Block since path.Path is intended to represent actual data, but schema + // paths represent any element in collection types. Rather than being + // intended for diagnostic paths, like most path information, this is + // intended for being stringified into diagnostic details. + Path path.Path +} + +// ValidateImplementationResponse contains the returned data from a +// ValidateImplementation method call to validate the Attribute +// implementation. ValidateImplementationRequest is the type used for +// requests. +type ValidateImplementationResponse struct { + // Diagnostics report errors or warnings related to validating the + // definition of the Attribute. An empty slice indicates success, with no + // warnings or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data.go new file mode 100644 index 00000000..d6cc7b79 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Data is the shared storage implementation for schema-based values, such as +// configuration, plan, and state. +type Data struct { + // Description contains the human friendly type of the data. Used in error + // diagnostics. + Description DataDescription + + // Schema contains the data structure and types for the value. + Schema fwschema.Schema + + // TerraformValue contains the terraform-plugin-go value implementation. + // + // TODO: In the future this may be migrated to attr.Value, or more + // succinctly, types.Object. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/172 + TerraformValue tftypes.Value +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_default.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_default.go new file mode 100644 index 00000000..d83f5ee0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_default.go @@ -0,0 +1,366 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "errors" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// TransformDefaults walks the schema and applies schema defined default values +// when configRaw contains a null value at the same path. +func (d *Data) TransformDefaults(ctx context.Context, configRaw tftypes.Value) diag.Diagnostics { + var diags diag.Diagnostics + var err error + + configData := Data{ + Description: DataDescriptionConfiguration, + Schema: d.Schema, + TerraformValue: configRaw, + } + + d.TerraformValue, err = tftypes.Transform(d.TerraformValue, func(tfTypePath *tftypes.AttributePath, tfTypeValue tftypes.Value) (tftypes.Value, error) { + // Skip the root of the data, only applying defaults to attributes + if len(tfTypePath.Steps()) < 1 { + return tfTypeValue, nil + } + + attrAtPath, err := d.Schema.AttributeAtTerraformPath(ctx, tfTypePath) + + if err != nil { + if errors.Is(err, fwschema.ErrPathInsideAtomicAttribute) { + // ignore attributes/elements inside schema.Attributes, they have no schema of their own + logging.FrameworkTrace(ctx, "attribute is a non-schema attribute, not setting default") + return tfTypeValue, nil + } + + if errors.Is(err, fwschema.ErrPathIsBlock) { + // ignore blocks, they do not have a computed field + logging.FrameworkTrace(ctx, "attribute is a block, not setting default") + return tfTypeValue, nil + } + + if errors.Is(err, fwschema.ErrPathInsideDynamicAttribute) { + // ignore attributes/elements inside schema.DynamicAttribute, they have no schema of their own + logging.FrameworkTrace(ctx, "attribute is inside of a dynamic attribute, not setting default") + return tfTypeValue, nil + } + + return tftypes.Value{}, fmt.Errorf("couldn't find attribute in resource schema: %w", err) + } + + fwPath, fwPathDiags := fromtftypes.AttributePath(ctx, tfTypePath, d.Schema) + + diags.Append(fwPathDiags...) + + // Do not transform if path cannot be converted. + // Checking against fwPathDiags will capture all errors. + if fwPathDiags.HasError() { + return tfTypeValue, nil + } + + configValue, configValueDiags := configData.ValueAtPath(ctx, fwPath) + + diags.Append(configValueDiags...) + + // Do not transform if rawConfig value cannot be retrieved. + if configValueDiags.HasError() { + return tfTypeValue, nil + } + + // Do not transform if rawConfig value is not null. + if !configValue.IsNull() { + // Dynamic values need to perform more logic to check the config value for null-ness + dynValuable, ok := configValue.(basetypes.DynamicValuable) + if !ok { + return tfTypeValue, nil + } + + dynConfigVal, dynDiags := dynValuable.ToDynamicValue(ctx) + if dynDiags.HasError() { + return tfTypeValue, nil + } + + // For dynamic values, it's possible to be known when only the type is known. + // The underlying value can still be null, so check for that here + if !dynConfigVal.IsUnderlyingValueNull() { + return tfTypeValue, nil + } + } + + switch a := attrAtPath.(type) { + case fwschema.AttributeWithBoolDefaultValue: + defaultValue := a.BoolDefaultValue() + + if defaultValue == nil { + return tfTypeValue, nil + } + + req := defaults.BoolRequest{ + Path: fwPath, + } + resp := defaults.BoolResponse{} + + defaultValue.DefaultBool(ctx, req, &resp) + + diags.Append(resp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return tfTypeValue, nil + } + + logging.FrameworkTrace(ctx, fmt.Sprintf("setting attribute %s to default value: %s", fwPath, resp.PlanValue)) + + return resp.PlanValue.ToTerraformValue(ctx) + case fwschema.AttributeWithFloat64DefaultValue: + defaultValue := a.Float64DefaultValue() + + if defaultValue == nil { + return tfTypeValue, nil + } + + req := defaults.Float64Request{ + Path: fwPath, + } + resp := defaults.Float64Response{} + + defaultValue.DefaultFloat64(ctx, req, &resp) + + diags.Append(resp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return tfTypeValue, nil + } + + logging.FrameworkTrace(ctx, fmt.Sprintf("setting attribute %s to default value: %s", fwPath, resp.PlanValue)) + + return resp.PlanValue.ToTerraformValue(ctx) + case fwschema.AttributeWithInt64DefaultValue: + defaultValue := a.Int64DefaultValue() + + if defaultValue == nil { + return tfTypeValue, nil + } + + req := defaults.Int64Request{ + Path: fwPath, + } + resp := defaults.Int64Response{} + + defaultValue.DefaultInt64(ctx, req, &resp) + + diags.Append(resp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return tfTypeValue, nil + } + + logging.FrameworkTrace(ctx, fmt.Sprintf("setting attribute %s to default value: %s", fwPath, resp.PlanValue)) + + return resp.PlanValue.ToTerraformValue(ctx) + case fwschema.AttributeWithListDefaultValue: + defaultValue := a.ListDefaultValue() + + if defaultValue == nil { + return tfTypeValue, nil + } + + req := defaults.ListRequest{ + Path: fwPath, + } + resp := defaults.ListResponse{} + + defaultValue.DefaultList(ctx, req, &resp) + + diags.Append(resp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return tfTypeValue, nil + } + + if resp.PlanValue.ElementType(ctx) == nil { + logging.FrameworkWarn(ctx, "attribute default declared, but returned no value") + + return tfTypeValue, nil + } + + logging.FrameworkTrace(ctx, fmt.Sprintf("setting attribute %s to default value: %s", fwPath, resp.PlanValue)) + + return resp.PlanValue.ToTerraformValue(ctx) + case fwschema.AttributeWithMapDefaultValue: + defaultValue := a.MapDefaultValue() + + if defaultValue == nil { + return tfTypeValue, nil + } + req := defaults.MapRequest{ + Path: fwPath, + } + resp := defaults.MapResponse{} + + defaultValue.DefaultMap(ctx, req, &resp) + + diags.Append(resp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return tfTypeValue, nil + } + + if resp.PlanValue.ElementType(ctx) == nil { + logging.FrameworkWarn(ctx, "attribute default declared, but returned no value") + + return tfTypeValue, nil + } + + logging.FrameworkTrace(ctx, fmt.Sprintf("setting attribute %s to default value: %s", fwPath, resp.PlanValue)) + + return resp.PlanValue.ToTerraformValue(ctx) + case fwschema.AttributeWithNumberDefaultValue: + defaultValue := a.NumberDefaultValue() + + if defaultValue == nil { + return tfTypeValue, nil + } + + req := defaults.NumberRequest{ + Path: fwPath, + } + resp := defaults.NumberResponse{} + + defaultValue.DefaultNumber(ctx, req, &resp) + + diags.Append(resp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return tfTypeValue, nil + } + + logging.FrameworkTrace(ctx, fmt.Sprintf("setting attribute %s to default value: %s", fwPath, resp.PlanValue)) + + return resp.PlanValue.ToTerraformValue(ctx) + case fwschema.AttributeWithObjectDefaultValue: + defaultValue := a.ObjectDefaultValue() + + if defaultValue == nil { + return tfTypeValue, nil + } + + req := defaults.ObjectRequest{ + Path: fwPath, + } + resp := defaults.ObjectResponse{} + + defaultValue.DefaultObject(ctx, req, &resp) + + diags.Append(resp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return tfTypeValue, nil + } + + logging.FrameworkTrace(ctx, fmt.Sprintf("setting attribute %s to default value: %s", fwPath, resp.PlanValue)) + + return resp.PlanValue.ToTerraformValue(ctx) + case fwschema.AttributeWithSetDefaultValue: + defaultValue := a.SetDefaultValue() + + if defaultValue == nil { + return tfTypeValue, nil + } + + req := defaults.SetRequest{ + Path: fwPath, + } + resp := defaults.SetResponse{} + + defaultValue.DefaultSet(ctx, req, &resp) + + diags.Append(resp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return tfTypeValue, nil + } + + if resp.PlanValue.ElementType(ctx) == nil { + logging.FrameworkWarn(ctx, "attribute default declared, but returned no value") + + return tfTypeValue, nil + } + + logging.FrameworkTrace(ctx, fmt.Sprintf("setting attribute %s to default value: %s", fwPath, resp.PlanValue)) + + return resp.PlanValue.ToTerraformValue(ctx) + case fwschema.AttributeWithStringDefaultValue: + defaultValue := a.StringDefaultValue() + + if defaultValue == nil { + return tfTypeValue, nil + } + + req := defaults.StringRequest{ + Path: fwPath, + } + resp := defaults.StringResponse{} + + defaultValue.DefaultString(ctx, req, &resp) + + diags.Append(resp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return tfTypeValue, nil + } + + logging.FrameworkTrace(ctx, fmt.Sprintf("setting attribute %s to default value: %s", fwPath, resp.PlanValue)) + + return resp.PlanValue.ToTerraformValue(ctx) + case fwschema.AttributeWithDynamicDefaultValue: + defaultValue := a.DynamicDefaultValue() + + if defaultValue == nil { + return tfTypeValue, nil + } + + req := defaults.DynamicRequest{ + Path: fwPath, + } + resp := defaults.DynamicResponse{} + + defaultValue.DefaultDynamic(ctx, req, &resp) + + diags.Append(resp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return tfTypeValue, nil + } + + logging.FrameworkTrace(ctx, fmt.Sprintf("setting attribute %s to default value: %s", fwPath, resp.PlanValue)) + + return resp.PlanValue.ToTerraformValue(ctx) + } + + return tfTypeValue, nil + }) + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/930 + if err != nil { + diags.Append(diag.NewErrorDiagnostic( + "Error Handling Schema Defaults", + "An unexpected error occurred while handling schema default values. "+ + "Please report the following to the provider developer:\n\n"+ + "Error: "+err.Error(), + )) + } + + return diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_description.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_description.go new file mode 100644 index 00000000..c002e988 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_description.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +const ( + // DataDescriptionConfiguration is used for Data that represents + // a configuration-based value. + DataDescriptionConfiguration DataDescription = "configuration" + + // DataDescriptionPlan is used for Data that represents + // a plan-based value. + DataDescriptionPlan DataDescription = "plan" + + // DataDescriptionState is used for Data that represents + // a state-based value. + DataDescriptionState DataDescription = "state" +) + +// DataDescription is a human friendly type for Data. Used in error +// diagnostics. +type DataDescription string + +// String returns the lowercase string of the description. +func (d DataDescription) String() string { + switch d { + case "": + return "data" + default: + return string(d) + } +} + +// Title returns the titlecase string of the description. +func (d DataDescription) Title() string { + switch d { + case DataDescriptionConfiguration: + return "Configuration" + case DataDescriptionPlan: + return "Plan" + case DataDescriptionState: + return "State" + default: + return "Data" + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_get.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_get.go new file mode 100644 index 00000000..f61954e1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_get.go @@ -0,0 +1,17 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Get populates the struct passed as `target` with the entire state. +func (d Data) Get(ctx context.Context, target any) diag.Diagnostics { + return reflect.Into(ctx, d.Schema.Type(), d.TerraformValue, target, reflect.Options{}, path.Empty()) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_get_at_path.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_get_at_path.go new file mode 100644 index 00000000..d3ab4f60 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_get_at_path.go @@ -0,0 +1,61 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// GetAtPath retrieves the attribute found at `path` and populates the +// `target` with the value. +func (d Data) GetAtPath(ctx context.Context, schemaPath path.Path, target any) diag.Diagnostics { + ctx = logging.FrameworkWithAttributePath(ctx, schemaPath.String()) + + attrValue, diags := d.ValueAtPath(ctx, schemaPath) + + if diags.HasError() { + return diags + } + + if attrValue == nil { + diags.AddAttributeError( + schemaPath, + d.Description.Title()+" Read Error", + "An unexpected error was encountered trying to read an attribute from the "+d.Description.String()+". This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + "Missing attribute value, however no error was returned. Preventing the panic from this situation.", + ) + return diags + } + + if reflect.IsGenericAttrValue(ctx, target) { + //nolint:forcetypeassert // Type assertion is guaranteed by the above `reflect.IsGenericAttrValue` function + *(target.(*attr.Value)) = attrValue + return nil + } + + raw, err := attrValue.ToTerraformValue(ctx) + + if err != nil { + diags.AddAttributeError( + schemaPath, + d.Description.Title()+" Value Conversion Error", + fmt.Sprintf("An unexpected error was encountered converting a %T to its equivalent Terraform representation. This is always a bug in the provider.\n\n"+ + "Error: %s", attrValue, err), + ) + return diags + } + + reflectDiags := reflect.Into(ctx, attrValue.Type(ctx), raw, target, reflect.Options{}, schemaPath) + + diags.Append(reflectDiags...) + + return diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_nullify_collection_blocks.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_nullify_collection_blocks.go new file mode 100644 index 00000000..f907d6d1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_nullify_collection_blocks.go @@ -0,0 +1,98 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "errors" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// NullifyCollectionBlocks converts list and set block empty values to null +// values. The reverse conversion is ReifyNullCollectionBlocks. +func (d *Data) NullifyCollectionBlocks(ctx context.Context) diag.Diagnostics { + var diags diag.Diagnostics + + blockPathExpressions := fwschema.SchemaBlockPathExpressions(ctx, d.Schema) + + // Errors are handled as richer diag.Diagnostics instead. + d.TerraformValue, _ = tftypes.Transform(d.TerraformValue, func(tfTypePath *tftypes.AttributePath, tfTypeValue tftypes.Value) (tftypes.Value, error) { + // Skip the root of the data + if len(tfTypePath.Steps()) < 1 { + return tfTypeValue, nil + } + + // Do not transform if value is already null or is not fully known. + if tfTypeValue.IsNull() || !tfTypeValue.IsFullyKnown() { + return tfTypeValue, nil + } + + _, err := d.Schema.AttributeAtTerraformPath(ctx, tfTypePath) + if err != nil { + if errors.Is(err, fwschema.ErrPathInsideDynamicAttribute) { + // ignore attributes/elements inside schema.DynamicAttribute + logging.FrameworkTrace(ctx, "attribute is inside of a dynamic attribute, skipping nullify collection blocks") + return tfTypeValue, nil + } + } + + fwPath, fwPathDiags := fromtftypes.AttributePath(ctx, tfTypePath, d.Schema) + + diags.Append(fwPathDiags...) + + // Do not transform if path cannot be converted. + // Checking against fwPathDiags will capture all errors. + if fwPathDiags.HasError() { + return tfTypeValue, nil + } + + // Do not transform if path is not a block. + if !blockPathExpressions.Matches(fwPath) { + return tfTypeValue, nil + } + + var elements []tftypes.Value + + switch tfTypeValue.Type().(type) { + case tftypes.List, tftypes.Set: + err := tfTypeValue.As(&elements) + + // If this occurs, it likely is an upstream issue in Terraform + // or terraform-plugin-go. + if err != nil { + diags.AddAttributeError( + fwPath, + d.Description.Title()+" Data Transformation Error", + "An unexpected error occurred while transforming "+d.Description.String()+" data. "+ + "This is always an issue with terraform-plugin-framework and should be reported to the provider developers.\n\n"+ + "Path: "+fwPath.String()+"\n"+ + "Error: (tftypes.Value).As() error: "+err.Error(), + ) + + return tfTypeValue, nil //nolint:nilerr // Using richer diag.Diagnostics instead. + } + default: + return tfTypeValue, nil + } + + // Do not transform if there are any elements. + if len(elements) > 0 { + return tfTypeValue, nil + } + + // Transform to null value. + logging.FrameworkTrace(ctx, "Transforming empty block to null block", map[string]any{ + logging.KeyAttributePath: fwPath.String(), + logging.KeyDescription: d.Description.String(), + }) + return tftypes.NewValue(tfTypeValue.Type(), nil), nil + }) + + return diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_path_exists.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_path_exists.go new file mode 100644 index 00000000..f6df9717 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_path_exists.go @@ -0,0 +1,47 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "errors" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/totftypes" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// PathExists returns true if the path can be reached. The value at the path +// may be null or unknown. +func (d Data) PathExists(ctx context.Context, path path.Path) (bool, diag.Diagnostics) { + var diags diag.Diagnostics + + tftypesPath, tftypesPathDiags := totftypes.AttributePath(ctx, path) + + diags.Append(tftypesPathDiags...) + + if diags.HasError() { + return false, diags + } + + _, remaining, err := tftypes.WalkAttributePath(d.TerraformValue, tftypesPath) + + if err != nil { + if errors.Is(err, tftypes.ErrInvalidStep) { + return false, diags + } + + diags.AddAttributeError( + path, + d.Description.Title()+" Read Error", + "An unexpected error was encountered trying to read an attribute from the "+d.Description.String()+". This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Cannot walk attribute path in %s: %s", d.Description, err), + ) + return false, diags + } + + return len(remaining.Steps()) == 0, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_path_matches.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_path_matches.go new file mode 100644 index 00000000..693d96f1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_path_matches.go @@ -0,0 +1,80 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// PathMatches returns all matching path.Paths from the given path.Expression. +// +// If a parent path is null or unknown, which would prevent a full expression +// from matching, the parent path is returned rather than no match to prevent +// false positives. +func (d Data) PathMatches(ctx context.Context, pathExpr path.Expression) (path.Paths, diag.Diagnostics) { + var diags diag.Diagnostics + var paths path.Paths + + if !d.ValidPathExpression(ctx, pathExpr) { + diags.AddError( + "Invalid Path Expression for Schema", + "The Terraform Provider unexpectedly provided a path expression that does not match the current schema. "+ + "This can happen if the path expression does not correctly follow the schema in structure or types. "+ + "Please report this to the provider developers.\n\n"+ + "Path Expression: "+pathExpr.String(), + ) + + return paths, diags + } + + _ = tftypes.Walk(d.TerraformValue, func(tfTypePath *tftypes.AttributePath, tfTypeValue tftypes.Value) (bool, error) { + fwPath, fwPathDiags := fromtftypes.AttributePath(ctx, tfTypePath, d.Schema) + + diags.Append(fwPathDiags...) + + if diags.HasError() { + // If there was an error with conversion of the path at this level, + // no need to traverse further since a deeper path will error. + return false, nil + } + + if pathExpr.Matches(fwPath) { + paths.Append(fwPath) + + // If we matched, there is no need to traverse further since a + // deeper path will never match. + return false, nil + } + + // If current path cannot be parent path, there is no need to traverse + // further since a deeper path will never match. + if !pathExpr.MatchesParent(fwPath) { + return false, nil + } + + // If value at current path (now known to be a parent path of the + // expression) is null or unknown, return it as a valid path match + // since Walk will stop traversing deeper anyways and we want + // consumers to know about the path with the null or unknown value. + // + // This behavior may be confusing for consumers as fetching the value + // at this parent path will return a potentially unexpected type, + // however this is an implementation tradeoff to prevent false + // positives of missing null or unknown values. + if tfTypeValue.IsNull() || !tfTypeValue.IsKnown() { + paths.Append(fwPath) + + return false, nil + } + + return true, nil + }) + + return paths, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_reify_null_collection_blocks.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_reify_null_collection_blocks.go new file mode 100644 index 00000000..64d10bd6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_reify_null_collection_blocks.go @@ -0,0 +1,74 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "errors" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fromtftypes" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// ReifyNullCollectionBlocks converts list and set block null values to empty +// values. This is the reverse conversion of NullifyCollectionBlocks. +func (d *Data) ReifyNullCollectionBlocks(ctx context.Context) diag.Diagnostics { + var diags diag.Diagnostics + + blockPathExpressions := fwschema.SchemaBlockPathExpressions(ctx, d.Schema) + + // Errors are handled as richer diag.Diagnostics instead. + d.TerraformValue, _ = tftypes.Transform(d.TerraformValue, func(tfTypePath *tftypes.AttributePath, tfTypeValue tftypes.Value) (tftypes.Value, error) { + // Skip the root of the data + if len(tfTypePath.Steps()) < 1 { + return tfTypeValue, nil + } + + // Only transform null values. + if !tfTypeValue.IsNull() { + return tfTypeValue, nil + } + + _, err := d.Schema.AttributeAtTerraformPath(ctx, tfTypePath) + if err != nil { + if errors.Is(err, fwschema.ErrPathInsideDynamicAttribute) { + // ignore attributes/elements inside schema.DynamicAttribute + logging.FrameworkTrace(ctx, "attribute is inside of a dynamic attribute, skipping reify null collection blocks") + return tfTypeValue, nil + } + } + + fwPath, fwPathDiags := fromtftypes.AttributePath(ctx, tfTypePath, d.Schema) + + diags.Append(fwPathDiags...) + + // Do not transform if path cannot be converted. + // Checking against fwPathDiags will capture all errors. + if fwPathDiags.HasError() { + return tfTypeValue, nil + } + + // Do not transform if path is not a block. + if !blockPathExpressions.Matches(fwPath) { + return tfTypeValue, nil + } + + // Transform to empty value. + switch tfTypeValue.Type().(type) { + case tftypes.List, tftypes.Set: + logging.FrameworkTrace(ctx, "Transforming null block to empty block", map[string]any{ + logging.KeyAttributePath: fwPath.String(), + logging.KeyDescription: d.Description.String(), + }) + return tftypes.NewValue(tfTypeValue.Type(), []tftypes.Value{}), nil + default: + return tfTypeValue, nil + } + }) + + return diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_set.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_set.go new file mode 100644 index 00000000..b53604b3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_set.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Set replaces the entire value. The value should be a struct whose fields +// have one of the attr.Value types. Each field must have the tfsdk field tag. +func (d *Data) Set(ctx context.Context, val any) diag.Diagnostics { + attrValue, diags := reflect.FromValue(ctx, d.Schema.Type(), val, path.Empty()) + + if diags.HasError() { + return diags + } + + tfValue, err := attrValue.ToTerraformValue(ctx) + + if err != nil { + diags.AddError( + d.Description.Title()+" Write Error", + "An unexpected error was encountered trying to write the "+d.Description.String()+". This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Error: Unable to run ToTerraformValue on new value: %s", err), + ) + return diags + } + + d.TerraformValue = tfValue + + return diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_set_at_path.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_set_at_path.go new file mode 100644 index 00000000..211e75c1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_set_at_path.go @@ -0,0 +1,264 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "errors" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/internal/totftypes" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// SetAtPath sets the attribute at `path` using the supplied Go value. +// +// The attribute path and value must be valid with the current schema. If the +// attribute path already has a value, it will be overwritten. If the attribute +// path does not have a value, it will be added, including any parent attribute +// paths as necessary. +// +// Lists can only have the next element added according to the current length. +func (d *Data) SetAtPath(ctx context.Context, path path.Path, val interface{}) diag.Diagnostics { + var diags diag.Diagnostics + + ctx = logging.FrameworkWithAttributePath(ctx, path.String()) + + tftypesPath, tftypesPathDiags := totftypes.AttributePath(ctx, path) + + diags.Append(tftypesPathDiags...) + + if diags.HasError() { + return diags + } + + attrType, err := d.Schema.TypeAtTerraformPath(ctx, tftypesPath) + + if err != nil { + diags.AddAttributeError( + path, + d.Description.Title()+" Write Error", + "An unexpected error was encountered trying to retrieve type information at a given path. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + "Error: "+err.Error(), + ) + return diags + } + + // MAINTAINER NOTE: The call to reflect.FromValue() checks for whether the type implements + // xattr.TypeWithValidate and calls Validate() if the type assertion succeeds. + newVal, newValDiags := reflect.FromValue(ctx, attrType, val, path) + diags.Append(newValDiags...) + + if diags.HasError() { + return diags + } + + tfVal, err := newVal.ToTerraformValue(ctx) + + if err != nil { + diags.AddAttributeError( + path, + d.Description.Title()+" Write Error", + "An unexpected error was encountered trying to write an attribute to the "+d.Description.String()+". This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + "Error: Cannot run ToTerraformValue on new data value: "+err.Error(), + ) + return diags + } + + switch t := newVal.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + logging.FrameworkTrace(ctx, "Value implements ValidateableAttribute") + logging.FrameworkTrace(ctx, "Calling provider defined Value ValidateAttribute") + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + logging.FrameworkTrace(ctx, "Called provider defined Value ValidateAttribute") + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if attrTypeWithValidate, ok := attrType.(xattr.TypeWithValidate); ok { + logging.FrameworkTrace(ctx, "Type implements TypeWithValidate") + logging.FrameworkTrace(ctx, "Calling provider defined Type Validate") + + diags.Append(attrTypeWithValidate.Validate(ctx, tfVal, path)...) + + logging.FrameworkTrace(ctx, "Called provider defined Type Validate") + + if diags.HasError() { + return diags + } + } + } + + transformFunc, transformFuncDiags := d.SetAtPathTransformFunc(ctx, path, tfVal, nil) + diags.Append(transformFuncDiags...) + + if diags.HasError() { + return diags + } + + d.TerraformValue, err = tftypes.Transform(d.TerraformValue, transformFunc) + + if err != nil { + diags.AddAttributeError( + path, + d.Description.Title()+" Write Error", + "An unexpected error was encountered trying to write an attribute to the "+d.Description.String()+". This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + "Error: Cannot transform data: "+err.Error(), + ) + return diags + } + + return diags +} + +// SetAtPathTransformFunc recursively creates a value based on the current +// Plan values along the path. If the value at the path does not yet exist, +// this will perform recursion to add the child value to a parent value, +// creating the parent value if necessary. +func (d Data) SetAtPathTransformFunc(ctx context.Context, path path.Path, tfVal tftypes.Value, diags diag.Diagnostics) (func(*tftypes.AttributePath, tftypes.Value) (tftypes.Value, error), diag.Diagnostics) { + exists, pathExistsDiags := d.PathExists(ctx, path) + diags.Append(pathExistsDiags...) + + if diags.HasError() { + return nil, diags + } + + tftypesPath, tftypesPathDiags := totftypes.AttributePath(ctx, path) + + diags.Append(tftypesPathDiags...) + + if diags.HasError() { + return nil, diags + } + + if exists { + // Overwrite existing value + return func(p *tftypes.AttributePath, v tftypes.Value) (tftypes.Value, error) { + if p.Equal(tftypesPath) { + return tfVal, nil + } + return v, nil + }, diags + } + + parentPath := path.ParentPath() + parentTftypesPath := tftypesPath.WithoutLastStep() + parentAttrType, err := d.Schema.TypeAtTerraformPath(ctx, parentTftypesPath) + + if err != nil { + err = fmt.Errorf("error getting parent attribute type in schema: %w", err) + diags.AddAttributeError( + parentPath, + d.Description.Title()+" Write Error", + "An unexpected error was encountered trying to write an attribute to the "+d.Description.String()+". This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + parentValue, err := d.TerraformValueAtTerraformPath(ctx, parentTftypesPath) + + if err != nil && !errors.Is(err, tftypes.ErrInvalidStep) { + diags.AddAttributeError( + parentPath, + d.Description.Title()+" Read Error", + "An unexpected error was encountered trying to read an attribute from the "+d.Description.String()+". This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + if parentValue.IsNull() || !parentValue.IsKnown() { + parentType := parentAttrType.TerraformType(ctx) + var childValue interface{} + + if !parentValue.IsKnown() { + childValue = tftypes.UnknownValue + } + + var parentValueDiags diag.Diagnostics + parentValue, parentValueDiags = CreateParentTerraformValue(ctx, parentPath, parentType, childValue) + diags.Append(parentValueDiags...) + + if diags.HasError() { + return nil, diags + } + } + + var childValueDiags diag.Diagnostics + childStep, _ := path.Steps().LastStep() + parentValue, childValueDiags = UpsertChildTerraformValue(ctx, parentPath, parentValue, childStep, tfVal) + diags.Append(childValueDiags...) + + if diags.HasError() { + return nil, diags + } + + parentAttrValue, err := parentAttrType.ValueFromTerraform(ctx, parentValue) + + if err != nil { + diags.AddAttributeError( + parentPath, + d.Description.Title()+" Read Error", + "An unexpected error was encountered trying to read an attribute from the "+d.Description.String()+". This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + switch t := parentAttrValue.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + logging.FrameworkTrace(ctx, "Value implements ValidateableAttribute") + logging.FrameworkTrace(ctx, "Calling provider defined Value ValidateAttribute") + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: parentPath, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + logging.FrameworkTrace(ctx, "Called provider defined Value ValidateAttribute") + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if attrTypeWithValidate, ok := parentAttrType.(xattr.TypeWithValidate); ok { + logging.FrameworkTrace(ctx, "Type implements TypeWithValidate") + logging.FrameworkTrace(ctx, "Calling provider defined Type ValidateAttribute") + + diags.Append(attrTypeWithValidate.Validate(ctx, parentValue, parentPath)...) + + logging.FrameworkTrace(ctx, "Called provider defined Type ValidateAttribute") + + if diags.HasError() { + return nil, diags + } + } + } + + return d.SetAtPathTransformFunc(ctx, parentPath, parentValue, diags) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_terraform_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_terraform_value.go new file mode 100644 index 00000000..b7208fc8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_terraform_value.go @@ -0,0 +1,29 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// TerraformValueAtTerraformPath returns the tftypes.Value at a given +// tftypes.AttributePath or an error. +func (d Data) TerraformValueAtTerraformPath(_ context.Context, path *tftypes.AttributePath) (tftypes.Value, error) { + rawValue, remaining, err := tftypes.WalkAttributePath(d.TerraformValue, path) + + if err != nil { + return tftypes.Value{}, fmt.Errorf("%v still remains in the path: %w", remaining, err) + } + + attrValue, ok := rawValue.(tftypes.Value) + + if !ok { + return tftypes.Value{}, fmt.Errorf("got non-tftypes.Value result %v", rawValue) + } + + return attrValue, err +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_valid_path_expression.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_valid_path_expression.go new file mode 100644 index 00000000..b59d7add --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_valid_path_expression.go @@ -0,0 +1,102 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// ValidPathExpression returns true if the given expression is valid for the +// schema underlying the Data. This can be used to determine if there was an +// expression implementation error versus an expression returning no path +// matches based on implementation details of the underlying data storage. +func (d Data) ValidPathExpression(ctx context.Context, expression path.Expression) bool { + expressionSteps := expression.Resolve().Steps() + + if len(expressionSteps) == 0 { + return false + } + + return validatePathExpressionSteps(ctx, d.Schema.Type(), expressionSteps) +} + +// validatePathExpressionSteps is a recursive function which returns true if +// the path expression steps can be applied to the type. +func validatePathExpressionSteps(ctx context.Context, currentType attr.Type, currentExpressionSteps path.ExpressionSteps) bool { + currentExpressionStep, nextSteps := currentExpressionSteps.NextStep() + + // Generate a tftypes step based on the expression. For type definitions, + // any value should be acceptable for element steps. + var currentTfStep tftypes.AttributePathStep + + switch step := currentExpressionStep.(type) { + case nil: + // There are no more expression steps. + return true + case path.ExpressionStepAttributeNameExact: + currentTfStep = tftypes.AttributeName(step) + case path.ExpressionStepElementKeyIntAny: + currentTfStep = tftypes.ElementKeyInt(0) + case path.ExpressionStepElementKeyIntExact: + currentTfStep = tftypes.ElementKeyInt(step) + case path.ExpressionStepElementKeyStringAny: + currentTfStep = tftypes.ElementKeyString("") + case path.ExpressionStepElementKeyStringExact: + currentTfStep = tftypes.ElementKeyString(step) + case path.ExpressionStepElementKeyValueAny: + tfValue := tftypes.NewValue( + currentType.TerraformType(ctx), + nil, + ) + currentTfStep = tftypes.ElementKeyValue(tfValue) + case path.ExpressionStepElementKeyValueExact: + // Best effort + tfValue, err := step.Value.ToTerraformValue(ctx) + + if err != nil { + tfValue = tftypes.NewValue( + currentType.TerraformType(ctx), + nil, + ) + } + + currentTfStep = tftypes.ElementKeyValue(tfValue) + default: + // If new, resolved path.ExpressionStep are introduced, they must be + // added as cases to this switch statement. + panic(fmt.Sprintf("unimplemented path.ExpressionStep type: %T", currentExpressionStep)) + } + + nextTypeIface, err := currentType.ApplyTerraform5AttributePathStep(currentTfStep) + + if err != nil { + // Debug, not error, log entry for troubleshooting as validation may + // be running in a scenario where invalid expressions are okay. + logging.FrameworkDebug( + ctx, + fmt.Sprintf("Returning false due to error while calling %T ApplyTerraform5AttributePathStep with %T", currentType, currentTfStep), + map[string]any{ + logging.KeyError: err, + }, + ) + + return false + } + + nextType, ok := nextTypeIface.(attr.Type) + + if !ok { + // Raise a more descriptive panic message instead of the type assertion + // panic. + panic(fmt.Sprintf("%T returned unexpected type %T from ApplyTerraform5AttributePathStep", currentType, nextTypeIface)) + } + + return validatePathExpressionSteps(ctx, nextType, nextSteps) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_value.go new file mode 100644 index 00000000..65e3336a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/data_value.go @@ -0,0 +1,130 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "errors" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/totftypes" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// ValueAtPath retrieves the attribute found at `path` and returns it as an +// attr.Value. Consumers should assert the type of the returned value with the +// desired attr.Type. +func (d Data) ValueAtPath(ctx context.Context, schemaPath path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + tftypesPath, tftypesPathDiags := totftypes.AttributePath(ctx, schemaPath) + + diags.Append(tftypesPathDiags...) + + if diags.HasError() { + return nil, diags + } + + attrType, err := d.Schema.TypeAtTerraformPath(ctx, tftypesPath) + + if err != nil { + diags.AddAttributeError( + schemaPath, + d.Description.Title()+" Read Error", + "An unexpected error was encountered trying to retrieve type information at a given path. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + "Error: "+err.Error(), + ) + return nil, diags + } + + // if the data is null, return a null value of the type + if d.TerraformValue.IsNull() { + attrValue, err := attrType.ValueFromTerraform(ctx, tftypes.NewValue(attrType.TerraformType(ctx), nil)) + + if err != nil { + diags.AddAttributeError( + schemaPath, + d.Description.Title()+" Read Error", + "An unexpected error was encountered trying to create a null attribute value from the given path. "+ + "Please report the following to the provider developer:\n\n"+ + "Type: "+attrType.String()+"\n"+ + "Error:"+err.Error(), + ) + } + + return attrValue, diags + } + + tfValue, err := d.TerraformValueAtTerraformPath(ctx, tftypesPath) + + // Ignoring ErrInvalidStep will allow this method to return a null value of the type. + if err != nil && !errors.Is(err, tftypes.ErrInvalidStep) { + diags.AddAttributeError( + schemaPath, + d.Description.Title()+" Read Error", + "An unexpected error was encountered trying to retrieve an attribute value from the given path. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + // TODO: If ErrInvalidStep, check parent paths for unknown value. + // If found, convert this value to an unknown value. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/186 + + attrValue, err := attrType.ValueFromTerraform(ctx, tfValue) + + if err != nil { + diags.AddAttributeError( + schemaPath, + d.Description.Title()+" Read Error", + "An unexpected error was encountered trying to convert an attribute value from the "+d.Description.String()+". This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + "Error: "+err.Error(), + ) + return nil, diags + } + + switch t := attrValue.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + logging.FrameworkTrace(ctx, "Value implements ValidateableAttribute") + logging.FrameworkTrace(ctx, "Calling provider defined Value ValidateAttribute") + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: schemaPath, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + logging.FrameworkTrace(ctx, "Called provider defined Value ValidateAttribute") + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if attrTypeWithValidate, ok := attrType.(xattr.TypeWithValidate); ok { + logging.FrameworkTrace(ctx, "Type implements TypeWithValidate") + logging.FrameworkTrace(ctx, "Calling provider defined Type Validate") + + diags.Append(attrTypeWithValidate.Validate(ctx, tfValue, schemaPath)...) + + logging.FrameworkTrace(ctx, "Called provider defined Type Validate") + + if diags.HasError() { + return nil, diags + } + } + } + + return attrValue, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/doc.go new file mode 100644 index 00000000..2dfea89b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package fwschemadata implements the shared schema-based data implementation +// for configuration, plan, and state values. +package fwschemadata diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/tftypes_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/tftypes_value.go new file mode 100644 index 00000000..df9ad40a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/tftypes_value.go @@ -0,0 +1,210 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// CreateParentTerraformValue ensures that the given parent value can have children +// values upserted. If the parent value is known and not null, it is returned +// without modification. A null Object or Tuple is converted to known with null +// children. An unknown Object or Tuple is converted to known with unknown +// children. List, Map, and Set are created with empty elements. +func CreateParentTerraformValue(_ context.Context, parentPath path.Path, parentType tftypes.Type, childValue interface{}) (tftypes.Value, diag.Diagnostics) { + var diags diag.Diagnostics + var parentValue tftypes.Value + + switch parentType := parentType.(type) { + case tftypes.List: + parentValue = tftypes.NewValue(parentType, []tftypes.Value{}) + case tftypes.Set: + parentValue = tftypes.NewValue(parentType, []tftypes.Value{}) + case tftypes.Map: + parentValue = tftypes.NewValue(parentType, map[string]tftypes.Value{}) + case tftypes.Object: + vals := map[string]tftypes.Value{} + + for name, t := range parentType.AttributeTypes { + vals[name] = tftypes.NewValue(t, childValue) + } + + parentValue = tftypes.NewValue(parentType, vals) + case tftypes.Tuple: + vals := []tftypes.Value{} + + for _, elementType := range parentType.ElementTypes { + vals = append(vals, tftypes.NewValue(elementType, childValue)) + } + + parentValue = tftypes.NewValue(parentType, vals) + default: + diags.AddAttributeError( + parentPath, + "Value Conversion Error", + "An unexpected error was encountered trying to create a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Unknown parent type %s to create value.", parentType), + ) + return parentValue, diags + } + + return parentValue, diags +} + +// UpsertChildTerraformValue will upsert a child value into a parent value. If the +// path step already has a value, it will be overwritten. Otherwise, the child +// value will be added. +// +// Lists can only have the next element added according to the current length. +func UpsertChildTerraformValue(_ context.Context, parentPath path.Path, parentValue tftypes.Value, childStep path.PathStep, childValue tftypes.Value) (tftypes.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + // TODO: Add Tuple support + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/54 + switch childStep := childStep.(type) { + case path.PathStepAttributeName: + // Set in Object + if !parentValue.Type().Is(tftypes.Object{}) { + diags.AddAttributeError( + parentPath, + "Value Conversion Error", + "An unexpected error was encountered trying to create a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Cannot add attribute into parent type: %s", parentValue.Type()), + ) + return parentValue, diags + } + + var parentAttrs map[string]tftypes.Value + err := parentValue.Copy().As(&parentAttrs) + + if err != nil { + diags.AddAttributeError( + parentPath, + "Value Conversion Error", + "An unexpected error was encountered trying to create a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Unable to extract object elements from parent value: %s", err), + ) + return parentValue, diags + } + + parentAttrs[string(childStep)] = childValue + parentValue = tftypes.NewValue(parentValue.Type(), parentAttrs) + case path.PathStepElementKeyInt: + // Upsert List element, except past length + 1 + if !parentValue.Type().Is(tftypes.List{}) { + diags.AddAttributeError( + parentPath, + "Value Conversion Error", + "An unexpected error was encountered trying to create a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Cannot add list element into parent type: %s", parentValue.Type()), + ) + return parentValue, diags + } + + var parentElems []tftypes.Value + err := parentValue.Copy().As(&parentElems) + + if err != nil { + diags.AddAttributeError( + parentPath, + "Value Conversion Error", + "An unexpected error was encountered trying to create a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Unable to extract list elements from parent value: %s", err), + ) + return parentValue, diags + } + + if int(childStep) > len(parentElems) { + diags.AddAttributeError( + parentPath, + "Value Conversion Error", + "An unexpected error was encountered trying to create a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Cannot add list element %d as list currently has %d length. To prevent ambiguity, only the next element can be added to a list. Add empty elements into the list prior to this call, if appropriate.", int(childStep)+1, len(parentElems)), + ) + return parentValue, diags + } + + if int(childStep) == len(parentElems) { + parentElems = append(parentElems, childValue) + } else { + parentElems[int(childStep)] = childValue + } + + parentValue = tftypes.NewValue(parentValue.Type(), parentElems) + case path.PathStepElementKeyString: + // Upsert Map element + if !parentValue.Type().Is(tftypes.Map{}) { + diags.AddAttributeError( + parentPath, + "Value Conversion Error", + "An unexpected error was encountered trying to create a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Cannot add map value into parent type: %s", parentValue.Type()), + ) + return parentValue, diags + } + + var parentElems map[string]tftypes.Value + err := parentValue.Copy().As(&parentElems) + + if err != nil { + diags.AddAttributeError( + parentPath, + "Value Conversion Error", + "An unexpected error was encountered trying to create a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Unable to extract map elements from parent value: %s", err), + ) + return parentValue, diags + } + + parentElems[string(childStep)] = childValue + parentValue = tftypes.NewValue(parentValue.Type(), parentElems) + case path.PathStepElementKeyValue: + // Upsert Set element + if !parentValue.Type().Is(tftypes.Set{}) { + diags.AddAttributeError( + parentPath, + "Value Conversion Error", + "An unexpected error was encountered trying to create a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Cannot add set element into parent type: %s", parentValue.Type()), + ) + return parentValue, diags + } + + var parentElems []tftypes.Value + err := parentValue.Copy().As(&parentElems) + + if err != nil { + diags.AddAttributeError( + parentPath, + "Value Conversion Error", + "An unexpected error was encountered trying to create a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Unable to extract set elements from parent value: %s", err), + ) + return parentValue, diags + } + + // Prevent duplicates + var found bool + + for _, parentElem := range parentElems { + if parentElem.Equal(childValue) { + found = true + break + } + } + + if !found { + parentElems = append(parentElems, childValue) + } + + parentValue = tftypes.NewValue(parentValue.Type(), parentElems) + } + + return parentValue, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality.go new file mode 100644 index 00000000..e93ae839 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality.go @@ -0,0 +1,89 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValueSemanticEqualityRequest represents a request for the provider to +// perform semantic equality logic on a value. +type ValueSemanticEqualityRequest struct { + // Path is the schema-based path of the value. + Path path.Path + + // PriorValue is the prior value. + PriorValue attr.Value + + // ProposedNewValue is the proposed new value. NewValue in the response + // contains the results of semantic equality logic. + ProposedNewValue attr.Value +} + +// ValueSemanticEqualityResponse represents a response to a +// ValueSemanticEqualityRequest. +type ValueSemanticEqualityResponse struct { + // NewValue contains the new value based on the semantic equality logic. + NewValue attr.Value + + // Diagnostics contains any errors and warnings for the logic. + Diagnostics diag.Diagnostics +} + +// ValueSemanticEquality runs all semantic equality logic for a value, including +// recursive checking against collection and structural types. +func ValueSemanticEquality(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + ctx = logging.FrameworkWithAttributePath(ctx, req.Path.String()) + + // Ensure the response NewValue always starts with the proposed new value. + // This is purely defensive coding to prevent subtle data handling bugs. + resp.NewValue = req.ProposedNewValue + + // If the prior value is null or unknown, no need to check semantic equality + // as the proposed new value is always correct. There is also no need to + // descend further into any nesting. + if req.PriorValue.IsNull() || req.PriorValue.IsUnknown() { + return + } + + // If the proposed new value is null or unknown, no need to check semantic + // equality as it should never be changed back to the prior value. There is + // also no need to descend further into any nesting. + if req.ProposedNewValue.IsNull() || req.ProposedNewValue.IsUnknown() { + return + } + + switch req.ProposedNewValue.(type) { + case basetypes.BoolValuable: + ValueSemanticEqualityBool(ctx, req, resp) + case basetypes.Float64Valuable: + ValueSemanticEqualityFloat64(ctx, req, resp) + case basetypes.Int64Valuable: + ValueSemanticEqualityInt64(ctx, req, resp) + case basetypes.ListValuable: + ValueSemanticEqualityList(ctx, req, resp) + case basetypes.MapValuable: + ValueSemanticEqualityMap(ctx, req, resp) + case basetypes.NumberValuable: + ValueSemanticEqualityNumber(ctx, req, resp) + case basetypes.ObjectValuable: + ValueSemanticEqualityObject(ctx, req, resp) + case basetypes.SetValuable: + ValueSemanticEqualitySet(ctx, req, resp) + case basetypes.StringValuable: + ValueSemanticEqualityString(ctx, req, resp) + case basetypes.DynamicValuable: + ValueSemanticEqualityDynamic(ctx, req, resp) + } + + if resp.NewValue.Equal(req.PriorValue) { + logging.FrameworkDebug(ctx, "Value switched to prior value due to semantic equality logic") + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_bool.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_bool.go new file mode 100644 index 00000000..794d02e2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_bool.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValueSemanticEqualityBool performs bool type semantic equality. +func ValueSemanticEqualityBool(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.BoolValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.BoolValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + usePriorValue, diags := proposedNewValuable.BoolSemanticEquals(ctx, priorValuable) + + logging.FrameworkTrace( + ctx, + "Called provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + resp.Diagnostics.Append(diags...) + + if !usePriorValue { + return + } + + resp.NewValue = priorValuable +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_dynamic.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_dynamic.go new file mode 100644 index 00000000..6a23cd1e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_dynamic.go @@ -0,0 +1,78 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValueSemanticEqualityDynamic performs dynamic type semantic equality. +func ValueSemanticEqualityDynamic(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.DynamicValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.DynamicValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + // The prior dynamic value has alredy been checked for null or unknown, however, we also + // need to check the underlying value for null or unknown. + priorValue, diags := priorValuable.ToDynamicValue(ctx) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if priorValue.IsUnderlyingValueNull() || priorValue.IsUnderlyingValueUnknown() { + return + } + + // The proposed new dynamic value has alredy been checked for null or unknown, however, we also + // need to check the underlying value for null or unknown. + proposedValue, diags := proposedNewValuable.ToDynamicValue(ctx) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if proposedValue.IsUnderlyingValueNull() || proposedValue.IsUnderlyingValueUnknown() { + return + } + + usePriorValue, diags := proposedNewValuable.DynamicSemanticEquals(ctx, priorValuable) + + logging.FrameworkTrace( + ctx, + "Called provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + resp.Diagnostics.Append(diags...) + + if !usePriorValue { + return + } + + resp.NewValue = priorValuable +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_float64.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_float64.go new file mode 100644 index 00000000..7c2600ce --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_float64.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValueSemanticEqualityFloat64 performs float64 type semantic equality. +func ValueSemanticEqualityFloat64(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.Float64ValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.Float64ValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + usePriorValue, diags := proposedNewValuable.Float64SemanticEquals(ctx, priorValuable) + + logging.FrameworkTrace( + ctx, + "Called provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + resp.Diagnostics.Append(diags...) + + if !usePriorValue { + return + } + + resp.NewValue = priorValuable +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_int64.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_int64.go new file mode 100644 index 00000000..19447118 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_int64.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValueSemanticEqualityInt64 performs int64 type semantic equality. +func ValueSemanticEqualityInt64(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.Int64ValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.Int64ValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + usePriorValue, diags := proposedNewValuable.Int64SemanticEquals(ctx, priorValuable) + + logging.FrameworkTrace( + ctx, + "Called provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + resp.Diagnostics.Append(diags...) + + if !usePriorValue { + return + } + + resp.NewValue = priorValuable +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_list.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_list.go new file mode 100644 index 00000000..8705d7f4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_list.go @@ -0,0 +1,210 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValueSemanticEqualityList performs list type semantic equality. +// +// This will perform semantic equality checking on elements, regardless of +// whether the collection type implements the expected interface, since it +// cannot be assumed that the collection type implementation runs all possible +// element implementations. +func ValueSemanticEqualityList(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.ListValuableWithSemanticEquals) + + // While the collection type itself does not implement the interface, + // underlying elements might. Check elements automatically, if possible. + if !ok { + ValueSemanticEqualityListElements(ctx, req, resp) + + return + } + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.ListValuableWithSemanticEquals) + + // While the collection type itself does not implement the interface, + // underlying elements might. Check elements automatically, if possible. + if !ok { + ValueSemanticEqualityListElements(ctx, req, resp) + + return + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + usePriorValue, diags := proposedNewValuable.ListSemanticEquals(ctx, priorValuable) + + logging.FrameworkTrace( + ctx, + "Called provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // If the collection type signaled semantic equality, respect the + // determination to use the whole prior value and return early since + // checking elements is not necessary. + if usePriorValue { + resp.NewValue = priorValuable + + return + } + + // While the collection type itself did not signal semantic equality, + // underlying elements might, which should still modify the collection. + // Check elements automatically, if possible. + // + // This logic pessimistically assumes that collection type semantic equality + // implementations may be missing proper element type handling. While + // correct implementations receive a small performance penalty of + // being re-checked, this ensures that less-correct implementations do not + // cause inconsistent data handling behaviors for developers. + ValueSemanticEqualityListElements(ctx, req, resp) +} + +// ValueSemanticEqualityListElements performs list type semantic equality +// on elements, returning a modified list as necessary. +func ValueSemanticEqualityListElements(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.ListValuable) + + // No changes required if the elements cannot be extracted. + if !ok { + return + } + + priorValue, diags := priorValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + priorValueElements := priorValue.Elements() + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.ListValuable) + + // No changes required if the elements cannot be extracted. + if !ok { + return + } + + proposedNewValue, diags := proposedNewValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + proposedNewValueElements := proposedNewValue.Elements() + + // Create a new element value slice, which will be used to create the final + // collection value after each element is evaluated. + newValueElements := make([]attr.Value, len(proposedNewValueElements)) + + // Short circuit flag + updatedElements := false + + // Loop through proposed elements by delegating to the recursive semantic + // equality logic. This ensures that recursion will catch a further + // underlying element type has its semantic equality logic checked, even if + // the current element type does not implement the interface. + for idx, proposedNewValueElement := range proposedNewValueElements { + // Ensure new value always contains all of proposed new value + newValueElements[idx] = proposedNewValueElement + + if idx >= len(priorValueElements) { + continue + } + + elementReq := ValueSemanticEqualityRequest{ + Path: req.Path.AtListIndex(idx), + PriorValue: priorValueElements[idx], + ProposedNewValue: proposedNewValueElement, + } + elementResp := &ValueSemanticEqualityResponse{ + NewValue: elementReq.ProposedNewValue, + } + + ValueSemanticEquality(ctx, elementReq, elementResp) + + resp.Diagnostics.Append(elementResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + if elementResp.NewValue.Equal(elementReq.ProposedNewValue) { + continue + } + + updatedElements = true + newValueElements[idx] = elementResp.NewValue + } + + // No changes required if the elements were not updated. + if !updatedElements { + return + } + + newValue, diags := basetypes.NewListValue(proposedNewValue.ElementType(ctx), newValueElements) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Convert the new value to the original ListValuable type to ensure + // downstream logic has the correct value type for the defined schema type. + newTypable, ok := proposedNewValuable.Type(ctx).(basetypes.ListTypable) + + // This should be a requirement of having a ListValuable, but defensively + // checking just in case. + if !ok { + resp.Diagnostics.AddAttributeError( + req.Path, + "Value Semantic Equality Type Error", + "An unexpected error occurred while performing value semantic equality logic. "+ + "This is either an error in terraform-plugin-framework or a provider custom type implementation. "+ + "Please report this to the provider developers.\n\n"+ + "Error: Expected basetypes.ListTypable type for value type: "+fmt.Sprintf("%T", proposedNewValuable)+"\n"+ + "Path: "+req.Path.String(), + ) + + return + } + + newValuable, diags := newTypable.ValueFromList(ctx, newValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.NewValue = newValuable +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_map.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_map.go new file mode 100644 index 00000000..c10d48a6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_map.go @@ -0,0 +1,212 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValueSemanticEqualityMap performs map type semantic equality. +// +// This will perform semantic equality checking on elements, regardless of +// whether the collection type implements the expected interface, since it +// cannot be assumed that the collection type implementation runs all possible +// element implementations. +func ValueSemanticEqualityMap(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.MapValuableWithSemanticEquals) + + // While the collection type itself does not implement the interface, + // underlying elements might. Check elements automatically, if possible. + if !ok { + ValueSemanticEqualityMapElements(ctx, req, resp) + + return + } + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.MapValuableWithSemanticEquals) + + // While the collection type itself does not implement the interface, + // underlying elements might. Check elements automatically, if possible. + if !ok { + ValueSemanticEqualityMapElements(ctx, req, resp) + + return + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + usePriorValue, diags := proposedNewValuable.MapSemanticEquals(ctx, priorValuable) + + logging.FrameworkTrace( + ctx, + "Called provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // If the collection type signaled semantic equality, respect the + // determination to use the whole prior value and return early since + // checking elements is not necessary. + if usePriorValue { + resp.NewValue = priorValuable + + return + } + + // While the collection type itself did not signal semantic equality, + // underlying elements might, which should still modify the collection. + // Check elements automatically, if possible. + // + // This logic pessimistically assumes that collection type semantic equality + // implementations may be missing proper element type handling. While + // correct implementations receive a small performance penalty of + // being re-checked, this ensures that less-correct implementations do not + // cause inconsistent data handling behaviors for developers. + ValueSemanticEqualityMapElements(ctx, req, resp) +} + +// ValueSemanticEqualityMapElements performs list type semantic equality +// on elements, returning a modified list as necessary. +func ValueSemanticEqualityMapElements(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.MapValuable) + + // No changes required if the elements cannot be extracted. + if !ok { + return + } + + priorValue, diags := priorValuable.ToMapValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + priorValueElements := priorValue.Elements() + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.MapValuable) + + // No changes required if the elements cannot be extracted. + if !ok { + return + } + + proposedNewValue, diags := proposedNewValuable.ToMapValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + proposedNewValueElements := proposedNewValue.Elements() + + // Create a new element value map, which will be used to create the final + // collection value after each element is evaluated. + newValueElements := make(map[string]attr.Value, len(proposedNewValueElements)) + + // Short circuit flag + updatedElements := false + + // Loop through proposed elements by delegating to the recursive semantic + // equality logic. This ensures that recursion will catch a further + // underlying element type has its semantic equality logic checked, even if + // the current element type does not implement the interface. + for key, proposedNewValueElement := range proposedNewValueElements { + // Ensure new value always contains all of proposed new value + newValueElements[key] = proposedNewValueElement + + priorValueElement, ok := priorValueElements[key] + + if !ok { + continue + } + + elementReq := ValueSemanticEqualityRequest{ + Path: req.Path.AtMapKey(key), + PriorValue: priorValueElement, + ProposedNewValue: proposedNewValueElement, + } + elementResp := &ValueSemanticEqualityResponse{ + NewValue: elementReq.ProposedNewValue, + } + + ValueSemanticEquality(ctx, elementReq, elementResp) + + resp.Diagnostics.Append(elementResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + if elementResp.NewValue.Equal(elementReq.ProposedNewValue) { + continue + } + + updatedElements = true + newValueElements[key] = elementResp.NewValue + } + + // No changes required if the elements were not updated. + if !updatedElements { + return + } + + newValue, diags := basetypes.NewMapValue(proposedNewValue.ElementType(ctx), newValueElements) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Convert the new value to the original MapValuable type to ensure + // downstream logic has the correct value type for the defined schema type. + newTypable, ok := proposedNewValuable.Type(ctx).(basetypes.MapTypable) + + // This should be a requirement of having a MapValuable, but defensively + // checking just in case. + if !ok { + resp.Diagnostics.AddAttributeError( + req.Path, + "Value Semantic Equality Type Error", + "An unexpected error occurred while performing value semantic equality logic. "+ + "This is either an error in terraform-plugin-framework or a provider custom type implementation. "+ + "Please report this to the provider developers.\n\n"+ + "Error: Expected basetypes.MapTypable type for value type: "+fmt.Sprintf("%T", proposedNewValuable)+"\n"+ + "Path: "+req.Path.String(), + ) + + return + } + + newValuable, diags := newTypable.ValueFromMap(ctx, newValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.NewValue = newValuable +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_number.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_number.go new file mode 100644 index 00000000..8a1daae2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_number.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValueSemanticEqualityNumber performs number type semantic equality. +func ValueSemanticEqualityNumber(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.NumberValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.NumberValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + usePriorValue, diags := proposedNewValuable.NumberSemanticEquals(ctx, priorValuable) + + logging.FrameworkTrace( + ctx, + "Called provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + resp.Diagnostics.Append(diags...) + + if !usePriorValue { + return + } + + resp.NewValue = priorValuable +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_object.go new file mode 100644 index 00000000..e1c8c56a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_object.go @@ -0,0 +1,212 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValueSemanticEqualityObject performs object type semantic equality. +// +// This will perform semantic equality checking on attributes, regardless of +// whether the structural type implements the expected interface, since it +// cannot be assumed that the structural type implementation runs all possible +// attribute implementations. +func ValueSemanticEqualityObject(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.ObjectValuableWithSemanticEquals) + + // While the structural type itself does not implement the interface, + // underlying attributes might. Check attributes automatically, if possible. + if !ok { + ValueSemanticEqualityObjectAttributes(ctx, req, resp) + + return + } + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.ObjectValuableWithSemanticEquals) + + // While the structural type itself does not implement the interface, + // underlying attributes might. Check attributes automatically, if possible. + if !ok { + ValueSemanticEqualityObjectAttributes(ctx, req, resp) + + return + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + usePriorValue, diags := proposedNewValuable.ObjectSemanticEquals(ctx, priorValuable) + + logging.FrameworkTrace( + ctx, + "Called provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // If the structural type signaled semantic equality, respect the + // determination to use the whole prior value and return early since + // checking attributes is not necessary. + if usePriorValue { + resp.NewValue = priorValuable + + return + } + + // While the structural type itself did not signal semantic equality, + // underlying attributes might, which should still modify the structural. + // Check attributes automatically, if possible. + // + // This logic pessimistically assumes that structural type semantic equality + // implementations may be missing proper attribute type handling. While + // correct implementations receive a small performance penalty of + // being re-checked, this ensures that less-correct implementations do not + // cause inconsistent data handling behaviors for developers. + ValueSemanticEqualityObjectAttributes(ctx, req, resp) +} + +// ValueSemanticEqualityObjectAttributes performs object type semantic equality +// on attributes, returning a modified object as necessary. +func ValueSemanticEqualityObjectAttributes(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.ObjectValuable) + + // No changes required if the attributes cannot be extracted. + if !ok { + return + } + + priorValue, diags := priorValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + priorValueAttributes := priorValue.Attributes() + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.ObjectValuable) + + // No changes required if the attributes cannot be extracted. + if !ok { + return + } + + proposedNewValue, diags := proposedNewValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + proposedNewValueAttributes := proposedNewValue.Attributes() + + // Create a new element value map, which will be used to create the final + // collection value after each element is evaluated. + newValueAttributes := make(map[string]attr.Value, len(proposedNewValueAttributes)) + + // Short circuit flag + updatedAttributes := false + + // Loop through proposed attributes by delegating to the recursive semantic + // equality logic. This ensures that recursion will catch a further + // underlying element type has its semantic equality logic checked, even if + // the current element type does not implement the interface. + for name, proposedNewValueElement := range proposedNewValueAttributes { + // Ensure new value always contains all of proposed new value + newValueAttributes[name] = proposedNewValueElement + + priorValueElement, ok := priorValueAttributes[name] + + if !ok { + continue + } + + elementReq := ValueSemanticEqualityRequest{ + Path: req.Path.AtName(name), + PriorValue: priorValueElement, + ProposedNewValue: proposedNewValueElement, + } + elementResp := &ValueSemanticEqualityResponse{ + NewValue: elementReq.ProposedNewValue, + } + + ValueSemanticEquality(ctx, elementReq, elementResp) + + resp.Diagnostics.Append(elementResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + if elementResp.NewValue.Equal(elementReq.ProposedNewValue) { + continue + } + + updatedAttributes = true + newValueAttributes[name] = elementResp.NewValue + } + + // No changes required if the attributes were not updated. + if !updatedAttributes { + return + } + + newValue, diags := basetypes.NewObjectValue(proposedNewValue.AttributeTypes(ctx), newValueAttributes) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Convert the new value to the original ObjectValuable type to ensure + // downstream logic has the correct value type for the defined schema type. + newTypable, ok := proposedNewValuable.Type(ctx).(basetypes.ObjectTypable) + + // This should be a requirement of having a ObjectValuable, but defensively + // checking just in case. + if !ok { + resp.Diagnostics.AddAttributeError( + req.Path, + "Value Semantic Equality Type Error", + "An unexpected error occurred while performing value semantic equality logic. "+ + "This is either an error in terraform-plugin-framework or a provider custom type implementation. "+ + "Please report this to the provider developers.\n\n"+ + "Error: Expected basetypes.ObjectTypable type for value type: "+fmt.Sprintf("%T", proposedNewValuable)+"\n"+ + "Path: "+req.Path.String(), + ) + + return + } + + newValuable, diags := newTypable.ValueFromObject(ctx, newValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.NewValue = newValuable +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_set.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_set.go new file mode 100644 index 00000000..1afe626f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_set.go @@ -0,0 +1,210 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValueSemanticEqualitySet performs set type semantic equality. +// +// This will perform semantic equality checking on elements, regardless of +// whether the collection type implements the expected interface, since it +// cannot be assumed that the collection type implementation runs all possible +// element implementations. +func ValueSemanticEqualitySet(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.SetValuableWithSemanticEquals) + + // While the collection type itself does not implement the interface, + // underlying elements might. Check elements automatically, if possible. + if !ok { + ValueSemanticEqualitySetElements(ctx, req, resp) + + return + } + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.SetValuableWithSemanticEquals) + + // While the collection type itself does not implement the interface, + // underlying elements might. Check elements automatically, if possible. + if !ok { + ValueSemanticEqualitySetElements(ctx, req, resp) + + return + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + usePriorValue, diags := proposedNewValuable.SetSemanticEquals(ctx, priorValuable) + + logging.FrameworkTrace( + ctx, + "Called provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // If the collection type signaled semantic equality, respect the + // determination to use the whole prior value and return early since + // checking elements is not necessary. + if usePriorValue { + resp.NewValue = priorValuable + + return + } + + // While the collection type itself did not signal semantic equality, + // underlying elements might, which should still modify the collection. + // Check elements automatically, if possible. + // + // This logic pessimistically assumes that collection type semantic equality + // implementations may be missing proper element type handling. While + // correct implementations receive a small performance penalty of + // being re-checked, this ensures that less-correct implementations do not + // cause inconsistent data handling behaviors for developers. + ValueSemanticEqualitySetElements(ctx, req, resp) +} + +// ValueSemanticEqualitySetElements performs list type semantic equality +// on elements, returning a modified list as necessary. +func ValueSemanticEqualitySetElements(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.SetValuable) + + // No changes required if the elements cannot be extracted. + if !ok { + return + } + + priorValue, diags := priorValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + priorValueElements := priorValue.Elements() + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.SetValuable) + + // No changes required if the elements cannot be extracted. + if !ok { + return + } + + proposedNewValue, diags := proposedNewValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + proposedNewValueElements := proposedNewValue.Elements() + + // Create a new element value slice, which will be used to create the final + // collection value after each element is evaluated. + newValueElements := make([]attr.Value, len(proposedNewValueElements)) + + // Short circuit flag + updatedElements := false + + // Loop through proposed elements by delegating to the recursive semantic + // equality logic. This ensures that recursion will catch a further + // underlying element type has its semantic equality logic checked, even if + // the current element type does not implement the interface. + for idx, proposedNewValueElement := range proposedNewValueElements { + // Ensure new value always contains all of proposed new value + newValueElements[idx] = proposedNewValueElement + + if idx >= len(priorValueElements) { + continue + } + + elementReq := ValueSemanticEqualityRequest{ + Path: req.Path.AtSetValue(proposedNewValueElement), + PriorValue: priorValueElements[idx], + ProposedNewValue: proposedNewValueElement, + } + elementResp := &ValueSemanticEqualityResponse{ + NewValue: elementReq.ProposedNewValue, + } + + ValueSemanticEquality(ctx, elementReq, elementResp) + + resp.Diagnostics.Append(elementResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + if elementResp.NewValue.Equal(elementReq.ProposedNewValue) { + continue + } + + updatedElements = true + newValueElements[idx] = elementResp.NewValue + } + + // No changes required if the elements were not updated. + if !updatedElements { + return + } + + newValue, diags := basetypes.NewSetValue(proposedNewValue.ElementType(ctx), newValueElements) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Convert the new value to the original SetValuable type to ensure + // downstream logic has the correct value type for the defined schema type. + newTypable, ok := proposedNewValuable.Type(ctx).(basetypes.SetTypable) + + // This should be a requirement of having a SetValuable, but defensively + // checking just in case. + if !ok { + resp.Diagnostics.AddAttributeError( + req.Path, + "Value Semantic Equality Type Error", + "An unexpected error occurred while performing value semantic equality logic. "+ + "This is either an error in terraform-plugin-framework or a provider custom type implementation. "+ + "Please report this to the provider developers.\n\n"+ + "Error: Expected basetypes.SetTypable type for value type: "+fmt.Sprintf("%T", proposedNewValuable)+"\n"+ + "Path: "+req.Path.String(), + ) + + return + } + + newValuable, diags := newTypable.ValueFromSet(ctx, newValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.NewValue = newValuable +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_string.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_string.go new file mode 100644 index 00000000..357edd8c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata/value_semantic_equality_string.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwschemadata + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValueSemanticEqualityString performs string type semantic equality. +func ValueSemanticEqualityString(ctx context.Context, req ValueSemanticEqualityRequest, resp *ValueSemanticEqualityResponse) { + priorValuable, ok := req.PriorValue.(basetypes.StringValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + proposedNewValuable, ok := req.ProposedNewValue.(basetypes.StringValuableWithSemanticEquals) + + // No changes required if the interface is not implemented. + if !ok { + return + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + usePriorValue, diags := proposedNewValuable.StringSemanticEquals(ctx, priorValuable) + + logging.FrameworkTrace( + ctx, + "Called provider defined type-based SemanticEquals", + map[string]interface{}{ + logging.KeyValueType: proposedNewValuable.String(), + }, + ) + + resp.Diagnostics.Append(diags...) + + if !usePriorValue { + return + } + + resp.NewValue = priorValuable +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attr_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attr_type.go new file mode 100644 index 00000000..85dd3bff --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attr_type.go @@ -0,0 +1,162 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +func coerceBoolTypable(ctx context.Context, schemaPath path.Path, valuable basetypes.BoolValuable) (basetypes.BoolTypable, diag.Diagnostics) { + typable, ok := valuable.Type(ctx).(basetypes.BoolTypable) + + // Type() of a Valuable should always be a Typable to recreate the Valuable, + // but if for some reason it is not, raise an implementation error instead + // of a panic. + if !ok { + return nil, diag.Diagnostics{ + attributePlanModificationTypableError(schemaPath, valuable), + } + } + + return typable, nil +} + +func coerceFloat64Typable(ctx context.Context, schemaPath path.Path, valuable basetypes.Float64Valuable) (basetypes.Float64Typable, diag.Diagnostics) { + typable, ok := valuable.Type(ctx).(basetypes.Float64Typable) + + // Type() of a Valuable should always be a Typable to recreate the Valuable, + // but if for some reason it is not, raise an implementation error instead + // of a panic. + if !ok { + return nil, diag.Diagnostics{ + attributePlanModificationTypableError(schemaPath, valuable), + } + } + + return typable, nil +} + +func coerceInt64Typable(ctx context.Context, schemaPath path.Path, valuable basetypes.Int64Valuable) (basetypes.Int64Typable, diag.Diagnostics) { + typable, ok := valuable.Type(ctx).(basetypes.Int64Typable) + + // Type() of a Valuable should always be a Typable to recreate the Valuable, + // but if for some reason it is not, raise an implementation error instead + // of a panic. + if !ok { + return nil, diag.Diagnostics{ + attributePlanModificationTypableError(schemaPath, valuable), + } + } + + return typable, nil +} + +func coerceListTypable(ctx context.Context, schemaPath path.Path, valuable basetypes.ListValuable) (basetypes.ListTypable, diag.Diagnostics) { + typable, ok := valuable.Type(ctx).(basetypes.ListTypable) + + // Type() of a Valuable should always be a Typable to recreate the Valuable, + // but if for some reason it is not, raise an implementation error instead + // of a panic. + if !ok { + return nil, diag.Diagnostics{ + attributePlanModificationTypableError(schemaPath, valuable), + } + } + + return typable, nil +} + +func coerceMapTypable(ctx context.Context, schemaPath path.Path, valuable basetypes.MapValuable) (basetypes.MapTypable, diag.Diagnostics) { + typable, ok := valuable.Type(ctx).(basetypes.MapTypable) + + // Type() of a Valuable should always be a Typable to recreate the Valuable, + // but if for some reason it is not, raise an implementation error instead + // of a panic. + if !ok { + return nil, diag.Diagnostics{ + attributePlanModificationTypableError(schemaPath, valuable), + } + } + + return typable, nil +} + +func coerceNumberTypable(ctx context.Context, schemaPath path.Path, valuable basetypes.NumberValuable) (basetypes.NumberTypable, diag.Diagnostics) { + typable, ok := valuable.Type(ctx).(basetypes.NumberTypable) + + // Type() of a Valuable should always be a Typable to recreate the Valuable, + // but if for some reason it is not, raise an implementation error instead + // of a panic. + if !ok { + return nil, diag.Diagnostics{ + attributePlanModificationTypableError(schemaPath, valuable), + } + } + + return typable, nil +} + +func coerceObjectTypable(ctx context.Context, schemaPath path.Path, valuable basetypes.ObjectValuable) (basetypes.ObjectTypable, diag.Diagnostics) { + typable, ok := valuable.Type(ctx).(basetypes.ObjectTypable) + + // Type() of a Valuable should always be a Typable to recreate the Valuable, + // but if for some reason it is not, raise an implementation error instead + // of a panic. + if !ok { + return nil, diag.Diagnostics{ + attributePlanModificationTypableError(schemaPath, valuable), + } + } + + return typable, nil +} + +func coerceSetTypable(ctx context.Context, schemaPath path.Path, valuable basetypes.SetValuable) (basetypes.SetTypable, diag.Diagnostics) { + typable, ok := valuable.Type(ctx).(basetypes.SetTypable) + + // Type() of a Valuable should always be a Typable to recreate the Valuable, + // but if for some reason it is not, raise an implementation error instead + // of a panic. + if !ok { + return nil, diag.Diagnostics{ + attributePlanModificationTypableError(schemaPath, valuable), + } + } + + return typable, nil +} + +func coerceStringTypable(ctx context.Context, schemaPath path.Path, valuable basetypes.StringValuable) (basetypes.StringTypable, diag.Diagnostics) { + typable, ok := valuable.Type(ctx).(basetypes.StringTypable) + + // Type() of a Valuable should always be a Typable to recreate the Valuable, + // but if for some reason it is not, raise an implementation error instead + // of a panic. + if !ok { + return nil, diag.Diagnostics{ + attributePlanModificationTypableError(schemaPath, valuable), + } + } + + return typable, nil +} + +func coerceDynamicTypable(ctx context.Context, schemaPath path.Path, valuable basetypes.DynamicValuable) (basetypes.DynamicTypable, diag.Diagnostics) { + typable, ok := valuable.Type(ctx).(basetypes.DynamicTypable) + + // Type() of a Valuable should always be a Typable to recreate the Valuable, + // but if for some reason it is not, raise an implementation error instead + // of a panic. + if !ok { + return nil, diag.Diagnostics{ + attributePlanModificationTypableError(schemaPath, valuable), + } + } + + return typable, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attr_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attr_value.go new file mode 100644 index 00000000..4fb154f9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attr_value.go @@ -0,0 +1,244 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +func coerceListValuable(_ context.Context, schemaPath path.Path, value attr.Value) (basetypes.ListValuable, diag.Diagnostics) { + listValuable, ok := value.(basetypes.ListValuable) + + if !ok { + return types.ListNull(nil), diag.Diagnostics{ + schemaDataWalkError(schemaPath, value), + } + } + + return listValuable, nil +} + +func coerceListValue(ctx context.Context, schemaPath path.Path, value attr.Value) (types.List, diag.Diagnostics) { + listValuable, diags := coerceListValuable(ctx, schemaPath, value) + + if diags.HasError() { + return types.ListNull(nil), diags + } + + listValue, listValueDiags := listValuable.ToListValue(ctx) + + // Ensure prior warnings are preserved. + diags.Append(listValueDiags...) + + return listValue, diags +} + +func coerceMapValuable(_ context.Context, schemaPath path.Path, value attr.Value) (basetypes.MapValuable, diag.Diagnostics) { + mapValuable, ok := value.(basetypes.MapValuable) + + if !ok { + return types.MapNull(nil), diag.Diagnostics{ + schemaDataWalkError(schemaPath, value), + } + } + + return mapValuable, nil +} + +func coerceMapValue(ctx context.Context, schemaPath path.Path, value attr.Value) (types.Map, diag.Diagnostics) { + mapValuable, diags := coerceMapValuable(ctx, schemaPath, value) + + if diags.HasError() { + return types.MapNull(nil), diags + } + + mapValue, mapValueDiags := mapValuable.ToMapValue(ctx) + + // Ensure prior warnings are preserved. + diags.Append(mapValueDiags...) + + return mapValue, diags +} + +func coerceObjectValuable(_ context.Context, schemaPath path.Path, value attr.Value) (basetypes.ObjectValuable, diag.Diagnostics) { + objectValuable, ok := value.(basetypes.ObjectValuable) + + if !ok { + return types.ObjectNull(nil), diag.Diagnostics{ + schemaDataWalkError(schemaPath, value), + } + } + + return objectValuable, nil +} + +func coerceObjectValue(ctx context.Context, schemaPath path.Path, value attr.Value) (types.Object, diag.Diagnostics) { + objectValuable, diags := coerceObjectValuable(ctx, schemaPath, value) + + if diags.HasError() { + return types.ObjectNull(nil), diags + } + + objectValue, objectValueDiags := objectValuable.ToObjectValue(ctx) + + // Ensure prior warnings are preserved. + diags.Append(objectValueDiags...) + + return objectValue, diags +} + +func coerceSetValuable(_ context.Context, schemaPath path.Path, value attr.Value) (basetypes.SetValuable, diag.Diagnostics) { + setValuable, ok := value.(basetypes.SetValuable) + + if !ok { + return types.SetNull(nil), diag.Diagnostics{ + schemaDataWalkError(schemaPath, value), + } + } + + return setValuable, nil +} + +func coerceSetValue(ctx context.Context, schemaPath path.Path, value attr.Value) (types.Set, diag.Diagnostics) { + setValuable, diags := coerceSetValuable(ctx, schemaPath, value) + + if diags.HasError() { + return types.SetNull(nil), diags + } + + setValue, setValueDiags := setValuable.ToSetValue(ctx) + + // Ensure prior warnings are preserved. + diags.Append(setValueDiags...) + + return setValue, diags +} + +func listElemObject(ctx context.Context, schemaPath path.Path, list types.List, index int, description fwschemadata.DataDescription) (types.Object, diag.Diagnostics) { + if list.IsNull() { + return listElemObjectFromTerraformValue(ctx, schemaPath, list, description, nil) + } + + if list.IsUnknown() { + return listElemObjectFromTerraformValue(ctx, schemaPath, list, description, tftypes.UnknownValue) + } + + if index >= len(list.Elements()) { + return listElemObjectFromTerraformValue(ctx, schemaPath, list, description, nil) + } + + return coerceObjectValue(ctx, schemaPath, list.Elements()[index]) +} + +func listElemObjectFromTerraformValue(ctx context.Context, schemaPath path.Path, list types.List, description fwschemadata.DataDescription, tfValue any) (types.Object, diag.Diagnostics) { + elemType := list.ElementType(ctx) + elemValue, err := elemType.ValueFromTerraform(ctx, tftypes.NewValue(elemType.TerraformType(ctx), tfValue)) + + if err != nil { + return types.ObjectNull(nil), diag.Diagnostics{ + schemaDataValueError(ctx, list, description, err), + } + } + + return coerceObjectValue(ctx, schemaPath, elemValue) +} + +func mapElemObject(ctx context.Context, schemaPath path.Path, m types.Map, key string, description fwschemadata.DataDescription) (types.Object, diag.Diagnostics) { + if m.IsNull() { + return mapElemObjectFromTerraformValue(ctx, schemaPath, m, description, nil) + } + + if m.IsUnknown() { + return mapElemObjectFromTerraformValue(ctx, schemaPath, m, description, tftypes.UnknownValue) + } + + elemValue, ok := m.Elements()[key] + + if !ok { + return mapElemObjectFromTerraformValue(ctx, schemaPath, m, description, nil) + } + + return coerceObjectValue(ctx, schemaPath, elemValue) +} + +func mapElemObjectFromTerraformValue(ctx context.Context, schemaPath path.Path, m types.Map, description fwschemadata.DataDescription, tfValue any) (types.Object, diag.Diagnostics) { + elemType := m.ElementType(ctx) + elemValue, err := elemType.ValueFromTerraform(ctx, tftypes.NewValue(elemType.TerraformType(ctx), tfValue)) + + if err != nil { + return types.ObjectNull(nil), diag.Diagnostics{ + schemaDataValueError(ctx, m, description, err), + } + } + + return coerceObjectValue(ctx, schemaPath, elemValue) +} + +func objectAttributeValue(ctx context.Context, object types.Object, attributeName string, description fwschemadata.DataDescription) (attr.Value, diag.Diagnostics) { + if object.IsNull() { + return objectAttributeValueFromTerraformValue(ctx, object, attributeName, description, nil) + } + + if object.IsUnknown() { + return objectAttributeValueFromTerraformValue(ctx, object, attributeName, description, tftypes.UnknownValue) + } + + // A panic here indicates a bug somewhere else in the framework or an + // invalid test case. + return object.Attributes()[attributeName], nil +} + +func objectAttributeValueFromTerraformValue(ctx context.Context, object types.Object, attributeName string, description fwschemadata.DataDescription, tfValue any) (attr.Value, diag.Diagnostics) { + // A panic here indicates a bug somewhere else in the framework or an + // invalid test case. + attrType := object.AttributeTypes(ctx)[attributeName] + + elemValue, err := attrType.ValueFromTerraform(ctx, tftypes.NewValue(attrType.TerraformType(ctx), tfValue)) + + if err != nil { + return nil, diag.Diagnostics{ + schemaDataValueError(ctx, object, description, err), + } + } + + return elemValue, nil +} + +func setElemObject(ctx context.Context, schemaPath path.Path, set types.Set, index int, description fwschemadata.DataDescription) (types.Object, diag.Diagnostics) { + if set.IsNull() { + return setElemObjectFromTerraformValue(ctx, schemaPath, set, description, nil) + } + + if set.IsUnknown() { + return setElemObjectFromTerraformValue(ctx, schemaPath, set, description, tftypes.UnknownValue) + } + + if index >= len(set.Elements()) { + return setElemObjectFromTerraformValue(ctx, schemaPath, set, description, nil) + } + + return coerceObjectValue(ctx, schemaPath, set.Elements()[index]) +} + +func setElemObjectFromTerraformValue(ctx context.Context, schemaPath path.Path, set types.Set, description fwschemadata.DataDescription, tfValue any) (types.Object, diag.Diagnostics) { + elemType := set.ElementType(ctx) + elemValue, err := elemType.ValueFromTerraform(ctx, tftypes.NewValue(elemType.TerraformType(ctx), tfValue)) + + if err != nil { + return types.ObjectNull(nil), diag.Diagnostics{ + schemaDataValueError(ctx, set, description, err), + } + } + + return coerceObjectValue(ctx, schemaPath, elemValue) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attribute_plan_modification.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attribute_plan_modification.go new file mode 100644 index 00000000..36e86dec --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attribute_plan_modification.go @@ -0,0 +1,2385 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ModifyAttributePlanRequest represents a request for the provider to modify an +// attribute value, or mark it as requiring replacement, at plan time. An +// instance of this request struct is supplied as an argument to the Modify +// function of an attribute's plan modifier(s). +type ModifyAttributePlanRequest struct { + // AttributePath is the path of the attribute. Use this path for any + // response diagnostics. + AttributePath path.Path + + // AttributePathExpression is the expression matching the exact path of the + // attribute. + AttributePathExpression path.Expression + + // Config is the configuration the user supplied for the resource. + Config tfsdk.Config + + // State is the current state of the resource. + State tfsdk.State + + // Plan is the planned new state for the resource. + Plan tfsdk.Plan + + // AttributeConfig is the configuration the user supplied for the attribute. + AttributeConfig attr.Value + + // AttributeState is the current state of the attribute. + AttributeState attr.Value + + // AttributePlan is the planned new state for the attribute. + AttributePlan attr.Value + + // ProviderMeta is metadata from the provider_meta block of the module. + ProviderMeta tfsdk.Config + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // ModifyAttributePlanResponse.Private to prevent accidental private state data loss. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + // + // Use the GetKey method to read data. Use the SetKey method on + // ModifyAttributePlanResponse.Private to update or remove a value. + Private *privatestate.ProviderData +} + +type ModifyAttributePlanResponse struct { + AttributePlan attr.Value + Diagnostics diag.Diagnostics + RequiresReplace path.Paths + Private *privatestate.ProviderData +} + +// AttributeModifyPlan runs all AttributePlanModifiers +// +// TODO: Clean up this abstraction back into an internal Attribute type method. +// The extra Attribute parameter is a carry-over of creating the proto6server +// package from the tfsdk package and not wanting to export the method. +// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/365 +func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + ctx = logging.FrameworkWithAttributePath(ctx, req.AttributePath.String()) + + if req.Private != nil { + resp.Private = req.Private + } + + switch attributeWithPlanModifiers := a.(type) { + case fwxschema.AttributeWithBoolPlanModifiers: + AttributePlanModifyBool(ctx, attributeWithPlanModifiers, req, resp) + case fwxschema.AttributeWithFloat64PlanModifiers: + AttributePlanModifyFloat64(ctx, attributeWithPlanModifiers, req, resp) + case fwxschema.AttributeWithInt64PlanModifiers: + AttributePlanModifyInt64(ctx, attributeWithPlanModifiers, req, resp) + case fwxschema.AttributeWithListPlanModifiers: + AttributePlanModifyList(ctx, attributeWithPlanModifiers, req, resp) + case fwxschema.AttributeWithMapPlanModifiers: + AttributePlanModifyMap(ctx, attributeWithPlanModifiers, req, resp) + case fwxschema.AttributeWithNumberPlanModifiers: + AttributePlanModifyNumber(ctx, attributeWithPlanModifiers, req, resp) + case fwxschema.AttributeWithObjectPlanModifiers: + AttributePlanModifyObject(ctx, attributeWithPlanModifiers, req, resp) + case fwxschema.AttributeWithSetPlanModifiers: + AttributePlanModifySet(ctx, attributeWithPlanModifiers, req, resp) + case fwxschema.AttributeWithStringPlanModifiers: + AttributePlanModifyString(ctx, attributeWithPlanModifiers, req, resp) + case fwxschema.AttributeWithDynamicPlanModifiers: + AttributePlanModifyDynamic(ctx, attributeWithPlanModifiers, req, resp) + } + + if resp.Diagnostics.HasError() { + return + } + + // Null and unknown values should not have nested schema to modify. + if resp.AttributePlan.IsNull() || resp.AttributePlan.IsUnknown() { + return + } + + nestedAttribute, ok := a.(fwschema.NestedAttribute) + + if !ok { + return + } + + nestedAttributeObject := nestedAttribute.GetNestedObject() + + nm := nestedAttribute.GetNestingMode() + switch nm { + case fwschema.NestingModeList: + configList, diags := coerceListValue(ctx, req.AttributePath, req.AttributeConfig) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Use response as the planned value may have been modified with list + // plan modifiers. + planListValuable, diags := coerceListValuable(ctx, req.AttributePath, resp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceListTypable(ctx, req.AttributePath, planListValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planList, diags := planListValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateList, diags := coerceListValue(ctx, req.AttributePath, req.AttributeState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planElements := planList.Elements() + + for idx, planElem := range planElements { + attrPath := req.AttributePath.AtListIndex(idx) + + configObject, diags := listElemObject(ctx, attrPath, configList, idx, fwschemadata.DataDescriptionConfiguration) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObject, diags := coerceObjectValue(ctx, attrPath, planElem) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObjectValuable, diags := coerceObjectValuable(ctx, attrPath, planElem) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceObjectTypable(ctx, attrPath, planObjectValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateObject, diags := listElemObject(ctx, attrPath, stateList, idx, fwschemadata.DataDescriptionState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + objectReq := planmodifier.ObjectRequest{ + Config: req.Config, + ConfigValue: configObject, + Path: attrPath, + PathExpression: attrPath.Expression(), + Plan: req.Plan, + PlanValue: planObject, + Private: resp.Private, + State: req.State, + StateValue: stateObject, + } + objectResp := &ModifyAttributePlanResponse{ + AttributePlan: objectReq.PlanValue, + Private: objectReq.Private, + } + + NestedAttributeObjectPlanModify(ctx, nestedAttributeObject, objectReq, objectResp) + + respValue, diags := coerceObjectValue(ctx, attrPath, objectResp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/821 + respValuable, diags := typable.ValueFromObject(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planElements[idx] = respValuable + resp.Diagnostics.Append(objectResp.Diagnostics...) + resp.Private = objectResp.Private + resp.RequiresReplace.Append(objectResp.RequiresReplace...) + } + + respValue, diags := types.ListValue(planList.ElementType(ctx), planElements) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + respValuable, diags := typable.ValueFromList(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.AttributePlan = respValuable + case fwschema.NestingModeSet: + configSet, diags := coerceSetValue(ctx, req.AttributePath, req.AttributeConfig) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Use response as the planned value may have been modified with set + // plan modifiers. + planSetValuable, diags := coerceSetValuable(ctx, req.AttributePath, resp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceSetTypable(ctx, req.AttributePath, planSetValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planSet, diags := planSetValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateSet, diags := coerceSetValue(ctx, req.AttributePath, req.AttributeState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planElements := planSet.Elements() + + for idx, planElem := range planElements { + attrPath := req.AttributePath.AtSetValue(planElem) + + configObject, diags := setElemObject(ctx, attrPath, configSet, idx, fwschemadata.DataDescriptionConfiguration) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObject, diags := coerceObjectValue(ctx, attrPath, planElem) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObjectValuable, diags := coerceObjectValuable(ctx, attrPath, planElem) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceObjectTypable(ctx, attrPath, planObjectValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateObject, diags := setElemObject(ctx, attrPath, stateSet, idx, fwschemadata.DataDescriptionState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + objectReq := planmodifier.ObjectRequest{ + Config: req.Config, + ConfigValue: configObject, + Path: attrPath, + PathExpression: attrPath.Expression(), + Plan: req.Plan, + PlanValue: planObject, + Private: resp.Private, + State: req.State, + StateValue: stateObject, + } + objectResp := &ModifyAttributePlanResponse{ + AttributePlan: objectReq.PlanValue, + Private: objectReq.Private, + } + + NestedAttributeObjectPlanModify(ctx, nestedAttributeObject, objectReq, objectResp) + + respValue, diags := coerceObjectValue(ctx, attrPath, objectResp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/821 + respValuable, diags := typable.ValueFromObject(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planElements[idx] = respValuable + resp.Diagnostics.Append(objectResp.Diagnostics...) + resp.Private = objectResp.Private + resp.RequiresReplace.Append(objectResp.RequiresReplace...) + } + + respValue, diags := types.SetValue(planSet.ElementType(ctx), planElements) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + respValuable, diags := typable.ValueFromSet(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.AttributePlan = respValuable + case fwschema.NestingModeMap: + configMap, diags := coerceMapValue(ctx, req.AttributePath, req.AttributeConfig) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Use response as the planned value may have been modified with map + // plan modifiers. + planMapValuable, diags := coerceMapValuable(ctx, req.AttributePath, resp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceMapTypable(ctx, req.AttributePath, planMapValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planMap, diags := planMapValuable.ToMapValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateMap, diags := coerceMapValue(ctx, req.AttributePath, req.AttributeState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planElements := planMap.Elements() + + for key, planElem := range planElements { + attrPath := req.AttributePath.AtMapKey(key) + + configObject, diags := mapElemObject(ctx, attrPath, configMap, key, fwschemadata.DataDescriptionConfiguration) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObject, diags := coerceObjectValue(ctx, attrPath, planElem) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObjectValuable, diags := coerceObjectValuable(ctx, attrPath, planElem) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceObjectTypable(ctx, attrPath, planObjectValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateObject, diags := mapElemObject(ctx, attrPath, stateMap, key, fwschemadata.DataDescriptionState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + objectReq := planmodifier.ObjectRequest{ + Config: req.Config, + ConfigValue: configObject, + Path: attrPath, + PathExpression: attrPath.Expression(), + Plan: req.Plan, + PlanValue: planObject, + Private: resp.Private, + State: req.State, + StateValue: stateObject, + } + objectResp := &ModifyAttributePlanResponse{ + AttributePlan: objectReq.PlanValue, + Private: objectReq.Private, + } + + NestedAttributeObjectPlanModify(ctx, nestedAttributeObject, objectReq, objectResp) + + respValue, diags := coerceObjectValue(ctx, attrPath, objectResp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/821 + respValuable, diags := typable.ValueFromObject(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planElements[key] = respValuable + resp.Diagnostics.Append(objectResp.Diagnostics...) + resp.Private = objectResp.Private + resp.RequiresReplace.Append(objectResp.RequiresReplace...) + } + + respValue, diags := types.MapValue(planMap.ElementType(ctx), planElements) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + respValuable, diags := typable.ValueFromMap(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.AttributePlan = respValuable + case fwschema.NestingModeSingle: + configObject, diags := coerceObjectValue(ctx, req.AttributePath, req.AttributeConfig) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Use response as the planned value may have been modified with object + // plan modifiers. + planObjectValuable, diags := coerceObjectValuable(ctx, req.AttributePath, resp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceObjectTypable(ctx, req.AttributePath, planObjectValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObject, diags := planObjectValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateObject, diags := coerceObjectValue(ctx, req.AttributePath, req.AttributeState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + objectReq := planmodifier.ObjectRequest{ + Config: req.Config, + ConfigValue: configObject, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planObject, + Private: resp.Private, + State: req.State, + StateValue: stateObject, + } + objectResp := &ModifyAttributePlanResponse{ + AttributePlan: objectReq.PlanValue, + Private: objectReq.Private, + } + + NestedAttributeObjectPlanModify(ctx, nestedAttributeObject, objectReq, objectResp) + + resp.Diagnostics.Append(objectResp.Diagnostics...) + resp.Private = objectResp.Private + resp.RequiresReplace.Append(objectResp.RequiresReplace...) + + respValue, diags := coerceObjectValue(ctx, req.AttributePath, objectResp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + respValuable, diags := typable.ValueFromObject(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.AttributePlan = respValuable + default: + err := fmt.Errorf("unknown attribute nesting mode (%T: %v) at path: %s", nm, nm, req.AttributePath) + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Attribute Plan Modification Error", + "Attribute plan modifier cannot walk schema. Report this to the provider developer:\n\n"+err.Error(), + ) + + return + } +} + +// AttributePlanModifyBool performs all types.Bool plan modification. +func AttributePlanModifyBool(ctx context.Context, attribute fwxschema.AttributeWithBoolPlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.BoolValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.BoolValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Bool Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Bool attribute plan modification. "+ + "The value type must implement the basetypes.BoolValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToBoolValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.BoolValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Bool Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Bool attribute plan modification. "+ + "The value type must implement the basetypes.BoolValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToBoolValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.BoolValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Bool Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Bool attribute plan modification. "+ + "The value type must implement the basetypes.BoolValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToBoolValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceBoolTypable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.BoolRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range attribute.BoolPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.BoolResponse{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Bool", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifyBool(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Bool", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromBool(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +// AttributePlanModifyFloat64 performs all types.Float64 plan modification. +func AttributePlanModifyFloat64(ctx context.Context, attribute fwxschema.AttributeWithFloat64PlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.Float64Valuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.Float64Valuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Float64 Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Float64 attribute plan modification. "+ + "The value type must implement the basetypes.Float64Valuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToFloat64Value(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.Float64Valuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Float64 Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Float64 attribute plan modification. "+ + "The value type must implement the basetypes.Float64Valuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToFloat64Value(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.Float64Valuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Float64 Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Float64 attribute plan modification. "+ + "The value type must implement the basetypes.Float64Valuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToFloat64Value(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceFloat64Typable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.Float64Request{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range attribute.Float64PlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.Float64Response{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Float64", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifyFloat64(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Float64", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromFloat64(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +// AttributePlanModifyInt64 performs all types.Int64 plan modification. +func AttributePlanModifyInt64(ctx context.Context, attribute fwxschema.AttributeWithInt64PlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.Int64Valuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.Int64Valuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Int64 Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Int64 attribute plan modification. "+ + "The value type must implement the basetypes.Int64Valuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToInt64Value(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.Int64Valuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Int64 Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Int64 attribute plan modification. "+ + "The value type must implement the basetypes.Int64Valuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToInt64Value(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.Int64Valuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Int64 Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Int64 attribute plan modification. "+ + "The value type must implement the basetypes.Int64Valuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToInt64Value(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceInt64Typable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.Int64Request{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range attribute.Int64PlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.Int64Response{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Int64", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifyInt64(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Int64", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromInt64(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +// AttributePlanModifyList performs all types.List plan modification. +func AttributePlanModifyList(ctx context.Context, attribute fwxschema.AttributeWithListPlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.ListValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.ListValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid List Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform List attribute plan modification. "+ + "The value type must implement the basetypes.ListValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.ListValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid List Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform List attribute plan modification. "+ + "The value type must implement the basetypes.ListValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.ListValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid List Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform List attribute plan modification. "+ + "The value type must implement the basetypes.ListValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceListTypable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.ListRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range attribute.ListPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.ListResponse{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.List", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifyList(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.List", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromList(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +// AttributePlanModifyMap performs all types.Map plan modification. +func AttributePlanModifyMap(ctx context.Context, attribute fwxschema.AttributeWithMapPlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.MapValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.MapValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Map Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Map attribute plan modification. "+ + "The value type must implement the basetypes.MapValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToMapValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.MapValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Map Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Map attribute plan modification. "+ + "The value type must implement the basetypes.MapValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToMapValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.MapValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Map Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Map attribute plan modification. "+ + "The value type must implement the basetypes.MapValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToMapValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceMapTypable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.MapRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range attribute.MapPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.MapResponse{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Map", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifyMap(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Map", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromMap(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +// AttributePlanModifyNumber performs all types.Number plan modification. +func AttributePlanModifyNumber(ctx context.Context, attribute fwxschema.AttributeWithNumberPlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.NumberValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.NumberValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Number Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Number attribute plan modification. "+ + "The value type must implement the basetypes.NumberValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToNumberValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.NumberValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Number Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Number attribute plan modification. "+ + "The value type must implement the basetypes.NumberValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToNumberValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.NumberValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Number Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Number attribute plan modification. "+ + "The value type must implement the basetypes.NumberValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToNumberValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceNumberTypable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.NumberRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range attribute.NumberPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.NumberResponse{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Number", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifyNumber(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Number", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromNumber(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +// AttributePlanModifyObject performs all types.Object plan modification. +func AttributePlanModifyObject(ctx context.Context, attribute fwxschema.AttributeWithObjectPlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.ObjectValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.ObjectValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Object Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Object attribute plan modification. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.ObjectValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Object Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Object attribute plan modification. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.ObjectValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Object Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Object attribute plan modification. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceObjectTypable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.ObjectRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range attribute.ObjectPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.ObjectResponse{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Object", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifyObject(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Object", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromObject(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +// AttributePlanModifySet performs all types.Set plan modification. +func AttributePlanModifySet(ctx context.Context, attribute fwxschema.AttributeWithSetPlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.SetValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.SetValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Set Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Set attribute plan modification. "+ + "The value type must implement the basetypes.SetValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.SetValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Set Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Set attribute plan modification. "+ + "The value type must implement the basetypes.SetValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.SetValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Set Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Set attribute plan modification. "+ + "The value type must implement the basetypes.SetValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceSetTypable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.SetRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range attribute.SetPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.SetResponse{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Set", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifySet(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Set", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromSet(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +// AttributePlanModifyString performs all types.String plan modification. +func AttributePlanModifyString(ctx context.Context, attribute fwxschema.AttributeWithStringPlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.StringValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.StringValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid String Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform String attribute plan modification. "+ + "The value type must implement the basetypes.StringValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToStringValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.StringValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid String Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform String attribute plan modification. "+ + "The value type must implement the basetypes.StringValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToStringValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.StringValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid String Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform String attribute plan modification. "+ + "The value type must implement the basetypes.StringValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToStringValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceStringTypable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.StringRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range attribute.StringPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.StringResponse{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.String", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifyString(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.String", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromString(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +// AttributePlanModifyDynamic performs all types.Dynamic plan modification. +func AttributePlanModifyDynamic(ctx context.Context, attribute fwxschema.AttributeWithDynamicPlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.DynamicValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.DynamicValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Dynamic Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Dynamic attribute plan modification. "+ + "The value type must implement the basetypes.DynamicValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToDynamicValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.DynamicValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Dynamic Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Dynamic attribute plan modification. "+ + "The value type must implement the basetypes.DynamicValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToDynamicValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.DynamicValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Dynamic Attribute Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Dynamic attribute plan modification. "+ + "The value type must implement the basetypes.DynamicValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToDynamicValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceDynamicTypable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.DynamicRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range attribute.DynamicPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.DynamicResponse{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Dynamic", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifyDynamic(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Dynamic", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromDynamic(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +func NestedAttributeObjectPlanModify(ctx context.Context, o fwschema.NestedAttributeObject, req planmodifier.ObjectRequest, resp *ModifyAttributePlanResponse) { + if objectWithPlanModifiers, ok := o.(fwxschema.NestedAttributeObjectWithPlanModifiers); ok { + for _, objectPlanModifier := range objectWithPlanModifiers.ObjectPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.ObjectResponse{ + PlanValue: req.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Object", + map[string]interface{}{ + logging.KeyDescription: objectPlanModifier.Description(ctx), + }, + ) + + objectPlanModifier.PlanModifyObject(ctx, req, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Object", + map[string]interface{}{ + logging.KeyDescription: objectPlanModifier.Description(ctx), + }, + ) + + req.PlanValue = planModifyResp.PlanValue + resp.AttributePlan = planModifyResp.PlanValue + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.Path) + } + + // only on new errors + if planModifyResp.Diagnostics.HasError() { + return + } + } + } + + newPlanValueAttributes := req.PlanValue.Attributes() + + for nestedName, nestedAttr := range o.GetAttributes() { + nestedAttrConfig, diags := objectAttributeValue(ctx, req.ConfigValue, nestedName, fwschemadata.DataDescriptionConfiguration) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + nestedAttrPlan, diags := objectAttributeValue(ctx, req.PlanValue, nestedName, fwschemadata.DataDescriptionPlan) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + nestedAttrState, diags := objectAttributeValue(ctx, req.StateValue, nestedName, fwschemadata.DataDescriptionState) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + nestedAttrReq := ModifyAttributePlanRequest{ + AttributeConfig: nestedAttrConfig, + AttributePath: req.Path.AtName(nestedName), + AttributePathExpression: req.PathExpression.AtName(nestedName), + AttributePlan: nestedAttrPlan, + AttributeState: nestedAttrState, + Config: req.Config, + Plan: req.Plan, + Private: resp.Private, + State: req.State, + } + nestedAttrResp := &ModifyAttributePlanResponse{ + AttributePlan: nestedAttrReq.AttributePlan, + RequiresReplace: resp.RequiresReplace, + Private: nestedAttrReq.Private, + } + + AttributeModifyPlan(ctx, nestedAttr, nestedAttrReq, nestedAttrResp) + + newPlanValueAttributes[nestedName] = nestedAttrResp.AttributePlan + resp.Diagnostics.Append(nestedAttrResp.Diagnostics...) + resp.Private = nestedAttrResp.Private + resp.RequiresReplace.Append(nestedAttrResp.RequiresReplace...) + } + + newPlanValue, diags := types.ObjectValue(req.PlanValue.AttributeTypes(ctx), newPlanValueAttributes) + + resp.Diagnostics.Append(diags...) + + resp.AttributePlan = newPlanValue +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attribute_validation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attribute_validation.go new file mode 100644 index 00000000..1fa4883b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/attribute_validation.go @@ -0,0 +1,1058 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValidateAttributeRequest repesents a request for attribute validation. +type ValidateAttributeRequest struct { + // AttributePath contains the path of the attribute. Use this path for any + // response diagnostics. + AttributePath path.Path + + // AttributePathExpression contains the expression matching the exact path + // of the attribute. + AttributePathExpression path.Expression + + // AttributeConfig contains the value of the attribute in the configuration. + AttributeConfig attr.Value + + // Config contains the entire configuration of the data source, provider, or resource. + Config tfsdk.Config +} + +// ValidateAttributeResponse represents a response to a +// ValidateAttributeRequest. An instance of this response struct is +// automatically passed through to each AttributeValidator. +type ValidateAttributeResponse struct { + // Diagnostics report errors or warnings related to validating the data + // source configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} + +// AttributeValidate performs all Attribute validation. +// +// TODO: Clean up this abstraction back into an internal Attribute type method. +// The extra Attribute parameter is a carry-over of creating the proto6server +// package from the tfsdk package and not wanting to export the method. +// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/365 +func AttributeValidate(ctx context.Context, a fwschema.Attribute, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + ctx = logging.FrameworkWithAttributePath(ctx, req.AttributePath.String()) + + if !a.IsRequired() && !a.IsOptional() && !a.IsComputed() { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Attribute Definition", + "Attribute missing Required, Optional, or Computed definition. This is always a problem with the provider and should be reported to the provider developer.", + ) + + return + } + + configData := &fwschemadata.Data{ + Description: fwschemadata.DataDescriptionConfiguration, + Schema: req.Config.Schema, + TerraformValue: req.Config.Raw, + } + + attributeConfig, diags := configData.ValueAtPath(ctx, req.AttributePath) + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + // Terraform CLI does not automatically perform certain configuration + // checks yet. If it eventually does, this logic should remain at least + // until Terraform CLI versions 0.12 through the release containing the + // checks are considered end-of-life. + // Reference: https://github.com/hashicorp/terraform/issues/30669 + if a.IsComputed() && !a.IsOptional() && !attributeConfig.IsNull() { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Configuration for Read-Only Attribute", + "Cannot set value for this attribute as the provider has marked it as read-only. Remove the configuration line setting the value.\n\n"+ + "Refer to the provider documentation or contact the provider developers for additional information about configurable and read-only attributes that are supported.", + ) + } + + // Terraform CLI does not automatically perform certain configuration + // checks yet. If it eventually does, this logic should remain at least + // until Terraform CLI versions 0.12 through the release containing the + // checks are considered end-of-life. + // Reference: https://github.com/hashicorp/terraform/issues/30669 + if a.IsRequired() && attributeConfig.IsNull() { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Missing Configuration for Required Attribute", + fmt.Sprintf("Must set a configuration value for the %s attribute as the provider has marked it as required.\n\n", req.AttributePath.String())+ + "Refer to the provider documentation or contact the provider developers for additional information about configurable attributes that are required.", + ) + } + + req.AttributeConfig = attributeConfig + + switch attributeWithValidators := a.(type) { + case fwxschema.AttributeWithBoolValidators: + AttributeValidateBool(ctx, attributeWithValidators, req, resp) + case fwxschema.AttributeWithFloat64Validators: + AttributeValidateFloat64(ctx, attributeWithValidators, req, resp) + case fwxschema.AttributeWithInt64Validators: + AttributeValidateInt64(ctx, attributeWithValidators, req, resp) + case fwxschema.AttributeWithListValidators: + AttributeValidateList(ctx, attributeWithValidators, req, resp) + case fwxschema.AttributeWithMapValidators: + AttributeValidateMap(ctx, attributeWithValidators, req, resp) + case fwxschema.AttributeWithNumberValidators: + AttributeValidateNumber(ctx, attributeWithValidators, req, resp) + case fwxschema.AttributeWithObjectValidators: + AttributeValidateObject(ctx, attributeWithValidators, req, resp) + case fwxschema.AttributeWithSetValidators: + AttributeValidateSet(ctx, attributeWithValidators, req, resp) + case fwxschema.AttributeWithStringValidators: + AttributeValidateString(ctx, attributeWithValidators, req, resp) + case fwxschema.AttributeWithDynamicValidators: + AttributeValidateDynamic(ctx, attributeWithValidators, req, resp) + } + + AttributeValidateNestedAttributes(ctx, a, req, resp) + + // Show deprecation warnings only for known values. + if a.GetDeprecationMessage() != "" && !attributeConfig.IsNull() && !attributeConfig.IsUnknown() { + // Dynamic values need to perform more logic to check the config value for null/unknown-ness + dynamicValuable, ok := attributeConfig.(basetypes.DynamicValuable) + if !ok { + resp.Diagnostics.AddAttributeWarning( + req.AttributePath, + "Attribute Deprecated", + a.GetDeprecationMessage(), + ) + return + } + + dynamicConfigVal, diags := dynamicValuable.ToDynamicValue(ctx) + resp.Diagnostics.Append(diags...) + if diags.HasError() { + return + } + + // For dynamic values, it's possible to be known when only the type is known. + // The underlying value can still be null or unknown, so check for that here + if !dynamicConfigVal.IsUnderlyingValueNull() && !dynamicConfigVal.IsUnderlyingValueUnknown() { + resp.Diagnostics.AddAttributeWarning( + req.AttributePath, + "Attribute Deprecated", + a.GetDeprecationMessage(), + ) + } + } +} + +// AttributeValidateBool performs all types.Bool validation. +func AttributeValidateBool(ctx context.Context, attribute fwxschema.AttributeWithBoolValidators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.BoolValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.BoolValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Bool Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform Bool attribute validation. "+ + "The value type must implement the basetypes.BoolValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToBoolValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.BoolRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, attributeValidator := range attribute.BoolValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.BoolResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Bool", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + attributeValidator.ValidateBool(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Bool", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// AttributeValidateFloat64 performs all types.Float64 validation. +func AttributeValidateFloat64(ctx context.Context, attribute fwxschema.AttributeWithFloat64Validators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.Float64Valuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.Float64Valuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Float64 Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform Float64 attribute validation. "+ + "The value type must implement the basetypes.Float64Valuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToFloat64Value(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.Float64Request{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, attributeValidator := range attribute.Float64Validators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.Float64Response{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Float64", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + attributeValidator.ValidateFloat64(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Float64", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// AttributeValidateInt64 performs all types.Int64 validation. +func AttributeValidateInt64(ctx context.Context, attribute fwxschema.AttributeWithInt64Validators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.Int64Valuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.Int64Valuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Int64 Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform Int64 attribute validation. "+ + "The value type must implement the basetypes.Int64Valuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToInt64Value(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.Int64Request{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, attributeValidator := range attribute.Int64Validators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.Int64Response{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Int64", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + attributeValidator.ValidateInt64(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Int64", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// AttributeValidateList performs all types.List validation. +func AttributeValidateList(ctx context.Context, attribute fwxschema.AttributeWithListValidators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.ListValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.ListValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid List Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform List attribute validation. "+ + "The value type must implement the basetypes.ListValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.ListRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, attributeValidator := range attribute.ListValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.ListResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.List", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + attributeValidator.ValidateList(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.List", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// AttributeValidateMap performs all types.Map validation. +func AttributeValidateMap(ctx context.Context, attribute fwxschema.AttributeWithMapValidators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.MapValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.MapValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Map Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform Map attribute validation. "+ + "The value type must implement the basetypes.MapValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToMapValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.MapRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, attributeValidator := range attribute.MapValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.MapResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Map", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + attributeValidator.ValidateMap(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Map", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// AttributeValidateNumber performs all types.Number validation. +func AttributeValidateNumber(ctx context.Context, attribute fwxschema.AttributeWithNumberValidators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.NumberValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.NumberValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Number Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform Number attribute validation. "+ + "The value type must implement the basetypes.NumberValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToNumberValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.NumberRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, attributeValidator := range attribute.NumberValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.NumberResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Number", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + attributeValidator.ValidateNumber(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Number", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// AttributeValidateObject performs all types.Object validation. +func AttributeValidateObject(ctx context.Context, attribute fwxschema.AttributeWithObjectValidators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.ObjectValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.ObjectValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Object Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform Object attribute validation. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.ObjectRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, attributeValidator := range attribute.ObjectValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.ObjectResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Object", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + attributeValidator.ValidateObject(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Object", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// AttributeValidateSet performs all types.Set validation. +func AttributeValidateSet(ctx context.Context, attribute fwxschema.AttributeWithSetValidators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.SetValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.SetValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Set Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform Set attribute validation. "+ + "The value type must implement the basetypes.SetValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.SetRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, attributeValidator := range attribute.SetValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.SetResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Set", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + attributeValidator.ValidateSet(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Set", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// AttributeValidateString performs all types.String validation. +func AttributeValidateString(ctx context.Context, attribute fwxschema.AttributeWithStringValidators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.StringValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.StringValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid String Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform String attribute validation. "+ + "The value type must implement the basetypes.StringValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToStringValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.StringRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, attributeValidator := range attribute.StringValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.StringResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.String", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + attributeValidator.ValidateString(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.String", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// AttributeValidateDynamic performs all types.Dynamic validation. +func AttributeValidateDynamic(ctx context.Context, attribute fwxschema.AttributeWithDynamicValidators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.DynamicValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.DynamicValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Dynamic Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform Dynamic attribute validation. "+ + "The value type must implement the basetypes.DynamicValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToDynamicValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.DynamicRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, attributeValidator := range attribute.DynamicValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.DynamicResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Dynamic", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + attributeValidator.ValidateDynamic(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Dynamic", + map[string]interface{}{ + logging.KeyDescription: attributeValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// AttributeValidateNestedAttributes performs all nested Attributes validation. +// +// TODO: Clean up this abstraction back into an internal Attribute type method. +// The extra Attribute parameter is a carry-over of creating the proto6server +// package from the tfsdk package and not wanting to export the method. +// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/365 +func AttributeValidateNestedAttributes(ctx context.Context, a fwschema.Attribute, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + nestedAttribute, ok := a.(fwschema.NestedAttribute) + + if !ok { + return + } + + nestedAttributeObject := nestedAttribute.GetNestedObject() + + nm := nestedAttribute.GetNestingMode() + switch nm { + case fwschema.NestingModeList: + listVal, ok := req.AttributeConfig.(basetypes.ListValuable) + + if !ok { + err := fmt.Errorf("unknown attribute value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Attribute Validation Error Invalid Value Type", + "A type that implements basetypes.ListValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + ) + + return + } + + l, diags := listVal.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + for idx, value := range l.Elements() { + nestedAttributeObjectReq := ValidateAttributeRequest{ + AttributeConfig: value, + AttributePath: req.AttributePath.AtListIndex(idx), + AttributePathExpression: req.AttributePathExpression.AtListIndex(idx), + Config: req.Config, + } + nestedAttributeObjectResp := &ValidateAttributeResponse{} + + NestedAttributeObjectValidate(ctx, nestedAttributeObject, nestedAttributeObjectReq, nestedAttributeObjectResp) + + resp.Diagnostics.Append(nestedAttributeObjectResp.Diagnostics...) + } + case fwschema.NestingModeSet: + setVal, ok := req.AttributeConfig.(basetypes.SetValuable) + + if !ok { + err := fmt.Errorf("unknown attribute value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Attribute Validation Error Invalid Value Type", + "A type that implements basetypes.SetValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + ) + + return + } + + s, diags := setVal.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + for _, value := range s.Elements() { + nestedAttributeObjectReq := ValidateAttributeRequest{ + AttributeConfig: value, + AttributePath: req.AttributePath.AtSetValue(value), + AttributePathExpression: req.AttributePathExpression.AtSetValue(value), + Config: req.Config, + } + nestedAttributeObjectResp := &ValidateAttributeResponse{} + + NestedAttributeObjectValidate(ctx, nestedAttributeObject, nestedAttributeObjectReq, nestedAttributeObjectResp) + + resp.Diagnostics.Append(nestedAttributeObjectResp.Diagnostics...) + } + case fwschema.NestingModeMap: + mapVal, ok := req.AttributeConfig.(basetypes.MapValuable) + + if !ok { + err := fmt.Errorf("unknown attribute value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Attribute Validation Error Invalid Value Type", + "A type that implements basetypes.MapValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + ) + + return + } + + m, diags := mapVal.ToMapValue(ctx) + + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + for key, value := range m.Elements() { + nestedAttributeObjectReq := ValidateAttributeRequest{ + AttributeConfig: value, + AttributePath: req.AttributePath.AtMapKey(key), + AttributePathExpression: req.AttributePathExpression.AtMapKey(key), + Config: req.Config, + } + nestedAttributeObjectResp := &ValidateAttributeResponse{} + + NestedAttributeObjectValidate(ctx, nestedAttributeObject, nestedAttributeObjectReq, nestedAttributeObjectResp) + + resp.Diagnostics.Append(nestedAttributeObjectResp.Diagnostics...) + } + case fwschema.NestingModeSingle: + objectVal, ok := req.AttributeConfig.(basetypes.ObjectValuable) + + if !ok { + err := fmt.Errorf("unknown attribute value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Attribute Validation Error Invalid Value Type", + "A type that implements basetypes.ObjectValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + ) + + return + } + + o, diags := objectVal.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if o.IsNull() || o.IsUnknown() { + return + } + + nestedAttributeObjectReq := ValidateAttributeRequest{ + AttributeConfig: o, + AttributePath: req.AttributePath, + AttributePathExpression: req.AttributePathExpression, + Config: req.Config, + } + nestedAttributeObjectResp := &ValidateAttributeResponse{} + + NestedAttributeObjectValidate(ctx, nestedAttributeObject, nestedAttributeObjectReq, nestedAttributeObjectResp) + + resp.Diagnostics.Append(nestedAttributeObjectResp.Diagnostics...) + default: + err := fmt.Errorf("unknown attribute validation nesting mode (%T: %v) at path: %s", nm, nm, req.AttributePath) + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Attribute Validation Error", + "Attribute validation cannot walk schema. Report this to the provider developer:\n\n"+err.Error(), + ) + + return + } +} + +func NestedAttributeObjectValidate(ctx context.Context, o fwschema.NestedAttributeObject, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + objectWithValidators, ok := o.(fwxschema.NestedAttributeObjectWithValidators) + + if ok { + objectVal, ok := req.AttributeConfig.(basetypes.ObjectValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Attribute Validation Walk Error", + "An unexpected error occurred while walking the schema for attribute validation. "+ + "This is an issue with terraform-plugin-framework and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Unknown attribute value type (%T) at path: %s", req.AttributeConfig, req.AttributePath), + ) + + return + } + + object, diags := objectVal.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have + // errors from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.ObjectRequest{ + Config: req.Config, + ConfigValue: object, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, objectValidator := range objectWithValidators.ObjectValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.ObjectResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Object", + map[string]interface{}{ + logging.KeyDescription: objectValidator.Description(ctx), + }, + ) + + objectValidator.ValidateObject(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Object", + map[string]interface{}{ + logging.KeyDescription: objectValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } + } + + for nestedName, nestedAttr := range o.GetAttributes() { + nestedAttrReq := ValidateAttributeRequest{ + AttributePath: req.AttributePath.AtName(nestedName), + AttributePathExpression: req.AttributePathExpression.AtName(nestedName), + Config: req.Config, + } + nestedAttrResp := &ValidateAttributeResponse{} + + AttributeValidate(ctx, nestedAttr, nestedAttrReq, nestedAttrResp) + + resp.Diagnostics.Append(nestedAttrResp.Diagnostics...) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/block_plan_modification.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/block_plan_modification.go new file mode 100644 index 00000000..94e9274a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/block_plan_modification.go @@ -0,0 +1,1082 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// BlockModifyPlan performs all Block plan modification. +// +// TODO: Clean up this abstraction back into an internal Block type method. +// The extra Block parameter is a carry-over of creating the proto6server +// package from the tfsdk package and not wanting to export the method. +// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/365 +func BlockModifyPlan(ctx context.Context, b fwschema.Block, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + if req.Private != nil { + resp.Private = req.Private + } + + switch blockWithPlanModifiers := b.(type) { + case fwxschema.BlockWithListPlanModifiers: + BlockPlanModifyList(ctx, blockWithPlanModifiers, req, resp) + case fwxschema.BlockWithObjectPlanModifiers: + BlockPlanModifyObject(ctx, blockWithPlanModifiers, req, resp) + case fwxschema.BlockWithSetPlanModifiers: + BlockPlanModifySet(ctx, blockWithPlanModifiers, req, resp) + } + + if resp.Diagnostics.HasError() { + return + } + + // Null and unknown values should not have nested schema to modify. + if resp.AttributePlan.IsNull() || resp.AttributePlan.IsUnknown() { + return + } + + nestedBlockObject := b.GetNestedObject() + + nm := b.GetNestingMode() + switch nm { + case fwschema.BlockNestingModeList: + configList, diags := coerceListValue(ctx, req.AttributePath, req.AttributeConfig) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Use response as the planned value may have been modified with list + // plan modifiers. + planListValuable, diags := coerceListValuable(ctx, req.AttributePath, resp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceListTypable(ctx, req.AttributePath, planListValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planList, diags := planListValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateList, diags := coerceListValue(ctx, req.AttributePath, req.AttributeState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planElements := planList.Elements() + + for idx, planElem := range planElements { + attrPath := req.AttributePath.AtListIndex(idx) + + configObject, diags := listElemObject(ctx, attrPath, configList, idx, fwschemadata.DataDescriptionConfiguration) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObject, diags := coerceObjectValue(ctx, attrPath, planElem) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObjectValuable, diags := coerceObjectValuable(ctx, attrPath, planElem) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceObjectTypable(ctx, attrPath, planObjectValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateObject, diags := listElemObject(ctx, attrPath, stateList, idx, fwschemadata.DataDescriptionState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + objectReq := planmodifier.ObjectRequest{ + Config: req.Config, + ConfigValue: configObject, + Path: attrPath, + PathExpression: attrPath.Expression(), + Plan: req.Plan, + PlanValue: planObject, + Private: resp.Private, + State: req.State, + StateValue: stateObject, + } + objectResp := &ModifyAttributePlanResponse{ + AttributePlan: objectReq.PlanValue, + Private: objectReq.Private, + } + + NestedBlockObjectPlanModify(ctx, nestedBlockObject, objectReq, objectResp) + + respValue, diags := coerceObjectValue(ctx, attrPath, objectResp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/821 + respValuable, diags := typable.ValueFromObject(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planElements[idx] = respValuable + resp.Diagnostics.Append(objectResp.Diagnostics...) + resp.Private = objectResp.Private + resp.RequiresReplace.Append(objectResp.RequiresReplace...) + } + + respValue, diags := types.ListValue(planList.ElementType(ctx), planElements) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + respValuable, diags := typable.ValueFromList(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.AttributePlan = respValuable + case fwschema.BlockNestingModeSet: + configSet, diags := coerceSetValue(ctx, req.AttributePath, req.AttributeConfig) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Use response as the planned value may have been modified with set + // plan modifiers. + planSetValuable, diags := coerceSetValuable(ctx, req.AttributePath, resp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceSetTypable(ctx, req.AttributePath, planSetValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planSet, diags := planSetValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateSet, diags := coerceSetValue(ctx, req.AttributePath, req.AttributeState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planElements := planSet.Elements() + + for idx, planElem := range planElements { + attrPath := req.AttributePath.AtSetValue(planElem) + + configObject, diags := setElemObject(ctx, attrPath, configSet, idx, fwschemadata.DataDescriptionConfiguration) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObject, diags := coerceObjectValue(ctx, attrPath, planElem) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObjectValuable, diags := coerceObjectValuable(ctx, attrPath, planElem) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceObjectTypable(ctx, attrPath, planObjectValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateObject, diags := setElemObject(ctx, attrPath, stateSet, idx, fwschemadata.DataDescriptionState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + objectReq := planmodifier.ObjectRequest{ + Config: req.Config, + ConfigValue: configObject, + Path: attrPath, + PathExpression: attrPath.Expression(), + Plan: req.Plan, + PlanValue: planObject, + Private: resp.Private, + State: req.State, + StateValue: stateObject, + } + objectResp := &ModifyAttributePlanResponse{ + AttributePlan: objectReq.PlanValue, + Private: objectReq.Private, + } + + NestedBlockObjectPlanModify(ctx, nestedBlockObject, objectReq, objectResp) + + respValue, diags := coerceObjectValue(ctx, attrPath, objectResp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/821 + respValuable, diags := typable.ValueFromObject(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planElements[idx] = respValuable + resp.Diagnostics.Append(objectResp.Diagnostics...) + resp.Private = objectResp.Private + resp.RequiresReplace.Append(objectResp.RequiresReplace...) + } + + respValue, diags := types.SetValue(planSet.ElementType(ctx), planElements) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + respValuable, diags := typable.ValueFromSet(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.AttributePlan = respValuable + case fwschema.BlockNestingModeSingle: + configObject, diags := coerceObjectValue(ctx, req.AttributePath, req.AttributeConfig) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Use response as the planned value may have been modified with object + // plan modifiers. + planObjectValuable, diags := coerceObjectValuable(ctx, req.AttributePath, resp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + typable, diags := coerceObjectTypable(ctx, req.AttributePath, planObjectValuable) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + planObject, diags := planObjectValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + stateObject, diags := coerceObjectValue(ctx, req.AttributePath, req.AttributeState) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + objectReq := planmodifier.ObjectRequest{ + Config: req.Config, + ConfigValue: configObject, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planObject, + Private: resp.Private, + State: req.State, + StateValue: stateObject, + } + objectResp := &ModifyAttributePlanResponse{ + AttributePlan: objectReq.PlanValue, + Private: objectReq.Private, + } + + NestedBlockObjectPlanModify(ctx, nestedBlockObject, objectReq, objectResp) + + resp.Diagnostics.Append(objectResp.Diagnostics...) + resp.Private = objectResp.Private + resp.RequiresReplace.Append(objectResp.RequiresReplace...) + + respValue, diags := coerceObjectValue(ctx, req.AttributePath, objectResp.AttributePlan) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + respValuable, diags := typable.ValueFromObject(ctx, respValue) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.AttributePlan = respValuable + default: + err := fmt.Errorf("unknown block plan modification nesting mode (%T: %v) at path: %s", nm, nm, req.AttributePath) + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Block Plan Modification Error", + "Block plan modification cannot walk schema. Report this to the provider developer:\n\n"+err.Error(), + ) + + return + } +} + +// BlockPlanModifyList performs all types.List plan modification. +func BlockPlanModifyList(ctx context.Context, block fwxschema.BlockWithListPlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.ListValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.ListValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid List Block Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform List block plan modification. "+ + "The value type must implement the basetypes.ListValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.ListValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid List Block Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform List block plan modification. "+ + "The value type must implement the basetypes.ListValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.ListValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid List Block Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform List block plan modification. "+ + "The value type must implement the basetypes.ListValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceListTypable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.ListRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range block.ListPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.ListResponse{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.List", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifyList(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.List", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromList(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +// BlockPlanModifyObject performs all types.Object plan modification. +func BlockPlanModifyObject(ctx context.Context, block fwxschema.BlockWithObjectPlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.ObjectValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.ObjectValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Object Block Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Object block plan modification. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.ObjectValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Object Block Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Object block plan modification. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.ObjectValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Object Block Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Object block plan modification. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceObjectTypable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.ObjectRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range block.ObjectPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.ObjectResponse{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Object", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifyObject(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Object", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromObject(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +// BlockPlanModifySet performs all types.Set plan modification. +func BlockPlanModifySet(ctx context.Context, block fwxschema.BlockWithSetPlanModifiers, req ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { + // Use basetypes.SetValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.SetValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Set Block Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Set block plan modification. "+ + "The value type must implement the basetypes.SetValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planValuable, ok := req.AttributePlan.(basetypes.SetValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Set Block Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Set block plan modification. "+ + "The value type must implement the basetypes.SetValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), + ) + + return + } + + planValue, diags := planValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + stateValuable, ok := req.AttributeState.(basetypes.SetValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Set Block Plan Modifier Value Type", + "An unexpected value type was encountered while attempting to perform Set block plan modification. "+ + "The value type must implement the basetypes.SetValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), + ) + + return + } + + stateValue, diags := stateValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + typable, diags := coerceSetTypable(ctx, req.AttributePath, planValuable) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + planModifyReq := planmodifier.SetRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + Plan: req.Plan, + PlanValue: planValue, + Private: req.Private, + State: req.State, + StateValue: stateValue, + } + + for _, planModifier := range block.SetPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.SetResponse{ + PlanValue: planModifyReq.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Set", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + planModifier.PlanModifySet(ctx, planModifyReq, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Set", + map[string]interface{}{ + logging.KeyDescription: planModifier.Description(ctx), + }, + ) + + // Prepare next request with base type. + planModifyReq.PlanValue = planModifyResp.PlanValue + + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.AttributePath) + } + + // Only on new errors. + if planModifyResp.Diagnostics.HasError() { + return + } + + // A custom value type must be returned in the final response to prevent + // later correctness errors. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/754 + valuable, valueFromDiags := typable.ValueFromSet(ctx, planModifyResp.PlanValue) + + resp.Diagnostics.Append(valueFromDiags...) + + // Only on new errors. + if valueFromDiags.HasError() { + return + } + + resp.AttributePlan = valuable + } +} + +func NestedBlockObjectPlanModify(ctx context.Context, o fwschema.NestedBlockObject, req planmodifier.ObjectRequest, resp *ModifyAttributePlanResponse) { + if objectWithPlanModifiers, ok := o.(fwxschema.NestedBlockObjectWithPlanModifiers); ok { + for _, objectPlanModifier := range objectWithPlanModifiers.ObjectPlanModifiers() { + // Instantiate a new response for each request to prevent plan modifiers + // from modifying or removing diagnostics. + planModifyResp := &planmodifier.ObjectResponse{ + PlanValue: req.PlanValue, + Private: resp.Private, + } + + logging.FrameworkTrace( + ctx, + "Calling provider defined planmodifier.Object", + map[string]interface{}{ + logging.KeyDescription: objectPlanModifier.Description(ctx), + }, + ) + + objectPlanModifier.PlanModifyObject(ctx, req, planModifyResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined planmodifier.Object", + map[string]interface{}{ + logging.KeyDescription: objectPlanModifier.Description(ctx), + }, + ) + + req.PlanValue = planModifyResp.PlanValue + resp.AttributePlan = planModifyResp.PlanValue + resp.Diagnostics.Append(planModifyResp.Diagnostics...) + resp.Private = planModifyResp.Private + + if planModifyResp.RequiresReplace { + resp.RequiresReplace.Append(req.Path) + } + + // only on new errors + if planModifyResp.Diagnostics.HasError() { + return + } + } + } + + newPlanValueAttributes := req.PlanValue.Attributes() + + for nestedName, nestedAttr := range o.GetAttributes() { + nestedAttrConfig, diags := objectAttributeValue(ctx, req.ConfigValue, nestedName, fwschemadata.DataDescriptionConfiguration) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + nestedAttrPlan, diags := objectAttributeValue(ctx, req.PlanValue, nestedName, fwschemadata.DataDescriptionPlan) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + nestedAttrState, diags := objectAttributeValue(ctx, req.StateValue, nestedName, fwschemadata.DataDescriptionState) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + nestedAttrReq := ModifyAttributePlanRequest{ + AttributeConfig: nestedAttrConfig, + AttributePath: req.Path.AtName(nestedName), + AttributePathExpression: req.PathExpression.AtName(nestedName), + AttributePlan: nestedAttrPlan, + AttributeState: nestedAttrState, + Config: req.Config, + Plan: req.Plan, + Private: resp.Private, + State: req.State, + } + nestedAttrResp := &ModifyAttributePlanResponse{ + AttributePlan: nestedAttrReq.AttributePlan, + RequiresReplace: resp.RequiresReplace, + Private: nestedAttrReq.Private, + } + + AttributeModifyPlan(ctx, nestedAttr, nestedAttrReq, nestedAttrResp) + + newPlanValueAttributes[nestedName] = nestedAttrResp.AttributePlan + resp.Diagnostics.Append(nestedAttrResp.Diagnostics...) + resp.Private = nestedAttrResp.Private + resp.RequiresReplace.Append(nestedAttrResp.RequiresReplace...) + } + + for nestedName, nestedBlock := range o.GetBlocks() { + nestedBlockConfig, diags := objectAttributeValue(ctx, req.ConfigValue, nestedName, fwschemadata.DataDescriptionConfiguration) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + nestedBlockPlan, diags := objectAttributeValue(ctx, req.PlanValue, nestedName, fwschemadata.DataDescriptionPlan) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + nestedBlockState, diags := objectAttributeValue(ctx, req.StateValue, nestedName, fwschemadata.DataDescriptionState) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + nestedBlockReq := ModifyAttributePlanRequest{ + AttributeConfig: nestedBlockConfig, + AttributePath: req.Path.AtName(nestedName), + AttributePathExpression: req.PathExpression.AtName(nestedName), + AttributePlan: nestedBlockPlan, + AttributeState: nestedBlockState, + Config: req.Config, + Plan: req.Plan, + Private: resp.Private, + State: req.State, + } + nestedBlockResp := &ModifyAttributePlanResponse{ + AttributePlan: nestedBlockReq.AttributePlan, + RequiresReplace: resp.RequiresReplace, + Private: nestedBlockReq.Private, + } + + BlockModifyPlan(ctx, nestedBlock, nestedBlockReq, nestedBlockResp) + + newPlanValueAttributes[nestedName] = nestedBlockResp.AttributePlan + resp.Diagnostics.Append(nestedBlockResp.Diagnostics...) + resp.Private = nestedBlockResp.Private + resp.RequiresReplace.Append(nestedBlockResp.RequiresReplace...) + } + + newPlanValue, diags := types.ObjectValue(req.PlanValue.AttributeTypes(ctx), newPlanValueAttributes) + + resp.Diagnostics.Append(diags...) + + resp.AttributePlan = newPlanValue +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/block_validation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/block_validation.go new file mode 100644 index 00000000..d65b1b5c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/block_validation.go @@ -0,0 +1,456 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// BlockValidate performs all Block validation. +// +// TODO: Clean up this abstraction back into an internal Block type method. +// The extra Block parameter is a carry-over of creating the proto6server +// package from the tfsdk package and not wanting to export the method. +// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/365 +func BlockValidate(ctx context.Context, b fwschema.Block, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + configData := &fwschemadata.Data{ + Description: fwschemadata.DataDescriptionConfiguration, + Schema: req.Config.Schema, + TerraformValue: req.Config.Raw, + } + + attributeConfig, diags := configData.ValueAtPath(ctx, req.AttributePath) + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + req.AttributeConfig = attributeConfig + + switch blockWithValidators := b.(type) { + case fwxschema.BlockWithListValidators: + BlockValidateList(ctx, blockWithValidators, req, resp) + case fwxschema.BlockWithObjectValidators: + BlockValidateObject(ctx, blockWithValidators, req, resp) + case fwxschema.BlockWithSetValidators: + BlockValidateSet(ctx, blockWithValidators, req, resp) + } + + nestedBlockObject := b.GetNestedObject() + + nm := b.GetNestingMode() + switch nm { + case fwschema.BlockNestingModeList: + listVal, ok := req.AttributeConfig.(basetypes.ListValuable) + + if !ok { + err := fmt.Errorf("unknown block value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Block Validation Error Invalid Value Type", + "A type that implements basetypes.ListValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + ) + + return + } + + l, diags := listVal.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + for idx, value := range l.Elements() { + nestedBlockObjectReq := ValidateAttributeRequest{ + AttributeConfig: value, + AttributePath: req.AttributePath.AtListIndex(idx), + AttributePathExpression: req.AttributePathExpression.AtListIndex(idx), + Config: req.Config, + } + nestedBlockObjectResp := &ValidateAttributeResponse{} + + NestedBlockObjectValidate(ctx, nestedBlockObject, nestedBlockObjectReq, nestedBlockObjectResp) + + resp.Diagnostics.Append(nestedBlockObjectResp.Diagnostics...) + } + case fwschema.BlockNestingModeSet: + setVal, ok := req.AttributeConfig.(basetypes.SetValuable) + + if !ok { + err := fmt.Errorf("unknown block value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Block Validation Error Invalid Value Type", + "A type that implements basetypes.SetValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + ) + + return + } + + s, diags := setVal.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + for _, value := range s.Elements() { + nestedBlockObjectReq := ValidateAttributeRequest{ + AttributeConfig: value, + AttributePath: req.AttributePath.AtSetValue(value), + AttributePathExpression: req.AttributePathExpression.AtSetValue(value), + Config: req.Config, + } + nestedBlockObjectResp := &ValidateAttributeResponse{} + + NestedBlockObjectValidate(ctx, nestedBlockObject, nestedBlockObjectReq, nestedBlockObjectResp) + + resp.Diagnostics.Append(nestedBlockObjectResp.Diagnostics...) + } + case fwschema.BlockNestingModeSingle: + objectVal, ok := req.AttributeConfig.(basetypes.ObjectValuable) + + if !ok { + err := fmt.Errorf("unknown block value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Block Validation Error Invalid Value Type", + "A type that implements basetypes.ObjectValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + ) + + return + } + + o, diags := objectVal.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + nestedBlockObjectReq := ValidateAttributeRequest{ + AttributeConfig: o, + AttributePath: req.AttributePath, + AttributePathExpression: req.AttributePathExpression, + Config: req.Config, + } + nestedBlockObjectResp := &ValidateAttributeResponse{} + + NestedBlockObjectValidate(ctx, nestedBlockObject, nestedBlockObjectReq, nestedBlockObjectResp) + + resp.Diagnostics.Append(nestedBlockObjectResp.Diagnostics...) + default: + err := fmt.Errorf("unknown block validation nesting mode (%T: %v) at path: %s", nm, nm, req.AttributePath) + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Block Validation Error", + "Block validation cannot walk schema. Report this to the provider developer:\n\n"+err.Error(), + ) + + return + } + + // Show deprecation warning only on known values. + if b.GetDeprecationMessage() != "" && !attributeConfig.IsNull() && !attributeConfig.IsUnknown() { + resp.Diagnostics.AddAttributeWarning( + req.AttributePath, + "Block Deprecated", + b.GetDeprecationMessage(), + ) + } +} + +// BlockValidateList performs all types.List validation. +func BlockValidateList(ctx context.Context, block fwxschema.BlockWithListValidators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.ListValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.ListValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid List Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform List attribute validation. "+ + "The value type must implement the basetypes.ListValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToListValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.ListRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, blockValidator := range block.ListValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.ListResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.List", + map[string]interface{}{ + logging.KeyDescription: blockValidator.Description(ctx), + }, + ) + + blockValidator.ValidateList(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.List", + map[string]interface{}{ + logging.KeyDescription: blockValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// BlockValidateObject performs all types.Object validation. +func BlockValidateObject(ctx context.Context, block fwxschema.BlockWithObjectValidators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.ObjectValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.ObjectValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Object Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform Object attribute validation. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.ObjectRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, blockValidator := range block.ObjectValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.ObjectResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Object", + map[string]interface{}{ + logging.KeyDescription: blockValidator.Description(ctx), + }, + ) + + blockValidator.ValidateObject(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Object", + map[string]interface{}{ + logging.KeyDescription: blockValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +// BlockValidateSet performs all types.Set validation. +func BlockValidateSet(ctx context.Context, block fwxschema.BlockWithSetValidators, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + // Use basetypes.SetValuable until custom types cannot re-implement + // ValueFromTerraform. Until then, custom types are not technically + // required to implement this interface. This opts to enforce the + // requirement before compatibility promises would interfere. + configValuable, ok := req.AttributeConfig.(basetypes.SetValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Invalid Set Attribute Validator Value Type", + "An unexpected value type was encountered while attempting to perform Set attribute validation. "+ + "The value type must implement the basetypes.SetValuable interface. "+ + "Please report this to the provider developers.\n\n"+ + fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), + ) + + return + } + + configValue, diags := configValuable.ToSetValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have errors + // from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.SetRequest{ + Config: req.Config, + ConfigValue: configValue, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, blockValidator := range block.SetValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.SetResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Set", + map[string]interface{}{ + logging.KeyDescription: blockValidator.Description(ctx), + }, + ) + + blockValidator.ValidateSet(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Set", + map[string]interface{}{ + logging.KeyDescription: blockValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} + +func NestedBlockObjectValidate(ctx context.Context, o fwschema.NestedBlockObject, req ValidateAttributeRequest, resp *ValidateAttributeResponse) { + objectWithValidators, ok := o.(fwxschema.NestedBlockObjectWithValidators) + + if ok { + objectVal, ok := req.AttributeConfig.(basetypes.ObjectValuable) + + if !ok { + resp.Diagnostics.AddAttributeError( + req.AttributePath, + "Block Validation Walk Error", + "An unexpected error occurred while walking the schema for block validation. "+ + "This is an issue with terraform-plugin-framework and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Unknown block value type (%T) at path: %s", req.AttributeConfig, req.AttributePath), + ) + + return + } + + object, diags := objectVal.ToObjectValue(ctx) + + resp.Diagnostics.Append(diags...) + + // Only return early on new errors as the resp.Diagnostics may have + // errors from other attributes. + if diags.HasError() { + return + } + + validateReq := validator.ObjectRequest{ + Config: req.Config, + ConfigValue: object, + Path: req.AttributePath, + PathExpression: req.AttributePathExpression, + } + + for _, objectValidator := range objectWithValidators.ObjectValidators() { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateResp := &validator.ObjectResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined validator.Object", + map[string]interface{}{ + logging.KeyDescription: objectValidator.Description(ctx), + }, + ) + + objectValidator.ValidateObject(ctx, validateReq, validateResp) + + logging.FrameworkTrace( + ctx, + "Called provider defined validator.Object", + map[string]interface{}{ + logging.KeyDescription: objectValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } + } + + for nestedName, nestedAttr := range o.GetAttributes() { + nestedAttrReq := ValidateAttributeRequest{ + AttributePath: req.AttributePath.AtName(nestedName), + AttributePathExpression: req.AttributePathExpression.AtName(nestedName), + Config: req.Config, + } + nestedAttrResp := &ValidateAttributeResponse{} + + AttributeValidate(ctx, nestedAttr, nestedAttrReq, nestedAttrResp) + + resp.Diagnostics.Append(nestedAttrResp.Diagnostics...) + } + + for nestedName, nestedBlock := range o.GetBlocks() { + nestedBlockReq := ValidateAttributeRequest{ + AttributePath: req.AttributePath.AtName(nestedName), + AttributePathExpression: req.AttributePathExpression.AtName(nestedName), + Config: req.Config, + } + nestedBlockResp := &ValidateAttributeResponse{} + + BlockValidate(ctx, nestedBlock, nestedBlockReq, nestedBlockResp) + + resp.Diagnostics.Append(nestedBlockResp.Diagnostics...) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/diagnostics.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/diagnostics.go new file mode 100644 index 00000000..c85f1db7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/diagnostics.go @@ -0,0 +1,45 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +func attributePlanModificationTypableError(schemaPath path.Path, value attr.Value) diag.Diagnostic { + return diag.NewAttributeErrorDiagnostic( + schemaPath, + "Unexpected Attribute Plan Modifier Type Conversion Error", + "An unexpected issue occurred while trying to get the correct type during attribute plan modification. "+ + "Expected the Valuable implementation Type() method to return a Typable. "+ + "This is likely an implementation error in terraform-plugin-framework and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Value Type: %T\n", value)+ + fmt.Sprintf("Path: %s", schemaPath), + ) +} + +func schemaDataValueError(ctx context.Context, value attr.Value, description fwschemadata.DataDescription, err error) diag.Diagnostic { + return diag.NewErrorDiagnostic( + description.Title()+" Value Error", + "An unexpected error occurred while fetching a "+value.Type(ctx).String()+" element value in the "+description.String()+". "+ + "This is an issue with the provider and should be reported to the provider developers.\n\n"+ + "Original Error: "+err.Error(), + ) +} + +func schemaDataWalkError(schemaPath path.Path, value attr.Value) diag.Diagnostic { + return diag.NewAttributeErrorDiagnostic( + schemaPath, + "Schema Data Walk Error", + "An unexpected error occurred while walking the schema for data modification. "+ + "This is an issue with terraform-plugin-framework and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("unknown attribute value type (%T) at path: %s", value, schemaPath), + ) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/doc.go new file mode 100644 index 00000000..2c8042b2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/doc.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package fwserver contains the framework provider server implementation. +// This package should only ever contain framework-native types, while specific +// protocol version compatible implementations, such as proto6server, are +// implemented on top of this abstraction. +package fwserver diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_plan_modification.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_plan_modification.go new file mode 100644 index 00000000..6e0327db --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_plan_modification.go @@ -0,0 +1,197 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ModifySchemaPlanRequest represents a request for a schema to run all +// attribute plan modification functions. +type ModifySchemaPlanRequest struct { + // Config is the configuration the user supplied for the resource. + Config tfsdk.Config + + // State is the current state of the resource. + State tfsdk.State + + // Plan is the planned new state for the resource. + Plan tfsdk.Plan + + // ProviderMeta is metadata from the provider_meta block of the module. + ProviderMeta tfsdk.Config + + // Private is provider private state data. + Private *privatestate.ProviderData +} + +// ModifySchemaPlanResponse represents a response to a ModifySchemaPlanRequest. +type ModifySchemaPlanResponse struct { + // Plan is the planned new state for the resource. + Plan tfsdk.Plan + + // RequiresReplace is a list of attribute paths that require the + // resource to be replaced. They should point to the specific field + // that changed that requires the resource to be destroyed and + // recreated. + RequiresReplace path.Paths + + // Private is provider private state data following potential modifications. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to running all attribute + // plan modifiers. Returning an empty slice indicates a successful + // plan modification with no warnings or errors generated. + Diagnostics diag.Diagnostics +} + +// SchemaModifyPlan runs all AttributePlanModifiers in all schema attributes +// and blocks. +// +// TODO: Clean up this abstraction back into an internal Schema type method. +// The extra Schema parameter is a carry-over of creating the proto6server +// package from the tfsdk package and not wanting to export the method. +// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/365 +func SchemaModifyPlan(ctx context.Context, s fwschema.Schema, req ModifySchemaPlanRequest, resp *ModifySchemaPlanResponse) { + var diags diag.Diagnostics + + configData := &fwschemadata.Data{ + Description: fwschemadata.DataDescriptionConfiguration, + Schema: req.Config.Schema, + TerraformValue: req.Config.Raw, + } + + planData := &fwschemadata.Data{ + Description: fwschemadata.DataDescriptionPlan, + Schema: req.Plan.Schema, + TerraformValue: req.Plan.Raw, + } + + stateData := &fwschemadata.Data{ + Description: fwschemadata.DataDescriptionState, + Schema: req.State.Schema, + TerraformValue: req.State.Raw, + } + + for name, attribute := range s.GetAttributes() { + attrReq := ModifyAttributePlanRequest{ + AttributePath: path.Root(name), + Config: req.Config, + State: req.State, + Plan: req.Plan, + ProviderMeta: req.ProviderMeta, + Private: req.Private, + } + + attrReq.AttributeConfig, diags = configData.ValueAtPath(ctx, attrReq.AttributePath) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + attrReq.AttributePlan, diags = planData.ValueAtPath(ctx, attrReq.AttributePath) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + attrReq.AttributeState, diags = stateData.ValueAtPath(ctx, attrReq.AttributePath) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + attrResp := ModifyAttributePlanResponse{ + AttributePlan: attrReq.AttributePlan, + Private: attrReq.Private, + } + + AttributeModifyPlan(ctx, attribute, attrReq, &attrResp) + + resp.Diagnostics.Append(attrResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, attrReq.AttributePath, attrResp.AttributePlan)...) + + if resp.Diagnostics.HasError() { + return + } + + resp.RequiresReplace = append(resp.RequiresReplace, attrResp.RequiresReplace...) + resp.Private = attrResp.Private + } + + for name, block := range s.GetBlocks() { + blockReq := ModifyAttributePlanRequest{ + AttributePath: path.Root(name), + Config: req.Config, + State: req.State, + Plan: req.Plan, + ProviderMeta: req.ProviderMeta, + Private: req.Private, + } + + blockReq.AttributeConfig, diags = configData.ValueAtPath(ctx, blockReq.AttributePath) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + blockReq.AttributePlan, diags = planData.ValueAtPath(ctx, blockReq.AttributePath) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + blockReq.AttributeState, diags = stateData.ValueAtPath(ctx, blockReq.AttributePath) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + blockResp := ModifyAttributePlanResponse{ + AttributePlan: blockReq.AttributePlan, + Private: blockReq.Private, + } + + BlockModifyPlan(ctx, block, blockReq, &blockResp) + + resp.Diagnostics.Append(blockResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, blockReq.AttributePath, blockResp.AttributePlan)...) + + if resp.Diagnostics.HasError() { + return + } + + resp.RequiresReplace = append(resp.RequiresReplace, blockResp.RequiresReplace...) + resp.Private = blockResp.Private + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_semantic_equality.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_semantic_equality.go new file mode 100644 index 00000000..2446a537 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_semantic_equality.go @@ -0,0 +1,146 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// SchemaSemanticEqualityRequest represents a request for a schema to run all +// semantic equality logic. +type SchemaSemanticEqualityRequest struct { + // PriorData is the prior schema-based data. + PriorData fwschemadata.Data + + // ProposedNewData is the proposed new schema-based data. The response + // NewData contains the results of any modifications. + ProposedNewData fwschemadata.Data +} + +// SchemaSemanticEqualityResponse represents a response to a +// SchemaSemanticEqualityRequest. +type SchemaSemanticEqualityResponse struct { + // NewData is the new schema-based data after any modifications. + NewData fwschemadata.Data + + // Diagnostics report errors or warnings related to running all attribute + // plan modifiers. Returning an empty slice indicates a successful + // plan modification with no warnings or errors generated. + Diagnostics diag.Diagnostics +} + +// SchemaSemanticEquality runs semantic equality logic for all schema attributes +// and blocks. +// +// MAINTAINER NOTE: Since semantic equality is purely value based, where +// attributes and blocks cannot currently introduce semantic equality logic +// based on those schema concepts, this logic immediately delegates to value +// based handling. On the off chance that the framework is enhanced with +// attribute and block level semantic equality support (not recommended since +// value types should really be the correct provider developer abstraction, +// rather than potentially causing confusing or duplicated provider logic), this +// logic will need to be redesigned similar to the plan modification and +// validation logic which walks the schema. That schema walk may interfere with +// the value based recursion for collection and structural types, so additional +// design may be necessary so that provider developer data handling intentions +// are kept based on both the value based logic and schema based logic. +func SchemaSemanticEquality(ctx context.Context, req SchemaSemanticEqualityRequest, resp *SchemaSemanticEqualityResponse) { + var diags diag.Diagnostics + + for name := range req.ProposedNewData.Schema.GetAttributes() { + valueReq := fwschemadata.ValueSemanticEqualityRequest{ + Path: path.Root(name), + } + + valueReq.PriorValue, diags = req.PriorData.ValueAtPath(ctx, valueReq.Path) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + valueReq.ProposedNewValue, diags = req.ProposedNewData.ValueAtPath(ctx, valueReq.Path) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + valueResp := &fwschemadata.ValueSemanticEqualityResponse{ + NewValue: valueReq.ProposedNewValue, + } + + fwschemadata.ValueSemanticEquality(ctx, valueReq, valueResp) + + resp.Diagnostics.Append(valueResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + // If the response value equals the original proposed new value, move + // to next attribute. + if valueResp.NewValue.Equal(valueReq.ProposedNewValue) { + continue + } + + resp.Diagnostics.Append(resp.NewData.SetAtPath(ctx, valueReq.Path, valueResp.NewValue)...) + + if resp.Diagnostics.HasError() { + return + } + } + + for name := range req.ProposedNewData.Schema.GetBlocks() { + valueReq := fwschemadata.ValueSemanticEqualityRequest{ + Path: path.Root(name), + } + + valueReq.PriorValue, diags = req.PriorData.ValueAtPath(ctx, valueReq.Path) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + valueReq.ProposedNewValue, diags = req.ProposedNewData.ValueAtPath(ctx, valueReq.Path) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + valueResp := &fwschemadata.ValueSemanticEqualityResponse{ + NewValue: valueReq.ProposedNewValue, + } + + fwschemadata.ValueSemanticEquality(ctx, valueReq, valueResp) + + resp.Diagnostics.Append(valueResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + // If the response value equals the original proposed new value, move + // to next block. + if valueResp.NewValue.Equal(valueReq.ProposedNewValue) { + continue + } + + resp.Diagnostics.Append(resp.NewData.SetAtPath(ctx, valueReq.Path, valueResp.NewValue)...) + + if resp.Diagnostics.HasError() { + return + } + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_validation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_validation.go new file mode 100644 index 00000000..32c50f9d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/schema_validation.go @@ -0,0 +1,77 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ValidateSchemaRequest repesents a request for validating a Schema. +type ValidateSchemaRequest struct { + // Config contains the entire configuration of the data source, provider, or resource. + // + // This configuration may contain unknown values if a user uses + // interpolation or other functionality that would prevent Terraform + // from knowing the value at request time. + Config tfsdk.Config +} + +// ValidateSchemaResponse represents a response to a +// ValidateSchemaRequest. +type ValidateSchemaResponse struct { + // Diagnostics report errors or warnings related to validating the schema. + // An empty slice indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics +} + +// SchemaValidate performs all Attribute and Block validation. +// +// TODO: Clean up this abstraction back into an internal Schema type method. +// The extra Schema parameter is a carry-over of creating the proto6server +// package from the tfsdk package and not wanting to export the method. +// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/365 +func SchemaValidate(ctx context.Context, s fwschema.Schema, req ValidateSchemaRequest, resp *ValidateSchemaResponse) { + for name, attribute := range s.GetAttributes() { + + attributeReq := ValidateAttributeRequest{ + AttributePath: path.Root(name), + AttributePathExpression: path.MatchRoot(name), + Config: req.Config, + } + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + attributeResp := &ValidateAttributeResponse{} + + AttributeValidate(ctx, attribute, attributeReq, attributeResp) + + resp.Diagnostics.Append(attributeResp.Diagnostics...) + } + + for name, block := range s.GetBlocks() { + attributeReq := ValidateAttributeRequest{ + AttributePath: path.Root(name), + AttributePathExpression: path.MatchRoot(name), + Config: req.Config, + } + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + attributeResp := &ValidateAttributeResponse{} + + BlockValidate(ctx, block, attributeReq, attributeResp) + + resp.Diagnostics.Append(attributeResp.Diagnostics...) + } + + if s.GetDeprecationMessage() != "" { + resp.Diagnostics.AddWarning( + "Deprecated", + s.GetDeprecationMessage(), + ) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server.go new file mode 100644 index 00000000..40fa631f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server.go @@ -0,0 +1,572 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + "fmt" + "sync" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +// Server implements the framework provider server. Protocol specific +// implementations wrap this handling along with calling all request and +// response type conversions. +type Server struct { + Provider provider.Provider + + // DataSourceConfigureData is the + // [provider.ConfigureResponse.DataSourceData] field value which is passed + // to [datasource.ConfigureRequest.ProviderData]. + DataSourceConfigureData any + + // ResourceConfigureData is the + // [provider.ConfigureResponse.ResourceData] field value which is passed + // to [resource.ConfigureRequest.ProviderData]. + ResourceConfigureData any + + // dataSourceSchemas is the cached DataSource Schemas for RPCs that need to + // convert configuration data from the protocol. If not found, it will be + // fetched from the DataSourceType.GetSchema() method. + dataSourceSchemas map[string]fwschema.Schema + + // dataSourceSchemasMutex is a mutex to protect concurrent dataSourceSchemas + // access from race conditions. + dataSourceSchemasMutex sync.RWMutex + + // dataSourceFuncs is the cached DataSource functions for RPCs that need to + // access data sources. If not found, it will be fetched from the + // Provider.DataSources() method. + dataSourceFuncs map[string]func() datasource.DataSource + + // dataSourceTypesDiags is the cached Diagnostics obtained while populating + // dataSourceTypes. This is to ensure any warnings or errors are also + // returned appropriately when fetching dataSourceTypes. + dataSourceTypesDiags diag.Diagnostics + + // dataSourceTypesMutex is a mutex to protect concurrent dataSourceTypes + // access from race conditions. + dataSourceTypesMutex sync.Mutex + + // functionDefinitions is the cached Function Definitions for RPCs that need to + // convert data from the protocol. If not found, it will be fetched from the + // Function.Definition() method. + functionDefinitions map[string]function.Definition + + // functionDefinitionsMutex is a mutex to protect concurrent functionDefinitions + // access from race conditions. + functionDefinitionsMutex sync.RWMutex + + // functionFuncs is the cached Function functions for RPCs that need to + // access functions. If not found, it will be fetched from the + // Provider.Functions() method. + functionFuncs map[string]func() function.Function + + // functionFuncsDiags is the cached Diagnostics obtained while populating + // functionFuncs. This is to ensure any warnings or errors are also + // returned appropriately when fetching functionFuncs. + functionFuncsDiags diag.Diagnostics + + // functionFuncsMutex is a mutex to protect concurrent functionFuncs + // access from race conditions. + functionFuncsMutex sync.Mutex + + // providerSchema is the cached Provider Schema for RPCs that need to + // convert configuration data from the protocol. If not found, it will be + // fetched from the Provider.GetSchema() method. + providerSchema fwschema.Schema + + // providerSchemaDiags is the cached Diagnostics obtained while populating + // providerSchema. This is to ensure any warnings or errors are also + // returned appropriately when fetching providerSchema. + providerSchemaDiags diag.Diagnostics + + // providerSchemaMutex is a mutex to protect concurrent providerSchema + // access from race conditions. + providerSchemaMutex sync.Mutex + + // providerMetaSchema is the cached Provider Meta Schema for RPCs that need + // to convert configuration data from the protocol. If not found, it will + // be fetched from the Provider.GetMetaSchema() method. + providerMetaSchema fwschema.Schema + + // providerMetaSchemaDiags is the cached Diagnostics obtained while populating + // providerMetaSchema. This is to ensure any warnings or errors are also + // returned appropriately when fetching providerMetaSchema. + providerMetaSchemaDiags diag.Diagnostics + + // providerMetaSchemaMutex is a mutex to protect concurrent providerMetaSchema + // access from race conditions. + providerMetaSchemaMutex sync.Mutex + + // providerTypeName is the cached type name of the provider, if the provider + // implemented the Metadata method. Access this field with the Provider.ProviderTypeName() method. + providerTypeName string + + // providerTypeNameMutex is a mutex to protect concurrent providerTypeName + // access from race conditions. + providerTypeNameMutex sync.Mutex + + // resourceSchemas is the cached Resource Schemas for RPCs that need to + // convert configuration data from the protocol. If not found, it will be + // fetched from the ResourceType.GetSchema() method. + resourceSchemas map[string]fwschema.Schema + + // resourceSchemasMutex is a mutex to protect concurrent resourceSchemas + // access from race conditions. + resourceSchemasMutex sync.RWMutex + + // resourceFuncs is the cached Resource functions for RPCs that need to + // access resources. If not found, it will be fetched from the + // Provider.Resources() method. + resourceFuncs map[string]func() resource.Resource + + // resourceTypesDiags is the cached Diagnostics obtained while populating + // resourceTypes. This is to ensure any warnings or errors are also + // returned appropriately when fetching resourceTypes. + resourceTypesDiags diag.Diagnostics + + // resourceTypesMutex is a mutex to protect concurrent resourceTypes + // access from race conditions. + resourceTypesMutex sync.Mutex +} + +// DataSource returns the DataSource for a given type name. +func (s *Server) DataSource(ctx context.Context, typeName string) (datasource.DataSource, diag.Diagnostics) { + dataSourceFuncs, diags := s.DataSourceFuncs(ctx) + + dataSourceFunc, ok := dataSourceFuncs[typeName] + + if !ok { + diags.AddError( + "Data Source Type Not Found", + fmt.Sprintf("No data source type named %q was found in the provider.", typeName), + ) + + return nil, diags + } + + return dataSourceFunc(), diags +} + +// DataSourceFuncs returns a map of DataSource functions. The results are cached +// on first use. +func (s *Server) DataSourceFuncs(ctx context.Context) (map[string]func() datasource.DataSource, diag.Diagnostics) { + logging.FrameworkTrace(ctx, "Checking DataSourceTypes lock") + s.dataSourceTypesMutex.Lock() + defer s.dataSourceTypesMutex.Unlock() + + if s.dataSourceFuncs != nil { + return s.dataSourceFuncs, s.dataSourceTypesDiags + } + + providerTypeName := s.ProviderTypeName(ctx) + s.dataSourceFuncs = make(map[string]func() datasource.DataSource) + + logging.FrameworkTrace(ctx, "Calling provider defined Provider DataSources") + dataSourceFuncsSlice := s.Provider.DataSources(ctx) + logging.FrameworkTrace(ctx, "Called provider defined Provider DataSources") + + for _, dataSourceFunc := range dataSourceFuncsSlice { + dataSource := dataSourceFunc() + + dataSourceTypeNameReq := datasource.MetadataRequest{ + ProviderTypeName: providerTypeName, + } + dataSourceTypeNameResp := datasource.MetadataResponse{} + + dataSource.Metadata(ctx, dataSourceTypeNameReq, &dataSourceTypeNameResp) + + if dataSourceTypeNameResp.TypeName == "" { + s.dataSourceTypesDiags.AddError( + "Data Source Type Name Missing", + fmt.Sprintf("The %T DataSource returned an empty string from the Metadata method. ", dataSource)+ + "This is always an issue with the provider and should be reported to the provider developers.", + ) + continue + } + + logging.FrameworkTrace(ctx, "Found data source type", map[string]interface{}{logging.KeyDataSourceType: dataSourceTypeNameResp.TypeName}) + + if _, ok := s.dataSourceFuncs[dataSourceTypeNameResp.TypeName]; ok { + s.dataSourceTypesDiags.AddError( + "Duplicate Data Source Type Defined", + fmt.Sprintf("The %s data source type name was returned for multiple data sources. ", dataSourceTypeNameResp.TypeName)+ + "Data source type names must be unique. "+ + "This is always an issue with the provider and should be reported to the provider developers.", + ) + continue + } + + s.dataSourceFuncs[dataSourceTypeNameResp.TypeName] = dataSourceFunc + } + + return s.dataSourceFuncs, s.dataSourceTypesDiags +} + +// DataSourceMetadatas returns a slice of DataSourceMetadata for the GetMetadata +// RPC. +func (s *Server) DataSourceMetadatas(ctx context.Context) ([]DataSourceMetadata, diag.Diagnostics) { + datasourceFuncs, diags := s.DataSourceFuncs(ctx) + + datasourceMetadatas := make([]DataSourceMetadata, 0, len(datasourceFuncs)) + + for typeName := range datasourceFuncs { + datasourceMetadatas = append(datasourceMetadatas, DataSourceMetadata{ + TypeName: typeName, + }) + } + + return datasourceMetadatas, diags +} + +// DataSourceSchema returns the DataSource Schema for the given type name and +// caches the result for later DataSource operations. +func (s *Server) DataSourceSchema(ctx context.Context, typeName string) (fwschema.Schema, diag.Diagnostics) { + s.dataSourceSchemasMutex.RLock() + dataSourceSchema, ok := s.dataSourceSchemas[typeName] + s.dataSourceSchemasMutex.RUnlock() + + if ok { + return dataSourceSchema, nil + } + + var diags diag.Diagnostics + + dataSource, dataSourceDiags := s.DataSource(ctx, typeName) + + diags.Append(dataSourceDiags...) + + if diags.HasError() { + return nil, diags + } + + schemaReq := datasource.SchemaRequest{} + schemaResp := datasource.SchemaResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined DataSource Schema method", map[string]interface{}{logging.KeyDataSourceType: typeName}) + dataSource.Schema(ctx, schemaReq, &schemaResp) + logging.FrameworkTrace(ctx, "Called provider defined DataSource Schema method", map[string]interface{}{logging.KeyDataSourceType: typeName}) + + diags.Append(schemaResp.Diagnostics...) + + if diags.HasError() { + return schemaResp.Schema, diags + } + + s.dataSourceSchemasMutex.Lock() + + if s.dataSourceSchemas == nil { + s.dataSourceSchemas = make(map[string]fwschema.Schema) + } + + s.dataSourceSchemas[typeName] = schemaResp.Schema + + s.dataSourceSchemasMutex.Unlock() + + return schemaResp.Schema, diags +} + +// DataSourceSchemas returns a map of DataSource Schemas for the +// GetProviderSchema RPC without caching since not all schemas are guaranteed to +// be necessary for later provider operations. The schema implementations are +// also validated. +func (s *Server) DataSourceSchemas(ctx context.Context) (map[string]fwschema.Schema, diag.Diagnostics) { + dataSourceSchemas := make(map[string]fwschema.Schema) + + dataSourceFuncs, diags := s.DataSourceFuncs(ctx) + + for typeName, dataSourceFunc := range dataSourceFuncs { + dataSource := dataSourceFunc() + + schemaReq := datasource.SchemaRequest{} + schemaResp := datasource.SchemaResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined DataSource Schema", map[string]interface{}{logging.KeyDataSourceType: typeName}) + dataSource.Schema(ctx, schemaReq, &schemaResp) + logging.FrameworkTrace(ctx, "Called provider defined DataSource Schema", map[string]interface{}{logging.KeyDataSourceType: typeName}) + + diags.Append(schemaResp.Diagnostics...) + + if schemaResp.Diagnostics.HasError() { + continue + } + + validateDiags := schemaResp.Schema.ValidateImplementation(ctx) + + diags.Append(validateDiags...) + + if validateDiags.HasError() { + continue + } + + dataSourceSchemas[typeName] = schemaResp.Schema + } + + return dataSourceSchemas, diags +} + +// ProviderTypeName returns the TypeName associated with the Provider. The TypeName is cached on first use. +func (s *Server) ProviderTypeName(ctx context.Context) string { + logging.FrameworkTrace(ctx, "Checking ProviderTypeName lock") + s.providerTypeNameMutex.Lock() + defer s.providerTypeNameMutex.Unlock() + + if s.providerTypeName != "" { + return s.providerTypeName + } + + metadataReq := provider.MetadataRequest{} + metadataResp := provider.MetadataResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Provider Metadata") + s.Provider.Metadata(ctx, metadataReq, &metadataResp) + logging.FrameworkTrace(ctx, "Called provider defined Provider Metadata") + + s.providerTypeName = metadataResp.TypeName + + return s.providerTypeName +} + +// ProviderSchema returns the Schema associated with the Provider. The Schema +// and Diagnostics are cached on first use. +func (s *Server) ProviderSchema(ctx context.Context) (fwschema.Schema, diag.Diagnostics) { + logging.FrameworkTrace(ctx, "Checking ProviderSchema lock") + s.providerSchemaMutex.Lock() + defer s.providerSchemaMutex.Unlock() + + if s.providerSchema != nil { + return s.providerSchema, s.providerSchemaDiags + } + + schemaReq := provider.SchemaRequest{} + schemaResp := provider.SchemaResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Provider Schema") + s.Provider.Schema(ctx, schemaReq, &schemaResp) + logging.FrameworkTrace(ctx, "Called provider defined Provider Schema") + + s.providerSchema = schemaResp.Schema + s.providerSchemaDiags = schemaResp.Diagnostics + + s.providerSchemaDiags.Append(schemaResp.Schema.ValidateImplementation(ctx)...) + + return s.providerSchema, s.providerSchemaDiags +} + +// ProviderMetaSchema returns the Meta Schema associated with the Provider, if +// it implements the ProviderWithMetaSchema interface. The Schema and +// Diagnostics are cached on first use. +func (s *Server) ProviderMetaSchema(ctx context.Context) (fwschema.Schema, diag.Diagnostics) { + providerWithMetaSchema, ok := s.Provider.(provider.ProviderWithMetaSchema) + + if !ok { + return nil, nil + } + + logging.FrameworkTrace(ctx, "Provider implements ProviderWithMetaSchema") + logging.FrameworkTrace(ctx, "Checking ProviderMetaSchema lock") + s.providerMetaSchemaMutex.Lock() + defer s.providerMetaSchemaMutex.Unlock() + + if s.providerMetaSchema != nil { + return s.providerMetaSchema, s.providerMetaSchemaDiags + } + + req := provider.MetaSchemaRequest{} + resp := &provider.MetaSchemaResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Provider MetaSchema") + providerWithMetaSchema.MetaSchema(ctx, req, resp) + logging.FrameworkTrace(ctx, "Called provider defined Provider MetaSchema") + + s.providerMetaSchema = resp.Schema + s.providerMetaSchemaDiags = resp.Diagnostics + + s.providerMetaSchemaDiags.Append(resp.Schema.ValidateImplementation(ctx)...) + + return s.providerMetaSchema, s.providerMetaSchemaDiags +} + +// Resource returns the Resource for a given type name. +func (s *Server) Resource(ctx context.Context, typeName string) (resource.Resource, diag.Diagnostics) { + resourceFuncs, diags := s.ResourceFuncs(ctx) + + resourceFunc, ok := resourceFuncs[typeName] + + if !ok { + diags.AddError( + "Resource Type Not Found", + fmt.Sprintf("No resource type named %q was found in the provider.", typeName), + ) + + return nil, diags + } + + return resourceFunc(), diags +} + +// ResourceFuncs returns a map of Resource functions. The results are cached +// on first use. +func (s *Server) ResourceFuncs(ctx context.Context) (map[string]func() resource.Resource, diag.Diagnostics) { + logging.FrameworkTrace(ctx, "Checking ResourceTypes lock") + s.resourceTypesMutex.Lock() + defer s.resourceTypesMutex.Unlock() + + if s.resourceFuncs != nil { + return s.resourceFuncs, s.resourceTypesDiags + } + + providerTypeName := s.ProviderTypeName(ctx) + s.resourceFuncs = make(map[string]func() resource.Resource) + + logging.FrameworkTrace(ctx, "Calling provider defined Provider Resources") + resourceFuncsSlice := s.Provider.Resources(ctx) + logging.FrameworkTrace(ctx, "Called provider defined Provider Resources") + + for _, resourceFunc := range resourceFuncsSlice { + res := resourceFunc() + + resourceTypeNameReq := resource.MetadataRequest{ + ProviderTypeName: providerTypeName, + } + resourceTypeNameResp := resource.MetadataResponse{} + + res.Metadata(ctx, resourceTypeNameReq, &resourceTypeNameResp) + + if resourceTypeNameResp.TypeName == "" { + s.resourceTypesDiags.AddError( + "Resource Type Name Missing", + fmt.Sprintf("The %T Resource returned an empty string from the Metadata method. ", res)+ + "This is always an issue with the provider and should be reported to the provider developers.", + ) + continue + } + + logging.FrameworkTrace(ctx, "Found resource type", map[string]interface{}{logging.KeyResourceType: resourceTypeNameResp.TypeName}) + + if _, ok := s.resourceFuncs[resourceTypeNameResp.TypeName]; ok { + s.resourceTypesDiags.AddError( + "Duplicate Resource Type Defined", + fmt.Sprintf("The %s resource type name was returned for multiple resources. ", resourceTypeNameResp.TypeName)+ + "Resource type names must be unique. "+ + "This is always an issue with the provider and should be reported to the provider developers.", + ) + continue + } + + s.resourceFuncs[resourceTypeNameResp.TypeName] = resourceFunc + } + + return s.resourceFuncs, s.resourceTypesDiags +} + +// ResourceMetadatas returns a slice of ResourceMetadata for the GetMetadata +// RPC. +func (s *Server) ResourceMetadatas(ctx context.Context) ([]ResourceMetadata, diag.Diagnostics) { + resourceFuncs, diags := s.ResourceFuncs(ctx) + + resourceMetadatas := make([]ResourceMetadata, 0, len(resourceFuncs)) + + for typeName := range resourceFuncs { + resourceMetadatas = append(resourceMetadatas, ResourceMetadata{ + TypeName: typeName, + }) + } + + return resourceMetadatas, diags +} + +// ResourceSchema returns the Resource Schema for the given type name and +// caches the result for later Resource operations. +func (s *Server) ResourceSchema(ctx context.Context, typeName string) (fwschema.Schema, diag.Diagnostics) { + s.resourceSchemasMutex.RLock() + resourceSchema, ok := s.resourceSchemas[typeName] + s.resourceSchemasMutex.RUnlock() + + if ok { + return resourceSchema, nil + } + + var diags diag.Diagnostics + + r, resourceDiags := s.Resource(ctx, typeName) + + diags.Append(resourceDiags...) + + if diags.HasError() { + return nil, diags + } + + schemaReq := resource.SchemaRequest{} + schemaResp := resource.SchemaResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Schema method", map[string]interface{}{logging.KeyResourceType: typeName}) + r.Schema(ctx, schemaReq, &schemaResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Schema method", map[string]interface{}{logging.KeyResourceType: typeName}) + + diags.Append(schemaResp.Diagnostics...) + + if diags.HasError() { + return schemaResp.Schema, diags + } + + s.resourceSchemasMutex.Lock() + + if s.resourceSchemas == nil { + s.resourceSchemas = make(map[string]fwschema.Schema) + } + + s.resourceSchemas[typeName] = schemaResp.Schema + + s.resourceSchemasMutex.Unlock() + + return schemaResp.Schema, diags +} + +// ResourceSchemas returns a map of Resource Schemas for the +// GetProviderSchema RPC without caching since not all schemas are guaranteed to +// be necessary for later provider operations. The schema implementations are +// also validated. +func (s *Server) ResourceSchemas(ctx context.Context) (map[string]fwschema.Schema, diag.Diagnostics) { + resourceSchemas := make(map[string]fwschema.Schema) + + resourceFuncs, diags := s.ResourceFuncs(ctx) + + for typeName, resourceFunc := range resourceFuncs { + r := resourceFunc() + + schemaReq := resource.SchemaRequest{} + schemaResp := resource.SchemaResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Schema method", map[string]interface{}{logging.KeyResourceType: typeName}) + r.Schema(ctx, schemaReq, &schemaResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Schema method", map[string]interface{}{logging.KeyResourceType: typeName}) + + diags.Append(schemaResp.Diagnostics...) + + if schemaResp.Diagnostics.HasError() { + continue + } + + validateDiags := schemaResp.Schema.ValidateImplementation(ctx) + + diags.Append(validateDiags...) + + if validateDiags.HasError() { + continue + } + + resourceSchemas[typeName] = schemaResp.Schema + } + + return resourceSchemas, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_applyresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_applyresourcechange.go new file mode 100644 index 00000000..a11a72e4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_applyresourcechange.go @@ -0,0 +1,107 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ApplyResourceChangeRequest is the framework server request for the +// ApplyResourceChange RPC. +type ApplyResourceChangeRequest struct { + Config *tfsdk.Config + PlannedPrivate *privatestate.Data + PlannedState *tfsdk.Plan + PriorState *tfsdk.State + ProviderMeta *tfsdk.Config + ResourceSchema fwschema.Schema + Resource resource.Resource +} + +// ApplyResourceChangeResponse is the framework server response for the +// ApplyResourceChange RPC. +type ApplyResourceChangeResponse struct { + Diagnostics diag.Diagnostics + NewState *tfsdk.State + Private *privatestate.Data +} + +// ApplyResourceChange implements the framework server ApplyResourceChange RPC. +func (s *Server) ApplyResourceChange(ctx context.Context, req *ApplyResourceChangeRequest, resp *ApplyResourceChangeResponse) { + if req == nil { + return + } + + // If PriorState is missing/null, its a Create request. + if req.PriorState == nil || req.PriorState.Raw.IsNull() { + logging.FrameworkTrace(ctx, "ApplyResourceChange received no PriorState, running CreateResource") + + createReq := &CreateResourceRequest{ + Config: req.Config, + PlannedPrivate: req.PlannedPrivate, + PlannedState: req.PlannedState, + ProviderMeta: req.ProviderMeta, + ResourceSchema: req.ResourceSchema, + Resource: req.Resource, + } + createResp := &CreateResourceResponse{} + + s.CreateResource(ctx, createReq, createResp) + + resp.Diagnostics = createResp.Diagnostics + resp.NewState = createResp.NewState + resp.Private = createResp.Private + + return + } + + // If PlannedState is missing/null, its a Delete request. + if req.PlannedState == nil || req.PlannedState.Raw.IsNull() { + logging.FrameworkTrace(ctx, "ApplyResourceChange received no PlannedState, running DeleteResource") + + deleteReq := &DeleteResourceRequest{ + PlannedPrivate: req.PlannedPrivate, + PriorState: req.PriorState, + ProviderMeta: req.ProviderMeta, + ResourceSchema: req.ResourceSchema, + Resource: req.Resource, + } + deleteResp := &DeleteResourceResponse{} + + s.DeleteResource(ctx, deleteReq, deleteResp) + + resp.Diagnostics = deleteResp.Diagnostics + resp.NewState = deleteResp.NewState + resp.Private = deleteResp.Private + + return + } + + // Otherwise, assume its an Update request. + logging.FrameworkTrace(ctx, "ApplyResourceChange running UpdateResource") + + updateReq := &UpdateResourceRequest{ + Config: req.Config, + PlannedPrivate: req.PlannedPrivate, + PlannedState: req.PlannedState, + PriorState: req.PriorState, + ProviderMeta: req.ProviderMeta, + ResourceSchema: req.ResourceSchema, + Resource: req.Resource, + } + updateResp := &UpdateResourceResponse{} + + s.UpdateResource(ctx, updateReq, updateResp) + + resp.Diagnostics = updateResp.Diagnostics + resp.NewState = updateResp.NewState + resp.Private = updateResp.Private +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_callfunction.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_callfunction.go new file mode 100644 index 00000000..99e164e4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_callfunction.go @@ -0,0 +1,56 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" +) + +// CallFunctionRequest is the framework server request for the +// CallFunction RPC. +type CallFunctionRequest struct { + Arguments function.ArgumentsData + Function function.Function + FunctionDefinition function.Definition +} + +// CallFunctionResponse is the framework server response for the +// CallFunction RPC. +type CallFunctionResponse struct { + Error *function.FuncError + Result function.ResultData +} + +// CallFunction implements the framework server CallFunction RPC. +func (s *Server) CallFunction(ctx context.Context, req *CallFunctionRequest, resp *CallFunctionResponse) { + if req == nil { + return + } + + resultData, err := req.FunctionDefinition.Return.NewResultData(ctx) + + resp.Error = function.ConcatFuncErrors(resp.Error, err) + + if resp.Error != nil { + return + } + + runReq := function.RunRequest{ + Arguments: req.Arguments, + } + runResp := function.RunResponse{ + Result: resultData, + } + + logging.FrameworkTrace(ctx, "Calling provider defined Function Run") + req.Function.Run(ctx, runReq, &runResp) + logging.FrameworkTrace(ctx, "Called provider defined Function Run") + + resp.Error = function.ConcatFuncErrors(resp.Error, runResp.Error) + + resp.Result = runResp.Result +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_capabilities.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_capabilities.go new file mode 100644 index 00000000..7f850ed8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_capabilities.go @@ -0,0 +1,40 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +// ServerCapabilities is a combination of tfprotov5.ServerCapabilities and +// tfprotov6.ServerCapabilties, which may diverge over time. If that happens, +// the toproto5 conversion logic will handle the appropriate filtering and the +// proto5server/fwserver logic will need to account for missing features. +type ServerCapabilities struct { + // GetProviderSchemaOptional signals that the provider does not require the + // GetProviderSchema RPC before other RPCs. + // + // This should always be enabled in framework providers and requires + // Terraform 1.6 or later. + GetProviderSchemaOptional bool + + // MoveResourceState signals that the provider is ready for the + // MoveResourceState RPC. + // + // This should always be enabled in framework providers and requires + // Terraform 1.8 or later. + MoveResourceState bool + + // PlanDestroy signals that the provider is ready for the + // PlanResourceChange RPC on resource destruction. + // + // This should always be enabled in framework providers and requires + // Terraform 1.3 or later. + PlanDestroy bool +} + +// ServerCapabilities returns the server capabilities. +func (s *Server) ServerCapabilities() *ServerCapabilities { + return &ServerCapabilities{ + GetProviderSchemaOptional: true, + MoveResourceState: true, + PlanDestroy: true, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_configureprovider.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_configureprovider.go new file mode 100644 index 00000000..3f841887 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_configureprovider.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/provider" +) + +// ConfigureProvider implements the framework server ConfigureProvider RPC. +func (s *Server) ConfigureProvider(ctx context.Context, req *provider.ConfigureRequest, resp *provider.ConfigureResponse) { + logging.FrameworkTrace(ctx, "Calling provider defined Provider Configure") + + if req != nil { + s.Provider.Configure(ctx, *req, resp) + } else { + s.Provider.Configure(ctx, provider.ConfigureRequest{}, resp) + } + + logging.FrameworkTrace(ctx, "Called provider defined Provider Configure") + + s.DataSourceConfigureData = resp.DataSourceData + s.ResourceConfigureData = resp.ResourceData +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_createresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_createresource.go new file mode 100644 index 00000000..30c49169 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_createresource.go @@ -0,0 +1,166 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// CreateResourceRequest is the framework server request for a create request +// with the ApplyResourceChange RPC. +type CreateResourceRequest struct { + Config *tfsdk.Config + PlannedPrivate *privatestate.Data + PlannedState *tfsdk.Plan + ProviderMeta *tfsdk.Config + ResourceSchema fwschema.Schema + Resource resource.Resource +} + +// CreateResourceResponse is the framework server response for a create request +// with the ApplyResourceChange RPC. +type CreateResourceResponse struct { + Diagnostics diag.Diagnostics + NewState *tfsdk.State + Private *privatestate.Data +} + +// CreateResource implements the framework server create request logic for the +// ApplyResourceChange RPC. +func (s *Server) CreateResource(ctx context.Context, req *CreateResourceRequest, resp *CreateResourceResponse) { + if req == nil { + return + } + + if resourceWithConfigure, ok := req.Resource.(resource.ResourceWithConfigure); ok { + logging.FrameworkTrace(ctx, "Resource implements ResourceWithConfigure") + + configureReq := resource.ConfigureRequest{ + ProviderData: s.ResourceConfigureData, + } + configureResp := resource.ConfigureResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Configure") + resourceWithConfigure.Configure(ctx, configureReq, &configureResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Configure") + + resp.Diagnostics.Append(configureResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + } + + nullSchemaData := tftypes.NewValue(req.ResourceSchema.Type().TerraformType(ctx), nil) + + createReq := resource.CreateRequest{ + Config: tfsdk.Config{ + Schema: req.ResourceSchema, + Raw: nullSchemaData, + }, + Plan: tfsdk.Plan{ + Schema: req.ResourceSchema, + Raw: nullSchemaData, + }, + } + + privateProviderData := privatestate.EmptyProviderData(ctx) + + createResp := resource.CreateResponse{ + State: tfsdk.State{ + Schema: req.ResourceSchema, + Raw: nullSchemaData, + }, + Private: privateProviderData, + } + + if req.Config != nil { + createReq.Config = *req.Config + } + + if req.PlannedState != nil { + createReq.Plan = *req.PlannedState + } + + if req.ProviderMeta != nil { + createReq.ProviderMeta = *req.ProviderMeta + } + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Create") + req.Resource.Create(ctx, createReq, &createResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Create") + + resp.Diagnostics = createResp.Diagnostics + resp.NewState = &createResp.State + + if !resp.Diagnostics.HasError() && createResp.State.Raw.Equal(nullSchemaData) { + detail := "The Terraform Provider unexpectedly returned no resource state after having no errors in the resource creation. " + + "This is always an issue in the Terraform Provider and should be reported to the provider developers.\n\n" + + "The resource may have been successfully created, but Terraform is not tracking it. " + + "Applying the configuration again with no other action may result in duplicate resource errors." + + if _, ok := req.Resource.(resource.ResourceWithImportState); ok { + detail += " Import the resource if the resource was actually created and Terraform should be tracking it." + } + + resp.Diagnostics.AddError( + "Missing Resource State After Create", + detail, + ) + } + + if createResp.Private != nil { + if resp.Private == nil { + resp.Private = &privatestate.Data{} + } + + resp.Private.Provider = createResp.Private + } + + if resp.Diagnostics.HasError() { + return + } + + semanticEqualityReq := SchemaSemanticEqualityRequest{ + PriorData: fwschemadata.Data{ + Description: fwschemadata.DataDescriptionPlan, + Schema: req.PlannedState.Schema, + TerraformValue: req.PlannedState.Raw.Copy(), + }, + ProposedNewData: fwschemadata.Data{ + Description: fwschemadata.DataDescriptionState, + Schema: resp.NewState.Schema, + TerraformValue: resp.NewState.Raw.Copy(), + }, + } + semanticEqualityResp := &SchemaSemanticEqualityResponse{ + NewData: semanticEqualityReq.ProposedNewData, + } + + SchemaSemanticEquality(ctx, semanticEqualityReq, semanticEqualityResp) + + resp.Diagnostics.Append(semanticEqualityResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + if semanticEqualityResp.NewData.TerraformValue.Equal(resp.NewState.Raw) { + return + } + + logging.FrameworkDebug(ctx, "State updated due to semantic equality") + + resp.NewState.Raw = semanticEqualityResp.NewData.TerraformValue +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_deleteresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_deleteresource.go new file mode 100644 index 00000000..5879b670 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_deleteresource.go @@ -0,0 +1,123 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// DeleteResourceRequest is the framework server request for a delete request +// with the ApplyResourceChange RPC. +type DeleteResourceRequest struct { + PlannedPrivate *privatestate.Data + PriorState *tfsdk.State + ProviderMeta *tfsdk.Config + ResourceSchema fwschema.Schema + Resource resource.Resource +} + +// DeleteResourceResponse is the framework server response for a delete request +// with the ApplyResourceChange RPC. +type DeleteResourceResponse struct { + Diagnostics diag.Diagnostics + NewState *tfsdk.State + Private *privatestate.Data +} + +// DeleteResource implements the framework server delete request logic for the +// ApplyResourceChange RPC. +func (s *Server) DeleteResource(ctx context.Context, req *DeleteResourceRequest, resp *DeleteResourceResponse) { + if req == nil { + return + } + + if resourceWithConfigure, ok := req.Resource.(resource.ResourceWithConfigure); ok { + logging.FrameworkTrace(ctx, "Resource implements ResourceWithConfigure") + + configureReq := resource.ConfigureRequest{ + ProviderData: s.ResourceConfigureData, + } + configureResp := resource.ConfigureResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Configure") + resourceWithConfigure.Configure(ctx, configureReq, &configureResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Configure") + + resp.Diagnostics.Append(configureResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + } + + deleteReq := resource.DeleteRequest{ + State: tfsdk.State{ + Schema: req.ResourceSchema, + Raw: tftypes.NewValue(req.ResourceSchema.Type().TerraformType(ctx), nil), + }, + } + deleteResp := resource.DeleteResponse{ + State: tfsdk.State{ + Schema: req.ResourceSchema, + Raw: tftypes.NewValue(req.ResourceSchema.Type().TerraformType(ctx), nil), + }, + } + + if req.PriorState != nil { + deleteReq.State = *req.PriorState + deleteResp.State = *req.PriorState + } + + if req.ProviderMeta != nil { + deleteReq.ProviderMeta = *req.ProviderMeta + } + + privateProviderData := privatestate.EmptyProviderData(ctx) + + deleteReq.Private = privateProviderData + deleteResp.Private = privateProviderData + + if req.PlannedPrivate != nil { + if req.PlannedPrivate.Provider != nil { + deleteReq.Private = req.PlannedPrivate.Provider + deleteResp.Private = req.PlannedPrivate.Provider + } + + resp.Private = req.PlannedPrivate + } + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Delete") + req.Resource.Delete(ctx, deleteReq, &deleteResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Delete") + + if !deleteResp.Diagnostics.HasError() { + logging.FrameworkTrace(ctx, "No provider defined Delete errors detected, ensuring State and Private are cleared") + deleteResp.State.RemoveResource(ctx) + + // Preserve prior behavior of always returning nil. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/863 + deleteResp.Private = nil + resp.Private = nil + } + + resp.Diagnostics = deleteResp.Diagnostics + resp.NewState = &deleteResp.State + + if deleteResp.Private != nil { + if resp.Private == nil { + resp.Private = &privatestate.Data{} + } + + resp.Private.Provider = deleteResp.Private + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_functions.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_functions.go new file mode 100644 index 00000000..37c87e7c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_functions.go @@ -0,0 +1,195 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/provider" +) + +// Function returns the Function for a given name. +func (s *Server) Function(ctx context.Context, name string) (function.Function, *function.FuncError) { + functionFuncs, diags := s.FunctionFuncs(ctx) + + funcErr := function.FuncErrorFromDiags(ctx, diags) + + functionFunc, ok := functionFuncs[name] + + if !ok { + funcErr = function.ConcatFuncErrors(funcErr, function.NewFuncError(fmt.Sprintf("Function Not Found: No function named %q was found in the provider.", name))) + + return nil, funcErr + } + + return functionFunc(), nil +} + +// FunctionDefinition returns the Function Definition for the given name and +// caches the result for later Function operations. +func (s *Server) FunctionDefinition(ctx context.Context, name string) (function.Definition, *function.FuncError) { + s.functionDefinitionsMutex.RLock() + functionDefinition, ok := s.functionDefinitions[name] + s.functionDefinitionsMutex.RUnlock() + + if ok { + return functionDefinition, nil + } + + functionImpl, funcErr := s.Function(ctx, name) + + if funcErr != nil { + return function.Definition{}, funcErr + } + + definitionReq := function.DefinitionRequest{} + definitionResp := function.DefinitionResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Function Definition method", map[string]interface{}{logging.KeyFunctionName: name}) + functionImpl.Definition(ctx, definitionReq, &definitionResp) + logging.FrameworkTrace(ctx, "Called provider defined Function Definition method", map[string]interface{}{logging.KeyFunctionName: name}) + + funcErr = function.ConcatFuncErrors(funcErr, function.FuncErrorFromDiags(ctx, definitionResp.Diagnostics)) + + if funcErr != nil { + return definitionResp.Definition, funcErr + } + + s.functionDefinitionsMutex.Lock() + + if s.functionDefinitions == nil { + s.functionDefinitions = make(map[string]function.Definition) + } + + s.functionDefinitions[name] = definitionResp.Definition + + s.functionDefinitionsMutex.Unlock() + + return definitionResp.Definition, funcErr +} + +// FunctionDefinitions returns a map of Function Definitions for the +// GetProviderSchema RPC without caching since not all definitions are +// guaranteed to be necessary for later provider operations. The definition +// implementations are also validated. +func (s *Server) FunctionDefinitions(ctx context.Context) (map[string]function.Definition, diag.Diagnostics) { + functionDefinitions := make(map[string]function.Definition) + + functionFuncs, diags := s.FunctionFuncs(ctx) + + for name, functionFunc := range functionFuncs { + functionImpl := functionFunc() + + definitionReq := function.DefinitionRequest{} + definitionResp := function.DefinitionResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Function Definition", map[string]interface{}{logging.KeyFunctionName: name}) + functionImpl.Definition(ctx, definitionReq, &definitionResp) + logging.FrameworkTrace(ctx, "Called provider defined Function Definition", map[string]interface{}{logging.KeyFunctionName: name}) + + diags.Append(definitionResp.Diagnostics...) + + if definitionResp.Diagnostics.HasError() { + continue + } + + validateReq := function.DefinitionValidateRequest{ + FuncName: name, + } + + validateResp := function.DefinitionValidateResponse{} + + definitionResp.Definition.ValidateImplementation(ctx, validateReq, &validateResp) + + diags.Append(validateResp.Diagnostics...) + + if validateResp.Diagnostics.HasError() { + continue + } + + functionDefinitions[name] = definitionResp.Definition + } + + return functionDefinitions, diags +} + +// FunctionFuncs returns a map of Function functions. The results are cached +// on first use. +func (s *Server) FunctionFuncs(ctx context.Context) (map[string]func() function.Function, diag.Diagnostics) { + logging.FrameworkTrace(ctx, "Checking FunctionTypes lock") + s.functionFuncsMutex.Lock() + defer s.functionFuncsMutex.Unlock() + + if s.functionFuncs != nil { + return s.functionFuncs, s.functionFuncsDiags + } + + s.functionFuncs = make(map[string]func() function.Function) + + provider, ok := s.Provider.(provider.ProviderWithFunctions) + + if !ok { + // Only function-specific RPCs should return diagnostics about the + // provider not implementing functions or missing functions. + return s.functionFuncs, s.functionFuncsDiags + } + + logging.FrameworkTrace(ctx, "Calling provider defined Provider Functions") + functionFuncs := provider.Functions(ctx) + logging.FrameworkTrace(ctx, "Called provider defined Provider Functions") + + for _, functionFunc := range functionFuncs { + functionImpl := functionFunc() + + metadataReq := function.MetadataRequest{} + metadataResp := function.MetadataResponse{} + + functionImpl.Metadata(ctx, metadataReq, &metadataResp) + + if metadataResp.Name == "" { + s.functionFuncsDiags.AddError( + "Function Name Missing", + fmt.Sprintf("The %T Function returned an empty string from the Metadata method. ", functionImpl)+ + "This is always an issue with the provider and should be reported to the provider developers.", + ) + continue + } + + logging.FrameworkTrace(ctx, "Found function", map[string]interface{}{logging.KeyFunctionName: metadataResp.Name}) + + if _, ok := s.functionFuncs[metadataResp.Name]; ok { + s.functionFuncsDiags.AddError( + "Duplicate Function Name Defined", + fmt.Sprintf("The %s function name was returned for multiple functions. ", metadataResp.Name)+ + "Function names must be unique. "+ + "This is always an issue with the provider and should be reported to the provider developers.", + ) + continue + } + + s.functionFuncs[metadataResp.Name] = functionFunc + } + + return s.functionFuncs, s.functionFuncsDiags +} + +// FunctionMetadatas returns a slice of FunctionMetadata for the GetMetadata +// RPC. +func (s *Server) FunctionMetadatas(ctx context.Context) ([]FunctionMetadata, diag.Diagnostics) { + functionFuncs, diags := s.FunctionFuncs(ctx) + + functionMetadatas := make([]FunctionMetadata, 0, len(functionFuncs)) + + for name := range functionFuncs { + functionMetadatas = append(functionMetadatas, FunctionMetadata{ + Name: name, + }) + } + + return functionMetadatas, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getfunctions.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getfunctions.go new file mode 100644 index 00000000..e2567be8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getfunctions.go @@ -0,0 +1,37 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/function" +) + +// GetFunctionsRequest is the framework server request for the +// GetFunctions RPC. +type GetFunctionsRequest struct{} + +// GetFunctionsResponse is the framework server response for the +// GetFunctions RPC. +type GetFunctionsResponse struct { + FunctionDefinitions map[string]function.Definition + Diagnostics diag.Diagnostics +} + +// GetFunctions implements the framework server GetFunctions RPC. +func (s *Server) GetFunctions(ctx context.Context, req *GetFunctionsRequest, resp *GetFunctionsResponse) { + resp.FunctionDefinitions = map[string]function.Definition{} + + functionDefinitions, diags := s.FunctionDefinitions(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.FunctionDefinitions = functionDefinitions +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getmetadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getmetadata.go new file mode 100644 index 00000000..ebd0728a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getmetadata.go @@ -0,0 +1,73 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +// GetMetadataRequest is the framework server request for the +// GetMetadata RPC. +type GetMetadataRequest struct{} + +// GetMetadataResponse is the framework server response for the +// GetMetadata RPC. +type GetMetadataResponse struct { + DataSources []DataSourceMetadata + Diagnostics diag.Diagnostics + Functions []FunctionMetadata + Resources []ResourceMetadata + ServerCapabilities *ServerCapabilities +} + +// DataSourceMetadata is the framework server equivalent of the +// tfprotov5.DataSourceMetadata and tfprotov6.DataSourceMetadata types. +type DataSourceMetadata struct { + // TypeName is the name of the data resource. + TypeName string +} + +// FunctionMetadata is the framework server equivalent of the +// tfprotov5.FunctionMetadata and tfprotov6.FunctionMetadata types. +type FunctionMetadata struct { + // Name is the name of the function. + Name string +} + +// ResourceMetadata is the framework server equivalent of the +// tfprotov5.ResourceMetadata and tfprotov6.ResourceMetadata types. +type ResourceMetadata struct { + // TypeName is the name of the managed resource. + TypeName string +} + +// GetMetadata implements the framework server GetMetadata RPC. +func (s *Server) GetMetadata(ctx context.Context, req *GetMetadataRequest, resp *GetMetadataResponse) { + resp.DataSources = []DataSourceMetadata{} + resp.Functions = []FunctionMetadata{} + resp.Resources = []ResourceMetadata{} + resp.ServerCapabilities = s.ServerCapabilities() + + datasourceMetadatas, diags := s.DataSourceMetadatas(ctx) + + resp.Diagnostics.Append(diags...) + + functionMetadatas, diags := s.FunctionMetadatas(ctx) + + resp.Diagnostics.Append(diags...) + + resourceMetadatas, diags := s.ResourceMetadatas(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.DataSources = datasourceMetadatas + resp.Functions = functionMetadatas + resp.Resources = resourceMetadatas +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getproviderschema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getproviderschema.go new file mode 100644 index 00000000..afcca835 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_getproviderschema.go @@ -0,0 +1,83 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// GetProviderSchemaRequest is the framework server request for the +// GetProviderSchema RPC. +type GetProviderSchemaRequest struct{} + +// GetProviderSchemaResponse is the framework server response for the +// GetProviderSchema RPC. +type GetProviderSchemaResponse struct { + ServerCapabilities *ServerCapabilities + Provider fwschema.Schema + ProviderMeta fwschema.Schema + ResourceSchemas map[string]fwschema.Schema + DataSourceSchemas map[string]fwschema.Schema + FunctionDefinitions map[string]function.Definition + Diagnostics diag.Diagnostics +} + +// GetProviderSchema implements the framework server GetProviderSchema RPC. +func (s *Server) GetProviderSchema(ctx context.Context, req *GetProviderSchemaRequest, resp *GetProviderSchemaResponse) { + resp.ServerCapabilities = s.ServerCapabilities() + + providerSchema, diags := s.ProviderSchema(ctx) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + resp.Provider = providerSchema + + providerMetaSchema, diags := s.ProviderMetaSchema(ctx) + + resp.Diagnostics.Append(diags...) + + if diags.HasError() { + return + } + + resp.ProviderMeta = providerMetaSchema + + resourceSchemas, diags := s.ResourceSchemas(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.ResourceSchemas = resourceSchemas + + dataSourceSchemas, diags := s.DataSourceSchemas(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.DataSourceSchemas = dataSourceSchemas + + functions, diags := s.FunctionDefinitions(ctx) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.FunctionDefinitions = functions +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_importresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_importresourcestate.go new file mode 100644 index 00000000..d89cee35 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_importresourcestate.go @@ -0,0 +1,138 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ImportedResource represents a resource that was imported. +type ImportedResource struct { + Private *privatestate.Data + State tfsdk.State + TypeName string +} + +// ImportResourceStateRequest is the framework server request for the +// ImportResourceState RPC. +type ImportResourceStateRequest struct { + ID string + Resource resource.Resource + + // EmptyState is an empty State for the resource schema. This is used to + // initialize the ImportedResource State of the ImportResourceStateResponse + // and allow the framework server to verify that the provider updated the + // state after the provider defined logic. + EmptyState tfsdk.State + + // TypeName is the resource type name, which is necessary for populating + // the ImportedResource TypeName of the ImportResourceStateResponse. + TypeName string +} + +// ImportResourceStateResponse is the framework server response for the +// ImportResourceState RPC. +type ImportResourceStateResponse struct { + Diagnostics diag.Diagnostics + ImportedResources []ImportedResource +} + +// ImportResourceState implements the framework server ImportResourceState RPC. +func (s *Server) ImportResourceState(ctx context.Context, req *ImportResourceStateRequest, resp *ImportResourceStateResponse) { + if req == nil { + return + } + + if resourceWithConfigure, ok := req.Resource.(resource.ResourceWithConfigure); ok { + logging.FrameworkTrace(ctx, "Resource implements ResourceWithConfigure") + + configureReq := resource.ConfigureRequest{ + ProviderData: s.ResourceConfigureData, + } + configureResp := resource.ConfigureResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Configure") + resourceWithConfigure.Configure(ctx, configureReq, &configureResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Configure") + + resp.Diagnostics.Append(configureResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + } + + resourceWithImportState, ok := req.Resource.(resource.ResourceWithImportState) + + if !ok { + // If there is a feature request for customizing this messaging, + // provider developers can implement a ImportState method that + // immediately returns a custom error diagnostic. + // + // However, implementing the ImportState method could cause issues + // with automated documentation generation, which likely would check + // if the resource implements the ResourceWithImportState interface. + // Instead, a separate "ResourceWithoutImportState" interface could be + // created with a method such as: + // ImportNotImplementedMessage(context.Context) string. + resp.Diagnostics.AddError( + "Resource Import Not Implemented", + "This resource does not support import. Please contact the provider developer for additional information.", + ) + return + } + + importReq := resource.ImportStateRequest{ + ID: req.ID, + } + + privateProviderData := privatestate.EmptyProviderData(ctx) + + importResp := resource.ImportStateResponse{ + State: tfsdk.State{ + Raw: req.EmptyState.Raw.Copy(), + Schema: req.EmptyState.Schema, + }, + Private: privateProviderData, + } + + logging.FrameworkTrace(ctx, "Calling provider defined Resource ImportState") + resourceWithImportState.ImportState(ctx, importReq, &importResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource ImportState") + + resp.Diagnostics.Append(importResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + if importResp.State.Raw.Equal(req.EmptyState.Raw) { + resp.Diagnostics.AddError( + "Missing Resource Import State", + "An unexpected error was encountered when importing the resource. This is always a problem with the provider. Please give the following information to the provider developer:\n\n"+ + "Resource ImportState method returned no State in response. If import is intentionally not supported, remove the Resource type ImportState method or return an error.", + ) + return + } + + private := &privatestate.Data{} + + if importResp.Private != nil { + private.Provider = importResp.Private + } + + resp.ImportedResources = []ImportedResource{ + { + State: importResp.State, + TypeName: req.TypeName, + Private: private, + }, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_moveresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_moveresourcestate.go new file mode 100644 index 00000000..480e4a95 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_moveresourcestate.go @@ -0,0 +1,230 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + "strconv" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// MoveResourceStateRequest is the framework server request for the +// MoveResourceState RPC. +type MoveResourceStateRequest struct { + // SourcePrivate is the private state of the source resource as given by + // Terraform across the protocol. + SourcePrivate *privatestate.Data + + // SourceProviderAddress is the address of the source provider as given by + // Terraform across the protocol. + SourceProviderAddress string + + // SourceSchemaVersion is the version of the source resource schema as given + // by Terraform across the protocol. + SourceSchemaVersion int64 + + // SourceRawState is the raw state of the source resource as given by + // Terraform across the protocol. + // + // Using the tfprotov6 type here was a pragmatic effort decision around when + // the framework introduced compatibility promises. This type was chosen as + // it was readily available and trivial to convert between tfprotov5. + // + // Using a terraform-plugin-go type is not ideal for the framework as almost + // all terraform-plugin-go types have framework abstractions, but if there + // is ever a time where it makes sense to re-evaluate this decision, such as + // a major version bump, it could be changed then. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/340 + SourceRawState *tfprotov6.RawState + + // SourceTypeName is the type name of the source resource as given by + // Terraform across the protocol. + SourceTypeName string + + // TargetResource is the provider-defined resource implementation as + // determined by the framework looking up the resource name from the + // provider.Provider implementation Resources method defined by the + // provider developer. + TargetResource resource.Resource + + // TargetResourceSchema is the evaluated schema definition of the target + // resource as determined by the framework calling the resource.Resource + // implementation Schema method defined by the provider developer. + TargetResourceSchema fwschema.Schema + + // TargetTypeName is the type name of the target resource as given by + // Terraform across the protocol. + TargetTypeName string +} + +// MoveResourceStateResponse is the framework server response for the +// MoveResourceState RPC. +type MoveResourceStateResponse struct { + Diagnostics diag.Diagnostics + TargetPrivate *privatestate.Data + TargetState *tfsdk.State +} + +// MoveResourceState implements the framework server MoveResourceState RPC. +func (s *Server) MoveResourceState(ctx context.Context, req *MoveResourceStateRequest, resp *MoveResourceStateResponse) { + if req == nil { + return + } + + if req.SourceRawState == nil { + resp.Diagnostics.AddError( + "Missing Source Resource State", + "The source resource state was not provided to the provider for the MoveResourceState operation. "+ + "This is always an issue in Terraform and should be reported to the Terraform maintainers.", + ) + + return + } + + resourceWithMoveState, ok := req.TargetResource.(resource.ResourceWithMoveState) + + if !ok { + resp.Diagnostics.AddError( + "Unable to Move Resource State", + "The target resource implementation does not include move resource state support. "+ + "The resource implementation can be updated by the provider developers to include this support with the ResourceWithMoveState interface.\n\n"+ + "Source Provider Address: "+req.SourceProviderAddress+"\n"+ + "Source Resource Type: "+req.SourceTypeName+"\n"+ + "Source Resource Schema Version: "+strconv.FormatInt(req.SourceSchemaVersion, 10)+"\n"+ + "Target Resource Type: "+req.TargetTypeName, + ) + + return + } + + logging.FrameworkTrace(ctx, "Resource implements ResourceWithMoveState") + + logging.FrameworkTrace(ctx, "Calling provider defined Resource MoveState") + resourceStateMovers := resourceWithMoveState.MoveState(ctx) + logging.FrameworkTrace(ctx, "Called provider defined Resource MoveState") + + sourcePrivate := privatestate.EmptyProviderData(ctx) + + if req.SourcePrivate != nil && req.SourcePrivate.Provider != nil { + sourcePrivate = req.SourcePrivate.Provider + } + + if resp.TargetPrivate == nil { + resp.TargetPrivate = privatestate.EmptyData(ctx) + } + + for _, resourceStateMover := range resourceStateMovers { + moveStateReq := resource.MoveStateRequest{ + SourcePrivate: sourcePrivate, + SourceProviderAddress: req.SourceProviderAddress, + SourceRawState: req.SourceRawState, + SourceSchemaVersion: req.SourceSchemaVersion, + SourceTypeName: req.SourceTypeName, + } + moveStateResp := resource.MoveStateResponse{ + TargetPrivate: privatestate.EmptyProviderData(ctx), + TargetState: tfsdk.State{ + Schema: req.TargetResourceSchema, + Raw: tftypes.NewValue(req.TargetResourceSchema.Type().TerraformType(ctx), nil), + }, + } + + if resourceStateMover.SourceSchema != nil { + logging.FrameworkTrace(ctx, "Attempting to populate MoveResourceStateRequest SourceState from provider defined SourceSchema") + + sourceSchemaType := resourceStateMover.SourceSchema.Type().TerraformType(ctx) + unmarshalOpts := tfprotov6.UnmarshalOpts{ + ValueFromJSONOpts: tftypes.ValueFromJSONOpts{ + // IgnoreUndefinedAttributes will silently skip over fields + // in the JSON that do not have a matching definition in the + // given schema. The purpose of this is to allow for + // additive changes to the source resource schema without + // breaking target resource state moves. It also enables + // simplified implementations, if certain source data is not + // needed anyways. + IgnoreUndefinedAttributes: true, + }, + } + + rawStateValue, err := req.SourceRawState.UnmarshalWithOpts(sourceSchemaType, unmarshalOpts) + + // Resources may support multiple source resources, so returning the + // error here as an error or warning diagnostic is not appropriate + // since both the developer and calling practitioner cannot avoid + // the situation. Instead, developers will still have a nil + // SourceState and they can investigate any error as logged here. + // + // It is also important to note that the error generally only occurs + // if the source schema declared incompatible types. The + // IgnoreUndefinedAttributes option above can cause the error to be + // nil and the SourceState to be populated with null values. It is + // always recommended for StateMover implementations to check the + // other request fields (SourceTypeName, SourceProviderAddress, + // etc.) instead of relying on SourceState to be populated or not. + if err != nil { + logging.FrameworkDebug( + ctx, + "Error unmarshalling SourceRawState using the provided SourceSchema for source "+ + req.SourceProviderAddress+" resource type "+ + req.SourceTypeName+" with schema version "+ + strconv.FormatInt(req.SourceSchemaVersion, 10)+". "+ + "This is not a fatal error since resources can support multiple source resources which cause this type of error to be unavoidable, "+ + "but due to this error the SourceState will not be populated for the implementation.", + map[string]any{ + logging.KeyError: err, + }, + ) + } else { + moveStateReq.SourceState = &tfsdk.State{ + Raw: rawStateValue, + Schema: *resourceStateMover.SourceSchema, + } + } + } + + logging.FrameworkTrace(ctx, "Calling provider defined Resource StateMover") + resourceStateMover.StateMover(ctx, moveStateReq, &moveStateResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource StateMover") + + resp.Diagnostics.Append(moveStateResp.Diagnostics...) + + // If the implementation has error diagnostics, return the diagnostics. + if moveStateResp.Diagnostics.HasError() { + resp.Diagnostics = moveStateResp.Diagnostics + + return + } + + // If the implement has set the state in any way, return the response. + if !moveStateResp.TargetState.Raw.Equal(tftypes.NewValue(req.TargetResourceSchema.Type().TerraformType(ctx), nil)) { + resp.Diagnostics = moveStateResp.Diagnostics + resp.TargetState = &moveStateResp.TargetState + + if moveStateResp.TargetPrivate != nil { + resp.TargetPrivate.Provider = moveStateResp.TargetPrivate + } + + return + } + } + + resp.Diagnostics.AddError( + "Unable to Move Resource State", + "The target resource implementation does not include support for the given source resource. "+ + "The resource implementation can be updated by the provider developers to include this support by returning the moved state when the request matches this source.\n\n"+ + "Source Provider Address: "+req.SourceProviderAddress+"\n"+ + "Source Resource Type: "+req.SourceTypeName+"\n"+ + "Source Resource Schema Version: "+strconv.FormatInt(req.SourceSchemaVersion, 10)+"\n"+ + "Target Resource Type: "+req.TargetTypeName, + ) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_planresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_planresourcechange.go new file mode 100644 index 00000000..f769eea3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_planresourcechange.go @@ -0,0 +1,470 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + "errors" + "fmt" + "sort" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// PlanResourceChangeRequest is the framework server request for the +// PlanResourceChange RPC. +type PlanResourceChangeRequest struct { + Config *tfsdk.Config + PriorPrivate *privatestate.Data + PriorState *tfsdk.State + ProposedNewState *tfsdk.Plan + ProviderMeta *tfsdk.Config + ResourceSchema fwschema.Schema + Resource resource.Resource +} + +// PlanResourceChangeResponse is the framework server response for the +// PlanResourceChange RPC. +type PlanResourceChangeResponse struct { + Diagnostics diag.Diagnostics + PlannedPrivate *privatestate.Data + PlannedState *tfsdk.State + RequiresReplace path.Paths +} + +// PlanResourceChange implements the framework server PlanResourceChange RPC. +func (s *Server) PlanResourceChange(ctx context.Context, req *PlanResourceChangeRequest, resp *PlanResourceChangeResponse) { + if req == nil { + return + } + + if resourceWithConfigure, ok := req.Resource.(resource.ResourceWithConfigure); ok { + logging.FrameworkTrace(ctx, "Resource implements ResourceWithConfigure") + + configureReq := resource.ConfigureRequest{ + ProviderData: s.ResourceConfigureData, + } + configureResp := resource.ConfigureResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Configure") + resourceWithConfigure.Configure(ctx, configureReq, &configureResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Configure") + + resp.Diagnostics.Append(configureResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + } + + nullTfValue := tftypes.NewValue(req.ResourceSchema.Type().TerraformType(ctx), nil) + + // Prevent potential panics by ensuring incoming Config/Plan/State are null + // instead of nil. + if req.Config == nil { + req.Config = &tfsdk.Config{ + Raw: nullTfValue, + Schema: req.ResourceSchema, + } + } + + if req.ProposedNewState == nil { + req.ProposedNewState = &tfsdk.Plan{ + Raw: nullTfValue, + Schema: req.ResourceSchema, + } + } + + if req.PriorState == nil { + req.PriorState = &tfsdk.State{ + Raw: nullTfValue, + Schema: req.ResourceSchema, + } + } + + // Ensure that resp.PlannedPrivate is never nil. + resp.PlannedPrivate = privatestate.EmptyData(ctx) + + if req.PriorPrivate != nil { + // Overwrite resp.PlannedPrivate with req.PriorPrivate providing + // it is not nil. + resp.PlannedPrivate = req.PriorPrivate + + // Ensure that resp.PlannedPrivate.Provider is never nil. + if resp.PlannedPrivate.Provider == nil { + resp.PlannedPrivate.Provider = privatestate.EmptyProviderData(ctx) + } + } + + resp.PlannedState = planToState(*req.ProposedNewState) + + // Set Defaults. + // + // If the planned state is not null (i.e., not a destroy operation) we traverse the schema, + // identifying any attributes which are null within the configuration, and if the attribute + // has a default value specified by the `Default` field on the attribute then the default + // value is assigned. + if !resp.PlannedState.Raw.IsNull() { + data := fwschemadata.Data{ + Description: fwschemadata.DataDescriptionState, + Schema: resp.PlannedState.Schema, + TerraformValue: resp.PlannedState.Raw, + } + + diags := data.TransformDefaults(ctx, req.Config.Raw) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.PlannedState.Raw = data.TerraformValue + } + + // After ensuring there are proposed changes, mark any computed attributes + // that are null in the config as unknown in the plan, so providers have + // the choice to update them. + // + // Later attribute and resource plan modifier passes can override the + // unknown with a known value using any plan modifiers. + // + // We only do this if there's a plan to modify; otherwise, it + // represents a resource being deleted and there's no point. + if !resp.PlannedState.Raw.IsNull() && !resp.PlannedState.Raw.Equal(req.PriorState.Raw) { + // Loop through top level attributes/blocks to individually emit logs + // for value changes. This is helpful for troubleshooting unexpected + // plan outputs and only needs to be done for resource update plans. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/627 + if !req.PriorState.Raw.IsNull() { + var allPaths, changedPaths path.Paths + + for attrName := range resp.PlannedState.Schema.GetAttributes() { + allPaths.Append(path.Root(attrName)) + } + + for blockName := range resp.PlannedState.Schema.GetBlocks() { + allPaths.Append(path.Root(blockName)) + } + + for _, p := range allPaths { + var plannedState, priorState attr.Value + + // This logging is best effort and any errors should not be + // returned to practitioners. + _ = resp.PlannedState.GetAttribute(ctx, p, &plannedState) + _ = req.PriorState.GetAttribute(ctx, p, &priorState) + + // Due to ignoring diagnostics, the value may not be populated. + // Prevent the panic and show the path as changed. + if plannedState == nil { + changedPaths.Append(p) + + continue + } + + if plannedState.Equal(priorState) { + continue + } + + changedPaths.Append(p) + } + + // Colocate these log entries to not intermix with GetAttribute logging + for _, p := range changedPaths { + logging.FrameworkDebug(ctx, + "Detected value change between proposed new state and prior state", + map[string]any{ + logging.KeyAttributePath: p.String(), + }, + ) + } + } + + logging.FrameworkDebug(ctx, "Marking Computed attributes with null configuration values as unknown (known after apply) in the plan to prevent potential Terraform errors") + + modifiedPlan, err := tftypes.Transform(resp.PlannedState.Raw, MarkComputedNilsAsUnknown(ctx, req.Config.Raw, req.ResourceSchema)) + + if err != nil { + resp.Diagnostics.AddError( + "Error modifying plan", + "There was an unexpected error updating the plan. This is always a problem with the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + + return + } + + if !resp.PlannedState.Raw.Equal(modifiedPlan) { + logging.FrameworkTrace(ctx, "At least one Computed null Config value was changed to unknown") + } + + resp.PlannedState.Raw = modifiedPlan + } + + // Execute any schema-based plan modifiers. This allows overwriting + // any unknown values. + // + // We only do this if there's a plan to modify; otherwise, it + // represents a resource being deleted and there's no point. + if !resp.PlannedState.Raw.IsNull() { + modifySchemaPlanReq := ModifySchemaPlanRequest{ + Config: *req.Config, + Plan: stateToPlan(*resp.PlannedState), + State: *req.PriorState, + Private: resp.PlannedPrivate.Provider, + } + + if req.ProviderMeta != nil { + modifySchemaPlanReq.ProviderMeta = *req.ProviderMeta + } + + modifySchemaPlanResp := ModifySchemaPlanResponse{ + Diagnostics: resp.Diagnostics, + Plan: modifySchemaPlanReq.Plan, + Private: modifySchemaPlanReq.Private, + } + + SchemaModifyPlan(ctx, req.ResourceSchema, modifySchemaPlanReq, &modifySchemaPlanResp) + + resp.Diagnostics = modifySchemaPlanResp.Diagnostics + resp.PlannedState = planToState(modifySchemaPlanResp.Plan) + resp.RequiresReplace = append(resp.RequiresReplace, modifySchemaPlanResp.RequiresReplace...) + resp.PlannedPrivate.Provider = modifySchemaPlanResp.Private + + if resp.Diagnostics.HasError() { + return + } + } + + // Execute any resource-level ModifyPlan method. This allows + // overwriting any unknown values. + // + // We do this regardless of whether the plan is null or not, because we + // want resources to be able to return diagnostics when planning to + // delete resources, e.g. to inform practitioners that the resource + // _can't_ be deleted in the API and will just be removed from + // Terraform's state + if resourceWithModifyPlan, ok := req.Resource.(resource.ResourceWithModifyPlan); ok { + logging.FrameworkTrace(ctx, "Resource implements ResourceWithModifyPlan") + + modifyPlanReq := resource.ModifyPlanRequest{ + Config: *req.Config, + Plan: stateToPlan(*resp.PlannedState), + State: *req.PriorState, + Private: resp.PlannedPrivate.Provider, + } + + if req.ProviderMeta != nil { + modifyPlanReq.ProviderMeta = *req.ProviderMeta + } + + modifyPlanResp := resource.ModifyPlanResponse{ + Diagnostics: resp.Diagnostics, + Plan: modifyPlanReq.Plan, + RequiresReplace: path.Paths{}, + Private: modifyPlanReq.Private, + } + + logging.FrameworkTrace(ctx, "Calling provider defined Resource ModifyPlan") + resourceWithModifyPlan.ModifyPlan(ctx, modifyPlanReq, &modifyPlanResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource ModifyPlan") + + resp.Diagnostics = modifyPlanResp.Diagnostics + resp.PlannedState = planToState(modifyPlanResp.Plan) + resp.RequiresReplace = append(resp.RequiresReplace, modifyPlanResp.RequiresReplace...) + resp.PlannedPrivate.Provider = modifyPlanResp.Private + } + + // Ensure deterministic RequiresReplace by sorting and deduplicating + resp.RequiresReplace = NormaliseRequiresReplace(ctx, resp.RequiresReplace) + + // If this was a destroy resource plan, ensure the plan remained null. + if req.ProposedNewState.Raw.IsNull() && !resp.PlannedState.Raw.IsNull() { + resp.Diagnostics.AddError( + "Unexpected Planned Resource State on Destroy", + "The Terraform Provider unexpectedly returned resource state data when the resource was planned for destruction. "+ + "This is always an issue in the Terraform Provider and should be reported to the provider developers.\n\n"+ + "Ensure all resource plan modifiers do not attempt to change resource plan data from being a null value if the request plan is a null value.", + ) + } +} + +func MarkComputedNilsAsUnknown(ctx context.Context, config tftypes.Value, resourceSchema fwschema.Schema) func(*tftypes.AttributePath, tftypes.Value) (tftypes.Value, error) { + return func(path *tftypes.AttributePath, val tftypes.Value) (tftypes.Value, error) { + ctx = logging.FrameworkWithAttributePath(ctx, path.String()) + + // we are only modifying attributes, not the entire resource + if len(path.Steps()) < 1 { + return val, nil + } + + attribute, err := resourceSchema.AttributeAtTerraformPath(ctx, path) + + if err != nil { + if errors.Is(err, fwschema.ErrPathInsideAtomicAttribute) { + // ignore attributes/elements inside schema.Attributes, they have no schema of their own + logging.FrameworkTrace(ctx, "attribute is a non-schema attribute, not marking unknown") + return val, nil + } + + if errors.Is(err, fwschema.ErrPathIsBlock) { + // ignore blocks, they do not have a computed field + logging.FrameworkTrace(ctx, "attribute is a block, not marking unknown") + return val, nil + } + + if errors.Is(err, fwschema.ErrPathInsideDynamicAttribute) { + // ignore attributes/elements inside schema.DynamicAttribute, they have no schema of their own + logging.FrameworkTrace(ctx, "attribute is inside of a dynamic attribute, not marking unknown") + return val, nil + } + + logging.FrameworkError(ctx, "couldn't find attribute in resource schema") + + return tftypes.Value{}, fmt.Errorf("couldn't find attribute in resource schema: %w", err) + } + + configValIface, _, err := tftypes.WalkAttributePath(config, path) + + if err != nil && err != tftypes.ErrInvalidStep { + logging.FrameworkError(ctx, + "Error walking attributes/block path during unknown marking", + map[string]any{ + logging.KeyError: err.Error(), + }, + ) + return val, fmt.Errorf("error walking attribute/block path during unknown marking: %w", err) + } + + configVal, ok := configValIface.(tftypes.Value) + if !ok { + return val, fmt.Errorf("unexpected type during unknown marking: %T", configValIface) + } + + if !configVal.IsNull() { + logging.FrameworkTrace(ctx, "Attribute/block not null in configuration, not marking unknown") + return val, nil + } + + if !attribute.IsComputed() { + logging.FrameworkTrace(ctx, "attribute is not computed in schema, not marking unknown") + + return val, nil + } + + switch a := attribute.(type) { + case fwschema.AttributeWithBoolDefaultValue: + if a.BoolDefaultValue() != nil { + return val, nil + } + case fwschema.AttributeWithFloat64DefaultValue: + if a.Float64DefaultValue() != nil { + return val, nil + } + case fwschema.AttributeWithInt64DefaultValue: + if a.Int64DefaultValue() != nil { + return val, nil + } + case fwschema.AttributeWithListDefaultValue: + if a.ListDefaultValue() != nil { + return val, nil + } + case fwschema.AttributeWithMapDefaultValue: + if a.MapDefaultValue() != nil { + return val, nil + } + case fwschema.AttributeWithNumberDefaultValue: + if a.NumberDefaultValue() != nil { + return val, nil + } + case fwschema.AttributeWithObjectDefaultValue: + if a.ObjectDefaultValue() != nil { + return val, nil + } + case fwschema.AttributeWithSetDefaultValue: + if a.SetDefaultValue() != nil { + return val, nil + } + case fwschema.AttributeWithStringDefaultValue: + if a.StringDefaultValue() != nil { + return val, nil + } + case fwschema.AttributeWithDynamicDefaultValue: + if a.DynamicDefaultValue() != nil { + return val, nil + } + } + + // Value type from planned state to create unknown with + newValueType := val.Type() + + // If the attribute is dynamic then we can't use the planned state value to create an unknown, as it may be a concrete type. + // This logic explicitly sets the unknown value type to dynamic so the type can be determined during apply. + _, isDynamic := attribute.GetType().(basetypes.DynamicTypable) + if isDynamic { + newValueType = tftypes.DynamicPseudoType + } + + logging.FrameworkDebug(ctx, "marking computed attribute that is null in the config as unknown") + + return tftypes.NewValue(newValueType, tftypes.UnknownValue), nil + } +} + +// NormaliseRequiresReplace sorts and deduplicates the slice of AttributePaths +// used in the RequiresReplace response field. +// Sorting is lexical based on the string representation of each AttributePath. +func NormaliseRequiresReplace(ctx context.Context, rs path.Paths) path.Paths { + if len(rs) < 2 { + return rs + } + + sort.Slice(rs, func(i, j int) bool { + return rs[i].String() < rs[j].String() + }) + + ret := make(path.Paths, len(rs)) + ret[0] = rs[0] + + // deduplicate + j := 1 + + for i := 1; i < len(rs); i++ { + if rs[i].Equal(ret[j-1]) { + logging.FrameworkDebug(ctx, "attribute found multiple times in RequiresReplace, removing duplicate", map[string]interface{}{logging.KeyAttributePath: rs[i]}) + continue + } + ret[j] = rs[i] + j++ + } + + return ret[:j] +} + +// planToState returns a *tfsdk.State with a copied value from a tfsdk.Plan. +func planToState(plan tfsdk.Plan) *tfsdk.State { + return &tfsdk.State{ + Raw: plan.Raw.Copy(), + Schema: plan.Schema, + } +} + +// stateToPlan returns a tfsdk.Plan with a copied value from a tfsdk.State. +func stateToPlan(state tfsdk.State) tfsdk.Plan { + return tfsdk.Plan{ + Raw: state.Raw.Copy(), + Schema: state.Schema, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_readdatasource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_readdatasource.go new file mode 100644 index 00000000..a95cd35d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_readdatasource.go @@ -0,0 +1,120 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ReadDataSourceRequest is the framework server request for the +// ReadDataSource RPC. +type ReadDataSourceRequest struct { + Config *tfsdk.Config + DataSourceSchema fwschema.Schema + DataSource datasource.DataSource + ProviderMeta *tfsdk.Config +} + +// ReadDataSourceResponse is the framework server response for the +// ReadDataSource RPC. +type ReadDataSourceResponse struct { + Diagnostics diag.Diagnostics + State *tfsdk.State +} + +// ReadDataSource implements the framework server ReadDataSource RPC. +func (s *Server) ReadDataSource(ctx context.Context, req *ReadDataSourceRequest, resp *ReadDataSourceResponse) { + if req == nil { + return + } + + if dataSourceWithConfigure, ok := req.DataSource.(datasource.DataSourceWithConfigure); ok { + logging.FrameworkTrace(ctx, "DataSource implements DataSourceWithConfigure") + + configureReq := datasource.ConfigureRequest{ + ProviderData: s.DataSourceConfigureData, + } + configureResp := datasource.ConfigureResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined DataSource Configure") + dataSourceWithConfigure.Configure(ctx, configureReq, &configureResp) + logging.FrameworkTrace(ctx, "Called provider defined DataSource Configure") + + resp.Diagnostics.Append(configureResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + } + + readReq := datasource.ReadRequest{ + Config: tfsdk.Config{ + Schema: req.DataSourceSchema, + }, + } + readResp := datasource.ReadResponse{ + State: tfsdk.State{ + Schema: req.DataSourceSchema, + }, + } + + if req.Config != nil { + readReq.Config = *req.Config + readResp.State.Raw = req.Config.Raw.Copy() + } + + if req.ProviderMeta != nil { + readReq.ProviderMeta = *req.ProviderMeta + } + + logging.FrameworkTrace(ctx, "Calling provider defined DataSource Read") + req.DataSource.Read(ctx, readReq, &readResp) + logging.FrameworkTrace(ctx, "Called provider defined DataSource Read") + + resp.Diagnostics = readResp.Diagnostics + resp.State = &readResp.State + + if resp.Diagnostics.HasError() { + return + } + + semanticEqualityReq := SchemaSemanticEqualityRequest{ + PriorData: fwschemadata.Data{ + Description: fwschemadata.DataDescriptionConfiguration, + Schema: req.Config.Schema, + TerraformValue: req.Config.Raw.Copy(), + }, + ProposedNewData: fwschemadata.Data{ + Description: fwschemadata.DataDescriptionState, + Schema: resp.State.Schema, + TerraformValue: resp.State.Raw.Copy(), + }, + } + semanticEqualityResp := &SchemaSemanticEqualityResponse{ + NewData: semanticEqualityReq.ProposedNewData, + } + + SchemaSemanticEquality(ctx, semanticEqualityReq, semanticEqualityResp) + + resp.Diagnostics.Append(semanticEqualityResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + if semanticEqualityResp.NewData.TerraformValue.Equal(resp.State.Raw) { + return + } + + logging.FrameworkDebug(ctx, "State updated due to semantic equality") + + resp.State.Raw = semanticEqualityResp.NewData.TerraformValue +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_readresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_readresource.go new file mode 100644 index 00000000..172a4800 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_readresource.go @@ -0,0 +1,150 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ReadResourceRequest is the framework server request for the +// ReadResource RPC. +type ReadResourceRequest struct { + CurrentState *tfsdk.State + Resource resource.Resource + Private *privatestate.Data + ProviderMeta *tfsdk.Config +} + +// ReadResourceResponse is the framework server response for the +// ReadResource RPC. +type ReadResourceResponse struct { + Diagnostics diag.Diagnostics + NewState *tfsdk.State + Private *privatestate.Data +} + +// ReadResource implements the framework server ReadResource RPC. +func (s *Server) ReadResource(ctx context.Context, req *ReadResourceRequest, resp *ReadResourceResponse) { + if req == nil { + return + } + + if req.CurrentState == nil { + resp.Diagnostics.AddError( + "Unexpected Read Request", + "An unexpected error was encountered when reading the resource. The current state was missing.\n\n"+ + "This is always a problem with Terraform or terraform-plugin-framework. Please report this to the provider developer.", + ) + + return + } + + if resourceWithConfigure, ok := req.Resource.(resource.ResourceWithConfigure); ok { + logging.FrameworkTrace(ctx, "Resource implements ResourceWithConfigure") + + configureReq := resource.ConfigureRequest{ + ProviderData: s.ResourceConfigureData, + } + configureResp := resource.ConfigureResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Configure") + resourceWithConfigure.Configure(ctx, configureReq, &configureResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Configure") + + resp.Diagnostics.Append(configureResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + } + + readReq := resource.ReadRequest{ + State: tfsdk.State{ + Schema: req.CurrentState.Schema, + Raw: req.CurrentState.Raw.Copy(), + }, + } + readResp := resource.ReadResponse{ + State: tfsdk.State{ + Schema: req.CurrentState.Schema, + Raw: req.CurrentState.Raw.Copy(), + }, + } + + if req.ProviderMeta != nil { + readReq.ProviderMeta = *req.ProviderMeta + } + + privateProviderData := privatestate.EmptyProviderData(ctx) + + readReq.Private = privateProviderData + readResp.Private = privateProviderData + + if req.Private != nil { + if req.Private.Provider != nil { + readReq.Private = req.Private.Provider + readResp.Private = req.Private.Provider + } + + resp.Private = req.Private + } + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Read") + req.Resource.Read(ctx, readReq, &readResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Read") + + resp.Diagnostics = readResp.Diagnostics + resp.NewState = &readResp.State + + if readResp.Private != nil { + if resp.Private == nil { + resp.Private = &privatestate.Data{} + } + + resp.Private.Provider = readResp.Private + } + + if resp.Diagnostics.HasError() { + return + } + + semanticEqualityReq := SchemaSemanticEqualityRequest{ + PriorData: fwschemadata.Data{ + Description: fwschemadata.DataDescriptionState, + Schema: req.CurrentState.Schema, + TerraformValue: req.CurrentState.Raw.Copy(), + }, + ProposedNewData: fwschemadata.Data{ + Description: fwschemadata.DataDescriptionState, + Schema: resp.NewState.Schema, + TerraformValue: resp.NewState.Raw.Copy(), + }, + } + semanticEqualityResp := &SchemaSemanticEqualityResponse{ + NewData: semanticEqualityReq.ProposedNewData, + } + + SchemaSemanticEquality(ctx, semanticEqualityReq, semanticEqualityResp) + + resp.Diagnostics.Append(semanticEqualityResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + if semanticEqualityResp.NewData.TerraformValue.Equal(resp.NewState.Raw) { + return + } + + logging.FrameworkDebug(ctx, "State updated due to semantic equality") + + resp.NewState.Raw = semanticEqualityResp.NewData.TerraformValue +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_updateresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_updateresource.go new file mode 100644 index 00000000..9112c35c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_updateresource.go @@ -0,0 +1,179 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// UpdateResourceRequest is the framework server request for an update request +// with the ApplyResourceChange RPC. +type UpdateResourceRequest struct { + Config *tfsdk.Config + PlannedPrivate *privatestate.Data + PlannedState *tfsdk.Plan + PriorState *tfsdk.State + ProviderMeta *tfsdk.Config + ResourceSchema fwschema.Schema + Resource resource.Resource +} + +// UpdateResourceResponse is the framework server response for an update request +// with the ApplyResourceChange RPC. +type UpdateResourceResponse struct { + Diagnostics diag.Diagnostics + NewState *tfsdk.State + Private *privatestate.Data +} + +// UpdateResource implements the framework server update request logic for the +// ApplyResourceChange RPC. +func (s *Server) UpdateResource(ctx context.Context, req *UpdateResourceRequest, resp *UpdateResourceResponse) { + if req == nil { + return + } + + if resourceWithConfigure, ok := req.Resource.(resource.ResourceWithConfigure); ok { + logging.FrameworkTrace(ctx, "Resource implements ResourceWithConfigure") + + configureReq := resource.ConfigureRequest{ + ProviderData: s.ResourceConfigureData, + } + configureResp := resource.ConfigureResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Configure") + resourceWithConfigure.Configure(ctx, configureReq, &configureResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Configure") + + resp.Diagnostics.Append(configureResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + } + + nullSchemaData := tftypes.NewValue(req.ResourceSchema.Type().TerraformType(ctx), nil) + + updateReq := resource.UpdateRequest{ + Config: tfsdk.Config{ + Schema: req.ResourceSchema, + Raw: nullSchemaData, + }, + Plan: tfsdk.Plan{ + Schema: req.ResourceSchema, + Raw: nullSchemaData, + }, + State: tfsdk.State{ + Schema: req.ResourceSchema, + Raw: nullSchemaData, + }, + } + updateResp := resource.UpdateResponse{ + State: tfsdk.State{ + Schema: req.ResourceSchema, + Raw: nullSchemaData, + }, + } + + if req.Config != nil { + updateReq.Config = *req.Config + } + + if req.PlannedState != nil { + updateReq.Plan = *req.PlannedState + } + + if req.PriorState != nil { + updateReq.State = *req.PriorState + // Require explicit provider updates for tracking successful updates. + updateResp.State = *req.PriorState + } + + if req.ProviderMeta != nil { + updateReq.ProviderMeta = *req.ProviderMeta + } + + privateProviderData := privatestate.EmptyProviderData(ctx) + + updateReq.Private = privateProviderData + updateResp.Private = privateProviderData + + if req.PlannedPrivate != nil { + if req.PlannedPrivate.Provider != nil { + updateReq.Private = req.PlannedPrivate.Provider + updateResp.Private = req.PlannedPrivate.Provider + } + + resp.Private = req.PlannedPrivate + } + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Update") + req.Resource.Update(ctx, updateReq, &updateResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Update") + + resp.Diagnostics = updateResp.Diagnostics + resp.NewState = &updateResp.State + + if !resp.Diagnostics.HasError() && updateResp.State.Raw.Equal(nullSchemaData) { + resp.Diagnostics.AddError( + "Missing Resource State After Update", + "The Terraform Provider unexpectedly returned no resource state after having no errors in the resource update. "+ + "This is always an issue in the Terraform Provider and should be reported to the provider developers.", + ) + } + + if updateResp.Private != nil { + if resp.Private == nil { + resp.Private = &privatestate.Data{} + } + + resp.Private.Provider = updateResp.Private + } + + if resp.Diagnostics.HasError() { + return + } + + semanticEqualityReq := SchemaSemanticEqualityRequest{ + PriorData: fwschemadata.Data{ + Description: fwschemadata.DataDescriptionPlan, + Schema: req.PlannedState.Schema, + TerraformValue: req.PlannedState.Raw.Copy(), + }, + ProposedNewData: fwschemadata.Data{ + Description: fwschemadata.DataDescriptionState, + Schema: resp.NewState.Schema, + TerraformValue: resp.NewState.Raw.Copy(), + }, + } + semanticEqualityResp := &SchemaSemanticEqualityResponse{ + NewData: semanticEqualityReq.ProposedNewData, + } + + SchemaSemanticEquality(ctx, semanticEqualityReq, semanticEqualityResp) + + resp.Diagnostics.Append(semanticEqualityResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + if semanticEqualityResp.NewData.TerraformValue.Equal(resp.NewState.Raw) { + return + } + + logging.FrameworkDebug(ctx, "State updated due to semantic equality") + + resp.NewState.Raw = semanticEqualityResp.NewData.TerraformValue +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_upgraderesourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_upgraderesourcestate.go new file mode 100644 index 00000000..b2cc340e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_upgraderesourcestate.go @@ -0,0 +1,247 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// UpgradeResourceStateRequest is the framework server request for the +// UpgradeResourceState RPC. +type UpgradeResourceStateRequest struct { + // Using the tfprotov6 type here was a pragmatic effort decision around when + // the framework introduced compatibility promises. This type was chosen as + // it was readily available and trivial to convert between tfprotov5. + // + // Using a terraform-plugin-go type is not ideal for the framework as almost + // all terraform-plugin-go types have framework abstractions, but if there + // is ever a time where it makes sense to re-evaluate this decision, such as + // a major version bump, it could be changed then. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/340 + RawState *tfprotov6.RawState + + ResourceSchema fwschema.Schema + Resource resource.Resource + Version int64 +} + +// UpgradeResourceStateResponse is the framework server response for the +// UpgradeResourceState RPC. +type UpgradeResourceStateResponse struct { + Diagnostics diag.Diagnostics + UpgradedState *tfsdk.State +} + +// UpgradeResourceState implements the framework server UpgradeResourceState RPC. +func (s *Server) UpgradeResourceState(ctx context.Context, req *UpgradeResourceStateRequest, resp *UpgradeResourceStateResponse) { + if req == nil { + return + } + + // No UpgradedState to return. This could return an error diagnostic about + // the odd scenario, but seems best to allow Terraform CLI to handle the + // situation itself in case it might be expected behavior. + if req.RawState == nil { + return + } + + // Define options to be used when unmarshalling raw state. + // IgnoreUndefinedAttributes will silently skip over fields in the JSON + // that do not have a matching entry in the schema. + unmarshalOpts := tfprotov6.UnmarshalOpts{ + ValueFromJSONOpts: tftypes.ValueFromJSONOpts{ + IgnoreUndefinedAttributes: true, + }, + } + + // Terraform CLI can call UpgradeResourceState even if the stored state + // version matches the current schema. Presumably this is to account for + // the previous terraform-plugin-sdk implementation, which handled some + // state fixups on behalf of Terraform CLI. When this happens, we do not + // want to return errors for a missing ResourceWithUpgradeState + // implementation or an undefined version within an existing + // ResourceWithUpgradeState implementation as that would be confusing + // detail for provider developers. Instead, the framework will attempt to + // roundtrip the prior RawState to a State matching the current Schema. + // + // TODO: To prevent provider developers from accidentally implementing + // ResourceWithUpgradeState with a version matching the current schema + // version which would never get called, the framework can introduce a + // unit test helper. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/113 + // + // UnmarshalWithOpts allows optionally ignoring instances in which elements being + // do not have a corresponding attribute within the schema. + if req.Version == req.ResourceSchema.GetVersion() { + logging.FrameworkTrace(ctx, "UpgradeResourceState request version matches current Schema version, using framework defined passthrough implementation") + + resourceSchemaType := req.ResourceSchema.Type().TerraformType(ctx) + + rawStateValue, err := req.RawState.UnmarshalWithOpts(resourceSchemaType, unmarshalOpts) + + if err != nil { + resp.Diagnostics.AddError( + "Unable to Read Previously Saved State for UpgradeResourceState", + "There was an error reading the saved resource state using the current resource schema.\n\n"+ + "If this resource state was last refreshed with Terraform CLI 0.11 and earlier, it must be refreshed or applied with an older provider version first. "+ + "If you manually modified the resource state, you will need to manually modify it to match the current resource schema. "+ + "Otherwise, please report this to the provider developer:\n\n"+err.Error(), + ) + return + } + + resp.UpgradedState = &tfsdk.State{ + Schema: req.ResourceSchema, + Raw: rawStateValue, + } + + return + } + + if resourceWithConfigure, ok := req.Resource.(resource.ResourceWithConfigure); ok { + logging.FrameworkTrace(ctx, "Resource implements ResourceWithConfigure") + + configureReq := resource.ConfigureRequest{ + ProviderData: s.ResourceConfigureData, + } + configureResp := resource.ConfigureResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Configure") + resourceWithConfigure.Configure(ctx, configureReq, &configureResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Configure") + + resp.Diagnostics.Append(configureResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + } + + resourceWithUpgradeState, ok := req.Resource.(resource.ResourceWithUpgradeState) + + if !ok { + resp.Diagnostics.AddError( + "Unable to Upgrade Resource State", + "This resource was implemented without an UpgradeState() method, "+ + fmt.Sprintf("however Terraform was expecting an implementation for version %d upgrade.\n\n", req.Version)+ + "This is always an issue with the Terraform Provider and should be reported to the provider developer.", + ) + return + } + + logging.FrameworkTrace(ctx, "Resource implements ResourceWithUpgradeState") + + logging.FrameworkTrace(ctx, "Calling provider defined Resource UpgradeState") + resourceStateUpgraders := resourceWithUpgradeState.UpgradeState(ctx) + logging.FrameworkTrace(ctx, "Called provider defined Resource UpgradeState") + + // Panic prevention + if resourceStateUpgraders == nil { + resourceStateUpgraders = make(map[int64]resource.StateUpgrader, 0) + } + + resourceStateUpgrader, ok := resourceStateUpgraders[req.Version] + + if !ok { + resp.Diagnostics.AddError( + "Unable to Upgrade Resource State", + "This resource was implemented with an UpgradeState() method, "+ + fmt.Sprintf("however Terraform was expecting an implementation for version %d upgrade.\n\n", req.Version)+ + "This is always an issue with the Terraform Provider and should be reported to the provider developer.", + ) + return + } + + upgradeResourceStateRequest := resource.UpgradeStateRequest{ + RawState: req.RawState, + } + + if resourceStateUpgrader.PriorSchema != nil { + logging.FrameworkTrace(ctx, "Initializing populated UpgradeResourceStateRequest state from provider defined prior schema and request RawState") + + priorSchemaType := resourceStateUpgrader.PriorSchema.Type().TerraformType(ctx) + + rawStateValue, err := req.RawState.UnmarshalWithOpts(priorSchemaType, unmarshalOpts) + + if err != nil { + resp.Diagnostics.AddError( + "Unable to Read Previously Saved State for UpgradeResourceState", + fmt.Sprintf("There was an error reading the saved resource state using the prior resource schema defined for version %d upgrade.\n\n", req.Version)+ + "Please report this to the provider developer:\n\n"+err.Error(), + ) + return + } + + upgradeResourceStateRequest.State = &tfsdk.State{ + Raw: rawStateValue, + Schema: *resourceStateUpgrader.PriorSchema, + } + } + + upgradeResourceStateResponse := resource.UpgradeStateResponse{ + State: tfsdk.State{ + Schema: req.ResourceSchema, + // Raw is intentionally not set. + }, + } + + // To simplify provider logic, this could perform a best effort attempt + // to populate the response State by looping through all Attribute/Block + // by calling the equivalent of SetAttribute(GetAttribute()) and skipping + // any errors. + + logging.FrameworkTrace(ctx, "Calling provider defined StateUpgrader") + resourceStateUpgrader.StateUpgrader(ctx, upgradeResourceStateRequest, &upgradeResourceStateResponse) + logging.FrameworkTrace(ctx, "Called provider defined StateUpgrader") + + resp.Diagnostics.Append(upgradeResourceStateResponse.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + + if upgradeResourceStateResponse.DynamicValue != nil { + logging.FrameworkTrace(ctx, "UpgradeResourceStateResponse DynamicValue set, overriding State") + + upgradedStateValue, err := upgradeResourceStateResponse.DynamicValue.Unmarshal(req.ResourceSchema.Type().TerraformType(ctx)) + + if err != nil { + resp.Diagnostics.AddError( + "Unable to Upgrade Resource State", + fmt.Sprintf("After attempting a resource state upgrade to version %d, the provider returned state data that was not compatible with the current schema.\n\n", req.Version)+ + "This is always an issue with the Terraform Provider and should be reported to the provider developer:\n\n"+err.Error(), + ) + return + } + + resp.UpgradedState = &tfsdk.State{ + Schema: req.ResourceSchema, + Raw: upgradedStateValue, + } + + return + } + + if upgradeResourceStateResponse.State.Raw.Type() == nil || upgradeResourceStateResponse.State.Raw.IsNull() { + resp.Diagnostics.AddError( + "Missing Upgraded Resource State", + fmt.Sprintf("After attempting a resource state upgrade to version %d, the provider did not return any state data. ", req.Version)+ + "Preventing the unexpected loss of resource state data. "+ + "This is always an issue with the Terraform Provider and should be reported to the provider developer.", + ) + return + } + + resp.UpgradedState = &upgradeResourceStateResponse.State +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validatedatasourceconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validatedatasourceconfig.go new file mode 100644 index 00000000..3379b15a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validatedatasourceconfig.go @@ -0,0 +1,109 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ValidateDataSourceConfigRequest is the framework server request for the +// ValidateDataSourceConfig RPC. +type ValidateDataSourceConfigRequest struct { + Config *tfsdk.Config + DataSource datasource.DataSource +} + +// ValidateDataSourceConfigResponse is the framework server response for the +// ValidateDataSourceConfig RPC. +type ValidateDataSourceConfigResponse struct { + Diagnostics diag.Diagnostics +} + +// ValidateDataSourceConfig implements the framework server ValidateDataSourceConfig RPC. +func (s *Server) ValidateDataSourceConfig(ctx context.Context, req *ValidateDataSourceConfigRequest, resp *ValidateDataSourceConfigResponse) { + if req == nil || req.Config == nil { + return + } + + if dataSourceWithConfigure, ok := req.DataSource.(datasource.DataSourceWithConfigure); ok { + logging.FrameworkTrace(ctx, "DataSource implements DataSourceWithConfigure") + + configureReq := datasource.ConfigureRequest{ + ProviderData: s.DataSourceConfigureData, + } + configureResp := datasource.ConfigureResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined DataSource Configure") + dataSourceWithConfigure.Configure(ctx, configureReq, &configureResp) + logging.FrameworkTrace(ctx, "Called provider defined DataSource Configure") + + resp.Diagnostics.Append(configureResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + } + + vdscReq := datasource.ValidateConfigRequest{ + Config: *req.Config, + } + + if dataSource, ok := req.DataSource.(datasource.DataSourceWithConfigValidators); ok { + logging.FrameworkTrace(ctx, "DataSource implements DataSourceWithConfigValidators") + + for _, configValidator := range dataSource.ConfigValidators(ctx) { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + vdscResp := &datasource.ValidateConfigResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined ConfigValidator", + map[string]interface{}{ + logging.KeyDescription: configValidator.Description(ctx), + }, + ) + configValidator.ValidateDataSource(ctx, vdscReq, vdscResp) + logging.FrameworkTrace( + ctx, + "Called provider defined ConfigValidator", + map[string]interface{}{ + logging.KeyDescription: configValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(vdscResp.Diagnostics...) + } + } + + if dataSource, ok := req.DataSource.(datasource.DataSourceWithValidateConfig); ok { + logging.FrameworkTrace(ctx, "DataSource implements DataSourceWithValidateConfig") + + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + vdscResp := &datasource.ValidateConfigResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined DataSource ValidateConfig") + dataSource.ValidateConfig(ctx, vdscReq, vdscResp) + logging.FrameworkTrace(ctx, "Called provider defined DataSource ValidateConfig") + + resp.Diagnostics.Append(vdscResp.Diagnostics...) + } + + validateSchemaReq := ValidateSchemaRequest{ + Config: *req.Config, + } + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateSchemaResp := ValidateSchemaResponse{} + + SchemaValidate(ctx, req.Config.Schema, validateSchemaReq, &validateSchemaResp) + + resp.Diagnostics.Append(validateSchemaResp.Diagnostics...) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validateproviderconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validateproviderconfig.go new file mode 100644 index 00000000..588f021c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validateproviderconfig.go @@ -0,0 +1,100 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ValidateProviderConfigRequest is the framework server request for the +// ValidateProviderConfig RPC. +type ValidateProviderConfigRequest struct { + Config *tfsdk.Config +} + +// ValidateProviderConfigResponse is the framework server response for the +// ValidateProviderConfig RPC. +type ValidateProviderConfigResponse struct { + PreparedConfig *tfsdk.Config + Diagnostics diag.Diagnostics +} + +// ValidateProviderConfig implements the framework server ValidateProviderConfig RPC. +func (s *Server) ValidateProviderConfig(ctx context.Context, req *ValidateProviderConfigRequest, resp *ValidateProviderConfigResponse) { + if req == nil || req.Config == nil { + return + } + + vpcReq := provider.ValidateConfigRequest{ + Config: *req.Config, + } + + if providerWithConfigValidators, ok := s.Provider.(provider.ProviderWithConfigValidators); ok { + logging.FrameworkTrace(ctx, "Provider implements ProviderWithConfigValidators") + + for _, configValidator := range providerWithConfigValidators.ConfigValidators(ctx) { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + vpcRes := &provider.ValidateConfigResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined ConfigValidator", + map[string]interface{}{ + logging.KeyDescription: configValidator.Description(ctx), + }, + ) + configValidator.ValidateProvider(ctx, vpcReq, vpcRes) + logging.FrameworkTrace( + ctx, + "Called provider defined ConfigValidator", + map[string]interface{}{ + logging.KeyDescription: configValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(vpcRes.Diagnostics...) + } + } + + if providerWithValidateConfig, ok := s.Provider.(provider.ProviderWithValidateConfig); ok { + logging.FrameworkTrace(ctx, "Provider implements ProviderWithValidateConfig") + + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + vpcRes := &provider.ValidateConfigResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Provider ValidateConfig") + providerWithValidateConfig.ValidateConfig(ctx, vpcReq, vpcRes) + logging.FrameworkTrace(ctx, "Called provider defined Provider ValidateConfig") + + resp.Diagnostics.Append(vpcRes.Diagnostics...) + } + + validateSchemaReq := ValidateSchemaRequest{ + Config: *req.Config, + } + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateSchemaResp := ValidateSchemaResponse{} + + SchemaValidate(ctx, req.Config.Schema, validateSchemaReq, &validateSchemaResp) + + resp.Diagnostics.Append(validateSchemaResp.Diagnostics...) + + // This RPC allows a modified configuration to be returned. This was + // previously used to allow a "required" provider attribute (as defined + // by a schema) to still be "optional" with a default value, typically + // through an environment variable. Other tooling based on the provider + // schema information could not determine this implementation detail. + // To ensure accuracy going forward, this implementation is opinionated + // towards accurate provider schema definitions and optional values + // can be filled in or return errors during ConfigureProvider(). + resp.PreparedConfig = req.Config +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validateresourceconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validateresourceconfig.go new file mode 100644 index 00000000..79e8ae9b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwserver/server_validateresourceconfig.go @@ -0,0 +1,109 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ValidateResourceConfigRequest is the framework server request for the +// ValidateResourceConfig RPC. +type ValidateResourceConfigRequest struct { + Config *tfsdk.Config + Resource resource.Resource +} + +// ValidateResourceConfigResponse is the framework server response for the +// ValidateResourceConfig RPC. +type ValidateResourceConfigResponse struct { + Diagnostics diag.Diagnostics +} + +// ValidateResourceConfig implements the framework server ValidateResourceConfig RPC. +func (s *Server) ValidateResourceConfig(ctx context.Context, req *ValidateResourceConfigRequest, resp *ValidateResourceConfigResponse) { + if req == nil || req.Config == nil { + return + } + + if resourceWithConfigure, ok := req.Resource.(resource.ResourceWithConfigure); ok { + logging.FrameworkTrace(ctx, "Resource implements ResourceWithConfigure") + + configureReq := resource.ConfigureRequest{ + ProviderData: s.ResourceConfigureData, + } + configureResp := resource.ConfigureResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource Configure") + resourceWithConfigure.Configure(ctx, configureReq, &configureResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource Configure") + + resp.Diagnostics.Append(configureResp.Diagnostics...) + + if resp.Diagnostics.HasError() { + return + } + } + + vdscReq := resource.ValidateConfigRequest{ + Config: *req.Config, + } + + if resourceWithConfigValidators, ok := req.Resource.(resource.ResourceWithConfigValidators); ok { + logging.FrameworkTrace(ctx, "Resource implements ResourceWithConfigValidators") + + for _, configValidator := range resourceWithConfigValidators.ConfigValidators(ctx) { + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + vdscResp := &resource.ValidateConfigResponse{} + + logging.FrameworkTrace( + ctx, + "Calling provider defined ResourceConfigValidator", + map[string]interface{}{ + logging.KeyDescription: configValidator.Description(ctx), + }, + ) + configValidator.ValidateResource(ctx, vdscReq, vdscResp) + logging.FrameworkTrace( + ctx, + "Called provider defined ResourceConfigValidator", + map[string]interface{}{ + logging.KeyDescription: configValidator.Description(ctx), + }, + ) + + resp.Diagnostics.Append(vdscResp.Diagnostics...) + } + } + + if resourceWithValidateConfig, ok := req.Resource.(resource.ResourceWithValidateConfig); ok { + logging.FrameworkTrace(ctx, "Resource implements ResourceWithValidateConfig") + + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + vdscResp := &resource.ValidateConfigResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource ValidateConfig") + resourceWithValidateConfig.ValidateConfig(ctx, vdscReq, vdscResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource ValidateConfig") + + resp.Diagnostics.Append(vdscResp.Diagnostics...) + } + + validateSchemaReq := ValidateSchemaRequest{ + Config: *req.Config, + } + // Instantiate a new response for each request to prevent validators + // from modifying or removing diagnostics. + validateSchemaResp := ValidateSchemaResponse{} + + SchemaValidate(ctx, req.Config.Schema, validateSchemaReq, &validateSchemaResp) + + resp.Diagnostics.Append(validateSchemaResp.Diagnostics...) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwtype/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwtype/doc.go new file mode 100644 index 00000000..3cd75b75 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwtype/doc.go @@ -0,0 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package fwtype implements shared logic for interacting with the framework type system. +package fwtype diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwtype/static_collection_validation.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwtype/static_collection_validation.go new file mode 100644 index 00000000..2a91e2fb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/fwtype/static_collection_validation.go @@ -0,0 +1,142 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwtype + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ContainsCollectionWithDynamic will return true if an attr.Type is a complex type that either is or contains any +// collection types with dynamic types, which are not supported by the framework type system. Primitives, invalid +// types (missingType), or nil will return false. +// +// Unsupported collection types include: +// - Lists that contain a dynamic type +// - Maps that contain a dynamic type +// - Sets that contain a dynamic type +func ContainsCollectionWithDynamic(typ attr.Type) bool { + switch attrType := typ.(type) { + // We haven't run into a collection type yet, so it's valid for this to be a dynamic type + case basetypes.DynamicTypable: + return false + // Lists, maps, sets + case attr.TypeWithElementType: + // We found a collection, need to ensure there are no dynamics from this point on. + return containsDynamic(attrType.ElementType()) + // Tuples + case attr.TypeWithElementTypes: + for _, elemType := range attrType.ElementTypes() { + hasDynamic := ContainsCollectionWithDynamic(elemType) + if hasDynamic { + return true + } + } + return false + // Objects + case attr.TypeWithAttributeTypes: + for _, objAttrType := range attrType.AttributeTypes() { + hasDynamic := ContainsCollectionWithDynamic(objAttrType) + if hasDynamic { + return true + } + } + return false + // Primitives, missing types, etc. + default: + return false + } +} + +// containsDynamic will return true if `typ` is a dynamic type or has any nested types that contain a dynamic type. +func containsDynamic(typ attr.Type) bool { + switch attrType := typ.(type) { + // Found a dynamic! + case basetypes.DynamicTypable: + return true + // Lists, maps, sets + case attr.TypeWithElementType: + return containsDynamic(attrType.ElementType()) + // Tuples + case attr.TypeWithElementTypes: + for _, elemType := range attrType.ElementTypes() { + hasDynamic := containsDynamic(elemType) + if hasDynamic { + return true + } + } + return false + // Objects + case attr.TypeWithAttributeTypes: + for _, objAttrType := range attrType.AttributeTypes() { + hasDynamic := containsDynamic(objAttrType) + if hasDynamic { + return true + } + } + return false + // Primitives, missing types, etc. + default: + return false + } +} + +func AttributeCollectionWithDynamicTypeDiag(attributePath path.Path) diag.Diagnostic { + return diag.NewErrorDiagnostic( + "Invalid Schema Implementation", + "When validating the schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("%q is an attribute that contains a collection type with a nested dynamic type.\n\n", attributePath)+ + "Dynamic types inside of collections are not currently supported in terraform-plugin-framework. "+ + fmt.Sprintf("If underlying dynamic values are required, replace the %q attribute definition with DynamicAttribute instead.", attributePath), + ) +} + +func BlockCollectionWithDynamicTypeDiag(attributePath path.Path) diag.Diagnostic { + return diag.NewErrorDiagnostic( + "Invalid Schema Implementation", + "When validating the schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("%q is a block that contains a collection type with a nested dynamic type.\n\n", attributePath)+ + "Dynamic types inside of collections are not currently supported in terraform-plugin-framework. "+ + fmt.Sprintf("If underlying dynamic values are required, replace the %q block definition with a DynamicAttribute.", attributePath), + ) +} + +func ParameterCollectionWithDynamicTypeDiag(argument int64, name string) diag.Diagnostic { + return diag.NewErrorDiagnostic( + "Invalid Function Definition", + "When validating the function definition, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Parameter %q at position %d contains a collection type with a nested dynamic type.\n\n", name, argument)+ + "Dynamic types inside of collections are not currently supported in terraform-plugin-framework. "+ + fmt.Sprintf("If underlying dynamic values are required, replace the %q parameter definition with DynamicParameter instead.", name), + ) +} + +func VariadicParameterCollectionWithDynamicTypeDiag(name string) diag.Diagnostic { + return diag.NewErrorDiagnostic( + "Invalid Function Definition", + "When validating the function definition, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Variadic parameter %q contains a collection type with a nested dynamic type.\n\n", name)+ + "Dynamic types inside of collections are not currently supported in terraform-plugin-framework. "+ + "If underlying dynamic values are required, replace the variadic parameter definition with DynamicParameter instead.", + ) +} + +func ReturnCollectionWithDynamicTypeDiag() diag.Diagnostic { + return diag.NewErrorDiagnostic( + "Invalid Function Definition", + "When validating the function definition, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + "Return contains a collection type with a nested dynamic type.\n\n"+ + "Dynamic types inside of collections are not currently supported in terraform-plugin-framework. "+ + "If underlying dynamic values are required, replace the return definition with DynamicReturn instead.", + ) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/context.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/context.go new file mode 100644 index 00000000..50828ef3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/context.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package logging + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-log/tfsdklog" +) + +// InitContext creates SDK logger contexts. The incoming context will +// already have the root SDK logger and root provider logger setup from +// terraform-plugin-go tf6server RPC handlers. +func InitContext(ctx context.Context) context.Context { + ctx = tfsdklog.NewSubsystem(ctx, SubsystemFramework, + // All calls are through the Framework* helper functions + tfsdklog.WithAdditionalLocationOffset(1), + tfsdklog.WithLevelFromEnv(EnvTfLogSdkFramework), + // Propagate tf_req_id, tf_rpc, etc. fields + tfsdklog.WithRootFields(), + ) + + return ctx +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/doc.go new file mode 100644 index 00000000..ff80b85e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package logging contains framework internal helpers for consistent logger +// and log entry handling. +package logging diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/environment_variables.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/environment_variables.go new file mode 100644 index 00000000..35d41ada --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/environment_variables.go @@ -0,0 +1,12 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package logging + +// Environment variables. +const ( + // EnvTfLogSdkFramework is an environment variable that sets the logging + // level of SDK framework loggers. Infers root SDK logging level, if + // unset. + EnvTfLogSdkFramework = "TF_LOG_SDK_FRAMEWORK" +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/framework.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/framework.go new file mode 100644 index 00000000..deeeee07 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/framework.go @@ -0,0 +1,43 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package logging + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-log/tfsdklog" +) + +const ( + // SubsystemFramework is the tfsdklog subsystem name for framework. + SubsystemFramework = "framework" +) + +// FrameworkDebug emits a framework subsystem log at DEBUG level. +func FrameworkDebug(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemDebug(ctx, SubsystemFramework, msg, additionalFields...) +} + +// FrameworkError emits a framework subsystem log at ERROR level. +func FrameworkError(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemError(ctx, SubsystemFramework, msg, additionalFields...) +} + +// FrameworkTrace emits a framework subsystem log at TRACE level. +func FrameworkTrace(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemTrace(ctx, SubsystemFramework, msg, additionalFields...) +} + +// FrameworkWarn emits a framework subsystem log at WARN level. +func FrameworkWarn(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemWarn(ctx, SubsystemFramework, msg, additionalFields...) +} + +// FrameworkWithAttributePath returns a new Context with KeyAttributePath set. +// The attribute path is expected to be string, so the logging package does not +// need to import path handling code. +func FrameworkWithAttributePath(ctx context.Context, attributePath string) context.Context { + ctx = tfsdklog.SubsystemSetField(ctx, SubsystemFramework, KeyAttributePath, attributePath) + return ctx +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/keys.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/keys.go new file mode 100644 index 00000000..7c68d0f1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/logging/keys.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package logging + +// Structured logging keys. +// +// Practitioners or tooling reading logs may be depending on these keys, so be +// conscious of that when changing them. +// +// Refer to the terraform-plugin-go logging keys as well, which should be +// equivalent to these when possible. +const ( + // Attribute path representation, which is typically in flatmap form such + // as parent.0.child in this project. + KeyAttributePath = "tf_attribute_path" + + // The type of data source being operated on, such as "archive_file" + KeyDataSourceType = "tf_data_source_type" + + // Human readable string when calling a provider defined type that must + // implement the Description() method, such as validators. + KeyDescription = "description" + + // Underlying Go error string when logging an error. + KeyError = "error" + + // The name of function being operated on, such as "parse_xyz" + KeyFunctionName = "tf_function_name" + + // The type of resource being operated on, such as "random_pet" + KeyResourceType = "tf_resource_type" + + // The type of value being operated on, such as "JSONStringValue". + KeyValueType = "tf_value_type" +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/privatestate/data.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/privatestate/data.go new file mode 100644 index 00000000..3e858026 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/privatestate/data.go @@ -0,0 +1,413 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package privatestate + +import ( + "context" + "encoding/json" + "fmt" + "reflect" + "strings" + "unicode/utf8" + + "github.com/hashicorp/terraform-plugin-log/tflog" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" +) + +// Data contains private state data for the framework and providers. +type Data struct { + // Potential future usage: + // Framework contains private state data for framework usage. + Framework map[string][]byte + + // Provider contains private state data for provider usage. + Provider *ProviderData +} + +// Bytes returns a JSON encoded slice of bytes containing the merged +// framework and provider private state data. +func (d *Data) Bytes(ctx context.Context) ([]byte, diag.Diagnostics) { + var diags diag.Diagnostics + + if d == nil { + return nil, nil + } + + if (d.Provider == nil || len(d.Provider.data) == 0) && len(d.Framework) == 0 { + return nil, nil + } + + var providerData map[string][]byte + + if d.Provider != nil { + providerData = d.Provider.data + } + + mergedMap := make(map[string][]byte, len(d.Framework)+len(providerData)) + + for _, m := range []map[string][]byte{d.Framework, providerData} { + for k, v := range m { + if len(v) == 0 { + continue + } + + // Values in FrameworkData and ProviderData should never be invalid UTF-8, but let's make sure. + if !utf8.Valid(v) { + diags.AddError( + "Error Encoding Private State", + "An error was encountered when validating private state value."+ + fmt.Sprintf("The value associated with key %q is is not valid UTF-8.\n\n", k)+ + "This is always a problem with Terraform or terraform-plugin-framework. Please report this to the provider developer.", + ) + + tflog.Error(ctx, "error encoding private state: invalid UTF-8 value", map[string]interface{}{"key": k, "value": v}) + + continue + } + + // Values in FrameworkData and ProviderData should never be invalid JSON, but let's make sure. + if !json.Valid(v) { + diags.AddError( + "Error Encoding Private State", + fmt.Sprintf("An error was encountered when validating private state value."+ + fmt.Sprintf("The value associated with key %q is is not valid JSON.\n\n", k)+ + "This is always a problem with Terraform or terraform-plugin-framework. Please report this to the provider developer."), + ) + + tflog.Error(ctx, "error encoding private state: invalid JSON value", map[string]interface{}{"key": k, "value": v}) + + continue + } + + mergedMap[k] = v + } + } + + if diags.HasError() { + return nil, diags + } + + bytes, err := json.Marshal(mergedMap) + if err != nil { + diags.AddError( + "Error Encoding Private State", + fmt.Sprintf("An error was encountered when encoding private state: %s.\n\n"+ + "This is always a problem with Terraform or terraform-plugin-framework. Please report this to the provider developer.", err), + ) + + return nil, diags + } + + return bytes, diags +} + +// NewData creates a new Data based on the given slice of bytes. +// It must be a JSON encoded slice of bytes, that is map[string][]byte. +func NewData(ctx context.Context, data []byte) (*Data, diag.Diagnostics) { + var ( + dataMap map[string][]byte + diags diag.Diagnostics + ) + + if len(data) == 0 { + return nil, nil + } + + err := json.Unmarshal(data, &dataMap) + if err != nil { + // terraform-plugin-sdk stored private state by marshalling its data + // as map[string]any, which is slightly incompatible with trying to + // unmarshal it as map[string][]byte. If unmarshalling with + // map[string]any works, we can ignore it for now, as provider + // developers did not have access to managing the private state data. + // + // TODO: We can extract the terraform-plugin-sdk resource timeouts key + // here to extract its prior data, if necessary. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/400 + if anyErr := json.Unmarshal(data, new(map[string]any)); anyErr == nil { + logging.FrameworkWarn(ctx, "Discarding incompatible resource private state data", map[string]any{logging.KeyError: err.Error()}) + return nil, nil + } + + diags.AddError( + "Error Decoding Private State", + fmt.Sprintf("An error was encountered when decoding private state: %s.\n\n"+ + "This is always a problem with Terraform or terraform-plugin-framework. Please report this to the provider developer.", err), + ) + + return nil, diags + } + + output := Data{ + Framework: make(map[string][]byte), + Provider: &ProviderData{ + make(map[string][]byte), + }, + } + + for k, v := range dataMap { + if !utf8.Valid(v) { + diags.AddError( + "Error Decoding Private State", + "An error was encountered when validating private state value.\n"+ + fmt.Sprintf("The value being supplied for key %q is is not valid UTF-8.\n\n", k)+ + "This is always a problem with Terraform or terraform-plugin-framework. Please report this to the provider developer.", + ) + + tflog.Error(ctx, "error decoding private state: invalid UTF-8 value", map[string]interface{}{"key": k, "value": v}) + + continue + } + + if !json.Valid(v) { + diags.AddError( + "Error Decoding Private State", + "An error was encountered when validating private state value.\n"+ + fmt.Sprintf("The value being supplied for key %q is is not valid JSON.\n\n", k)+ + "This is always a problem with Terraform or terraform-plugin-framework. Please report this to the provider developer.", + ) + + tflog.Error(ctx, "error decoding private state: invalid JSON value", map[string]interface{}{"key": k, "value": v}) + + continue + } + + if isInvalidProviderDataKey(ctx, k) { + output.Framework[k] = v + continue + } + + output.Provider.data[k] = v + } + + if diags.HasError() { + return nil, diags + } + + return &output, diags +} + +// EmptyData creates an initialised but empty Data. +func EmptyData(ctx context.Context) *Data { + return &Data{ + Provider: EmptyProviderData(ctx), + } +} + +// NewProviderData creates a new ProviderData based on the given slice of bytes. +// It must be a JSON encoded slice of bytes, that is map[string][]byte. +func NewProviderData(ctx context.Context, data []byte) (*ProviderData, diag.Diagnostics) { + providerData := EmptyProviderData(ctx) + + if len(data) == 0 { + return providerData, nil + } + + var ( + dataMap map[string][]byte + diags diag.Diagnostics + ) + + err := json.Unmarshal(data, &dataMap) + if err != nil { + diags.AddError( + "Error Decoding Provider Data", + fmt.Sprintf("An error was encountered when decoding provider data: %s.\n\n"+ + "Please check that the data you are supplying is a byte representation of valid JSON.", err), + ) + + return nil, diags + } + + for k, v := range dataMap { + diags.Append(providerData.SetKey(ctx, k, v)...) + } + + if diags.HasError() { + return nil, diags + } + + return providerData, diags +} + +// EmptyProviderData creates a ProviderData containing initialised but empty data. +func EmptyProviderData(ctx context.Context) *ProviderData { + return &ProviderData{ + data: make(map[string][]byte), + } +} + +// ProviderData contains private state data for provider usage. +type ProviderData struct { + data map[string][]byte +} + +// Equal returns true if the given ProviderData is exactly equivalent. The +// internal data is compared byte-for-byte, not accounting for semantic +// equivalency such as JSON whitespace or property reordering. +func (d *ProviderData) Equal(o *ProviderData) bool { + if d == nil && o == nil { + return true + } + + if d == nil || o == nil { + return false + } + + if !reflect.DeepEqual(d.data, o.data) { + return false + } + + return true +} + +// GetKey returns the private state data associated with the given key. +// +// If the key is reserved for framework usage, an error diagnostic +// is returned. If the key is valid, but private state data is not found, +// nil is returned. +// +// The naming of keys only matters in context of a single resource, +// however care should be taken that any historical keys are not reused +// without accounting for older resource instances that may still have +// older data at the key. +func (d *ProviderData) GetKey(ctx context.Context, key string) ([]byte, diag.Diagnostics) { + if d == nil || d.data == nil { + return nil, nil + } + + diags := ValidateProviderDataKey(ctx, key) + + if diags.HasError() { + return nil, diags + } + + value, ok := d.data[key] + if !ok { + return nil, nil + } + + return value, nil +} + +// SetKey sets the private state data at the given key. +// +// If the key is reserved for framework usage, an error diagnostic +// is returned. The data must be valid JSON and UTF-8 safe or an error +// diagnostic is returned. +// +// The naming of keys only matters in context of a single resource, +// however care should be taken that any historical keys are not reused +// without accounting for older resource instances that may still have +// older data at the key. +func (d *ProviderData) SetKey(ctx context.Context, key string, value []byte) diag.Diagnostics { + var diags diag.Diagnostics + + if d == nil { + tflog.Error(ctx, "error calling SetKey on uninitialized ProviderData") + + diags.AddError("Uninitialized ProviderData", + "ProviderData must be initialized before it is used.\n\n"+ + "Call privatestate.NewProviderData to obtain an initialized instance of ProviderData.", + ) + + return diags + } + + if d.data == nil { + d.data = make(map[string][]byte) + } + + diags.Append(ValidateProviderDataKey(ctx, key)...) + + if diags.HasError() { + return diags + } + + // Support removing keys by setting them to nil or zero-length value. + if len(value) == 0 { + delete(d.data, key) + + return diags + } + + if !utf8.Valid(value) { + tflog.Error(ctx, "invalid UTF-8 value", map[string]interface{}{"key": key, "value": value}) + + diags.AddError("UTF-8 Invalid", + "Values stored in private state must be valid UTF-8.\n\n"+ + fmt.Sprintf("The value being supplied for key %q is invalid. Please verify that the value is valid UTF-8.", key), + ) + + return diags + } + + if !json.Valid(value) { + tflog.Error(ctx, "invalid JSON value", map[string]interface{}{"key": key, "value": value}) + + diags.AddError("JSON Invalid", + "Values stored in private state must be valid JSON.\n\n"+ + fmt.Sprintf("The value being supplied for key %q is invalid. Please verify that the value is valid JSON.", key), + ) + + return diags + } + + d.data[key] = value + + return nil +} + +// ValidateProviderDataKey determines whether the key supplied is allowed on the basis of any +// restrictions that are in place, such as key prefixes that are reserved for use with +// framework private state data. +func ValidateProviderDataKey(ctx context.Context, key string) diag.Diagnostics { + if isInvalidProviderDataKey(ctx, key) { + return diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Restricted Resource Private State Namespace", + "Using a period ('.') as a prefix for a key used in private state is not allowed.\n\n"+ + fmt.Sprintf("The key %q is invalid. Please check the key you are supplying does not use a a period ('.') as a prefix.", key), + ), + } + } + + return nil +} + +// isInvalidProviderDataKey determines whether the supplied key has a prefix that is reserved for +// keys in Data.Framework +func isInvalidProviderDataKey(_ context.Context, key string) bool { + return strings.HasPrefix(key, ".") +} + +// MustMarshalToJson is for use in tests and panics if input cannot be marshalled to JSON. +func MustMarshalToJson(input map[string][]byte) []byte { + output, err := json.Marshal(input) + if err != nil { + panic(err) + } + + return output +} + +// MustProviderData is for use in tests and panics if the underlying call to NewProviderData +// returns diag.Diagnostics that contains any errors. +func MustProviderData(ctx context.Context, data []byte) *ProviderData { + providerData, diags := NewProviderData(ctx, data) + + if diags.HasError() { + var diagMsgs []string + + for _, v := range diags { + diagMsgs = append(diagMsgs, fmt.Sprintf("%s: %s", v.Summary(), v.Detail())) + } + + panic(fmt.Sprintf("error creating new provider data: %s", strings.Join(diagMsgs, ", "))) + } + + return providerData +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/privatestate/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/privatestate/doc.go new file mode 100644 index 00000000..6e9a54f4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/privatestate/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package privatestate contains the type used for handling private resource +// state data. +package privatestate diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/doc.go new file mode 100644 index 00000000..c3cc736f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package proto5server contains the provider server implementation compatible +// with protocol version 5 (tfprotov5.ProviderServer). +package proto5server diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/serve.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/serve.go new file mode 100644 index 00000000..c0f44d92 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/serve.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + "sync" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +var _ tfprotov5.ProviderServer = &Server{} + +// Provider server implementation. +type Server struct { + FrameworkServer fwserver.Server + + contextCancels []context.CancelFunc + contextCancelsMu sync.Mutex +} + +func (s *Server) registerContext(in context.Context) context.Context { + ctx, cancel := context.WithCancel(in) + s.contextCancelsMu.Lock() + defer s.contextCancelsMu.Unlock() + s.contextCancels = append(s.contextCancels, cancel) + return ctx +} + +func (s *Server) cancelRegisteredContexts(_ context.Context) { + s.contextCancelsMu.Lock() + defer s.contextCancelsMu.Unlock() + for _, cancel := range s.contextCancels { + cancel() + } + s.contextCancels = nil +} + +// StopProvider satisfies the tfprotov5.ProviderServer interface. +func (s *Server) StopProvider(ctx context.Context, _ *tfprotov5.StopProviderRequest) (*tfprotov5.StopProviderResponse, error) { + s.cancelRegisteredContexts(ctx) + + return &tfprotov5.StopProviderResponse{}, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_applyresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_applyresourcechange.go new file mode 100644 index 00000000..e4e8bb92 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_applyresourcechange.go @@ -0,0 +1,58 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ApplyResourceChange satisfies the tfprotov5.ProviderServer interface. +func (s *Server) ApplyResourceChange(ctx context.Context, proto5Req *tfprotov5.ApplyResourceChangeRequest) (*tfprotov5.ApplyResourceChangeResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ApplyResourceChangeResponse{} + + resource, diags := s.FrameworkServer.Resource(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ApplyResourceChangeResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ApplyResourceChangeResponse(ctx, fwResp), nil + } + + providerMetaSchema, diags := s.FrameworkServer.ProviderMetaSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ApplyResourceChangeResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto5.ApplyResourceChangeRequest(ctx, proto5Req, resource, resourceSchema, providerMetaSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ApplyResourceChangeResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ApplyResourceChange(ctx, fwReq, fwResp) + + return toproto5.ApplyResourceChangeResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_callfunction.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_callfunction.go new file mode 100644 index 00000000..01050821 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_callfunction.go @@ -0,0 +1,55 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" +) + +// CallFunction satisfies the tfprotov5.ProviderServer interface. +func (s *Server) CallFunction(ctx context.Context, protoReq *tfprotov5.CallFunctionRequest) (*tfprotov5.CallFunctionResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.CallFunctionResponse{} + + serverFunction, err := s.FrameworkServer.Function(ctx, protoReq.Name) + + fwResp.Error = err + + if fwResp.Error != nil { + //nolint:nilerr // error is assigned to fwResp.Error + return toproto5.CallFunctionResponse(ctx, fwResp), nil + } + + functionDefinition, err := s.FrameworkServer.FunctionDefinition(ctx, protoReq.Name) + + fwResp.Error = function.ConcatFuncErrors(fwResp.Error, err) + + if fwResp.Error != nil { + //nolint:nilerr // error is assigned to fwResp.Error + return toproto5.CallFunctionResponse(ctx, fwResp), nil + } + + fwReq, fwReqError := fromproto5.CallFunctionRequest(ctx, protoReq, serverFunction, functionDefinition) + + fwResp.Error = function.ConcatFuncErrors(fwResp.Error, fwReqError) + + if fwResp.Error != nil { + //nolint:nilerr // error is assigned to fwResp.Error + return toproto5.CallFunctionResponse(ctx, fwResp), nil + } + + s.FrameworkServer.CallFunction(ctx, fwReq, fwResp) + + return toproto5.CallFunctionResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_configureprovider.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_configureprovider.go new file mode 100644 index 00000000..3f5d22e3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_configureprovider.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ConfigureProvider satisfies the tfprotov5.ProviderServer interface. +func (s *Server) ConfigureProvider(ctx context.Context, proto5Req *tfprotov5.ConfigureProviderRequest) (*tfprotov5.ConfigureProviderResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &provider.ConfigureResponse{} + + providerSchema, diags := s.FrameworkServer.ProviderSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ConfigureProviderResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto5.ConfigureProviderRequest(ctx, proto5Req, providerSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ConfigureProviderResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ConfigureProvider(ctx, fwReq, fwResp) + + return toproto5.ConfigureProviderResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getfunctions.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getfunctions.go new file mode 100644 index 00000000..25c93c5c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getfunctions.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetFunctions satisfies the tfprotov5.ProviderServer interface. +func (s *Server) GetFunctions(ctx context.Context, protoReq *tfprotov5.GetFunctionsRequest) (*tfprotov5.GetFunctionsResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwReq := fromproto5.GetFunctionsRequest(ctx, protoReq) + fwResp := &fwserver.GetFunctionsResponse{} + + s.FrameworkServer.GetFunctions(ctx, fwReq, fwResp) + + return toproto5.GetFunctionsResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getmetadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getmetadata.go new file mode 100644 index 00000000..8888d1a8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getmetadata.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetMetadata satisfies the tfprotov5.ProviderServer interface. +func (s *Server) GetMetadata(ctx context.Context, proto6Req *tfprotov5.GetMetadataRequest) (*tfprotov5.GetMetadataResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwReq := fromproto5.GetMetadataRequest(ctx, proto6Req) + fwResp := &fwserver.GetMetadataResponse{} + + s.FrameworkServer.GetMetadata(ctx, fwReq, fwResp) + + return toproto5.GetMetadataResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getproviderschema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getproviderschema.go new file mode 100644 index 00000000..ef5a5ce2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_getproviderschema.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetProviderSchema satisfies the tfprotov5.ProviderServer interface. +func (s *Server) GetProviderSchema(ctx context.Context, proto5Req *tfprotov5.GetProviderSchemaRequest) (*tfprotov5.GetProviderSchemaResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwReq := fromproto5.GetProviderSchemaRequest(ctx, proto5Req) + fwResp := &fwserver.GetProviderSchemaResponse{} + + s.FrameworkServer.GetProviderSchema(ctx, fwReq, fwResp) + + return toproto5.GetProviderSchemaResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_importresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_importresourcestate.go new file mode 100644 index 00000000..5d89dc90 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_importresourcestate.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ImportResourceState satisfies the tfprotov5.ProviderServer interface. +func (s *Server) ImportResourceState(ctx context.Context, proto5Req *tfprotov5.ImportResourceStateRequest) (*tfprotov5.ImportResourceStateResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ImportResourceStateResponse{} + + resource, diags := s.FrameworkServer.Resource(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ImportResourceStateResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ImportResourceStateResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto5.ImportResourceStateRequest(ctx, proto5Req, resource, resourceSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ImportResourceStateResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ImportResourceState(ctx, fwReq, fwResp) + + return toproto5.ImportResourceStateResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_moveresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_moveresourcestate.go new file mode 100644 index 00000000..efa1b118 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_moveresourcestate.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// MoveResourceState satisfies the tfprotov5.ProviderServer interface. +func (s *Server) MoveResourceState(ctx context.Context, proto5Req *tfprotov5.MoveResourceStateRequest) (*tfprotov5.MoveResourceStateResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.MoveResourceStateResponse{} + + if proto5Req == nil { + return toproto5.MoveResourceStateResponse(ctx, fwResp), nil + } + + resource, diags := s.FrameworkServer.Resource(ctx, proto5Req.TargetTypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.MoveResourceStateResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto5Req.TargetTypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.MoveResourceStateResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto5.MoveResourceStateRequest(ctx, proto5Req, resource, resourceSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.MoveResourceStateResponse(ctx, fwResp), nil + } + + s.FrameworkServer.MoveResourceState(ctx, fwReq, fwResp) + + return toproto5.MoveResourceStateResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_planresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_planresourcechange.go new file mode 100644 index 00000000..6cc995da --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_planresourcechange.go @@ -0,0 +1,58 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// PlanResourceChange satisfies the tfprotov5.ProviderServer interface. +func (s *Server) PlanResourceChange(ctx context.Context, proto5Req *tfprotov5.PlanResourceChangeRequest) (*tfprotov5.PlanResourceChangeResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.PlanResourceChangeResponse{} + + resource, diags := s.FrameworkServer.Resource(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.PlanResourceChangeResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.PlanResourceChangeResponse(ctx, fwResp), nil + } + + providerMetaSchema, diags := s.FrameworkServer.ProviderMetaSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.PlanResourceChangeResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto5.PlanResourceChangeRequest(ctx, proto5Req, resource, resourceSchema, providerMetaSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.PlanResourceChangeResponse(ctx, fwResp), nil + } + + s.FrameworkServer.PlanResourceChange(ctx, fwReq, fwResp) + + return toproto5.PlanResourceChangeResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_prepareproviderconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_prepareproviderconfig.go new file mode 100644 index 00000000..b6cd119d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_prepareproviderconfig.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// PrepareProviderConfig satisfies the tfprotov5.ProviderServer interface. +func (s *Server) PrepareProviderConfig(ctx context.Context, proto5Req *tfprotov5.PrepareProviderConfigRequest) (*tfprotov5.PrepareProviderConfigResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ValidateProviderConfigResponse{} + + providerSchema, diags := s.FrameworkServer.ProviderSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.PrepareProviderConfigResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto5.PrepareProviderConfigRequest(ctx, proto5Req, providerSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.PrepareProviderConfigResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ValidateProviderConfig(ctx, fwReq, fwResp) + + return toproto5.PrepareProviderConfigResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_readdatasource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_readdatasource.go new file mode 100644 index 00000000..e35e4e90 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_readdatasource.go @@ -0,0 +1,58 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ReadDataSource satisfies the tfprotov5.ProviderServer interface. +func (s *Server) ReadDataSource(ctx context.Context, proto5Req *tfprotov5.ReadDataSourceRequest) (*tfprotov5.ReadDataSourceResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ReadDataSourceResponse{} + + dataSource, diags := s.FrameworkServer.DataSource(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ReadDataSourceResponse(ctx, fwResp), nil + } + + dataSourceSchema, diags := s.FrameworkServer.DataSourceSchema(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ReadDataSourceResponse(ctx, fwResp), nil + } + + providerMetaSchema, diags := s.FrameworkServer.ProviderMetaSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ReadDataSourceResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto5.ReadDataSourceRequest(ctx, proto5Req, dataSource, dataSourceSchema, providerMetaSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ReadDataSourceResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ReadDataSource(ctx, fwReq, fwResp) + + return toproto5.ReadDataSourceResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_readresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_readresource.go new file mode 100644 index 00000000..e9863e14 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_readresource.go @@ -0,0 +1,59 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" +) + +// ReadResource satisfies the tfprotov5.ProviderServer interface. +func (s *Server) ReadResource(ctx context.Context, proto5Req *tfprotov5.ReadResourceRequest) (*tfprotov5.ReadResourceResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ReadResourceResponse{} + + resource, diags := s.FrameworkServer.Resource(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ReadResourceResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ReadResourceResponse(ctx, fwResp), nil + } + + providerMetaSchema, diags := s.FrameworkServer.ProviderMetaSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ReadResourceResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto5.ReadResourceRequest(ctx, proto5Req, resource, resourceSchema, providerMetaSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ReadResourceResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ReadResource(ctx, fwReq, fwResp) + + return toproto5.ReadResourceResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_upgraderesourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_upgraderesourcestate.go new file mode 100644 index 00000000..ca20c928 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_upgraderesourcestate.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// UpgradeResourceState satisfies the tfprotov5.ProviderServer interface. +func (s *Server) UpgradeResourceState(ctx context.Context, proto5Req *tfprotov5.UpgradeResourceStateRequest) (*tfprotov5.UpgradeResourceStateResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.UpgradeResourceStateResponse{} + + if proto5Req == nil { + return toproto5.UpgradeResourceStateResponse(ctx, fwResp), nil + } + + resource, diags := s.FrameworkServer.Resource(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.UpgradeResourceStateResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.UpgradeResourceStateResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto5.UpgradeResourceStateRequest(ctx, proto5Req, resource, resourceSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.UpgradeResourceStateResponse(ctx, fwResp), nil + } + + s.FrameworkServer.UpgradeResourceState(ctx, fwReq, fwResp) + + return toproto5.UpgradeResourceStateResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_validatedatasourceconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_validatedatasourceconfig.go new file mode 100644 index 00000000..3958168e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_validatedatasourceconfig.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ValidateDataSourceConfig satisfies the tfprotov5.ProviderServer interface. +func (s *Server) ValidateDataSourceConfig(ctx context.Context, proto5Req *tfprotov5.ValidateDataSourceConfigRequest) (*tfprotov5.ValidateDataSourceConfigResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ValidateDataSourceConfigResponse{} + + dataSource, diags := s.FrameworkServer.DataSource(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ValidateDataSourceConfigResponse(ctx, fwResp), nil + } + + dataSourceSchema, diags := s.FrameworkServer.DataSourceSchema(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ValidateDataSourceConfigResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto5.ValidateDataSourceConfigRequest(ctx, proto5Req, dataSource, dataSourceSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ValidateDataSourceConfigResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ValidateDataSourceConfig(ctx, fwReq, fwResp) + + return toproto5.ValidateDataSourceConfigResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_validateresourcetypeconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_validateresourcetypeconfig.go new file mode 100644 index 00000000..d2802926 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto5server/server_validateresourcetypeconfig.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ValidateResourceTypeConfig satisfies the tfprotov5.ProviderServer interface. +func (s *Server) ValidateResourceTypeConfig(ctx context.Context, proto5Req *tfprotov5.ValidateResourceTypeConfigRequest) (*tfprotov5.ValidateResourceTypeConfigResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ValidateResourceConfigResponse{} + + resource, diags := s.FrameworkServer.Resource(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ValidateResourceTypeConfigResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto5Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ValidateResourceTypeConfigResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto5.ValidateResourceTypeConfigRequest(ctx, proto5Req, resource, resourceSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto5.ValidateResourceTypeConfigResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ValidateResourceConfig(ctx, fwReq, fwResp) + + return toproto5.ValidateResourceTypeConfigResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/doc.go new file mode 100644 index 00000000..5f9f7c35 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package proto6server contains the provider server implementation compatible +// with protocol version 6 (tfprotov6.ProviderServer). +package proto6server diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/serve.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/serve.go new file mode 100644 index 00000000..26cf0c4e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/serve.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + "sync" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +var _ tfprotov6.ProviderServer = &Server{} + +// Provider server implementation. +type Server struct { + FrameworkServer fwserver.Server + + contextCancels []context.CancelFunc + contextCancelsMu sync.Mutex +} + +func (s *Server) registerContext(in context.Context) context.Context { + ctx, cancel := context.WithCancel(in) + s.contextCancelsMu.Lock() + defer s.contextCancelsMu.Unlock() + s.contextCancels = append(s.contextCancels, cancel) + return ctx +} + +func (s *Server) cancelRegisteredContexts(_ context.Context) { + s.contextCancelsMu.Lock() + defer s.contextCancelsMu.Unlock() + for _, cancel := range s.contextCancels { + cancel() + } + s.contextCancels = nil +} + +// StopProvider satisfies the tfprotov6.ProviderServer interface. +func (s *Server) StopProvider(ctx context.Context, _ *tfprotov6.StopProviderRequest) (*tfprotov6.StopProviderResponse, error) { + s.cancelRegisteredContexts(ctx) + + return &tfprotov6.StopProviderResponse{}, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_applyresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_applyresourcechange.go new file mode 100644 index 00000000..0762368b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_applyresourcechange.go @@ -0,0 +1,58 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ApplyResourceChange satisfies the tfprotov6.ProviderServer interface. +func (s *Server) ApplyResourceChange(ctx context.Context, proto6Req *tfprotov6.ApplyResourceChangeRequest) (*tfprotov6.ApplyResourceChangeResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ApplyResourceChangeResponse{} + + resource, diags := s.FrameworkServer.Resource(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ApplyResourceChangeResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ApplyResourceChangeResponse(ctx, fwResp), nil + } + + providerMetaSchema, diags := s.FrameworkServer.ProviderMetaSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ApplyResourceChangeResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto6.ApplyResourceChangeRequest(ctx, proto6Req, resource, resourceSchema, providerMetaSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ApplyResourceChangeResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ApplyResourceChange(ctx, fwReq, fwResp) + + return toproto6.ApplyResourceChangeResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_callfunction.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_callfunction.go new file mode 100644 index 00000000..4ca13f53 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_callfunction.go @@ -0,0 +1,55 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" +) + +// CallFunction satisfies the tfprotov6.ProviderServer interface. +func (s *Server) CallFunction(ctx context.Context, protoReq *tfprotov6.CallFunctionRequest) (*tfprotov6.CallFunctionResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.CallFunctionResponse{} + + serverFunction, err := s.FrameworkServer.Function(ctx, protoReq.Name) + + fwResp.Error = err + + if fwResp.Error != nil { + //nolint:nilerr // error is assigned to fwResp.Error + return toproto6.CallFunctionResponse(ctx, fwResp), nil + } + + functionDefinition, err := s.FrameworkServer.FunctionDefinition(ctx, protoReq.Name) + + fwResp.Error = function.ConcatFuncErrors(fwResp.Error, err) + + if fwResp.Error != nil { + //nolint:nilerr // error is assigned to fwResp.Error + return toproto6.CallFunctionResponse(ctx, fwResp), nil + } + + fwReq, fwReqError := fromproto6.CallFunctionRequest(ctx, protoReq, serverFunction, functionDefinition) + + fwResp.Error = function.ConcatFuncErrors(fwResp.Error, fwReqError) + + if fwResp.Error != nil { + //nolint:nilerr // error is assigned to fwResp.Error + return toproto6.CallFunctionResponse(ctx, fwResp), nil + } + + s.FrameworkServer.CallFunction(ctx, fwReq, fwResp) + + return toproto6.CallFunctionResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_configureprovider.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_configureprovider.go new file mode 100644 index 00000000..c4c70ebc --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_configureprovider.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ConfigureProvider satisfies the tfprotov6.ProviderServer interface. +func (s *Server) ConfigureProvider(ctx context.Context, proto6Req *tfprotov6.ConfigureProviderRequest) (*tfprotov6.ConfigureProviderResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &provider.ConfigureResponse{} + + providerSchema, diags := s.FrameworkServer.ProviderSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ConfigureProviderResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto6.ConfigureProviderRequest(ctx, proto6Req, providerSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ConfigureProviderResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ConfigureProvider(ctx, fwReq, fwResp) + + return toproto6.ConfigureProviderResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getfunctions.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getfunctions.go new file mode 100644 index 00000000..6201672c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getfunctions.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetFunctions satisfies the tfprotov6.ProviderServer interface. +func (s *Server) GetFunctions(ctx context.Context, protoReq *tfprotov6.GetFunctionsRequest) (*tfprotov6.GetFunctionsResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwReq := fromproto6.GetFunctionsRequest(ctx, protoReq) + fwResp := &fwserver.GetFunctionsResponse{} + + s.FrameworkServer.GetFunctions(ctx, fwReq, fwResp) + + return toproto6.GetFunctionsResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getmetadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getmetadata.go new file mode 100644 index 00000000..589f6682 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getmetadata.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetMetadata satisfies the tfprotov6.ProviderServer interface. +func (s *Server) GetMetadata(ctx context.Context, proto6Req *tfprotov6.GetMetadataRequest) (*tfprotov6.GetMetadataResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwReq := fromproto6.GetMetadataRequest(ctx, proto6Req) + fwResp := &fwserver.GetMetadataResponse{} + + s.FrameworkServer.GetMetadata(ctx, fwReq, fwResp) + + return toproto6.GetMetadataResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getproviderschema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getproviderschema.go new file mode 100644 index 00000000..3f025ff8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_getproviderschema.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetProviderSchema satisfies the tfprotov6.ProviderServer interface. +func (s *Server) GetProviderSchema(ctx context.Context, proto6Req *tfprotov6.GetProviderSchemaRequest) (*tfprotov6.GetProviderSchemaResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwReq := fromproto6.GetProviderSchemaRequest(ctx, proto6Req) + fwResp := &fwserver.GetProviderSchemaResponse{} + + s.FrameworkServer.GetProviderSchema(ctx, fwReq, fwResp) + + return toproto6.GetProviderSchemaResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_importresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_importresourcestate.go new file mode 100644 index 00000000..46a58c63 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_importresourcestate.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ImportResourceState satisfies the tfprotov6.ProviderServer interface. +func (s *Server) ImportResourceState(ctx context.Context, proto6Req *tfprotov6.ImportResourceStateRequest) (*tfprotov6.ImportResourceStateResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ImportResourceStateResponse{} + + resource, diags := s.FrameworkServer.Resource(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ImportResourceStateResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ImportResourceStateResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto6.ImportResourceStateRequest(ctx, proto6Req, resource, resourceSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ImportResourceStateResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ImportResourceState(ctx, fwReq, fwResp) + + return toproto6.ImportResourceStateResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_moveresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_moveresourcestate.go new file mode 100644 index 00000000..1010b5d7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_moveresourcestate.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// MoveResourceState satisfies the tfprotov6.ProviderServer interface. +func (s *Server) MoveResourceState(ctx context.Context, proto6Req *tfprotov6.MoveResourceStateRequest) (*tfprotov6.MoveResourceStateResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.MoveResourceStateResponse{} + + if proto6Req == nil { + return toproto6.MoveResourceStateResponse(ctx, fwResp), nil + } + + resource, diags := s.FrameworkServer.Resource(ctx, proto6Req.TargetTypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.MoveResourceStateResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto6Req.TargetTypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.MoveResourceStateResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto6.MoveResourceStateRequest(ctx, proto6Req, resource, resourceSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.MoveResourceStateResponse(ctx, fwResp), nil + } + + s.FrameworkServer.MoveResourceState(ctx, fwReq, fwResp) + + return toproto6.MoveResourceStateResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_planresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_planresourcechange.go new file mode 100644 index 00000000..9782fc04 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_planresourcechange.go @@ -0,0 +1,58 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// PlanResourceChange satisfies the tfprotov6.ProviderServer interface. +func (s *Server) PlanResourceChange(ctx context.Context, proto6Req *tfprotov6.PlanResourceChangeRequest) (*tfprotov6.PlanResourceChangeResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.PlanResourceChangeResponse{} + + resource, diags := s.FrameworkServer.Resource(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.PlanResourceChangeResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.PlanResourceChangeResponse(ctx, fwResp), nil + } + + providerMetaSchema, diags := s.FrameworkServer.ProviderMetaSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.PlanResourceChangeResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto6.PlanResourceChangeRequest(ctx, proto6Req, resource, resourceSchema, providerMetaSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.PlanResourceChangeResponse(ctx, fwResp), nil + } + + s.FrameworkServer.PlanResourceChange(ctx, fwReq, fwResp) + + return toproto6.PlanResourceChangeResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_readdatasource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_readdatasource.go new file mode 100644 index 00000000..c89cd535 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_readdatasource.go @@ -0,0 +1,58 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ReadDataSource satisfies the tfprotov6.ProviderServer interface. +func (s *Server) ReadDataSource(ctx context.Context, proto6Req *tfprotov6.ReadDataSourceRequest) (*tfprotov6.ReadDataSourceResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ReadDataSourceResponse{} + + dataSource, diags := s.FrameworkServer.DataSource(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ReadDataSourceResponse(ctx, fwResp), nil + } + + dataSourceSchema, diags := s.FrameworkServer.DataSourceSchema(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ReadDataSourceResponse(ctx, fwResp), nil + } + + providerMetaSchema, diags := s.FrameworkServer.ProviderMetaSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ReadDataSourceResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto6.ReadDataSourceRequest(ctx, proto6Req, dataSource, dataSourceSchema, providerMetaSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ReadDataSourceResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ReadDataSource(ctx, fwReq, fwResp) + + return toproto6.ReadDataSourceResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_readresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_readresource.go new file mode 100644 index 00000000..d5b0cfab --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_readresource.go @@ -0,0 +1,58 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ReadResource satisfies the tfprotov6.ProviderServer interface. +func (s *Server) ReadResource(ctx context.Context, proto6Req *tfprotov6.ReadResourceRequest) (*tfprotov6.ReadResourceResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ReadResourceResponse{} + + resource, diags := s.FrameworkServer.Resource(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ReadResourceResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ReadResourceResponse(ctx, fwResp), nil + } + + providerMetaSchema, diags := s.FrameworkServer.ProviderMetaSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ReadResourceResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto6.ReadResourceRequest(ctx, proto6Req, resource, resourceSchema, providerMetaSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ReadResourceResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ReadResource(ctx, fwReq, fwResp) + + return toproto6.ReadResourceResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_upgraderesourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_upgraderesourcestate.go new file mode 100644 index 00000000..4a2ebea1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_upgraderesourcestate.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// UpgradeResourceState satisfies the tfprotov6.ProviderServer interface. +func (s *Server) UpgradeResourceState(ctx context.Context, proto6Req *tfprotov6.UpgradeResourceStateRequest) (*tfprotov6.UpgradeResourceStateResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.UpgradeResourceStateResponse{} + + if proto6Req == nil { + return toproto6.UpgradeResourceStateResponse(ctx, fwResp), nil + } + + resource, diags := s.FrameworkServer.Resource(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.UpgradeResourceStateResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.UpgradeResourceStateResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto6.UpgradeResourceStateRequest(ctx, proto6Req, resource, resourceSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.UpgradeResourceStateResponse(ctx, fwResp), nil + } + + s.FrameworkServer.UpgradeResourceState(ctx, fwReq, fwResp) + + return toproto6.UpgradeResourceStateResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validatedataresourceconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validatedataresourceconfig.go new file mode 100644 index 00000000..e5d6e4fd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validatedataresourceconfig.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ValidateDataResourceConfig satisfies the tfprotov6.ProviderServer interface. +func (s *Server) ValidateDataResourceConfig(ctx context.Context, proto6Req *tfprotov6.ValidateDataResourceConfigRequest) (*tfprotov6.ValidateDataResourceConfigResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ValidateDataSourceConfigResponse{} + + dataSource, diags := s.FrameworkServer.DataSource(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ValidateDataSourceConfigResponse(ctx, fwResp), nil + } + + dataSourceSchema, diags := s.FrameworkServer.DataSourceSchema(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ValidateDataSourceConfigResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto6.ValidateDataSourceConfigRequest(ctx, proto6Req, dataSource, dataSourceSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ValidateDataSourceConfigResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ValidateDataSourceConfig(ctx, fwReq, fwResp) + + return toproto6.ValidateDataSourceConfigResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validateproviderconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validateproviderconfig.go new file mode 100644 index 00000000..757bd536 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validateproviderconfig.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ValidateProviderConfig satisfies the tfprotov6.ProviderServer interface. +func (s *Server) ValidateProviderConfig(ctx context.Context, proto6Req *tfprotov6.ValidateProviderConfigRequest) (*tfprotov6.ValidateProviderConfigResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ValidateProviderConfigResponse{} + + providerSchema, diags := s.FrameworkServer.ProviderSchema(ctx) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ValidateProviderConfigResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto6.ValidateProviderConfigRequest(ctx, proto6Req, providerSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ValidateProviderConfigResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ValidateProviderConfig(ctx, fwReq, fwResp) + + return toproto6.ValidateProviderConfigResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validateresourceconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validateresourceconfig.go new file mode 100644 index 00000000..9e4316cd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/proto6server/server_validateresourceconfig.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ValidateResourceConfig satisfies the tfprotov6.ProviderServer interface. +func (s *Server) ValidateResourceConfig(ctx context.Context, proto6Req *tfprotov6.ValidateResourceConfigRequest) (*tfprotov6.ValidateResourceConfigResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwResp := &fwserver.ValidateResourceConfigResponse{} + + resource, diags := s.FrameworkServer.Resource(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ValidateResourceConfigResponse(ctx, fwResp), nil + } + + resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, proto6Req.TypeName) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ValidateResourceConfigResponse(ctx, fwResp), nil + } + + fwReq, diags := fromproto6.ValidateResourceConfigRequest(ctx, proto6Req, resource, resourceSchema) + + fwResp.Diagnostics.Append(diags...) + + if fwResp.Diagnostics.HasError() { + return toproto6.ValidateResourceConfigResponse(ctx, fwResp), nil + } + + s.FrameworkServer.ValidateResourceConfig(ctx, fwReq, fwResp) + + return toproto6.ValidateResourceConfigResponse(ctx, fwResp), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/diags.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/diags.go new file mode 100644 index 00000000..eb67d4de --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/diags.go @@ -0,0 +1,116 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "fmt" + "reflect" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +func toTerraform5ValueErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { + return diag.NewAttributeErrorDiagnostic( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) +} + +func toTerraformValueErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { + return diag.NewAttributeErrorDiagnostic( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert the Attribute value into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) +} + +func validateValueErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { + return diag.NewAttributeErrorDiagnostic( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to validate the Terraform value type. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) +} + +func valueFromTerraformErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { + return diag.NewAttributeErrorDiagnostic( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert the Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) +} + +type DiagIntoIncompatibleType struct { + Val tftypes.Value + TargetType reflect.Type + Err error +} + +func (d DiagIntoIncompatibleType) Severity() diag.Severity { + return diag.SeverityError +} + +func (d DiagIntoIncompatibleType) Summary() string { + return "Value Conversion Error" +} + +func (d DiagIntoIncompatibleType) Detail() string { + return fmt.Sprintf("An unexpected error was encountered trying to convert %T into %s. This is always an error in the provider. Please report the following to the provider developer:\n\n%s", d.Val, d.TargetType, d.Err.Error()) +} + +func (d DiagIntoIncompatibleType) Equal(o diag.Diagnostic) bool { + od, ok := o.(DiagIntoIncompatibleType) + if !ok { + return false + } + if !d.Val.Equal(od.Val) { + return false + } + if d.TargetType != od.TargetType { + return false + } + if d.Err.Error() != od.Err.Error() { + return false + } + return true +} + +type DiagNewAttributeValueIntoWrongType struct { + ValType reflect.Type + TargetType reflect.Type + SchemaType attr.Type +} + +func (d DiagNewAttributeValueIntoWrongType) Severity() diag.Severity { + return diag.SeverityError +} + +func (d DiagNewAttributeValueIntoWrongType) Summary() string { + return "Value Conversion Error" +} + +func (d DiagNewAttributeValueIntoWrongType) Detail() string { + return fmt.Sprintf("An unexpected error was encountered trying to convert into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\nCannot use attr.Value %s, only %s is supported because %T is the type in the schema", d.TargetType, d.ValType, d.SchemaType) +} + +func (d DiagNewAttributeValueIntoWrongType) Equal(o diag.Diagnostic) bool { + od, ok := o.(DiagNewAttributeValueIntoWrongType) + if !ok { + return false + } + if d.ValType != od.ValType { + return false + } + if d.TargetType != od.TargetType { + return false + } + if !d.SchemaType.Equal(od.SchemaType) { + return false + } + return true +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/doc.go new file mode 100644 index 00000000..4c1fa713 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package reflect contains the implementation for converting framework-defined +// data into and from provider-defined Go types. +package reflect diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/generic_attr_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/generic_attr_value.go new file mode 100644 index 00000000..5be5b284 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/generic_attr_value.go @@ -0,0 +1,15 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "context" + "reflect" + + "github.com/hashicorp/terraform-plugin-framework/attr" +) + +func IsGenericAttrValue(ctx context.Context, target interface{}) bool { + return reflect.TypeOf((*attr.Value)(nil)) == reflect.TypeOf(target) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/helpers.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/helpers.go new file mode 100644 index 00000000..52634dfb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/helpers.go @@ -0,0 +1,99 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "context" + "fmt" + "reflect" + "regexp" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// trueReflectValue returns the reflect.Value for `in` after derefencing all +// the pointers and unwrapping all the interfaces. It's the concrete value +// beneath it all. +func trueReflectValue(val reflect.Value) reflect.Value { + kind := val.Type().Kind() + for kind == reflect.Interface || kind == reflect.Ptr { + innerVal := val.Elem() + if !innerVal.IsValid() { + break + } + val = innerVal + kind = val.Type().Kind() + } + return val +} + +// commaSeparatedString returns an English joining of the strings in `in`, +// using "and" and commas as appropriate. +func commaSeparatedString(in []string) string { + switch len(in) { + case 0: + return "" + case 1: + return in[0] + case 2: + return strings.Join(in, " and ") + default: + in[len(in)-1] = "and " + in[len(in)-1] + return strings.Join(in, ", ") + } +} + +// getStructTags returns a map of Terraform field names to their position in +// the tags of the struct `in`. `in` must be a struct. +func getStructTags(_ context.Context, in reflect.Value, path path.Path) (map[string]int, error) { + tags := map[string]int{} + typ := trueReflectValue(in).Type() + if typ.Kind() != reflect.Struct { + return nil, fmt.Errorf("%s: can't get struct tags of %s, is not a struct", path, in.Type()) + } + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + if field.PkgPath != "" { + // skip unexported fields + continue + } + tag := field.Tag.Get(`tfsdk`) + if tag == "-" { + // skip explicitly excluded fields + continue + } + if tag == "" { + return nil, fmt.Errorf(`%s: need a struct tag for "tfsdk" on %s`, path, field.Name) + } + path := path.AtName(tag) + if !isValidFieldName(tag) { + return nil, fmt.Errorf("%s: invalid field name, must only use lowercase letters, underscores, and numbers, and must start with a letter", path) + } + if other, ok := tags[tag]; ok { + return nil, fmt.Errorf("%s: can't use field name for both %s and %s", path, typ.Field(other).Name, field.Name) + } + tags[tag] = i + } + return tags, nil +} + +// isValidFieldName returns true if `name` can be used as a field name in a +// Terraform resource or data source. +func isValidFieldName(name string) bool { + re := regexp.MustCompile("^[a-z][a-z0-9_]*$") + return re.MatchString(name) +} + +// canBeNil returns true if `target`'s type can hold a nil value +func canBeNil(target reflect.Value) bool { + switch target.Kind() { + case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Interface: + // these types can all hold nils + return true + default: + // nothing else can be set to nil + return false + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/interfaces.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/interfaces.go new file mode 100644 index 00000000..1811a1b8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/interfaces.go @@ -0,0 +1,491 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "context" + "fmt" + "reflect" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Unknownable is an interface for types that can be explicitly set to known or +// unknown. +type Unknownable interface { + SetUnknown(context.Context, bool) error + SetValue(context.Context, interface{}) error + GetUnknown(context.Context) bool + GetValue(context.Context) interface{} +} + +// NewUnknownable creates a zero value of `target` (or the concrete type it's +// referencing, if it's a pointer) and calls its SetUnknown method. +// +// It is meant to be called through Into, not directly. +func NewUnknownable(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + receiver := pointerSafeZeroValue(ctx, target) + method := receiver.MethodByName("SetUnknown") + if !method.IsValid() { + err := fmt.Errorf("cannot find SetUnknown method on type %s", receiver.Type().String()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + results := method.Call([]reflect.Value{ + reflect.ValueOf(ctx), + reflect.ValueOf(!val.IsKnown()), + }) + err := results[0].Interface() + if err != nil { + var underlyingErr error + switch e := err.(type) { + case error: + underlyingErr = e + default: + underlyingErr = fmt.Errorf("unknown error type %T: %v", e, e) + } + underlyingErr = fmt.Errorf("reflection error: %w", underlyingErr) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+underlyingErr.Error(), + ) + return target, diags + } + return receiver, diags +} + +// FromUnknownable creates an attr.Value from the data in an Unknownable. +// +// It is meant to be called through FromValue, not directly. +func FromUnknownable(ctx context.Context, typ attr.Type, val Unknownable, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + if val.GetUnknown(ctx) { + tfVal := tftypes.NewValue(typ.TerraformType(ctx), tftypes.UnknownValue) + + res, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := res.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return res, nil + } + err := tftypes.ValidateValue(typ.TerraformType(ctx), val.GetValue(ctx)) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + + tfVal := tftypes.NewValue(typ.TerraformType(ctx), val.GetValue(ctx)) + + res, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := res.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return res, nil +} + +// Nullable is an interface for types that can be explicitly set to null. +type Nullable interface { + SetNull(context.Context, bool) error + SetValue(context.Context, interface{}) error + GetNull(context.Context) bool + GetValue(context.Context) interface{} +} + +// NewNullable creates a zero value of `target` (or the concrete type it's +// referencing, if it's a pointer) and calls its SetNull method. +// +// It is meant to be called through Into, not directly. +func NewNullable(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + receiver := pointerSafeZeroValue(ctx, target) + method := receiver.MethodByName("SetNull") + if !method.IsValid() { + err := fmt.Errorf("cannot find SetNull method on type %s", receiver.Type().String()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + results := method.Call([]reflect.Value{ + reflect.ValueOf(ctx), + reflect.ValueOf(val.IsNull()), + }) + err := results[0].Interface() + if err != nil { + var underlyingErr error + switch e := err.(type) { + case error: + underlyingErr = e + default: + underlyingErr = fmt.Errorf("unknown error type: %T", e) + } + underlyingErr = fmt.Errorf("reflection error: %w", underlyingErr) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+underlyingErr.Error(), + ) + return target, diags + } + return receiver, diags +} + +// FromNullable creates an attr.Value from the data in a Nullable. +// +// It is meant to be called through FromValue, not directly. +func FromNullable(ctx context.Context, typ attr.Type, val Nullable, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + if val.GetNull(ctx) { + tfVal := tftypes.NewValue(typ.TerraformType(ctx), nil) + + res, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := res.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return res, nil + } + err := tftypes.ValidateValue(typ.TerraformType(ctx), val.GetValue(ctx)) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + + tfVal := tftypes.NewValue(typ.TerraformType(ctx), val.GetValue(ctx)) + + res, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := res.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return res, diags +} + +// NewValueConverter creates a zero value of `target` (or the concrete type +// it's referencing, if it's a pointer) and calls its FromTerraform5Value +// method. +// +// It is meant to be called through Into, not directly. +func NewValueConverter(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + receiver := pointerSafeZeroValue(ctx, target) + method := receiver.MethodByName("FromTerraform5Value") + if !method.IsValid() { + err := fmt.Errorf("could not find FromTerraform5Type method on type %s", receiver.Type().String()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + results := method.Call([]reflect.Value{reflect.ValueOf(val)}) + err := results[0].Interface() + if err != nil { + var underlyingErr error + switch e := err.(type) { + case error: + underlyingErr = e + default: + underlyingErr = fmt.Errorf("unknown error type: %T", e) + } + underlyingErr = fmt.Errorf("reflection error: %w", underlyingErr) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+underlyingErr.Error(), + ) + return target, diags + } + return receiver, diags +} + +// FromValueCreator creates an attr.Value from the data in a +// tftypes.ValueCreator, calling its ToTerraform5Value method and converting +// the result to an attr.Value using `typ`. +// +// It is meant to be called from FromValue, not directly. +func FromValueCreator(ctx context.Context, typ attr.Type, val tftypes.ValueCreator, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + raw, err := val.ToTerraform5Value() + if err != nil { + return nil, append(diags, toTerraform5ValueErrorDiag(err, path)) + } + err = tftypes.ValidateValue(typ.TerraformType(ctx), raw) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfVal := tftypes.NewValue(typ.TerraformType(ctx), raw) + + res, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := res.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return res, diags +} + +// NewAttributeValue creates a new reflect.Value by calling the +// ValueFromTerraform method on `typ`. It will return an error if the returned +// `attr.Value` is not the same type as `target`. +// +// It is meant to be called through Into, not directly. +func NewAttributeValue(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + res, err := typ.ValueFromTerraform(ctx, val) + if err != nil { + return target, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := res.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return target, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, val, path)...) + + if diags.HasError() { + return target, diags + } + } + } + + if reflect.TypeOf(res) != target.Type() { + diags.Append(diag.WithPath(path, DiagNewAttributeValueIntoWrongType{ + ValType: reflect.TypeOf(res), + TargetType: target.Type(), + SchemaType: typ, + })) + return target, diags + } + return reflect.ValueOf(res), diags +} + +// FromAttributeValue creates an attr.Value from an attr.Value. It just returns +// the attr.Value it is passed or an error if there is an unexpected mismatch +// between the attr.Type and attr.Value. +// +// It is meant to be called through FromValue, not directly. +func FromAttributeValue(ctx context.Context, typ attr.Type, val attr.Value, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + // Since the reflection logic is a generic Go type implementation with + // user input, it is possible to get into awkward situations where + // the logic is expecting a certain type while a value may not be + // compatible. This check will ensure the framework raises its own + // error is there is a mismatch, rather than a terraform-plugin-go + // error or worse a panic. + if !typ.TerraformType(ctx).Equal(val.Type(ctx).TerraformType(ctx)) { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered while verifying an attribute value matched its expected type to prevent unexpected behavior or panics. "+ + "This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Expected framework type from provider logic: %s / underlying type: %s\n", typ, typ.TerraformType(ctx))+ + fmt.Sprintf("Received framework type from provider logic: %s / underlying type: %s\n", val.Type(ctx), val.Type(ctx).TerraformType(ctx))+ + fmt.Sprintf("Path: %s", path), + ) + + return nil, diags + } + + switch t := val.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return val, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + tfVal, err := val.ToTerraformValue(ctx) + if err != nil { + return val, append(diags, toTerraformValueErrorDiag(err, path)) + } + + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return val, diags + } + } + } + + return val, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/into.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/into.go new file mode 100644 index 00000000..5615b8b8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/into.go @@ -0,0 +1,212 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "context" + "fmt" + "math/big" + "reflect" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Into uses the data in `val` to populate `target`, using the reflection +// package to recursively reflect into structs and slices. If `target` is an +// attr.Value, its assignment method will be used instead of reflecting. If +// `target` is a tftypes.ValueConverter, the FromTerraformValue method will be +// used instead of using reflection. Primitives are set using the val.As +// method. Structs use reflection: each exported struct field must have a +// "tfsdk" tag with the name of the field in the tftypes.Value, and all fields +// in the tftypes.Value must have a corresponding property in the struct. Into +// will be called for each struct field. Slices will have Into called for each +// element. +func Into(ctx context.Context, typ attr.Type, val tftypes.Value, target interface{}, opts Options, path path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + v := reflect.ValueOf(target) + if v.Kind() != reflect.Ptr { + err := fmt.Errorf("target must be a pointer, got %T, which is a %s", target, v.Kind()) + diags.AddAttributeError( + path, + "Value Conversion Error", + fmt.Sprintf("An unexpected error was encountered trying to convert the value. This is always an error in the provider. Please report the following to the provider developer:\n\nPath: %s\nError: %s", path.String(), err.Error()), + ) + return diags + } + result, diags := BuildValue(ctx, typ, val, v.Elem(), opts, path) + if diags.HasError() { + return diags + } + v.Elem().Set(result) + return diags +} + +// BuildValue constructs a reflect.Value of the same type as `target`, +// populated with the data in `val`. It will defensively instantiate new values +// to set, making it safe for use with pointer types which may be nil. It tries +// to give consumers the ability to override its default behaviors wherever +// possible. +func BuildValue(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + // if this isn't a valid reflect.Value, bail before we accidentally + // panic + if !target.IsValid() { + err := fmt.Errorf("invalid target") + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + // if this is an attr.Value, build the type from that + if target.Type().Implements(reflect.TypeOf((*attr.Value)(nil)).Elem()) { + return NewAttributeValue(ctx, typ, val, target, opts, path) + } + // if this tells tftypes how to build an instance of it out of a + // tftypes.Value, well, that's what we want, so do that instead of our + // default logic. + if target.Type().Implements(reflect.TypeOf((*tftypes.ValueConverter)(nil)).Elem()) { + return NewValueConverter(ctx, typ, val, target, opts, path) + } + // if this can explicitly be set to unknown, do that + if target.Type().Implements(reflect.TypeOf((*Unknownable)(nil)).Elem()) { + res, unknownableDiags := NewUnknownable(ctx, typ, val, target, opts, path) + diags.Append(unknownableDiags...) + if diags.HasError() { + return target, diags + } + target = res + // only return if it's unknown; we want to call SetUnknown + // either way, but if the value is unknown, there's nothing + // else to do, so bail + if !val.IsKnown() { + return target, nil + } + } + // if this can explicitly be set to null, do that + if target.Type().Implements(reflect.TypeOf((*Nullable)(nil)).Elem()) { + res, nullableDiags := NewNullable(ctx, typ, val, target, opts, path) + diags.Append(nullableDiags...) + if diags.HasError() { + return target, diags + } + target = res + // only return if it's null; we want to call SetNull either + // way, but if the value is null, there's nothing else to do, + // so bail + if val.IsNull() { + return target, nil + } + } + if !val.IsKnown() { + // we already handled unknown the only ways we can + // we checked that target doesn't have a SetUnknown method we + // can call + // we checked that target isn't an attr.Value + // all that's left to us now is to set it as an empty value or + // throw an error, depending on what's in opts + if !opts.UnhandledUnknownAsEmpty { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ + fmt.Sprintf("Path: %s\nTarget Type: %s\nSuggested Type: %s", path.String(), target.Type(), reflect.TypeOf(typ.ValueType(ctx))), + ) + return target, diags + } + // we want to set unhandled unknowns to the empty value + return reflect.Zero(target.Type()), diags + } + + if val.IsNull() { + // we already handled null the only ways we can + // we checked that target doesn't have a SetNull method we can + // call + // we checked that target isn't an attr.Value + // all that's left to us now is to set it as an empty value or + // throw an error, depending on what's in opts + if canBeNil(target) || opts.UnhandledNullAsEmpty { + return reflect.Zero(target.Type()), nil + } + + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ + fmt.Sprintf("Path: %s\nTarget Type: %s\nSuggested `types` Type: %s\nSuggested Pointer Type: *%s", path.String(), target.Type(), reflect.TypeOf(typ.ValueType(ctx)), target.Type()), + ) + + return target, diags + } + + // Dynamic reflection is currently only supported using an `attr.Value`, which should have happened in logic above. + if typ.TerraformType(ctx).Is(tftypes.DynamicPseudoType) { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + "Reflection for dynamic types is currently not supported. Use the corresponding `types` package type or a custom type that handles dynamic values.\n\n"+ + fmt.Sprintf("Path: %s\nTarget Type: %s\nSuggested `types` Type: %s", path.String(), target.Type(), reflect.TypeOf(typ.ValueType(ctx))), + ) + + return target, diags + } + + // *big.Float and *big.Int are technically pointers, but we want them + // handled as numbers + if target.Type() == reflect.TypeOf(big.NewFloat(0)) || target.Type() == reflect.TypeOf(big.NewInt(0)) { + return Number(ctx, typ, val, target, opts, path) + } + switch target.Kind() { + case reflect.Struct: + val, valDiags := Struct(ctx, typ, val, target, opts, path) + diags.Append(valDiags...) + return val, diags + case reflect.Bool, reflect.String: + val, valDiags := Primitive(ctx, typ, val, target, path) + diags.Append(valDiags...) + return val, diags + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, + reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64: + // numbers are the wooooorst and need their own special handling + // because we can't just hand them off to tftypes and also + // because we can't just make people use *big.Floats, because a + // nil *big.Float will crash everything if we don't handle it + // as a special case, so let's just special case numbers and + // let people use the types they want + val, valDiags := Number(ctx, typ, val, target, opts, path) + diags.Append(valDiags...) + return val, diags + case reflect.Slice: + val, valDiags := reflectSlice(ctx, typ, val, target, opts, path) + diags.Append(valDiags...) + return val, diags + case reflect.Map: + val, valDiags := Map(ctx, typ, val, target, opts, path) + diags.Append(valDiags...) + return val, diags + case reflect.Ptr: + val, valDiags := Pointer(ctx, typ, val, target, opts, path) + diags.Append(valDiags...) + return val, diags + default: + err := fmt.Errorf("don't know how to reflect %s into %s", val.Type(), target.Type()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/map.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/map.go new file mode 100644 index 00000000..602061d7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/map.go @@ -0,0 +1,254 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "context" + "fmt" + "reflect" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Map creates a map value that matches the type of `target`, and populates it +// with the contents of `val`. +func Map(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + underlyingValue := trueReflectValue(target) + + // this only works with maps, so check that out first + if underlyingValue.Kind() != reflect.Map { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("expected a map type, got %s", target.Type()), + })) + return target, diags + } + if !val.Type().Is(tftypes.Map{}) { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect %s into a map, must be a map", val.Type().String()), + })) + return target, diags + } + elemTyper, ok := typ.(attr.TypeWithElementType) + if !ok { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect map using type information provided by %T, %T must be an attr.TypeWithElementType", typ, typ), + })) + return target, diags + } + + // we need our value to become a map of values so we can iterate over + // them and handle them individually + values := map[string]tftypes.Value{} + err := val.As(&values) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: err, + })) + return target, diags + } + + // we need to know the type the slice is wrapping + elemType := underlyingValue.Type().Elem() + elemAttrType := elemTyper.ElementType() + + // we want an empty version of the map + m := reflect.MakeMapWithSize(underlyingValue.Type(), len(values)) + + // go over each of the values passed in, create a Go value of the right + // type for them, and add it to our new map + for key, value := range values { + // create a new Go value of the type that can go in the map + targetValue := reflect.Zero(elemType) + + // update our path so we can have nice errors + path := path.AtMapKey(key) + + // reflect the value into our new target + result, elemDiags := BuildValue(ctx, elemAttrType, value, targetValue, opts, path) + diags.Append(elemDiags...) + + if diags.HasError() { + return target, diags + } + + m.SetMapIndex(reflect.ValueOf(key), result) + } + + return m, diags +} + +// FromMap returns an attr.Value representing the data contained in `val`. +// `val` must be a map type with keys that are a string type. The attr.Value +// will be of the type produced by `typ`. +// +// It is meant to be called through FromValue, not directly. +func FromMap(ctx context.Context, typ attr.TypeWithElementType, val reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + tfType := typ.TerraformType(ctx) + + if val.IsNil() { + tfVal := tftypes.NewValue(tfType, nil) + + attrVal, err := typ.ValueFromTerraform(ctx, tfVal) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from map value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + switch t := attrVal.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return attrVal, diags + } + + elemType := typ.ElementType() + tfElems := map[string]tftypes.Value{} + for _, key := range val.MapKeys() { + if key.Kind() != reflect.String { + err := fmt.Errorf("map keys must be strings, got %s", key.Type()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + mapKeyPath := path.AtMapKey(key.String()) + + // If the element implements xattr.ValidateableAttribute, or xattr.TypeWithValidate, + // and the element does not validate then diagnostics will be added here and returned + // before reaching the switch statement below. + val, valDiags := FromValue(ctx, elemType, val.MapIndex(key).Interface(), mapKeyPath) + diags.Append(valDiags...) + + if diags.HasError() { + return nil, diags + } + + tfVal, err := val.ToTerraformValue(ctx) + if err != nil { + return nil, append(diags, toTerraformValueErrorDiag(err, path)) + } + + switch t := val.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: mapKeyPath, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := elemType.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, mapKeyPath)...) + + if diags.HasError() { + return nil, diags + } + } + } + + tfElems[key.String()] = tfVal + } + + err := tftypes.ValidateValue(tfType, tfElems) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + + tfVal := tftypes.NewValue(tfType, tfElems) + + attrVal, err := typ.ValueFromTerraform(ctx, tfVal) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to map value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + switch t := attrVal.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return attrVal, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/number.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/number.go new file mode 100644 index 00000000..c4983be6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/number.go @@ -0,0 +1,400 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "context" + "fmt" + "math" + "math/big" + "reflect" + "strconv" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Number creates a *big.Float and populates it with the data in `val`. It then +// gets converted to the type of `target`, as long as `target` is a valid +// number type (any of the built-in int, uint, or float types, *big.Float, and +// *big.Int). +// +// Number will loudly fail when a number cannot be losslessly represented using +// the requested type. +// +// It is meant to be called through Into, not directly. +func Number(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + result := big.NewFloat(0) + err := val.As(&result) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Err: err, + TargetType: target.Type(), + Val: val, + })) + return target, diags + } + roundingError := fmt.Errorf("cannot store %s in %s", result.String(), target.Type()) + roundingErrorDiag := diag.NewAttributeErrorDiagnostic( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+roundingError.Error(), + ) + + switch target.Type() { + case reflect.TypeOf(big.NewFloat(0)): + return reflect.ValueOf(result), diags + case reflect.TypeOf(big.NewInt(0)): + intResult, acc := result.Int(nil) + if acc != big.Exact { + return reflect.ValueOf(result), append(diags, roundingErrorDiag) + } + return reflect.ValueOf(intResult), diags + } + + switch target.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64: + intResult, acc := result.Int64() + if acc != big.Exact { + return target, append(diags, roundingErrorDiag) + } + switch target.Kind() { + case reflect.Int: + if strconv.IntSize == 32 && intResult > math.MaxInt32 { + return target, append(diags, roundingErrorDiag) + } + if strconv.IntSize == 32 && intResult < math.MinInt32 { + return target, append(diags, roundingErrorDiag) + } + return reflect.ValueOf(int(intResult)), diags + case reflect.Int8: + if intResult > math.MaxInt8 { + return target, append(diags, roundingErrorDiag) + } + if intResult < math.MinInt8 { + return target, append(diags, roundingErrorDiag) + } + return reflect.ValueOf(int8(intResult)), diags + case reflect.Int16: + if intResult > math.MaxInt16 { + return target, append(diags, roundingErrorDiag) + } + if intResult < math.MinInt16 { + return target, append(diags, roundingErrorDiag) + } + return reflect.ValueOf(int16(intResult)), diags + case reflect.Int32: + if intResult > math.MaxInt32 { + return target, append(diags, roundingErrorDiag) + } + if intResult < math.MinInt32 { + return target, append(diags, roundingErrorDiag) + } + return reflect.ValueOf(int32(intResult)), diags + case reflect.Int64: + return reflect.ValueOf(intResult), diags + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, + reflect.Uint64: + uintResult, acc := result.Uint64() + if acc != big.Exact { + return target, append(diags, roundingErrorDiag) + } + switch target.Kind() { + case reflect.Uint: + if strconv.IntSize == 32 && uintResult > math.MaxUint32 { + return target, append(diags, roundingErrorDiag) + } + return reflect.ValueOf(uint(uintResult)), diags + case reflect.Uint8: + if uintResult > math.MaxUint8 { + return target, append(diags, roundingErrorDiag) + } + return reflect.ValueOf(uint8(uintResult)), diags + case reflect.Uint16: + if uintResult > math.MaxUint16 { + return target, append(diags, roundingErrorDiag) + } + return reflect.ValueOf(uint16(uintResult)), diags + case reflect.Uint32: + if uintResult > math.MaxUint32 { + return target, append(diags, roundingErrorDiag) + } + return reflect.ValueOf(uint32(uintResult)), diags + case reflect.Uint64: + return reflect.ValueOf(uintResult), diags + } + case reflect.Float32: + floatResult, _ := result.Float32() + + bf := big.NewFloat(float64(floatResult)) + + if result.Text('f', -1) != bf.Text('f', -1) { + diags.Append(roundingErrorDiag) + + return target, diags + } + + return reflect.ValueOf(floatResult), diags + case reflect.Float64: + floatResult, _ := result.Float64() + + bf := big.NewFloat(floatResult) + + if result.Text('f', -1) != bf.Text('f', -1) { + diags.Append(roundingErrorDiag) + + return target, diags + } + + return reflect.ValueOf(floatResult), diags + } + + err = fmt.Errorf("cannot convert number to %s", target.Type()) + + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + + return target, diags +} + +// FromInt creates an attr.Value using `typ` from an int64. +// +// It is meant to be called through FromValue, not directly. +func FromInt(ctx context.Context, typ attr.Type, val int64, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.Number, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfNum := tftypes.NewValue(tftypes.Number, val) + + num, err := typ.ValueFromTerraform(ctx, tfNum) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := num.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return num, diags +} + +// FromUint creates an attr.Value using `typ` from a uint64. +// +// It is meant to be called through FromValue, not directly. +func FromUint(ctx context.Context, typ attr.Type, val uint64, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.Number, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfNum := tftypes.NewValue(tftypes.Number, val) + + num, err := typ.ValueFromTerraform(ctx, tfNum) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := num.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return num, diags +} + +// FromFloat creates an attr.Value using `typ` from a float64. +// +// It is meant to be called through FromValue, not directly. +func FromFloat(ctx context.Context, typ attr.Type, val float64, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.Number, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfNum := tftypes.NewValue(tftypes.Number, val) + + num, err := typ.ValueFromTerraform(ctx, tfNum) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := num.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return num, diags +} + +// FromBigFloat creates an attr.Value using `typ` from a *big.Float. +// +// It is meant to be called through FromValue, not directly. +func FromBigFloat(ctx context.Context, typ attr.Type, val *big.Float, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.Number, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfNum := tftypes.NewValue(tftypes.Number, val) + + num, err := typ.ValueFromTerraform(ctx, tfNum) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := num.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return num, diags +} + +// FromBigInt creates an attr.Value using `typ` from a *big.Int. +// +// It is meant to be called through FromValue, not directly. +func FromBigInt(ctx context.Context, typ attr.Type, val *big.Int, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + fl := big.NewFloat(0).SetInt(val) + err := tftypes.ValidateValue(tftypes.Number, fl) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfNum := tftypes.NewValue(tftypes.Number, fl) + + num, err := typ.ValueFromTerraform(ctx, tfNum) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := num.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return num, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/options.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/options.go new file mode 100644 index 00000000..a59abd97 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/options.go @@ -0,0 +1,18 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +// Options provides configuration settings for how the reflection behavior +// works, letting callers tweak different behaviors based on their needs. +type Options struct { + // UnhandledNullAsEmpty controls whether null values should be + // translated into empty values without provider interaction, or if + // they must be explicitly handled. + UnhandledNullAsEmpty bool + + // UnhandledUnknownAsEmpty controls whether null values should be + // translated into empty values without provider interaction, or if + // they must be explicitly handled. + UnhandledUnknownAsEmpty bool +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/outof.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/outof.go new file mode 100644 index 00000000..359f29a5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/outof.go @@ -0,0 +1,95 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "context" + "fmt" + "math/big" + "reflect" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// FromValue is the inverse of Into, taking a Go value (`val`) and transforming it +// into an attr.Value using the attr.Type supplied. `val` will first be +// transformed into a tftypes.Value, then passed to `typ`'s ValueFromTerraform +// method. +func FromValue(ctx context.Context, typ attr.Type, val interface{}, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + if v, ok := val.(attr.Value); ok { + return FromAttributeValue(ctx, typ, v, path) + } + if v, ok := val.(tftypes.ValueCreator); ok { + return FromValueCreator(ctx, typ, v, path) + } + if v, ok := val.(Unknownable); ok { + return FromUnknownable(ctx, typ, v, path) + } + if v, ok := val.(Nullable); ok { + return FromNullable(ctx, typ, v, path) + } + if bf, ok := val.(*big.Float); ok { + return FromBigFloat(ctx, typ, bf, path) + } + if bi, ok := val.(*big.Int); ok { + return FromBigInt(ctx, typ, bi, path) + } + value := reflect.ValueOf(val) + kind := value.Kind() + switch kind { + case reflect.Struct: + t, ok := typ.(attr.TypeWithAttributeTypes) + if !ok { + err := fmt.Errorf("cannot use type %T as schema type %T; %T must be an attr.TypeWithAttributeTypes to hold %T", val, typ, typ, val) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + return FromStruct(ctx, t, value, path) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64: + return FromInt(ctx, typ, value.Int(), path) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, + reflect.Uint64: + return FromUint(ctx, typ, value.Uint(), path) + case reflect.Float32, reflect.Float64: + return FromFloat(ctx, typ, value.Float(), path) + case reflect.Bool: + return FromBool(ctx, typ, value.Bool(), path) + case reflect.String: + return FromString(ctx, typ, value.String(), path) + case reflect.Slice: + return FromSlice(ctx, typ, value, path) + case reflect.Map: + t, ok := typ.(attr.TypeWithElementType) + if !ok { + err := fmt.Errorf("cannot use type %T as schema type %T; %T must be an attr.TypeWithElementType to hold %T", val, typ, typ, val) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + return FromMap(ctx, t, value, path) + case reflect.Ptr: + return FromPointer(ctx, typ, value, path) + default: + err := fmt.Errorf("cannot construct attr.Type from %T (%s)", val, kind) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/pointer.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/pointer.go new file mode 100644 index 00000000..d9d16206 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/pointer.go @@ -0,0 +1,142 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "context" + "fmt" + "reflect" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Pointer builds a new zero value of the concrete type that `target` +// references, populates it with BuildValue, and takes a pointer to it. +// +// It is meant to be called through Into, not directly. +func Pointer(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + if target.Kind() != reflect.Ptr { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("cannot dereference pointer, not a pointer, is a %s (%s)", target.Type(), target.Kind()), + })) + return target, diags + } + // we may have gotten a nil pointer, so we need to create our own that + // we can set + pointer := reflect.New(target.Type().Elem()) + // build out whatever the pointer is pointing to + pointed, pointedDiags := BuildValue(ctx, typ, val, pointer.Elem(), opts, path) + diags.Append(pointedDiags...) + + if diags.HasError() { + return target, diags + } + // to be able to set the pointer to our new pointer, we need to create + // a pointer to the pointer + pointerPointer := reflect.New(pointer.Type()) + // we set the pointer we created on the pointer to the pointer + pointerPointer.Elem().Set(pointer) + // then it's settable, so we can now set the concrete value we created + // on the pointer + pointerPointer.Elem().Elem().Set(pointed) + // return the pointer we created + return pointerPointer.Elem(), diags +} + +// create a zero value of concrete type underlying any number of pointers, then +// wrap it in that number of pointers again. The end result is to wind up with +// the same exact type, except now you can be sure it's pointing to actual data +// and will not give you a nil pointer dereference panic unexpectedly. +func pointerSafeZeroValue(_ context.Context, target reflect.Value) reflect.Value { + pointer := target.Type() + var pointers int + for pointer.Kind() == reflect.Ptr { + pointer = pointer.Elem() + pointers++ + } + receiver := reflect.Zero(pointer) + for i := 0; i < pointers; i++ { + newReceiver := reflect.New(receiver.Type()) + newReceiver.Elem().Set(receiver) + receiver = newReceiver + } + return receiver +} + +// FromPointer turns a pointer into an attr.Value using `typ`. If the pointer +// is nil, the attr.Value will use its null representation. If it is not nil, +// it will recurse into FromValue to find the attr.Value of the type the value +// the pointer is referencing. +// +// It is meant to be called through FromValue, not directly. +func FromPointer(ctx context.Context, typ attr.Type, value reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + if value.Kind() != reflect.Ptr { + err := fmt.Errorf("cannot use type %s as a pointer", value.Type()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from pointer value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + if value.IsNil() { + tfVal := tftypes.NewValue(typ.TerraformType(ctx), nil) + + attrVal, err := typ.ValueFromTerraform(ctx, tfVal) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from pointer value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + switch t := attrVal.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return attrVal, diags + } + + attrVal, attrValDiags := FromValue(ctx, typ, value.Elem().Interface(), path) + diags.Append(attrValDiags...) + + return attrVal, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/primitive.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/primitive.go new file mode 100644 index 00000000..813e7e47 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/primitive.go @@ -0,0 +1,151 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "context" + "errors" + "reflect" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Primitive builds a string or boolean, depending on the type of `target`, and +// populates it with the data in `val`. +// +// It is meant to be called through `Into`, not directly. +func Primitive(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + switch target.Kind() { + case reflect.Bool: + var b bool + err := val.As(&b) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: err, + })) + return target, diags + } + return reflect.ValueOf(b).Convert(target.Type()), nil + case reflect.String: + var s string + err := val.As(&s) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: err, + })) + return target, diags + } + return reflect.ValueOf(s).Convert(target.Type()), nil + default: + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: errors.New("unknown type"), + })) + return target, diags + } +} + +// FromString returns an attr.Value as produced by `typ` from a string. +// +// It is meant to be called through FromValue, not directly. +func FromString(ctx context.Context, typ attr.Type, val string, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.String, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfStr := tftypes.NewValue(tftypes.String, val) + + str, err := typ.ValueFromTerraform(ctx, tfStr) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := str.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfStr, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return str, diags +} + +// FromBool returns an attr.Value as produced by `typ` from a bool. +// +// It is meant to be called through FromValue, not directly. +func FromBool(ctx context.Context, typ attr.Type, val bool, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.Bool, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfBool := tftypes.NewValue(tftypes.Bool, val) + + b, err := typ.ValueFromTerraform(ctx, tfBool) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := b.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfBool, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return b, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/slice.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/slice.go new file mode 100644 index 00000000..794b4ef9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/slice.go @@ -0,0 +1,437 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "context" + "fmt" + "reflect" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// build a slice of elements, matching the type of `target`, and fill it with +// the data in `val`. +func reflectSlice(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + // this only works with slices, so check that out first + if target.Kind() != reflect.Slice { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("expected a slice type, got %s", target.Type()), + })) + return target, diags + } + + // we need our value to become a list of values so we can iterate over + // them and handle them individually + var values []tftypes.Value + err := val.As(&values) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: err, + })) + return target, diags + } + + switch t := typ.(type) { + // List or Set + case attr.TypeWithElementType: + // we need to know the type the slice is wrapping + elemType := target.Type().Elem() + elemAttrType := t.ElementType() + + // we want an empty version of the slice + slice := reflect.MakeSlice(target.Type(), 0, len(values)) + + // go over each of the values passed in, create a Go value of the right + // type for them, and add it to our new slice + for pos, value := range values { + // create a new Go value of the type that can go in the slice + targetValue := reflect.Zero(elemType) + + // update our path so we can have nice errors + valPath := path.AtListIndex(pos) + + if typ.TerraformType(ctx).Is(tftypes.Set{}) { + attrVal, err := elemAttrType.ValueFromTerraform(ctx, value) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + + valPath = path.AtSetValue(attrVal) + } + + // reflect the value into our new target + val, valDiags := BuildValue(ctx, elemAttrType, value, targetValue, opts, valPath) + diags.Append(valDiags...) + + if diags.HasError() { + return target, diags + } + + // add the new target to our slice + slice = reflect.Append(slice, val) + } + + return slice, diags + + // Tuple reflection into slices is currently limited to use-cases where all tuple element types are the same. + // + // Overall, Tuple support is limited in the framework, but the main path that executes tuple reflection is the provider-defined function variadic + // parameter. All tuple elements in this variadic parameter will have the same element type. For use-cases where the variadic parameter is a dynamic type, + // all elements will have the same type of `DynamicType` and value of `DynamicValue`, with an underlying value that may be different. + case attr.TypeWithElementTypes: + // we need to know the type the slice is wrapping + elemType := target.Type().Elem() + + // we want an empty version of the slice + slice := reflect.MakeSlice(target.Type(), 0, len(values)) + + if len(t.ElementTypes()) <= 0 { + // If the tuple values are empty as well, we can just pass back an empty slice of the type we received. + if len(values) == 0 { + return slice, diags + } + + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect %s using type information provided by %T, tuple type contained no element types but received values", val.Type(), t), + })) + return target, diags + } + + // Ensure that all tuple element types are the same by comparing each element type to the first + multipleTypes := false + allElemTypes := t.ElementTypes() + elemAttrType := allElemTypes[0] + for _, elemType := range allElemTypes[1:] { + if !elemAttrType.Equal(elemType) { + multipleTypes = true + break + } + } + + if multipleTypes { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect %s using type information provided by %T, reflection support for tuples is limited to multiple elements of the same element type. Expected all element types to be %T", val.Type(), t, elemAttrType), + })) + return target, diags + } + + // go over each of the values passed in, create a Go value of the right + // type for them, and add it to our new slice + for pos, value := range values { + // create a new Go value of the type that can go in the slice + targetValue := reflect.Zero(elemType) + + // update our path so we can have nice errors + valPath := path.AtTupleIndex(pos) + + // reflect the value into our new target + val, valDiags := BuildValue(ctx, elemAttrType, value, targetValue, opts, valPath) + diags.Append(valDiags...) + + if diags.HasError() { + return target, diags + } + + // add the new target to our slice + slice = reflect.Append(slice, val) + } + + return slice, diags + default: + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect %s using type information provided by %T, %T must be an attr.TypeWithElementType or attr.TypeWithElementTypes", val.Type(), typ, typ), + })) + return target, diags + } +} + +// FromSlice returns an attr.Value as produced by `typ` using the data in +// `val`. `val` must be a slice. `typ` must be an attr.TypeWithElementType or +// attr.TypeWithElementTypes. If the slice is nil, the representation of null +// for `typ` will be returned. Otherwise, FromSlice will recurse into FromValue +// for each element in the slice, using the element type or types defined on +// `typ` to construct values for them. +// +// It is meant to be called through FromValue, not directly. +func FromSlice(ctx context.Context, typ attr.Type, val reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + tfType := typ.TerraformType(ctx) + + if val.IsNil() { + tfVal := tftypes.NewValue(tfType, nil) + + attrVal, err := typ.ValueFromTerraform(ctx, tfVal) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + switch t := attrVal.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return attrVal, diags + } + + tfElems := make([]tftypes.Value, 0, val.Len()) + switch t := typ.(type) { + // List or Set + case attr.TypeWithElementType: + elemType := t.ElementType() + for i := 0; i < val.Len(); i++ { + // The underlying reflect.Slice is fetched by Index(). For set types, + // the path is value-based instead of index-based. Since there is only + // the index until the value is retrieved, this will pass the + // technically incorrect index-based path at first for framework + // debugging purposes, then correct the path afterwards. + valPath := path.AtListIndex(i) + + // If the element implements xattr.ValidateableAttribute, or xattr.TypeWithValidate, + // and the element does not validate then diagnostics will be added here and returned + // before reaching the switch statement below. + val, valDiags := FromValue(ctx, elemType, val.Index(i).Interface(), valPath) + diags.Append(valDiags...) + + if diags.HasError() { + return nil, diags + } + + tfVal, err := val.ToTerraformValue(ctx) + if err != nil { + return nil, append(diags, toTerraformValueErrorDiag(err, path)) + } + + if tfType.Is(tftypes.Set{}) { + valPath = path.AtSetValue(val) + } + + switch t := val.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: valPath, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := elemType.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, valPath)...) + + if diags.HasError() { + return nil, diags + } + } + } + + tfElems = append(tfElems, tfVal) + } + + // Tuple reflection from slices is currently limited to use-cases where all tuple element types are the same. + // + // Overall, Tuple support is limited in the framework, but the main path that executes tuple reflection is the provider-defined function variadic + // parameter. All tuple elements in this variadic parameter will have the same element type. For use-cases where the variadic parameter is a dynamic type, + // all elements will have the same type of `DynamicType` and value of `DynamicValue`, with an underlying value that may be different. + case attr.TypeWithElementTypes: + if len(t.ElementTypes()) <= 0 { + // If the tuple values are empty as well, we can just pass back an empty slice of the type we received. + if val.Len() == 0 { + break + } + + err := fmt.Errorf("cannot use type %s as schema type %T; tuple type contained no element types but received values", val.Type(), t) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + // Ensure that all tuple element types are the same by comparing each element type to the first + multipleTypes := false + allElemTypes := t.ElementTypes() + elemAttrType := allElemTypes[0] + for _, elemType := range allElemTypes[1:] { + if !elemAttrType.Equal(elemType) { + multipleTypes = true + break + } + } + + if multipleTypes { + err := fmt.Errorf("cannot use type %s as schema type %T; reflection support for tuples is limited to multiple elements of the same element type. Expected all element types to be %T", val.Type(), t, elemAttrType) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + for i := 0; i < val.Len(); i++ { + valPath := path.AtTupleIndex(i) + + // If the element implements xattr.ValidateableAttribute, or xattr.TypeWithValidate, + // and the element does not validate then diagnostics will be added here and returned + // before reaching the switch statement below. + val, valDiags := FromValue(ctx, elemAttrType, val.Index(i).Interface(), valPath) + diags.Append(valDiags...) + + if diags.HasError() { + return nil, diags + } + + tfVal, err := val.ToTerraformValue(ctx) + if err != nil { + return nil, append(diags, toTerraformValueErrorDiag(err, path)) + } + + switch t := val.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: valPath, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := elemAttrType.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, valPath)...) + + if diags.HasError() { + return nil, diags + } + } + } + + tfElems = append(tfElems, tfVal) + } + default: + err := fmt.Errorf("cannot use type %s as schema type %T; %T must be an attr.TypeWithElementType or attr.TypeWithElementTypes", val.Type(), t, t) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + err := tftypes.ValidateValue(tfType, tfElems) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + + tfVal := tftypes.NewValue(tfType, tfElems) + + attrVal, err := typ.ValueFromTerraform(ctx, tfVal) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + switch t := attrVal.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return attrVal, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/struct.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/struct.go new file mode 100644 index 00000000..d48ff2d3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/reflect/struct.go @@ -0,0 +1,310 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package reflect + +import ( + "context" + "fmt" + "reflect" + "strings" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Struct builds a new struct using the data in `object`, as long as `object` +// is a `tftypes.Object`. It will take the struct type from `target`, which +// must be a struct type. +// +// The properties on `target` must be tagged with a "tfsdk" label containing +// the field name to map to that property. Every property must be tagged, and +// every property must be present in the type of `object`, and all the +// attributes in the type of `object` must have a corresponding property. +// Properties that don't map to object attributes must have a `tfsdk:"-"` tag, +// explicitly defining them as not part of the object. This is to catch typos +// and other mistakes early. +// +// Struct is meant to be called from Into, not directly. +func Struct(ctx context.Context, typ attr.Type, object tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + // this only works with object values, so make sure that constraint is + // met + if target.Kind() != reflect.Struct { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("expected a struct type, got %s", target.Type()), + })) + return target, diags + } + if !object.Type().Is(tftypes.Object{}) { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect %s into a struct, must be an object", object.Type().String()), + })) + return target, diags + } + attrsType, ok := typ.(attr.TypeWithAttributeTypes) + if !ok { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect object using type information provided by %T, %T must be an attr.TypeWithAttributeTypes", typ, typ), + })) + return target, diags + } + + // collect a map of fields that are in the object passed in + var objectFields map[string]tftypes.Value + err := object.As(&objectFields) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: err, + })) + return target, diags + } + + // collect a map of fields that are defined in the tags of the struct + // passed in + targetFields, err := getStructTags(ctx, target, path) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("error retrieving field names from struct tags: %w", err), + })) + return target, diags + } + + // we require an exact, 1:1 match of these fields to avoid typos + // leading to surprises, so let's ensure they have the exact same + // fields defined + var objectMissing, targetMissing []string + for field := range targetFields { + if _, ok := objectFields[field]; !ok { + objectMissing = append(objectMissing, field) + } + } + for field := range objectFields { + if _, ok := targetFields[field]; !ok { + targetMissing = append(targetMissing, field) + } + } + if len(objectMissing) > 0 || len(targetMissing) > 0 { + var missing []string + if len(objectMissing) > 0 { + missing = append(missing, fmt.Sprintf("Struct defines fields not found in object: %s.", commaSeparatedString(objectMissing))) + } + if len(targetMissing) > 0 { + missing = append(missing, fmt.Sprintf("Object defines fields not found in struct: %s.", commaSeparatedString(targetMissing))) + } + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("mismatch between struct and object: %s", strings.Join(missing, " ")), + })) + return target, diags + } + + attrTypes := attrsType.AttributeTypes() + + // now that we know they match perfectly, fill the struct with the + // values in the object + result := reflect.New(target.Type()).Elem() + for field, structFieldPos := range targetFields { + attrType, ok := attrTypes[field] + if !ok { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("could not find type information for attribute in supplied attr.Type %T", typ), + })) + return target, diags + } + structField := result.Field(structFieldPos) + fieldVal, fieldValDiags := BuildValue(ctx, attrType, objectFields[field], structField, opts, path.AtName(field)) + diags.Append(fieldValDiags...) + + if diags.HasError() { + return target, diags + } + structField.Set(fieldVal) + } + return result, diags +} + +// FromStruct builds an attr.Value as produced by `typ` from the data in `val`. +// `val` must be a struct type, and must have all its properties tagged and be +// a 1:1 match with the attributes reported by `typ`. FromStruct will recurse +// into FromValue for each attribute, using the type of the attribute as +// reported by `typ`. +// +// It is meant to be called through FromValue, not directly. +func FromStruct(ctx context.Context, typ attr.TypeWithAttributeTypes, val reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + objTypes := map[string]tftypes.Type{} + objValues := map[string]tftypes.Value{} + + // collect a map of fields that are defined in the tags of the struct + // passed in + targetFields, err := getStructTags(ctx, val, path) + if err != nil { + err = fmt.Errorf("error retrieving field names from struct tags: %w", err) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from struct value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + attrTypes := typ.AttributeTypes() + + var objectMissing, structMissing []string + + for field := range targetFields { + if _, ok := attrTypes[field]; !ok { + objectMissing = append(objectMissing, field) + } + } + + for attrName, attrType := range attrTypes { + if attrType == nil { + objectMissing = append(objectMissing, attrName) + } + + if _, ok := targetFields[attrName]; !ok { + structMissing = append(structMissing, attrName) + } + } + + if len(objectMissing) > 0 || len(structMissing) > 0 { + missing := make([]string, 0, len(objectMissing)+len(structMissing)) + + if len(objectMissing) > 0 { + missing = append(missing, fmt.Sprintf("Struct defines fields not found in object: %s.", commaSeparatedString(objectMissing))) + } + + if len(structMissing) > 0 { + missing = append(missing, fmt.Sprintf("Object defines fields not found in struct: %s.", commaSeparatedString(structMissing))) + } + + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from struct into an object. "+ + "This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Mismatch between struct and object type: %s\n", strings.Join(missing, " "))+ + fmt.Sprintf("Struct: %s\n", val.Type())+ + fmt.Sprintf("Object type: %s", typ), + ) + + return nil, diags + } + + for name, fieldNo := range targetFields { + path := path.AtName(name) + fieldValue := val.Field(fieldNo) + + // If the attr implements xattr.ValidateableAttribute, or xattr.TypeWithValidate, + // and the attr does not validate then diagnostics will be added here and returned + // before reaching the switch statement below. + attrVal, attrValDiags := FromValue(ctx, attrTypes[name], fieldValue.Interface(), path) + diags.Append(attrValDiags...) + + if diags.HasError() { + return nil, diags + } + + tfObjVal, err := attrVal.ToTerraformValue(ctx) + if err != nil { + return nil, append(diags, toTerraformValueErrorDiag(err, path)) + } + + switch t := attrVal.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := attrTypes[name].(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfObjVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + tfObjTyp := tfObjVal.Type() + + // If the original attribute type is tftypes.DynamicPseudoType, the value could end up being + // a concrete type (like tftypes.String, tftypes.List, etc.). In this scenario, the type used + // to build the final tftypes.Object must stay as tftypes.DynamicPseudoType + if attrTypes[name].TerraformType(ctx).Is(tftypes.DynamicPseudoType) { + tfObjTyp = tftypes.DynamicPseudoType + } + + objValues[name] = tfObjVal + objTypes[name] = tfObjTyp + } + + tfVal := tftypes.NewValue(tftypes.Object{ + AttributeTypes: objTypes, + }, objValues) + + ret, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + switch t := ret.(type) { + case xattr.ValidateableAttribute: + resp := xattr.ValidateAttributeResponse{} + + t.ValidateAttribute(ctx, + xattr.ValidateAttributeRequest{ + Path: path, + }, + &resp, + ) + + diags.Append(resp.Diagnostics...) + + if diags.HasError() { + return nil, diags + } + default: + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + } + + return ret, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/applyresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/applyresourcechange.go new file mode 100644 index 00000000..28937399 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/applyresourcechange.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// ApplyResourceChangeResponse returns the *tfprotov5.ApplyResourceChangeResponse +// equivalent of a *fwserver.ApplyResourceChangeResponse. +func ApplyResourceChangeResponse(ctx context.Context, fw *fwserver.ApplyResourceChangeResponse) *tfprotov5.ApplyResourceChangeResponse { + if fw == nil { + return nil + } + + proto5 := &tfprotov5.ApplyResourceChangeResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + newState, diags := State(ctx, fw.NewState) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.NewState = newState + + newPrivate, diags := fw.Private.Bytes(ctx) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.Private = newPrivate + + return proto5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/block.go new file mode 100644 index 00000000..c9c95e39 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/block.go @@ -0,0 +1,97 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + "sort" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Block returns the *tfprotov5.SchemaNestedBlock equivalent of a Block. +// Errors will be tftypes.AttributePathErrors based on `path`. `name` is the +// name of the attribute. +func Block(ctx context.Context, name string, path *tftypes.AttributePath, b fwschema.Block) (*tfprotov5.SchemaNestedBlock, error) { + schemaNestedBlock := &tfprotov5.SchemaNestedBlock{ + Block: &tfprotov5.SchemaBlock{ + Deprecated: b.GetDeprecationMessage() != "", + }, + TypeName: name, + } + + if b.GetDescription() != "" { + schemaNestedBlock.Block.Description = b.GetDescription() + schemaNestedBlock.Block.DescriptionKind = tfprotov5.StringKindPlain + } + + if b.GetMarkdownDescription() != "" { + schemaNestedBlock.Block.Description = b.GetMarkdownDescription() + schemaNestedBlock.Block.DescriptionKind = tfprotov5.StringKindMarkdown + } + + nm := b.GetNestingMode() + switch nm { + case fwschema.BlockNestingModeList: + schemaNestedBlock.Nesting = tfprotov5.SchemaNestedBlockNestingModeList + case fwschema.BlockNestingModeSet: + schemaNestedBlock.Nesting = tfprotov5.SchemaNestedBlockNestingModeSet + case fwschema.BlockNestingModeSingle: + schemaNestedBlock.Nesting = tfprotov5.SchemaNestedBlockNestingModeSingle + default: + return nil, path.NewErrorf("unrecognized nesting mode %v", nm) + } + + nestedBlockObject := b.GetNestedObject() + + for attrName, attr := range nestedBlockObject.GetAttributes() { + attrPath := path.WithAttributeName(attrName) + attrProto5, err := SchemaAttribute(ctx, attrName, attrPath, attr) + + if err != nil { + return nil, err + } + + schemaNestedBlock.Block.Attributes = append(schemaNestedBlock.Block.Attributes, attrProto5) + } + + for blockName, block := range nestedBlockObject.GetBlocks() { + blockPath := path.WithAttributeName(blockName) + blockProto5, err := Block(ctx, blockName, blockPath, block) + + if err != nil { + return nil, err + } + + schemaNestedBlock.Block.BlockTypes = append(schemaNestedBlock.Block.BlockTypes, blockProto5) + } + + sort.Slice(schemaNestedBlock.Block.Attributes, func(i, j int) bool { + if schemaNestedBlock.Block.Attributes[i] == nil { + return true + } + + if schemaNestedBlock.Block.Attributes[j] == nil { + return false + } + + return schemaNestedBlock.Block.Attributes[i].Name < schemaNestedBlock.Block.Attributes[j].Name + }) + + sort.Slice(schemaNestedBlock.Block.BlockTypes, func(i, j int) bool { + if schemaNestedBlock.Block.BlockTypes[i] == nil { + return true + } + + if schemaNestedBlock.Block.BlockTypes[j] == nil { + return false + } + + return schemaNestedBlock.Block.BlockTypes[i].TypeName < schemaNestedBlock.Block.BlockTypes[j].TypeName + }) + + return schemaNestedBlock, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/callfunction.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/callfunction.go new file mode 100644 index 00000000..a5105a94 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/callfunction.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// CallFunctionResponse returns the *tfprotov5.CallFunctionResponse +// equivalent of a *fwserver.CallFunctionResponse. +func CallFunctionResponse(ctx context.Context, fw *fwserver.CallFunctionResponse) *tfprotov5.CallFunctionResponse { + if fw == nil { + return nil + } + + result, resultErr := FunctionResultData(ctx, fw.Result) + + funcErr := function.ConcatFuncErrors(fw.Error, resultErr) + + return &tfprotov5.CallFunctionResponse{ + Error: FunctionError(ctx, funcErr), + Result: result, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/config.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/config.go new file mode 100644 index 00000000..6eea687e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/config.go @@ -0,0 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// Config returns the *tfprotov5.DynamicValue for a *tfsdk.Config. +func Config(ctx context.Context, fw *tfsdk.Config) (*tfprotov5.DynamicValue, diag.Diagnostics) { + if fw == nil { + return nil, nil + } + + data := &fwschemadata.Data{ + Description: fwschemadata.DataDescriptionConfiguration, + Schema: fw.Schema, + TerraformValue: fw.Raw, + } + + return DynamicValue(ctx, data) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/configureprovider.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/configureprovider.go new file mode 100644 index 00000000..a3dfd7b6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/configureprovider.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ConfigureProviderResponse returns the *tfprotov5.ConfigureProviderResponse +// equivalent of a *fwserver.ConfigureProviderResponse. +func ConfigureProviderResponse(ctx context.Context, fw *provider.ConfigureResponse) *tfprotov5.ConfigureProviderResponse { + if fw == nil { + return nil + } + + proto5 := &tfprotov5.ConfigureProviderResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + return proto5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/datasourcemetadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/datasourcemetadata.go new file mode 100644 index 00000000..98e6c4f4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/datasourcemetadata.go @@ -0,0 +1,19 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// DataSourceMetadata returns the tfprotov5.DataSourceMetadata for a +// fwserver.DataSourceMetadata. +func DataSourceMetadata(ctx context.Context, fw fwserver.DataSourceMetadata) tfprotov5.DataSourceMetadata { + return tfprotov5.DataSourceMetadata{ + TypeName: fw.TypeName, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/diagnostics.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/diagnostics.go new file mode 100644 index 00000000..564d8979 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/diagnostics.go @@ -0,0 +1,52 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/totftypes" +) + +// DiagnosticSeverity converts diag.Severity into tfprotov5.DiagnosticSeverity. +func DiagnosticSeverity(s diag.Severity) tfprotov5.DiagnosticSeverity { + switch s { + case diag.SeverityError: + return tfprotov5.DiagnosticSeverityError + case diag.SeverityWarning: + return tfprotov5.DiagnosticSeverityWarning + default: + return tfprotov5.DiagnosticSeverityInvalid + } +} + +// Diagnostics converts the diagnostics into the tfprotov5 collection type. +func Diagnostics(ctx context.Context, diagnostics diag.Diagnostics) []*tfprotov5.Diagnostic { + var results []*tfprotov5.Diagnostic + + for _, diagnostic := range diagnostics { + tfprotov5Diagnostic := &tfprotov5.Diagnostic{ + Detail: diagnostic.Detail(), + Severity: DiagnosticSeverity(diagnostic.Severity()), + Summary: diagnostic.Summary(), + } + + if diagWithPath, ok := diagnostic.(diag.DiagnosticWithPath); ok { + var diags diag.Diagnostics + + tfprotov5Diagnostic.Attribute, diags = totftypes.AttributePath(ctx, diagWithPath.Path()) + + if diags.HasError() { + results = append(results, Diagnostics(ctx, diags)...) + } + } + + results = append(results, tfprotov5Diagnostic) + } + + return results +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/doc.go new file mode 100644 index 00000000..c9377e6f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package toproto5 contains functions to convert from framework types to +// protocol version 5 (tfprotov5) types. +package toproto5 diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/dynamic_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/dynamic_value.go new file mode 100644 index 00000000..04a16954 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/dynamic_value.go @@ -0,0 +1,47 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// DynamicValue returns the *tfprotov5.DynamicValue for a given +// fwschemadata.Data. +// +// If necessary, the underlying data is modified to convert list and set block +// values from a null collection to an empty collection. This is to prevent +// developers from needing to understand Terraform's differences between +// block and attribute values where blocks are technically never null, but from +// a developer perspective this distinction introduces unnecessary complexity. +func DynamicValue(ctx context.Context, data *fwschemadata.Data) (*tfprotov5.DynamicValue, diag.Diagnostics) { + if data == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Prevent Terraform core errors for null list/set blocks. + diags.Append(data.ReifyNullCollectionBlocks(ctx)...) + + proto5, err := tfprotov5.NewDynamicValue(data.Schema.Type().TerraformType(ctx), data.TerraformValue) + + if err != nil { + diags.AddError( + "Unable to Convert "+data.Description.Title(), + "An unexpected error was encountered when converting the "+data.Description.String()+" to the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Unable to create DynamicValue: "+err.Error(), + ) + + return nil, diags + } + + return &proto5, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/function.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/function.go new file mode 100644 index 00000000..5ee2e16e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/function.go @@ -0,0 +1,125 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// Function returns the *tfprotov5.Function for a function.Definition. +func Function(ctx context.Context, fw function.Definition) *tfprotov5.Function { + proto := &tfprotov5.Function{ + DeprecationMessage: fw.DeprecationMessage, + Parameters: make([]*tfprotov5.FunctionParameter, 0, len(fw.Parameters)), + Return: FunctionReturn(ctx, fw.Return), + Summary: fw.Summary, + } + + if fw.MarkdownDescription != "" { + proto.Description = fw.MarkdownDescription + proto.DescriptionKind = tfprotov5.StringKindMarkdown + } else if fw.Description != "" { + proto.Description = fw.Description + proto.DescriptionKind = tfprotov5.StringKindPlain + } + + for _, fwParameter := range fw.Parameters { + protoParam := FunctionParameter(ctx, fwParameter) + proto.Parameters = append(proto.Parameters, protoParam) + } + + if fw.VariadicParameter != nil { + protoParam := FunctionParameter(ctx, fw.VariadicParameter) + proto.VariadicParameter = protoParam + } + + return proto +} + +// FunctionParameter returns the *tfprotov5.FunctionParameter for a +// function.Parameter. +func FunctionParameter(ctx context.Context, fw function.Parameter) *tfprotov5.FunctionParameter { + if fw == nil { + return nil + } + + proto := &tfprotov5.FunctionParameter{ + AllowNullValue: fw.GetAllowNullValue(), + AllowUnknownValues: fw.GetAllowUnknownValues(), + Name: fw.GetName(), + Type: fw.GetType().TerraformType(ctx), + } + + if fw.GetMarkdownDescription() != "" { + proto.Description = fw.GetMarkdownDescription() + proto.DescriptionKind = tfprotov5.StringKindMarkdown + } else if fw.GetDescription() != "" { + proto.Description = fw.GetDescription() + proto.DescriptionKind = tfprotov5.StringKindPlain + } + + return proto +} + +// FunctionMetadata returns the tfprotov5.FunctionMetadata for a +// fwserver.FunctionMetadata. +func FunctionMetadata(ctx context.Context, fw fwserver.FunctionMetadata) tfprotov5.FunctionMetadata { + proto := tfprotov5.FunctionMetadata{ + Name: fw.Name, + } + + return proto +} + +// FunctionReturn returns the *tfprotov5.FunctionReturn for a +// function.Return. +func FunctionReturn(ctx context.Context, fw function.Return) *tfprotov5.FunctionReturn { + if fw == nil { + return nil + } + + proto := &tfprotov5.FunctionReturn{ + Type: fw.GetType().TerraformType(ctx), + } + + return proto +} + +// FunctionResultData returns the *tfprotov5.DynamicValue for a given +// function.ResultData. +func FunctionResultData(ctx context.Context, data function.ResultData) (*tfprotov5.DynamicValue, *function.FuncError) { + attrValue := data.Value() + + if attrValue == nil { + return nil, nil + } + + tfType := attrValue.Type(ctx).TerraformType(ctx) + tfValue, err := attrValue.ToTerraformValue(ctx) + + if err != nil { + msg := "Unable to Convert Function Result Data: An unexpected error was encountered when converting the function result data to the protocol type. " + + "Please report this to the provider developer:\n\n" + + "Unable to convert framework type to tftypes: " + err.Error() + + return nil, function.NewFuncError(msg) + } + + dynamicValue, err := tfprotov5.NewDynamicValue(tfType, tfValue) + + if err != nil { + msg := "Unable to Convert Function Result Data: An unexpected error was encountered when converting the function result data to the protocol type. " + + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n" + + "Unable to create DynamicValue: " + err.Error() + + return nil, function.NewFuncError(msg) + } + + return &dynamicValue, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/function_errors.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/function_errors.go new file mode 100644 index 00000000..7c58f36e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/function_errors.go @@ -0,0 +1,24 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/function" +) + +// FunctionError converts the function error into the tfprotov5 function error. +func FunctionError(ctx context.Context, funcErr *function.FuncError) *tfprotov5.FunctionError { + if funcErr == nil { + return nil + } + + return &tfprotov5.FunctionError{ + Text: funcErr.Text, + FunctionArgument: funcErr.FunctionArgument, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getfunctions.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getfunctions.go new file mode 100644 index 00000000..1fa61a3f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getfunctions.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetFunctionsResponse returns the *tfprotov5.GetFunctionsResponse +// equivalent of a *fwserver.GetFunctionsResponse. +func GetFunctionsResponse(ctx context.Context, fw *fwserver.GetFunctionsResponse) *tfprotov5.GetFunctionsResponse { + if fw == nil { + return nil + } + + proto := &tfprotov5.GetFunctionsResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + Functions: make(map[string]*tfprotov5.Function, len(fw.FunctionDefinitions)), + } + + for name, functionDefinition := range fw.FunctionDefinitions { + proto.Functions[name] = Function(ctx, functionDefinition) + } + + return proto +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getmetadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getmetadata.go new file mode 100644 index 00000000..9c1892d8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getmetadata.go @@ -0,0 +1,41 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetMetadataResponse returns the *tfprotov5.GetMetadataResponse +// equivalent of a *fwserver.GetMetadataResponse. +func GetMetadataResponse(ctx context.Context, fw *fwserver.GetMetadataResponse) *tfprotov5.GetMetadataResponse { + if fw == nil { + return nil + } + + protov6 := &tfprotov5.GetMetadataResponse{ + DataSources: make([]tfprotov5.DataSourceMetadata, 0, len(fw.DataSources)), + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + Functions: make([]tfprotov5.FunctionMetadata, 0, len(fw.Functions)), + Resources: make([]tfprotov5.ResourceMetadata, 0, len(fw.Resources)), + ServerCapabilities: ServerCapabilities(ctx, fw.ServerCapabilities), + } + + for _, datasource := range fw.DataSources { + protov6.DataSources = append(protov6.DataSources, DataSourceMetadata(ctx, datasource)) + } + + for _, function := range fw.Functions { + protov6.Functions = append(protov6.Functions, FunctionMetadata(ctx, function)) + } + + for _, resource := range fw.Resources { + protov6.Resources = append(protov6.Resources, ResourceMetadata(ctx, resource)) + } + + return protov6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getproviderschema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getproviderschema.go new file mode 100644 index 00000000..1fec486a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/getproviderschema.go @@ -0,0 +1,87 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetProviderSchemaResponse returns the *tfprotov5.GetProviderSchemaResponse +// equivalent of a *fwserver.GetProviderSchemaResponse. +func GetProviderSchemaResponse(ctx context.Context, fw *fwserver.GetProviderSchemaResponse) *tfprotov5.GetProviderSchemaResponse { + if fw == nil { + return nil + } + + protov5 := &tfprotov5.GetProviderSchemaResponse{ + DataSourceSchemas: make(map[string]*tfprotov5.Schema, len(fw.DataSourceSchemas)), + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + Functions: make(map[string]*tfprotov5.Function, len(fw.FunctionDefinitions)), + ResourceSchemas: make(map[string]*tfprotov5.Schema, len(fw.ResourceSchemas)), + ServerCapabilities: ServerCapabilities(ctx, fw.ServerCapabilities), + } + + var err error + + protov5.Provider, err = Schema(ctx, fw.Provider) + + if err != nil { + protov5.Diagnostics = append(protov5.Diagnostics, &tfprotov5.Diagnostic{ + Severity: tfprotov5.DiagnosticSeverityError, + Summary: "Error converting provider schema", + Detail: "The provider schema couldn't be converted into a usable type. This is always a problem with the provider. Please report the following to the provider developer:\n\n" + err.Error(), + }) + + return protov5 + } + + protov5.ProviderMeta, err = Schema(ctx, fw.ProviderMeta) + + if err != nil { + protov5.Diagnostics = append(protov5.Diagnostics, &tfprotov5.Diagnostic{ + Severity: tfprotov5.DiagnosticSeverityError, + Summary: "Error converting provider_meta schema", + Detail: "The provider_meta schema couldn't be converted into a usable type. This is always a problem with the provider. Please report the following to the provider developer:\n\n" + err.Error(), + }) + + return protov5 + } + + for dataSourceType, dataSourceSchema := range fw.DataSourceSchemas { + protov5.DataSourceSchemas[dataSourceType], err = Schema(ctx, dataSourceSchema) + + if err != nil { + protov5.Diagnostics = append(protov5.Diagnostics, &tfprotov5.Diagnostic{ + Severity: tfprotov5.DiagnosticSeverityError, + Summary: "Error converting data source schema", + Detail: "The schema for the data source \"" + dataSourceType + "\" couldn't be converted into a usable type. This is always a problem with the provider. Please report the following to the provider developer:\n\n" + err.Error(), + }) + + return protov5 + } + } + + for name, functionDefinition := range fw.FunctionDefinitions { + protov5.Functions[name] = Function(ctx, functionDefinition) + } + + for resourceType, resourceSchema := range fw.ResourceSchemas { + protov5.ResourceSchemas[resourceType], err = Schema(ctx, resourceSchema) + + if err != nil { + protov5.Diagnostics = append(protov5.Diagnostics, &tfprotov5.Diagnostic{ + Severity: tfprotov5.DiagnosticSeverityError, + Summary: "Error converting resource schema", + Detail: "The schema for the resource \"" + resourceType + "\" couldn't be converted into a usable type. This is always a problem with the provider. Please report the following to the provider developer:\n\n" + err.Error(), + }) + + return protov5 + } + } + + return protov5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/importedresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/importedresource.go new file mode 100644 index 00000000..1a208db6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/importedresource.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// ImportedResource returns the *tfprotov5.ImportedResource equivalent of a +// *fwserver.ImportedResource. +func ImportedResource(ctx context.Context, fw *fwserver.ImportedResource) (*tfprotov5.ImportedResource, diag.Diagnostics) { + if fw == nil { + return nil, nil + } + + proto5 := &tfprotov5.ImportedResource{ + TypeName: fw.TypeName, + } + + state, diags := State(ctx, &fw.State) + + proto5.State = state + + newPrivate, privateDiags := fw.Private.Bytes(ctx) + + diags = append(diags, privateDiags...) + proto5.Private = newPrivate + + return proto5, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/importresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/importresourcestate.go new file mode 100644 index 00000000..654b84b6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/importresourcestate.go @@ -0,0 +1,37 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ImportResourceStateResponse returns the *tfprotov5.ImportResourceStateResponse +// equivalent of a *fwserver.ImportResourceStateResponse. +func ImportResourceStateResponse(ctx context.Context, fw *fwserver.ImportResourceStateResponse) *tfprotov5.ImportResourceStateResponse { + if fw == nil { + return nil + } + + proto5 := &tfprotov5.ImportResourceStateResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + for _, fwImportedResource := range fw.ImportedResources { + proto5ImportedResource, diags := ImportedResource(ctx, &fwImportedResource) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + + if diags.HasError() { + continue + } + + proto5.ImportedResources = append(proto5.ImportedResources, proto5ImportedResource) + } + + return proto5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/moveresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/moveresourcestate.go new file mode 100644 index 00000000..bfffadf1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/moveresourcestate.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// MoveResourceStateResponse returns the *tfprotov5.MoveResourceStateResponse +// equivalent of a *fwserver.MoveResourceStateResponse. +func MoveResourceStateResponse(ctx context.Context, fw *fwserver.MoveResourceStateResponse) *tfprotov5.MoveResourceStateResponse { + if fw == nil { + return nil + } + + proto5 := &tfprotov5.MoveResourceStateResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + targetPrivate, diags := fw.TargetPrivate.Bytes(ctx) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.TargetPrivate = targetPrivate + + targetState, diags := State(ctx, fw.TargetState) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.TargetState = targetState + + return proto5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/planresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/planresourcechange.go new file mode 100644 index 00000000..1677b359 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/planresourcechange.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/totftypes" +) + +// PlanResourceChangeResponse returns the *tfprotov5.PlanResourceChangeResponse +// equivalent of a *fwserver.PlanResourceChangeResponse. +func PlanResourceChangeResponse(ctx context.Context, fw *fwserver.PlanResourceChangeResponse) *tfprotov5.PlanResourceChangeResponse { + if fw == nil { + return nil + } + + proto5 := &tfprotov5.PlanResourceChangeResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + plannedState, diags := State(ctx, fw.PlannedState) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.PlannedState = plannedState + + requiresReplace, diags := totftypes.AttributePaths(ctx, fw.RequiresReplace) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.RequiresReplace = requiresReplace + + plannedPrivate, diags := fw.PlannedPrivate.Bytes(ctx) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.PlannedPrivate = plannedPrivate + + return proto5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/prepareproviderconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/prepareproviderconfig.go new file mode 100644 index 00000000..f152befc --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/prepareproviderconfig.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// PrepareProviderConfigResponse returns the *tfprotov5.PrepareProviderConfigResponse +// equivalent of a *fwserver.ValidateProviderConfigResponse. +func PrepareProviderConfigResponse(ctx context.Context, fw *fwserver.ValidateProviderConfigResponse) *tfprotov5.PrepareProviderConfigResponse { + if fw == nil { + return nil + } + + proto5 := &tfprotov5.PrepareProviderConfigResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + preparedConfig, diags := Config(ctx, fw.PreparedConfig) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.PreparedConfig = preparedConfig + + return proto5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/readdatasource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/readdatasource.go new file mode 100644 index 00000000..4e977d1d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/readdatasource.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ReadDataSourceResponse returns the *tfprotov5.ReadDataSourceResponse +// equivalent of a *fwserver.ReadDataSourceResponse. +func ReadDataSourceResponse(ctx context.Context, fw *fwserver.ReadDataSourceResponse) *tfprotov5.ReadDataSourceResponse { + if fw == nil { + return nil + } + + proto5 := &tfprotov5.ReadDataSourceResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + state, diags := State(ctx, fw.State) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.State = state + + return proto5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/readresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/readresource.go new file mode 100644 index 00000000..43401ab0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/readresource.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// ReadResourceResponse returns the *tfprotov5.ReadResourceResponse +// equivalent of a *fwserver.ReadResourceResponse. +func ReadResourceResponse(ctx context.Context, fw *fwserver.ReadResourceResponse) *tfprotov5.ReadResourceResponse { + if fw == nil { + return nil + } + + proto5 := &tfprotov5.ReadResourceResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + newState, diags := State(ctx, fw.NewState) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.NewState = newState + + newPrivate, diags := fw.Private.Bytes(ctx) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.Private = newPrivate + + return proto5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/resourcemetadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/resourcemetadata.go new file mode 100644 index 00000000..e13af0c5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/resourcemetadata.go @@ -0,0 +1,19 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ResourceMetadata returns the tfprotov5.ResourceMetadata for a +// fwserver.ResourceMetadata. +func ResourceMetadata(ctx context.Context, fw fwserver.ResourceMetadata) tfprotov5.ResourceMetadata { + return tfprotov5.ResourceMetadata{ + TypeName: fw.TypeName, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/schema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/schema.go new file mode 100644 index 00000000..d4060043 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/schema.go @@ -0,0 +1,91 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + "sort" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Schema returns the *tfprotov5.Schema equivalent of a Schema. +func Schema(ctx context.Context, s fwschema.Schema) (*tfprotov5.Schema, error) { + if s == nil { + return nil, nil + } + + result := &tfprotov5.Schema{ + Version: s.GetVersion(), + } + + var attrs []*tfprotov5.SchemaAttribute + var blocks []*tfprotov5.SchemaNestedBlock + + for name, attr := range s.GetAttributes() { + a, err := SchemaAttribute(ctx, name, tftypes.NewAttributePath().WithAttributeName(name), attr) + + if err != nil { + return nil, err + } + + attrs = append(attrs, a) + } + + for name, block := range s.GetBlocks() { + proto5, err := Block(ctx, name, tftypes.NewAttributePath().WithAttributeName(name), block) + + if err != nil { + return nil, err + } + + blocks = append(blocks, proto5) + } + + sort.Slice(attrs, func(i, j int) bool { + if attrs[i] == nil { + return true + } + + if attrs[j] == nil { + return false + } + + return attrs[i].Name < attrs[j].Name + }) + + sort.Slice(blocks, func(i, j int) bool { + if blocks[i] == nil { + return true + } + + if blocks[j] == nil { + return false + } + + return blocks[i].TypeName < blocks[j].TypeName + }) + + result.Block = &tfprotov5.SchemaBlock{ + // core doesn't do anything with version, as far as I can tell, + // so let's not set it. + Attributes: attrs, + BlockTypes: blocks, + Deprecated: s.GetDeprecationMessage() != "", + } + + if s.GetDescription() != "" { + result.Block.Description = s.GetDescription() + result.Block.DescriptionKind = tfprotov5.StringKindPlain + } + + if s.GetMarkdownDescription() != "" { + result.Block.Description = s.GetMarkdownDescription() + result.Block.DescriptionKind = tfprotov5.StringKindMarkdown + } + + return result, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/schema_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/schema_attribute.go new file mode 100644 index 00000000..74d8fa55 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/schema_attribute.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// SchemaAttribute returns the *tfprotov5.SchemaAttribute equivalent of an +// Attribute. Errors will be tftypes.AttributePathErrors based on `path`. +// `name` is the name of the attribute. +func SchemaAttribute(ctx context.Context, name string, path *tftypes.AttributePath, a fwschema.Attribute) (*tfprotov5.SchemaAttribute, error) { + if _, ok := a.(fwschema.NestedAttribute); ok { + return nil, path.NewErrorf("protocol version 5 cannot have Attributes set") + } + + if a.GetType() == nil { + return nil, path.NewErrorf("must have Type set") + } + + if !a.IsRequired() && !a.IsOptional() && !a.IsComputed() { + return nil, path.NewErrorf("must have Required, Optional, or Computed set") + } + + schemaAttribute := &tfprotov5.SchemaAttribute{ + Name: name, + Required: a.IsRequired(), + Optional: a.IsOptional(), + Computed: a.IsComputed(), + Sensitive: a.IsSensitive(), + Type: a.GetType().TerraformType(ctx), + } + + if a.GetDeprecationMessage() != "" { + schemaAttribute.Deprecated = true + } + + if a.GetDescription() != "" { + schemaAttribute.Description = a.GetDescription() + schemaAttribute.DescriptionKind = tfprotov5.StringKindPlain + } + + if a.GetMarkdownDescription() != "" { + schemaAttribute.Description = a.GetMarkdownDescription() + schemaAttribute.DescriptionKind = tfprotov5.StringKindMarkdown + } + + return schemaAttribute, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/server_capabilities.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/server_capabilities.go new file mode 100644 index 00000000..fd968906 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/server_capabilities.go @@ -0,0 +1,24 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ServerCapabilities returns the *tfprotov5.ServerCapabilities for a +// *fwserver.ServerCapabilities. +func ServerCapabilities(ctx context.Context, fw *fwserver.ServerCapabilities) *tfprotov5.ServerCapabilities { + if fw == nil { + return nil + } + + return &tfprotov5.ServerCapabilities{ + GetProviderSchemaOptional: fw.GetProviderSchemaOptional, + PlanDestroy: fw.PlanDestroy, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/state.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/state.go new file mode 100644 index 00000000..9037ea70 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/state.go @@ -0,0 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// State returns the *tfprotov5.DynamicValue for a *tfsdk.State. +func State(ctx context.Context, fw *tfsdk.State) (*tfprotov5.DynamicValue, diag.Diagnostics) { + if fw == nil { + return nil, nil + } + + data := &fwschemadata.Data{ + Description: fwschemadata.DataDescriptionState, + Schema: fw.Schema, + TerraformValue: fw.Raw, + } + + return DynamicValue(ctx, data) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/upgraderesourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/upgraderesourcestate.go new file mode 100644 index 00000000..e9ce947c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/upgraderesourcestate.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// UpgradeResourceStateResponse returns the *tfprotov5.UpgradeResourceStateResponse +// equivalent of a *fwserver.UpgradeResourceStateResponse. +func UpgradeResourceStateResponse(ctx context.Context, fw *fwserver.UpgradeResourceStateResponse) *tfprotov5.UpgradeResourceStateResponse { + if fw == nil { + return nil + } + + proto5 := &tfprotov5.UpgradeResourceStateResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + upgradedState, diags := State(ctx, fw.UpgradedState) + + proto5.Diagnostics = append(proto5.Diagnostics, Diagnostics(ctx, diags)...) + proto5.UpgradedState = upgradedState + + return proto5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/validatedatasourceconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/validatedatasourceconfig.go new file mode 100644 index 00000000..9fe0b634 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/validatedatasourceconfig.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ValidateDataSourceConfigResponse returns the *tfprotov5.ValidateDataSourceConfigResponse +// equivalent of a *fwserver.ValidateDataSourceConfigResponse. +func ValidateDataSourceConfigResponse(ctx context.Context, fw *fwserver.ValidateDataSourceConfigResponse) *tfprotov5.ValidateDataSourceConfigResponse { + if fw == nil { + return nil + } + + proto5 := &tfprotov5.ValidateDataSourceConfigResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + return proto5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/validateresourcetypeconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/validateresourcetypeconfig.go new file mode 100644 index 00000000..f20cee65 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto5/validateresourcetypeconfig.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// ValidateResourceTypeConfigResponse returns the *tfprotov5.ValidateResourceTypeConfigResponse +// equivalent of a *fwserver.ValidateResourceConfigResponse. +func ValidateResourceTypeConfigResponse(ctx context.Context, fw *fwserver.ValidateResourceConfigResponse) *tfprotov5.ValidateResourceTypeConfigResponse { + if fw == nil { + return nil + } + + proto5 := &tfprotov5.ValidateResourceTypeConfigResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + return proto5 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/applyresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/applyresourcechange.go new file mode 100644 index 00000000..c3d158f0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/applyresourcechange.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// ApplyResourceChangeResponse returns the *tfprotov6.ApplyResourceChangeResponse +// equivalent of a *fwserver.ApplyResourceChangeResponse. +func ApplyResourceChangeResponse(ctx context.Context, fw *fwserver.ApplyResourceChangeResponse) *tfprotov6.ApplyResourceChangeResponse { + if fw == nil { + return nil + } + + proto6 := &tfprotov6.ApplyResourceChangeResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + newState, diags := State(ctx, fw.NewState) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.NewState = newState + + newPrivate, diags := fw.Private.Bytes(ctx) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.Private = newPrivate + + return proto6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/block.go new file mode 100644 index 00000000..d5e9abb7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/block.go @@ -0,0 +1,97 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + "sort" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Block returns the *tfprotov6.SchemaNestedBlock equivalent of a Block. +// Errors will be tftypes.AttributePathErrors based on `path`. `name` is the +// name of the attribute. +func Block(ctx context.Context, name string, path *tftypes.AttributePath, b fwschema.Block) (*tfprotov6.SchemaNestedBlock, error) { + schemaNestedBlock := &tfprotov6.SchemaNestedBlock{ + Block: &tfprotov6.SchemaBlock{ + Deprecated: b.GetDeprecationMessage() != "", + }, + TypeName: name, + } + + if b.GetDescription() != "" { + schemaNestedBlock.Block.Description = b.GetDescription() + schemaNestedBlock.Block.DescriptionKind = tfprotov6.StringKindPlain + } + + if b.GetMarkdownDescription() != "" { + schemaNestedBlock.Block.Description = b.GetMarkdownDescription() + schemaNestedBlock.Block.DescriptionKind = tfprotov6.StringKindMarkdown + } + + nm := b.GetNestingMode() + switch nm { + case fwschema.BlockNestingModeList: + schemaNestedBlock.Nesting = tfprotov6.SchemaNestedBlockNestingModeList + case fwschema.BlockNestingModeSet: + schemaNestedBlock.Nesting = tfprotov6.SchemaNestedBlockNestingModeSet + case fwschema.BlockNestingModeSingle: + schemaNestedBlock.Nesting = tfprotov6.SchemaNestedBlockNestingModeSingle + default: + return nil, path.NewErrorf("unrecognized nesting mode %v", nm) + } + + nestedBlockObject := b.GetNestedObject() + + for attrName, attr := range nestedBlockObject.GetAttributes() { + attrPath := path.WithAttributeName(attrName) + attrProto6, err := SchemaAttribute(ctx, attrName, attrPath, attr) + + if err != nil { + return nil, err + } + + schemaNestedBlock.Block.Attributes = append(schemaNestedBlock.Block.Attributes, attrProto6) + } + + for blockName, block := range nestedBlockObject.GetBlocks() { + blockPath := path.WithAttributeName(blockName) + blockProto6, err := Block(ctx, blockName, blockPath, block) + + if err != nil { + return nil, err + } + + schemaNestedBlock.Block.BlockTypes = append(schemaNestedBlock.Block.BlockTypes, blockProto6) + } + + sort.Slice(schemaNestedBlock.Block.Attributes, func(i, j int) bool { + if schemaNestedBlock.Block.Attributes[i] == nil { + return true + } + + if schemaNestedBlock.Block.Attributes[j] == nil { + return false + } + + return schemaNestedBlock.Block.Attributes[i].Name < schemaNestedBlock.Block.Attributes[j].Name + }) + + sort.Slice(schemaNestedBlock.Block.BlockTypes, func(i, j int) bool { + if schemaNestedBlock.Block.BlockTypes[i] == nil { + return true + } + + if schemaNestedBlock.Block.BlockTypes[j] == nil { + return false + } + + return schemaNestedBlock.Block.BlockTypes[i].TypeName < schemaNestedBlock.Block.BlockTypes[j].TypeName + }) + + return schemaNestedBlock, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/callfunction.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/callfunction.go new file mode 100644 index 00000000..14afb8f2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/callfunction.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// CallFunctionResponse returns the *tfprotov6.CallFunctionResponse +// equivalent of a *fwserver.CallFunctionResponse. +func CallFunctionResponse(ctx context.Context, fw *fwserver.CallFunctionResponse) *tfprotov6.CallFunctionResponse { + if fw == nil { + return nil + } + + result, resultErr := FunctionResultData(ctx, fw.Result) + + funcErr := function.ConcatFuncErrors(fw.Error, resultErr) + + return &tfprotov6.CallFunctionResponse{ + Error: FunctionError(ctx, funcErr), + Result: result, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/config.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/config.go new file mode 100644 index 00000000..9e8271d8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/config.go @@ -0,0 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// Config returns the *tfprotov6.DynamicValue for a *tfsdk.Config. +func Config(ctx context.Context, fw *tfsdk.Config) (*tfprotov6.DynamicValue, diag.Diagnostics) { + if fw == nil { + return nil, nil + } + + data := &fwschemadata.Data{ + Description: fwschemadata.DataDescriptionConfiguration, + Schema: fw.Schema, + TerraformValue: fw.Raw, + } + + return DynamicValue(ctx, data) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/configureprovider.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/configureprovider.go new file mode 100644 index 00000000..807cc5bf --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/configureprovider.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ConfigureProviderResponse returns the *tfprotov6.ConfigureProviderResponse +// equivalent of a *fwserver.ConfigureProviderResponse. +func ConfigureProviderResponse(ctx context.Context, fw *provider.ConfigureResponse) *tfprotov6.ConfigureProviderResponse { + if fw == nil { + return nil + } + + proto6 := &tfprotov6.ConfigureProviderResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + return proto6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/datasourcemetadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/datasourcemetadata.go new file mode 100644 index 00000000..24c8bbb0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/datasourcemetadata.go @@ -0,0 +1,19 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// DataSourceMetadata returns the tfprotov6.DataSourceMetadata for a +// fwserver.DataSourceMetadata. +func DataSourceMetadata(ctx context.Context, fw fwserver.DataSourceMetadata) tfprotov6.DataSourceMetadata { + return tfprotov6.DataSourceMetadata{ + TypeName: fw.TypeName, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/diagnostics.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/diagnostics.go new file mode 100644 index 00000000..42e7fb5e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/diagnostics.go @@ -0,0 +1,52 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/totftypes" +) + +// DiagnosticSeverity converts diag.Severity into tfprotov6.DiagnosticSeverity. +func DiagnosticSeverity(s diag.Severity) tfprotov6.DiagnosticSeverity { + switch s { + case diag.SeverityError: + return tfprotov6.DiagnosticSeverityError + case diag.SeverityWarning: + return tfprotov6.DiagnosticSeverityWarning + default: + return tfprotov6.DiagnosticSeverityInvalid + } +} + +// Diagnostics converts the diagnostics into the tfprotov6 collection type. +func Diagnostics(ctx context.Context, diagnostics diag.Diagnostics) []*tfprotov6.Diagnostic { + var results []*tfprotov6.Diagnostic + + for _, diagnostic := range diagnostics { + tfprotov6Diagnostic := &tfprotov6.Diagnostic{ + Detail: diagnostic.Detail(), + Severity: DiagnosticSeverity(diagnostic.Severity()), + Summary: diagnostic.Summary(), + } + + if diagWithPath, ok := diagnostic.(diag.DiagnosticWithPath); ok { + var diags diag.Diagnostics + + tfprotov6Diagnostic.Attribute, diags = totftypes.AttributePath(ctx, diagWithPath.Path()) + + if diags.HasError() { + results = append(results, Diagnostics(ctx, diags)...) + } + } + + results = append(results, tfprotov6Diagnostic) + } + + return results +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/doc.go new file mode 100644 index 00000000..f28bff2c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package toproto6 contains functions to convert from framework types to +// protocol version 6 (tfprotov6) types. +package toproto6 diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/dynamic_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/dynamic_value.go new file mode 100644 index 00000000..4f04fdbb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/dynamic_value.go @@ -0,0 +1,47 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// DynamicValue returns the *tfprotov6.DynamicValue for a given +// fwschemadata.Data. +// +// If necessary, the underlying data is modified to convert list and set block +// values from a null collection to an empty collection. This is to prevent +// developers from needing to understand Terraform's differences between +// block and attribute values where blocks are technically never null, but from +// a developer perspective this distinction introduces unnecessary complexity. +func DynamicValue(ctx context.Context, data *fwschemadata.Data) (*tfprotov6.DynamicValue, diag.Diagnostics) { + if data == nil { + return nil, nil + } + + var diags diag.Diagnostics + + // Prevent Terraform core errors for null list/set blocks. + diags.Append(data.ReifyNullCollectionBlocks(ctx)...) + + proto6, err := tfprotov6.NewDynamicValue(data.Schema.Type().TerraformType(ctx), data.TerraformValue) + + if err != nil { + diags.AddError( + "Unable to Convert "+data.Description.Title(), + "An unexpected error was encountered when converting the "+data.Description.String()+" to the protocol type. "+ + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+ + "Please report this to the provider developer:\n\n"+ + "Unable to create DynamicValue: "+err.Error(), + ) + + return nil, diags + } + + return &proto6, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/function.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/function.go new file mode 100644 index 00000000..70edabf2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/function.go @@ -0,0 +1,125 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// Function returns the *tfprotov6.Function for a function.Definition. +func Function(ctx context.Context, fw function.Definition) *tfprotov6.Function { + proto := &tfprotov6.Function{ + DeprecationMessage: fw.DeprecationMessage, + Parameters: make([]*tfprotov6.FunctionParameter, 0, len(fw.Parameters)), + Return: FunctionReturn(ctx, fw.Return), + Summary: fw.Summary, + } + + if fw.MarkdownDescription != "" { + proto.Description = fw.MarkdownDescription + proto.DescriptionKind = tfprotov6.StringKindMarkdown + } else if fw.Description != "" { + proto.Description = fw.Description + proto.DescriptionKind = tfprotov6.StringKindPlain + } + + for _, fwParameter := range fw.Parameters { + protoParam := FunctionParameter(ctx, fwParameter) + proto.Parameters = append(proto.Parameters, protoParam) + } + + if fw.VariadicParameter != nil { + protoParam := FunctionParameter(ctx, fw.VariadicParameter) + proto.VariadicParameter = protoParam + } + + return proto +} + +// FunctionParameter returns the *tfprotov6.FunctionParameter for a +// function.Parameter. +func FunctionParameter(ctx context.Context, fw function.Parameter) *tfprotov6.FunctionParameter { + if fw == nil { + return nil + } + + proto := &tfprotov6.FunctionParameter{ + AllowNullValue: fw.GetAllowNullValue(), + AllowUnknownValues: fw.GetAllowUnknownValues(), + Name: fw.GetName(), + Type: fw.GetType().TerraformType(ctx), + } + + if fw.GetMarkdownDescription() != "" { + proto.Description = fw.GetMarkdownDescription() + proto.DescriptionKind = tfprotov6.StringKindMarkdown + } else if fw.GetDescription() != "" { + proto.Description = fw.GetDescription() + proto.DescriptionKind = tfprotov6.StringKindPlain + } + + return proto +} + +// FunctionMetadata returns the tfprotov6.FunctionMetadata for a +// fwserver.FunctionMetadata. +func FunctionMetadata(ctx context.Context, fw fwserver.FunctionMetadata) tfprotov6.FunctionMetadata { + proto := tfprotov6.FunctionMetadata{ + Name: fw.Name, + } + + return proto +} + +// FunctionReturn returns the *tfprotov6.FunctionReturn for a +// function.Return. +func FunctionReturn(ctx context.Context, fw function.Return) *tfprotov6.FunctionReturn { + if fw == nil { + return nil + } + + proto := &tfprotov6.FunctionReturn{ + Type: fw.GetType().TerraformType(ctx), + } + + return proto +} + +// FunctionResultData returns the *tfprotov6.DynamicValue for a given +// function.ResultData. +func FunctionResultData(ctx context.Context, data function.ResultData) (*tfprotov6.DynamicValue, *function.FuncError) { + attrValue := data.Value() + + if attrValue == nil { + return nil, nil + } + + tfType := attrValue.Type(ctx).TerraformType(ctx) + tfValue, err := attrValue.ToTerraformValue(ctx) + + if err != nil { + msg := "Unable to Convert Function Result Data: An unexpected error was encountered when converting the function result data to the protocol type. " + + "Please report this to the provider developer:\n\n" + + "Unable to convert framework type to tftypes: " + err.Error() + + return nil, function.NewFuncError(msg) + } + + dynamicValue, err := tfprotov6.NewDynamicValue(tfType, tfValue) + + if err != nil { + msg := "Unable to Convert Function Result Data: An unexpected error was encountered when converting the function result data to the protocol type. " + + "This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n" + + "Unable to create DynamicValue: " + err.Error() + + return nil, function.NewFuncError(msg) + } + + return &dynamicValue, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/function_errors.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/function_errors.go new file mode 100644 index 00000000..062d3eae --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/function_errors.go @@ -0,0 +1,24 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/function" +) + +// FunctionError converts the function error into the tfprotov6 function error. +func FunctionError(ctx context.Context, funcErr *function.FuncError) *tfprotov6.FunctionError { + if funcErr == nil { + return nil + } + + return &tfprotov6.FunctionError{ + Text: funcErr.Text, + FunctionArgument: funcErr.FunctionArgument, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getfunctions.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getfunctions.go new file mode 100644 index 00000000..30cc7bde --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getfunctions.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetFunctionsResponse returns the *tfprotov6.GetFunctionsResponse +// equivalent of a *fwserver.GetFunctionsResponse. +func GetFunctionsResponse(ctx context.Context, fw *fwserver.GetFunctionsResponse) *tfprotov6.GetFunctionsResponse { + if fw == nil { + return nil + } + + proto := &tfprotov6.GetFunctionsResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + Functions: make(map[string]*tfprotov6.Function, len(fw.FunctionDefinitions)), + } + + for name, functionDefinition := range fw.FunctionDefinitions { + proto.Functions[name] = Function(ctx, functionDefinition) + } + + return proto +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getmetadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getmetadata.go new file mode 100644 index 00000000..0924f3c9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getmetadata.go @@ -0,0 +1,41 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetMetadataResponse returns the *tfprotov6.GetMetadataResponse +// equivalent of a *fwserver.GetMetadataResponse. +func GetMetadataResponse(ctx context.Context, fw *fwserver.GetMetadataResponse) *tfprotov6.GetMetadataResponse { + if fw == nil { + return nil + } + + protov6 := &tfprotov6.GetMetadataResponse{ + DataSources: make([]tfprotov6.DataSourceMetadata, 0, len(fw.DataSources)), + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + Functions: make([]tfprotov6.FunctionMetadata, 0, len(fw.Functions)), + Resources: make([]tfprotov6.ResourceMetadata, 0, len(fw.Resources)), + ServerCapabilities: ServerCapabilities(ctx, fw.ServerCapabilities), + } + + for _, datasource := range fw.DataSources { + protov6.DataSources = append(protov6.DataSources, DataSourceMetadata(ctx, datasource)) + } + + for _, function := range fw.Functions { + protov6.Functions = append(protov6.Functions, FunctionMetadata(ctx, function)) + } + + for _, resource := range fw.Resources { + protov6.Resources = append(protov6.Resources, ResourceMetadata(ctx, resource)) + } + + return protov6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getproviderschema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getproviderschema.go new file mode 100644 index 00000000..ee221abb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/getproviderschema.go @@ -0,0 +1,87 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetProviderSchemaResponse returns the *tfprotov6.GetProviderSchemaResponse +// equivalent of a *fwserver.GetProviderSchemaResponse. +func GetProviderSchemaResponse(ctx context.Context, fw *fwserver.GetProviderSchemaResponse) *tfprotov6.GetProviderSchemaResponse { + if fw == nil { + return nil + } + + protov6 := &tfprotov6.GetProviderSchemaResponse{ + DataSourceSchemas: make(map[string]*tfprotov6.Schema, len(fw.DataSourceSchemas)), + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + Functions: make(map[string]*tfprotov6.Function, len(fw.FunctionDefinitions)), + ResourceSchemas: make(map[string]*tfprotov6.Schema, len(fw.ResourceSchemas)), + ServerCapabilities: ServerCapabilities(ctx, fw.ServerCapabilities), + } + + var err error + + protov6.Provider, err = Schema(ctx, fw.Provider) + + if err != nil { + protov6.Diagnostics = append(protov6.Diagnostics, &tfprotov6.Diagnostic{ + Severity: tfprotov6.DiagnosticSeverityError, + Summary: "Error converting provider schema", + Detail: "The provider schema couldn't be converted into a usable type. This is always a problem with the provider. Please report the following to the provider developer:\n\n" + err.Error(), + }) + + return protov6 + } + + protov6.ProviderMeta, err = Schema(ctx, fw.ProviderMeta) + + if err != nil { + protov6.Diagnostics = append(protov6.Diagnostics, &tfprotov6.Diagnostic{ + Severity: tfprotov6.DiagnosticSeverityError, + Summary: "Error converting provider_meta schema", + Detail: "The provider_meta schema couldn't be converted into a usable type. This is always a problem with the provider. Please report the following to the provider developer:\n\n" + err.Error(), + }) + + return protov6 + } + + for dataSourceType, dataSourceSchema := range fw.DataSourceSchemas { + protov6.DataSourceSchemas[dataSourceType], err = Schema(ctx, dataSourceSchema) + + if err != nil { + protov6.Diagnostics = append(protov6.Diagnostics, &tfprotov6.Diagnostic{ + Severity: tfprotov6.DiagnosticSeverityError, + Summary: "Error converting data source schema", + Detail: "The schema for the data source \"" + dataSourceType + "\" couldn't be converted into a usable type. This is always a problem with the provider. Please report the following to the provider developer:\n\n" + err.Error(), + }) + + return protov6 + } + } + + for name, functionDefinition := range fw.FunctionDefinitions { + protov6.Functions[name] = Function(ctx, functionDefinition) + } + + for resourceType, resourceSchema := range fw.ResourceSchemas { + protov6.ResourceSchemas[resourceType], err = Schema(ctx, resourceSchema) + + if err != nil { + protov6.Diagnostics = append(protov6.Diagnostics, &tfprotov6.Diagnostic{ + Severity: tfprotov6.DiagnosticSeverityError, + Summary: "Error converting resource schema", + Detail: "The schema for the resource \"" + resourceType + "\" couldn't be converted into a usable type. This is always a problem with the provider. Please report the following to the provider developer:\n\n" + err.Error(), + }) + + return protov6 + } + } + + return protov6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/importedresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/importedresource.go new file mode 100644 index 00000000..28fea4b5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/importedresource.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// ImportedResource returns the *tfprotov6.ImportedResource equivalent of a +// *fwserver.ImportedResource. +func ImportedResource(ctx context.Context, fw *fwserver.ImportedResource) (*tfprotov6.ImportedResource, diag.Diagnostics) { + if fw == nil { + return nil, nil + } + + proto6 := &tfprotov6.ImportedResource{ + TypeName: fw.TypeName, + } + + state, diags := State(ctx, &fw.State) + + proto6.State = state + + newPrivate, privateDiags := fw.Private.Bytes(ctx) + + diags = append(diags, privateDiags...) + proto6.Private = newPrivate + + return proto6, diags +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/importresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/importresourcestate.go new file mode 100644 index 00000000..a5a29a69 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/importresourcestate.go @@ -0,0 +1,37 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ImportResourceStateResponse returns the *tfprotov6.ImportResourceStateResponse +// equivalent of a *fwserver.ImportResourceStateResponse. +func ImportResourceStateResponse(ctx context.Context, fw *fwserver.ImportResourceStateResponse) *tfprotov6.ImportResourceStateResponse { + if fw == nil { + return nil + } + + proto6 := &tfprotov6.ImportResourceStateResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + for _, fwImportedResource := range fw.ImportedResources { + proto6ImportedResource, diags := ImportedResource(ctx, &fwImportedResource) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + + if diags.HasError() { + continue + } + + proto6.ImportedResources = append(proto6.ImportedResources, proto6ImportedResource) + } + + return proto6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/moveresourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/moveresourcestate.go new file mode 100644 index 00000000..86c2a55a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/moveresourcestate.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// MoveResourceStateResponse returns the *tfprotov6.MoveResourceStateResponse +// equivalent of a *fwserver.MoveResourceStateResponse. +func MoveResourceStateResponse(ctx context.Context, fw *fwserver.MoveResourceStateResponse) *tfprotov6.MoveResourceStateResponse { + if fw == nil { + return nil + } + + proto6 := &tfprotov6.MoveResourceStateResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + targetPrivate, diags := fw.TargetPrivate.Bytes(ctx) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.TargetPrivate = targetPrivate + + targetState, diags := State(ctx, fw.TargetState) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.TargetState = targetState + + return proto6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/planresourcechange.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/planresourcechange.go new file mode 100644 index 00000000..8cb2b66b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/planresourcechange.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/totftypes" +) + +// PlanResourceChangeResponse returns the *tfprotov6.PlanResourceChangeResponse +// equivalent of a *fwserver.PlanResourceChangeResponse. +func PlanResourceChangeResponse(ctx context.Context, fw *fwserver.PlanResourceChangeResponse) *tfprotov6.PlanResourceChangeResponse { + if fw == nil { + return nil + } + + proto6 := &tfprotov6.PlanResourceChangeResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + plannedState, diags := State(ctx, fw.PlannedState) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.PlannedState = plannedState + + requiresReplace, diags := totftypes.AttributePaths(ctx, fw.RequiresReplace) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.RequiresReplace = requiresReplace + + plannedPrivate, diags := fw.PlannedPrivate.Bytes(ctx) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.PlannedPrivate = plannedPrivate + + return proto6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/readdatasource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/readdatasource.go new file mode 100644 index 00000000..f9a59f0e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/readdatasource.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ReadDataSourceResponse returns the *tfprotov6.ReadDataSourceResponse +// equivalent of a *fwserver.ReadDataSourceResponse. +func ReadDataSourceResponse(ctx context.Context, fw *fwserver.ReadDataSourceResponse) *tfprotov6.ReadDataSourceResponse { + if fw == nil { + return nil + } + + proto6 := &tfprotov6.ReadDataSourceResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + state, diags := State(ctx, fw.State) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.State = state + + return proto6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/readresource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/readresource.go new file mode 100644 index 00000000..d5e600e1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/readresource.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" +) + +// ReadResourceResponse returns the *tfprotov6.ReadResourceResponse +// equivalent of a *fwserver.ReadResourceResponse. +func ReadResourceResponse(ctx context.Context, fw *fwserver.ReadResourceResponse) *tfprotov6.ReadResourceResponse { + if fw == nil { + return nil + } + + proto6 := &tfprotov6.ReadResourceResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + newState, diags := State(ctx, fw.NewState) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.NewState = newState + + newPrivate, diags := fw.Private.Bytes(ctx) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.Private = newPrivate + + return proto6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/resourcemetadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/resourcemetadata.go new file mode 100644 index 00000000..3f54952b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/resourcemetadata.go @@ -0,0 +1,19 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ResourceMetadata returns the tfprotov6.ResourceMetadata for a +// fwserver.ResourceMetadata. +func ResourceMetadata(ctx context.Context, fw fwserver.ResourceMetadata) tfprotov6.ResourceMetadata { + return tfprotov6.ResourceMetadata{ + TypeName: fw.TypeName, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/schema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/schema.go new file mode 100644 index 00000000..e51d453a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/schema.go @@ -0,0 +1,91 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + "sort" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Schema returns the *tfprotov6.Schema equivalent of a Schema. +func Schema(ctx context.Context, s fwschema.Schema) (*tfprotov6.Schema, error) { + if s == nil { + return nil, nil + } + + result := &tfprotov6.Schema{ + Version: s.GetVersion(), + } + + var attrs []*tfprotov6.SchemaAttribute + var blocks []*tfprotov6.SchemaNestedBlock + + for name, attr := range s.GetAttributes() { + a, err := SchemaAttribute(ctx, name, tftypes.NewAttributePath().WithAttributeName(name), attr) + + if err != nil { + return nil, err + } + + attrs = append(attrs, a) + } + + for name, block := range s.GetBlocks() { + proto6, err := Block(ctx, name, tftypes.NewAttributePath().WithAttributeName(name), block) + + if err != nil { + return nil, err + } + + blocks = append(blocks, proto6) + } + + sort.Slice(attrs, func(i, j int) bool { + if attrs[i] == nil { + return true + } + + if attrs[j] == nil { + return false + } + + return attrs[i].Name < attrs[j].Name + }) + + sort.Slice(blocks, func(i, j int) bool { + if blocks[i] == nil { + return true + } + + if blocks[j] == nil { + return false + } + + return blocks[i].TypeName < blocks[j].TypeName + }) + + result.Block = &tfprotov6.SchemaBlock{ + // core doesn't do anything with version, as far as I can tell, + // so let's not set it. + Attributes: attrs, + BlockTypes: blocks, + Deprecated: s.GetDeprecationMessage() != "", + } + + if s.GetDescription() != "" { + result.Block.Description = s.GetDescription() + result.Block.DescriptionKind = tfprotov6.StringKindPlain + } + + if s.GetMarkdownDescription() != "" { + result.Block.Description = s.GetMarkdownDescription() + result.Block.DescriptionKind = tfprotov6.StringKindMarkdown + } + + return result, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/schema_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/schema_attribute.go new file mode 100644 index 00000000..492a5a2a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/schema_attribute.go @@ -0,0 +1,93 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + "sort" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// SchemaAttribute returns the *tfprotov6.SchemaAttribute equivalent of an +// Attribute. Errors will be tftypes.AttributePathErrors based on `path`. +// `name` is the name of the attribute. +func SchemaAttribute(ctx context.Context, name string, path *tftypes.AttributePath, a fwschema.Attribute) (*tfprotov6.SchemaAttribute, error) { + if !a.IsRequired() && !a.IsOptional() && !a.IsComputed() { + return nil, path.NewErrorf("must have Required, Optional, or Computed set") + } + + schemaAttribute := &tfprotov6.SchemaAttribute{ + Name: name, + Required: a.IsRequired(), + Optional: a.IsOptional(), + Computed: a.IsComputed(), + Sensitive: a.IsSensitive(), + Type: a.GetType().TerraformType(ctx), + } + + if a.GetDeprecationMessage() != "" { + schemaAttribute.Deprecated = true + } + + if a.GetDescription() != "" { + schemaAttribute.Description = a.GetDescription() + schemaAttribute.DescriptionKind = tfprotov6.StringKindPlain + } + + if a.GetMarkdownDescription() != "" { + schemaAttribute.Description = a.GetMarkdownDescription() + schemaAttribute.DescriptionKind = tfprotov6.StringKindMarkdown + } + + nestedAttribute, ok := a.(fwschema.NestedAttribute) + + if !ok { + return schemaAttribute, nil + } + + object := &tfprotov6.SchemaObject{} + nm := nestedAttribute.GetNestingMode() + switch nm { + case fwschema.NestingModeSingle: + object.Nesting = tfprotov6.SchemaObjectNestingModeSingle + case fwschema.NestingModeList: + object.Nesting = tfprotov6.SchemaObjectNestingModeList + case fwschema.NestingModeSet: + object.Nesting = tfprotov6.SchemaObjectNestingModeSet + case fwschema.NestingModeMap: + object.Nesting = tfprotov6.SchemaObjectNestingModeMap + default: + return nil, path.NewErrorf("unrecognized nesting mode %v", nm) + } + + for nestedName, nestedA := range nestedAttribute.GetNestedObject().GetAttributes() { + nestedSchemaAttribute, err := SchemaAttribute(ctx, nestedName, path.WithAttributeName(nestedName), nestedA) + + if err != nil { + return nil, err + } + + object.Attributes = append(object.Attributes, nestedSchemaAttribute) + } + + sort.Slice(object.Attributes, func(i, j int) bool { + if object.Attributes[i] == nil { + return true + } + + if object.Attributes[j] == nil { + return false + } + + return object.Attributes[i].Name < object.Attributes[j].Name + }) + + schemaAttribute.NestedType = object + schemaAttribute.Type = nil + + return schemaAttribute, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/server_capabilities.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/server_capabilities.go new file mode 100644 index 00000000..ef46cbf1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/server_capabilities.go @@ -0,0 +1,24 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ServerCapabilities returns the *tfprotov6.ServerCapabilities for a +// *fwserver.ServerCapabilities. +func ServerCapabilities(ctx context.Context, fw *fwserver.ServerCapabilities) *tfprotov6.ServerCapabilities { + if fw == nil { + return nil + } + + return &tfprotov6.ServerCapabilities{ + GetProviderSchemaOptional: fw.GetProviderSchemaOptional, + PlanDestroy: fw.PlanDestroy, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/state.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/state.go new file mode 100644 index 00000000..1b0a0d9d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/state.go @@ -0,0 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// State returns the *tfprotov6.DynamicValue for a *tfsdk.State. +func State(ctx context.Context, fw *tfsdk.State) (*tfprotov6.DynamicValue, diag.Diagnostics) { + if fw == nil { + return nil, nil + } + + data := &fwschemadata.Data{ + Description: fwschemadata.DataDescriptionState, + Schema: fw.Schema, + TerraformValue: fw.Raw, + } + + return DynamicValue(ctx, data) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/upgraderesourcestate.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/upgraderesourcestate.go new file mode 100644 index 00000000..ddb1d678 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/upgraderesourcestate.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// UpgradeResourceStateResponse returns the *tfprotov6.UpgradeResourceStateResponse +// equivalent of a *fwserver.UpgradeResourceStateResponse. +func UpgradeResourceStateResponse(ctx context.Context, fw *fwserver.UpgradeResourceStateResponse) *tfprotov6.UpgradeResourceStateResponse { + if fw == nil { + return nil + } + + proto6 := &tfprotov6.UpgradeResourceStateResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + upgradedState, diags := State(ctx, fw.UpgradedState) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.UpgradedState = upgradedState + + return proto6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validatedatasourceconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validatedatasourceconfig.go new file mode 100644 index 00000000..83c68bcb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validatedatasourceconfig.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ValidateDataSourceConfigResponse returns the *tfprotov6.ValidateDataSourceConfigResponse +// equivalent of a *fwserver.ValidateDataSourceConfigResponse. +func ValidateDataSourceConfigResponse(ctx context.Context, fw *fwserver.ValidateDataSourceConfigResponse) *tfprotov6.ValidateDataResourceConfigResponse { + if fw == nil { + return nil + } + + proto6 := &tfprotov6.ValidateDataResourceConfigResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + return proto6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validateproviderconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validateproviderconfig.go new file mode 100644 index 00000000..c67417b8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validateproviderconfig.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ValidateProviderConfigResponse returns the *tfprotov6.ValidateProviderConfigResponse +// equivalent of a *fwserver.ValidateProviderConfigResponse. +func ValidateProviderConfigResponse(ctx context.Context, fw *fwserver.ValidateProviderConfigResponse) *tfprotov6.ValidateProviderConfigResponse { + if fw == nil { + return nil + } + + proto6 := &tfprotov6.ValidateProviderConfigResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + preparedConfig, diags := Config(ctx, fw.PreparedConfig) + + proto6.Diagnostics = append(proto6.Diagnostics, Diagnostics(ctx, diags)...) + proto6.PreparedConfig = preparedConfig + + return proto6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validateresourceconfig.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validateresourceconfig.go new file mode 100644 index 00000000..e6fa1f72 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/toproto6/validateresourceconfig.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// ValidateResourceConfigResponse returns the *tfprotov6.ValidateResourceConfigResponse +// equivalent of a *fwserver.ValidateResourceConfigResponse. +func ValidateResourceConfigResponse(ctx context.Context, fw *fwserver.ValidateResourceConfigResponse) *tfprotov6.ValidateResourceConfigResponse { + if fw == nil { + return nil + } + + proto6 := &tfprotov6.ValidateResourceConfigResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + } + + return proto6 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_path.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_path.go new file mode 100644 index 00000000..e3ca6f38 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_path.go @@ -0,0 +1,43 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package totftypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// AttributePath returns the *tftypes.AttributePath equivalent of a path.Path. +func AttributePath(ctx context.Context, fw path.Path) (*tftypes.AttributePath, diag.Diagnostics) { + var tfTypeSteps []tftypes.AttributePathStep + + for _, step := range fw.Steps() { + tfTypeStep, err := AttributePathStep(ctx, step) + + if err != nil { + return nil, diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Unable to Convert Attribute Path", + "An unexpected error occurred while trying to convert an attribute path. "+ + "This is either an error in terraform-plugin-framework or a custom attribute type used by the provider. "+ + "Please report the following to the provider developers.\n\n"+ + // Since this is an error with the attribute path + // conversion, we cannot return a protocol path-based + // diagnostic. Returning a framework human-readable + // representation seems like the next best thing to do. + fmt.Sprintf("Attribute Path: %s\n", fw.String())+ + fmt.Sprintf("Original Error: %s", err), + ), + } + } + + tfTypeSteps = append(tfTypeSteps, tfTypeStep) + } + + return tftypes.NewAttributePathWithSteps(tfTypeSteps), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_path_step.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_path_step.go new file mode 100644 index 00000000..42dff132 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_path_step.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package totftypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// AttributePathStep returns the tftypes.AttributePathStep equivalent of an +// path.PathStep. An error is returned instead of diag.Diagnostics so callers +// can include appropriate logical context about when the error occurred. +func AttributePathStep(ctx context.Context, fw path.PathStep) (tftypes.AttributePathStep, error) { + switch fw := fw.(type) { + case path.PathStepAttributeName: + return tftypes.AttributeName(string(fw)), nil + case path.PathStepElementKeyInt: + return tftypes.ElementKeyInt(int64(fw)), nil + case path.PathStepElementKeyString: + return tftypes.ElementKeyString(string(fw)), nil + case path.PathStepElementKeyValue: + tfTypesValue, err := fw.Value.ToTerraformValue(ctx) + + if err != nil { + return nil, fmt.Errorf("unable to convert attr.Value (%s) to tftypes.Value: %w", fw.Value.String(), err) + } + + return tftypes.ElementKeyValue(tfTypesValue), nil + default: + return nil, fmt.Errorf("unknown path.PathStep: %#v", fw) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_paths.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_paths.go new file mode 100644 index 00000000..d92e7d12 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/attribute_paths.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package totftypes + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// AttributePaths returns the []*tftypes.AttributePath equivalent of a path.Paths. +func AttributePaths(ctx context.Context, fw path.Paths) ([]*tftypes.AttributePath, diag.Diagnostics) { + if fw == nil { + return nil, nil + } + + result := make([]*tftypes.AttributePath, 0, len(fw)) + + for _, path := range fw { + tfType, diags := AttributePath(ctx, path) + + if diags.HasError() { + return result, diags + } + + result = append(result, tfType) + } + + return result, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/doc.go new file mode 100644 index 00000000..25cf3765 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/internal/totftypes/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package totftypes contains functions to convert from framework types to +// terraform-plugin-go tftypes types. +package totftypes diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/doc.go new file mode 100644 index 00000000..1ceadfa9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package path implements attribute path functionality, which defines +// transversals into schema-based data. +package path diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression.go new file mode 100644 index 00000000..9b5301f0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression.go @@ -0,0 +1,280 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" +) + +// Expression represents an attribute path with expression steps, which can +// represent zero, one, or more actual paths in schema data. This logic is +// either based on an absolute path starting at the root of the schema data, +// similar to Path, or a relative path which is intended to be merged with an +// existing absolute path. +// +// Use the MatchRoot() function to create an Expression for an absolute path +// with an initial AtName() step. Use the MatchRelative() function to create +// an Expression for a relative path, which will be merged with an existing +// absolute path. +// +// Similar to Path, Expression functionality has some overlapping method names +// and follows a builder pattern, which allows for chaining method calls to +// construct a full expression. The available traversal steps after Expression +// creation are: +// +// - AtAnyListIndex(): Step into a list at any index +// - AtAnyMapKey(): Step into a map at any key +// - AtAnySetValue(): Step into a set at any attr.Value element +// - AtListIndex(): Step into a list at a specific index +// - AtMapKey(): Step into a map at a specific key +// - AtName(): Step into an attribute or block with a specific name +// - AtParent(): Step backwards one step +// - AtSetValue(): Step into a set at a specific attr.Value element +// +// For example, to express any list element with a root list attribute named +// "some_attribute": +// +// path.MatchRoot("some_attribute").AtAnyListIndex() +// +// An Expression is generally preferable over a Path in schema-defined +// functionality that is intended to accept paths as parameters, such as +// attribute validators and attribute plan modifiers, since it allows consumers +// to support relative paths. Use the Merge() or MergeExpressions() method to +// combine the current attribute path expression with those expression(s). +// +// To find Paths from an Expression in schema based data structures, such as +// tfsdk.Config, tfsdk.Plan, and tfsdk.State, use their PathMatches() method. +type Expression struct { + // root stores whether an expression was intentionally created to start + // from the root of the data. This is used with Merge to overwrite steps + // instead of appending steps. + root bool + + // steps is the transversals included with the expression. In general, + // operations against the path should protect against modification of the + // original. + steps ExpressionSteps +} + +// AtAnyListIndex returns a copied expression with a new list index step at the +// end. The returned path is safe to modify without affecting the original. +func (e Expression) AtAnyListIndex() Expression { + copiedPath := e.Copy() + + copiedPath.steps.Append(ExpressionStepElementKeyIntAny{}) + + return copiedPath +} + +// AtAnyMapKey returns a copied expression with a new map key step at the end. +// The returned path is safe to modify without affecting the original. +func (e Expression) AtAnyMapKey() Expression { + copiedPath := e.Copy() + + copiedPath.steps.Append(ExpressionStepElementKeyStringAny{}) + + return copiedPath +} + +// AtAnySetValue returns a copied expression with a new set value step at the +// end. The returned path is safe to modify without affecting the original. +func (e Expression) AtAnySetValue() Expression { + copiedPath := e.Copy() + + copiedPath.steps.Append(ExpressionStepElementKeyValueAny{}) + + return copiedPath +} + +// AtListIndex returns a copied expression with a new list index step at the +// end. The returned path is safe to modify without affecting the original. +func (e Expression) AtListIndex(index int) Expression { + copiedPath := e.Copy() + + copiedPath.steps.Append(ExpressionStepElementKeyIntExact(index)) + + return copiedPath +} + +// AtMapKey returns a copied expression with a new map key step at the end. +// The returned path is safe to modify without affecting the original. +func (e Expression) AtMapKey(key string) Expression { + copiedPath := e.Copy() + + copiedPath.steps.Append(ExpressionStepElementKeyStringExact(key)) + + return copiedPath +} + +// AtName returns a copied expression with a new attribute or block name step +// at the end. The returned path is safe to modify without affecting the +// original. +func (e Expression) AtName(name string) Expression { + copiedPath := e.Copy() + + copiedPath.steps.Append(ExpressionStepAttributeNameExact(name)) + + return copiedPath +} + +// AtParent returns a copied expression with a new parent step at the end. +// The returned path is safe to modify without affecting the original. +func (e Expression) AtParent() Expression { + copiedPath := e.Copy() + + copiedPath.steps.Append(ExpressionStepParent{}) + + return copiedPath +} + +// AtSetValue returns a copied expression with a new set value step at the end. +// The returned path is safe to modify without affecting the original. +func (e Expression) AtSetValue(value attr.Value) Expression { + copiedPath := e.Copy() + + copiedPath.steps.Append(ExpressionStepElementKeyValueExact{Value: value}) + + return copiedPath +} + +// Copy returns a duplicate of the expression that is safe to modify without +// affecting the original. +func (e Expression) Copy() Expression { + return Expression{ + root: e.root, + steps: e.Steps().Copy(), + } +} + +// Equal returns true if the given expression is exactly equivalent. +func (e Expression) Equal(o Expression) bool { + if e.root != o.root { + return false + } + + if e.steps == nil && o.steps == nil { + return true + } + + if e.steps == nil { + return false + } + + if !e.steps.Equal(o.steps) { + return false + } + + return true +} + +// Matches returns true if the given Path is valid for the Expression. Any +// relative expression steps, such as ExpressionStepParent, are automatically +// resolved before matching. +func (e Expression) Matches(path Path) bool { + return e.steps.Matches(path.Steps()) +} + +// MatchesParent returns true if the given Path is a valid parent for the +// Expression. This is helpful for determining if a child Path would +// potentially match the full Expression during depth-first traversal. Any +// relative expression steps, such as ExpressionStepParent, are automatically +// resolved before matching. +func (e Expression) MatchesParent(path Path) bool { + return e.steps.MatchesParent(path.Steps()) +} + +// Merge returns a copied expression either with the steps of the given +// expression added to the end of the existing steps, or overwriting the +// steps if the given expression was a root expression. +// +// Any merged expressions will preserve all expressions steps, such as +// ExpressionStepParent, for troubleshooting. Methods such as Matches() will +// automatically resolve the expression when using it. Call the Resolve() +// method explicitly if a resolved expression without any ExpressionStepParent +// is desired. +func (e Expression) Merge(other Expression) Expression { + if other.root { + return other.Copy() + } + + copiedExpression := e.Copy() + + copiedExpression.steps.Append(other.steps...) + + return copiedExpression +} + +// MergeExpressions returns collection of expressions that calls Merge() on +// the current expression with each of the others. +// +// If no Expression are given, then it will return a collection of expressions +// containing only the current expression. +func (e Expression) MergeExpressions(others ...Expression) Expressions { + var result Expressions + + if len(others) == 0 { + result.Append(e) + + return result + } + + for _, other := range others { + result.Append(e.Merge(other)) + } + + return result +} + +// Resolve returns a copied expression with any relative steps, such as +// ExpressionStepParent, resolved. This is not necessary before calling methods +// such as Matches(), however it can be useful before returning the String() +// method so the path information is simplified. +// +// Returns an empty expression if any ExpressionStepParent attempt to go +// beyond the first element. +func (e Expression) Resolve() Expression { + copiedExpression := e.Copy() + + copiedExpression.steps = copiedExpression.steps.Resolve() + + return copiedExpression +} + +// Steps returns a copy of the underlying expression steps. Returns an empty +// collection of steps if expression is nil. +func (e Expression) Steps() ExpressionSteps { + if len(e.steps) == 0 { + return ExpressionSteps{} + } + + return e.steps.Copy() +} + +// String returns the human-readable representation of the path. +// It is intended for logging and error messages and is not protected by +// compatibility guarantees. +func (e Expression) String() string { + return e.steps.String() +} + +// MatchRelative creates an empty attribute path expression that is intended +// to be combined with an existing attribute path expression. This allows +// creating a relative expression in nested schemas, using AtParent() to +// traverse up the path or other At methods to traverse further down. +func MatchRelative() Expression { + return Expression{ + steps: ExpressionSteps{}, + } +} + +// MatchRoot creates an attribute path expression starting with +// ExpressionStepAttributeNameExact. +func MatchRoot(rootAttributeName string) Expression { + return Expression{ + root: true, + steps: ExpressionSteps{ + ExpressionStepAttributeNameExact(rootAttributeName), + }, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step.go new file mode 100644 index 00000000..7f52f79f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step.go @@ -0,0 +1,23 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +// ExpressionStep represents an expression of an attribute path step, which may +// match zero, one, or more actual paths. +type ExpressionStep interface { + // Equal should return true if the given Step is exactly equivalent. + Equal(ExpressionStep) bool + + // Matches should return true if the given PathStep can be fulfilled by the + // ExpressionStep. + Matches(PathStep) bool + + // String should return a human-readable representation of the step + // intended for logging and error messages. There should not be usage + // that needs to be protected by compatibility guarantees. + String() string + + // unexported prevents outside types from satisfying the interface. + unexported() +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_attribute_name_exact.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_attribute_name_exact.go new file mode 100644 index 00000000..b0a63fb5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_attribute_name_exact.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +// Ensure ExpressionStepAttributeNameExact satisfies the ExpressionStep +// interface. +var _ ExpressionStep = ExpressionStepAttributeNameExact("") + +// ExpressionStepAttributeNameExact is an attribute path expression for an +// exact attribute name match within an object. +type ExpressionStepAttributeNameExact string + +// Equal returns true if the given ExpressionStep is a +// ExpressionStepAttributeNameExact and the attribute name is equivalent. +func (s ExpressionStepAttributeNameExact) Equal(o ExpressionStep) bool { + other, ok := o.(ExpressionStepAttributeNameExact) + + if !ok { + return false + } + + return string(s) == string(other) +} + +// Matches returns true if the given PathStep is fulfilled by the +// ExpressionStepAttributeNameExact condition. +func (s ExpressionStepAttributeNameExact) Matches(pathStep PathStep) bool { + pathStepAttributeName, ok := pathStep.(PathStepAttributeName) + + if !ok { + return false + } + + return string(s) == string(pathStepAttributeName) +} + +// String returns the human-readable representation of the attribute name +// expression. It is intended for logging and error messages and is not +// protected by compatibility guarantees. +func (s ExpressionStepAttributeNameExact) String() string { + return string(s) +} + +// unexported satisfies the Step interface. +func (s ExpressionStepAttributeNameExact) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_int_any.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_int_any.go new file mode 100644 index 00000000..b8fe243b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_int_any.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +// Ensure ExpressionStepElementKeyIntAny satisfies the ExpressionStep +// interface. +var _ ExpressionStep = ExpressionStepElementKeyIntAny{} + +// ExpressionStepElementKeyIntAny is an attribute path expression for a matching any +// integer element key within a list. +type ExpressionStepElementKeyIntAny struct{} + +// Equal returns true if the given ExpressionStep is a +// ExpressionStepElementKeyIntAny. +func (s ExpressionStepElementKeyIntAny) Equal(o ExpressionStep) bool { + _, ok := o.(ExpressionStepElementKeyIntAny) + + return ok +} + +// Matches returns true if the given PathStep is fulfilled by the +// ExpressionStepElementKeyIntAny condition. +func (s ExpressionStepElementKeyIntAny) Matches(pathStep PathStep) bool { + _, ok := pathStep.(PathStepElementKeyInt) + + return ok +} + +// String returns the human-readable representation of the element key +// expression. It is intended for logging and error messages and is not +// protected by compatibility guarantees. +func (s ExpressionStepElementKeyIntAny) String() string { + return "[*]" +} + +// unexported satisfies the Step interface. +func (s ExpressionStepElementKeyIntAny) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_int_exact.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_int_exact.go new file mode 100644 index 00000000..90dd1ecb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_int_exact.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import ( + "fmt" +) + +// Ensure ExpressionStepElementKeyIntExact satisfies the ExpressionStep +// interface. +var _ ExpressionStep = ExpressionStepElementKeyIntExact(0) + +// ExpressionStepElementKeyIntExact is an attribute path expression for an exact integer +// element key match within a list. List indexing starts at 0. +type ExpressionStepElementKeyIntExact int64 + +// Equal returns true if the given ExpressionStep is a +// ExpressionStepElementKeyIntExact and the integer element key is equivalent. +func (s ExpressionStepElementKeyIntExact) Equal(o ExpressionStep) bool { + other, ok := o.(ExpressionStepElementKeyIntExact) + + if !ok { + return false + } + + return int64(s) == int64(other) +} + +// Matches returns true if the given PathStep is fulfilled by the +// ExpressionStepElementKeyIntExact condition. +func (s ExpressionStepElementKeyIntExact) Matches(pathStep PathStep) bool { + pathStepElementKeyInt, ok := pathStep.(PathStepElementKeyInt) + + if !ok { + return false + } + + return int64(s) == int64(pathStepElementKeyInt) +} + +// String returns the human-readable representation of the element key +// expression. It is intended for logging and error messages and is not +// protected by compatibility guarantees. +func (s ExpressionStepElementKeyIntExact) String() string { + return fmt.Sprintf("[%d]", s) +} + +// unexported satisfies the Step interface. +func (s ExpressionStepElementKeyIntExact) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_string_any.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_string_any.go new file mode 100644 index 00000000..0a3c7b67 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_string_any.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +// Ensure ExpressionStepElementKeyStringAny satisfies the ExpressionStep +// interface. +var _ ExpressionStep = ExpressionStepElementKeyStringAny{} + +// ExpressionStepElementKeyStringAny is an attribute path expression for a matching any +// string key within a map. +type ExpressionStepElementKeyStringAny struct{} + +// Equal returns true if the given ExpressionStep is a +// ExpressionStepElementKeyStringAny. +func (s ExpressionStepElementKeyStringAny) Equal(o ExpressionStep) bool { + _, ok := o.(ExpressionStepElementKeyStringAny) + + return ok +} + +// Matches returns true if the given PathStep is fulfilled by the +// ExpressionStepElementKeyStringAny condition. +func (s ExpressionStepElementKeyStringAny) Matches(pathStep PathStep) bool { + _, ok := pathStep.(PathStepElementKeyString) + + return ok +} + +// String returns the human-readable representation of the element key +// expression. It is intended for logging and error messages and is not +// protected by compatibility guarantees. +func (s ExpressionStepElementKeyStringAny) String() string { + return `["*"]` +} + +// unexported satisfies the Step interface. +func (s ExpressionStepElementKeyStringAny) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_string_exact.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_string_exact.go new file mode 100644 index 00000000..1d138e69 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_string_exact.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import ( + "fmt" +) + +// Ensure ExpressionStepElementKeyStringExact satisfies the ExpressionStep +// interface. +var _ ExpressionStep = ExpressionStepElementKeyStringExact("") + +// ExpressionStepElementKeyStringExact is an attribute path expression for an exact string +// key within a map. Map keys are always strings. +type ExpressionStepElementKeyStringExact string + +// Equal returns true if the given ExpressionStep is a +// ExpressionStepElementKeyStringExact and the string element key is equivalent. +func (s ExpressionStepElementKeyStringExact) Equal(o ExpressionStep) bool { + other, ok := o.(ExpressionStepElementKeyStringExact) + + if !ok { + return false + } + + return string(s) == string(other) +} + +// Matches returns true if the given PathStep is fulfilled by the +// ExpressionStepElementKeyStringExact condition. +func (s ExpressionStepElementKeyStringExact) Matches(pathStep PathStep) bool { + pathStepElementKeyString, ok := pathStep.(PathStepElementKeyString) + + if !ok { + return false + } + + return string(s) == string(pathStepElementKeyString) +} + +// String returns the human-readable representation of the element key +// expression. It is intended for logging and error messages and is not +// protected by compatibility guarantees. +func (s ExpressionStepElementKeyStringExact) String() string { + return fmt.Sprintf("[%q]", string(s)) +} + +// unexported satisfies the Step interface. +func (s ExpressionStepElementKeyStringExact) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_value_any.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_value_any.go new file mode 100644 index 00000000..f222c3fd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_value_any.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +// Ensure ExpressionStepElementKeyValueAny satisfies the ExpressionStep +// interface. +var _ ExpressionStep = ExpressionStepElementKeyValueAny{} + +// ExpressionStepElementKeyValueAny is an attribute path expression for a matching any +// Value element within a set. +type ExpressionStepElementKeyValueAny struct{} + +// Equal returns true if the given ExpressionStep is a +// ExpressionStepElementKeyValueAny. +func (s ExpressionStepElementKeyValueAny) Equal(o ExpressionStep) bool { + _, ok := o.(ExpressionStepElementKeyValueAny) + + return ok +} + +// Matches returns true if the given PathStep is fulfilled by the +// ExpressionStepElementKeyValueAny condition. +func (s ExpressionStepElementKeyValueAny) Matches(pathStep PathStep) bool { + _, ok := pathStep.(PathStepElementKeyValue) + + return ok +} + +// String returns the human-readable representation of the element key +// expression. It is intended for logging and error messages and is not +// protected by compatibility guarantees. +func (s ExpressionStepElementKeyValueAny) String() string { + return "[Value(*)]" +} + +// unexported satisfies the Step interface. +func (s ExpressionStepElementKeyValueAny) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_value_exact.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_value_exact.go new file mode 100644 index 00000000..cfa3780a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_element_key_value_exact.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" +) + +// Ensure ExpressionStepElementKeyValueExact satisfies the Step interface. +// var _ Step = ExpressionStepElementKeyValueExact(/* ... */) + +// ExpressionStepElementKeyValueExact is an attribute path expression for an exact Value +// element within a set. Sets do not use integer-based indexing. +type ExpressionStepElementKeyValueExact struct { + // Value is an interface, so it cannot be type aliased with methods. + attr.Value +} + +// Equal returns true if the given ExpressionStep is a +// ExpressionStepElementKeyValueExact and the Value element key is equivalent. +func (s ExpressionStepElementKeyValueExact) Equal(o ExpressionStep) bool { + other, ok := o.(ExpressionStepElementKeyValueExact) + + if !ok { + return false + } + + return s.Value.Equal(other.Value) +} + +// Matches returns true if the given PathStep is fulfilled by the +// ExpressionStepElementKeyValueExact condition. +func (s ExpressionStepElementKeyValueExact) Matches(pathStep PathStep) bool { + pathStepElementKeyValue, ok := pathStep.(PathStepElementKeyValue) + + if !ok { + return false + } + + return s.Value.Equal(pathStepElementKeyValue.Value) +} + +// String returns the human-readable representation of the element key +// expression. It is intended for logging and error messages and is not +// protected by compatibility guarantees. +func (s ExpressionStepElementKeyValueExact) String() string { + return fmt.Sprintf("[Value(%s)]", s.Value.String()) +} + +// unexported satisfies the Step interface. +func (s ExpressionStepElementKeyValueExact) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_parent.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_parent.go new file mode 100644 index 00000000..255df4d3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_step_parent.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +// Ensure StepParent satisfies the ExpressionStep interface. +var _ ExpressionStep = ExpressionStepParent{} + +// StepParent is an attribute path expression for a traversing to the parent +// attribute path relative to the current one. This is intended only for the +// start of attribute-level expressions which will be combined with the current +// attribute path being called. +type ExpressionStepParent struct{} + +// Equal returns true if the given ExpressionStep is a ExpressionStepParent. +func (s ExpressionStepParent) Equal(o ExpressionStep) bool { + _, ok := o.(ExpressionStepParent) + + return ok +} + +// Matches returns true if the given PathStep is fulfilled by the +// ExpressionStepParent condition. +func (s ExpressionStepParent) Matches(_ PathStep) bool { + // This return value should have no effect, as this Step is a + // sentinel type, rather than one that should be used in matching. + return false +} + +// String returns the human-readable representation of the element key +// expression. It is intended for logging and error messages and is not +// protected by compatibility guarantees. +func (s ExpressionStepParent) String() string { + return "<" +} + +// unexported satisfies the Step interface. +func (s ExpressionStepParent) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_steps.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_steps.go new file mode 100644 index 00000000..3abe0ed8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expression_steps.go @@ -0,0 +1,189 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import "strings" + +// ExpressionSteps represents an ordered collection of attribute path +// expressions. +type ExpressionSteps []ExpressionStep + +// Append adds the given ExpressionSteps to the end of the previous ExpressionSteps and +// returns the combined result. +func (s *ExpressionSteps) Append(steps ...ExpressionStep) ExpressionSteps { + if s == nil { + return steps + } + + *s = append(*s, steps...) + + return *s +} + +// Copy returns a duplicate of the steps that is safe to modify without +// affecting the original. Returns nil if the original steps is nil. +func (s ExpressionSteps) Copy() ExpressionSteps { + if s == nil { + return nil + } + + copiedExpressionSteps := make(ExpressionSteps, len(s)) + + copy(copiedExpressionSteps, s) + + return copiedExpressionSteps +} + +// Equal returns true if the given ExpressionSteps are equivalent. +func (s ExpressionSteps) Equal(o ExpressionSteps) bool { + if len(s) != len(o) { + return false + } + + for stepIndex, step := range s { + if !step.Equal(o[stepIndex]) { + return false + } + } + + return true +} + +// LastStep returns the final ExpressionStep and the remaining ExpressionSteps. +func (s ExpressionSteps) LastStep() (ExpressionStep, ExpressionSteps) { + if len(s) == 0 { + return nil, ExpressionSteps{} + } + + if len(s) == 1 { + return s[0], ExpressionSteps{} + } + + return s[len(s)-1], s[:len(s)-1] +} + +// Matches returns true if the given PathSteps match each ExpressionStep. +// +// Any ExpressionStepParent will automatically be resolved. +func (s ExpressionSteps) Matches(pathSteps PathSteps) bool { + resolvedExpressionSteps := s.Resolve() + + // Empty expression should not match anything to prevent false positives. + if len(resolvedExpressionSteps) == 0 { + return false + } + + if len(resolvedExpressionSteps) != len(pathSteps) { + return false + } + + for stepIndex, expressionStep := range resolvedExpressionSteps { + if !expressionStep.Matches(pathSteps[stepIndex]) { + return false + } + } + + return true +} + +// MatchesParent returns true if the given PathSteps match each ExpressionStep +// until there are no more PathSteps. This is helpful for determining if the +// PathSteps would potentially match the full ExpressionSteps during +// depth-first traversal. +// +// Any ExpressionStepParent will automatically be resolved. +func (s ExpressionSteps) MatchesParent(pathSteps PathSteps) bool { + resolvedExpressionSteps := s.Resolve() + + // Empty expression should not match anything to prevent false positives. + // Ensure to not return false on an empty path since walking a path always + // starts with no steps. + if len(resolvedExpressionSteps) == 0 { + return false + } + + // Path steps deeper than or equal to the expression steps should not match + // as a potential parent. + if len(pathSteps) >= len(resolvedExpressionSteps) { + return false + } + + for stepIndex, pathStep := range pathSteps { + if !resolvedExpressionSteps[stepIndex].Matches(pathStep) { + return false + } + } + + return true +} + +// NextStep returns the first ExpressionStep and the remaining ExpressionSteps. +func (s ExpressionSteps) NextStep() (ExpressionStep, ExpressionSteps) { + if len(s) == 0 { + return nil, s + } + + return s[0], s[1:] +} + +// Resolve returns a copy of ExpressionSteps without any ExpressionStepParent. +// +// Returns empty ExpressionSteps if any ExpressionStepParent attempt to go +// beyond the first element. Returns nil if the original steps is nil. +func (s ExpressionSteps) Resolve() ExpressionSteps { + if s == nil { + return nil + } + + result := make(ExpressionSteps, 0, len(s)) + + // This might not be the most efficient or prettiest algorithm, but it + // works for now. + for _, step := range s { + _, ok := step.(ExpressionStepParent) + + if !ok { + result.Append(step) + + continue + } + + // Allow parent traversal up to the root, but not beyond. + if len(result) == 0 { + return ExpressionSteps{} + } + + _, remaining := result.LastStep() + + if len(remaining) == 0 { + result = ExpressionSteps{} + + continue + } + + result = remaining + } + + return result +} + +// String returns the human-readable representation of the ExpressionSteps. +// It is intended for logging and error messages and is not protected by +// compatibility guarantees. +func (s ExpressionSteps) String() string { + var result strings.Builder + + for stepIndex, step := range s { + if stepIndex != 0 { + switch step.(type) { + case ExpressionStepAttributeNameExact, ExpressionStepParent: + result.WriteString(".") + } + } + + result.WriteString(step.String()) + } + + return result.String() +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/expressions.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expressions.go new file mode 100644 index 00000000..4362e7c1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/expressions.go @@ -0,0 +1,80 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import "strings" + +// Expressions is a collection of attribute path expressions. +// +// Refer to the Expression documentation for more details about intended usage. +type Expressions []Expression + +// Append adds the given Expressions to the collection without duplication and +// returns the combined result. +func (e *Expressions) Append(expressions ...Expression) Expressions { + if e == nil { + return expressions + } + + for _, newExpression := range expressions { + if e.Contains(newExpression) { + continue + } + + *e = append(*e, newExpression) + } + + return *e +} + +// Contains returns true if the collection of expressions includes the given +// expression. +func (e Expressions) Contains(checkExpression Expression) bool { + for _, expression := range e { + if expression.Equal(checkExpression) { + return true + } + } + + return false +} + +// Matches returns true if one of the expressions in the collection matches the +// given path. +func (e Expressions) Matches(checkPath Path) bool { + for _, expression := range e { + if expression.Matches(checkPath) { + return true + } + } + + return false +} + +// String returns the human-readable representation of the expression +// collection. It is intended for logging and error messages and is not +// protected by compatibility guarantees. +// +// Empty expressions are skipped. +func (p Expressions) String() string { + var result strings.Builder + + result.WriteString("[") + + for pathIndex, path := range p { + if path.Equal(Expression{}) { + continue + } + + if pathIndex != 0 { + result.WriteString(",") + } + + result.WriteString(path.String()) + } + + result.WriteString("]") + + return result.String() +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/path.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path.go new file mode 100644 index 00000000..4e060bd9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path.go @@ -0,0 +1,176 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" +) + +// Path represents exact traversal steps into a schema or schema-based data. +// These steps always start from the root of the schema, which is an object +// with zero or more attributes and blocks. +// +// Use the Root() function to create a Path with an initial AtName() step. Path +// functionality follows a builder pattern, which allows for chaining method +// calls to construct a full path. The available traversal steps after Path +// creation are: +// +// - AtListIndex(): Step into a list at a specific 0-based index +// - AtMapKey(): Step into a map at a specific key +// - AtName(): Step into an attribute or block with a specific name +// - AtSetValue(): Step into a set at a specific attr.Value element +// +// For example, to represent the first list element with a root list attribute +// named "some_attribute": +// +// path.MatchRoot("some_attribute").AtListIndex(0) +// +// Path is used for functionality which must exactly match the underlying +// schema structure and types, such as diagnostics that are intended for a +// specific attribute or working with specific attribute values in a schema +// based data structure such as tfsdk.Config, tfsdk.Plan, or tfsdk.State. +// +// Refer to Expression for situations where relative or wildcard step logic is +// desirable for schema defined functionality, such as attribute validators or +// attribute plan modifiers. +type Path struct { + // steps is the transversals included with the path. In general, operations + // against the path should protect against modification of the original. + steps PathSteps +} + +// AtListIndex returns a copied path with a new list index step at the end. +// The returned path is safe to modify without affecting the original. +// +// List indices are 0-based. The first element of a list is 0. +func (p Path) AtListIndex(index int) Path { + copiedPath := p.Copy() + + copiedPath.steps.Append(PathStepElementKeyInt(index)) + + return copiedPath +} + +// AtTupleIndex returns a copied path with a new tuple index step at the end. +// The returned path is safe to modify without affecting the original. +// +// Tuple indices are 0-based. The first element of a tuple is 0. +func (p Path) AtTupleIndex(index int) Path { + copiedPath := p.Copy() + + copiedPath.steps.Append(PathStepElementKeyInt(index)) + + return copiedPath +} + +// AtMapKey returns a copied path with a new map key step at the end. +// The returned path is safe to modify without affecting the original. +func (p Path) AtMapKey(key string) Path { + copiedPath := p.Copy() + + copiedPath.steps.Append(PathStepElementKeyString(key)) + + return copiedPath +} + +// AtName returns a copied path with a new attribute or block name step at the +// end. The returned path is safe to modify without affecting the original. +func (p Path) AtName(name string) Path { + copiedPath := p.Copy() + + copiedPath.steps.Append(PathStepAttributeName(name)) + + return copiedPath +} + +// AtSetValue returns a copied path with a new set value step at the end. +// The returned path is safe to modify without affecting the original. +func (p Path) AtSetValue(value attr.Value) Path { + copiedPath := p.Copy() + + copiedPath.steps.Append(PathStepElementKeyValue{Value: value}) + + return copiedPath +} + +// Copy returns a duplicate of the path that is safe to modify without +// affecting the original. +func (p Path) Copy() Path { + return Path{ + steps: p.Steps(), + } +} + +// Equal returns true if the given path is exactly equivalent. +func (p Path) Equal(o Path) bool { + if p.steps == nil && o.steps == nil { + return true + } + + if p.steps == nil { + return false + } + + if !p.steps.Equal(o.steps) { + return false + } + + return true +} + +// Expression returns an Expression which exactly matches the Path. +func (p Path) Expression() Expression { + return Expression{ + root: true, + steps: p.steps.ExpressionSteps(), + } +} + +// ParentPath returns a copy of the path with the last step removed. +// +// If the current path is empty, an empty path is returned. +func (p Path) ParentPath() Path { + if len(p.steps) == 0 { + return Empty() + } + + _, remainingSteps := p.steps.Copy().LastStep() + + return Path{ + steps: remainingSteps, + } +} + +// Steps returns a copy of the underlying path steps. Returns an empty +// collection of steps if path is nil. +func (p Path) Steps() PathSteps { + if len(p.steps) == 0 { + return PathSteps{} + } + + return p.steps.Copy() +} + +// String returns the human-readable representation of the path. +// It is intended for logging and error messages and is not protected by +// compatibility guarantees. +func (p Path) String() string { + return p.steps.String() +} + +// Empty creates an empty attribute path. Provider code should use Root. +func Empty() Path { + return Path{ + steps: PathSteps{}, + } +} + +// Root creates an attribute path starting with a PathStepAttributeName. +func Root(rootAttributeName string) Path { + return Path{ + steps: PathSteps{ + PathStepAttributeName(rootAttributeName), + }, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step.go new file mode 100644 index 00000000..31e435d8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step.go @@ -0,0 +1,24 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +// PathStep represents a transversal for an attribute path. Only exact path +// transversals are supported as implementations of this interface must remain +// compatible with all protocol implementations. +type PathStep interface { + // Equal should return true if the given PathStep is exactly equivalent. + Equal(PathStep) bool + + // ExpressionStep should return an ExpressionStep which exactly + // matches the PathStep. + ExpressionStep() ExpressionStep + + // String should return a human-readable representation of the step + // intended for logging and error messages. There should not be usage + // that needs to be protected by compatibility guarantees. + String() string + + // unexported prevents outside types from satisfying the interface. + unexported() +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_attribute_name.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_attribute_name.go new file mode 100644 index 00000000..164ec6c0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_attribute_name.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +// Ensure PathStepAttributeName satisfies the PathStep interface. +var _ PathStep = PathStepAttributeName("") + +// PathStepAttributeName is an attribute path tranversal for an attribute name +// within an object. +// +// List elements must be transversed by PathStepElementKeyInt. +// Map elements must be transversed by PathStepElementKeyString. +// Set elements must be transversed by PathStepElementKeyValue. +type PathStepAttributeName string + +// Equal returns true if the given PathStep is a PathStepAttributeName and the +// attribute name is equivalent. +func (s PathStepAttributeName) Equal(o PathStep) bool { + other, ok := o.(PathStepAttributeName) + + if !ok { + return false + } + + return string(s) == string(other) +} + +// ExpressionStep returns the ExpressionStep for the PathStep. +func (s PathStepAttributeName) ExpressionStep() ExpressionStep { + return ExpressionStepAttributeNameExact(s) +} + +// String returns the human-readable representation of the attribute name. +// It is intended for logging and error messages and is not protected by +// compatibility guarantees. +func (s PathStepAttributeName) String() string { + return string(s) +} + +// unexported satisfies the PathStep interface. +func (s PathStepAttributeName) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_int.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_int.go new file mode 100644 index 00000000..2dd94787 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_int.go @@ -0,0 +1,44 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import "fmt" + +// Ensure PathStepElementKeyInt satisfies the PathStep interface. +var _ PathStep = PathStepElementKeyInt(0) + +// PathStepElementKeyInt is an attribute path transversal for an integer +// element of a list. List indexing starts a 0. +// +// Map elements must be transversed by PathStepElementKeyString. +// Object attributes must be transversed by PathStepAttributeName. +// Set elements must be transversed by PathStepElementKeyValue. +type PathStepElementKeyInt int64 + +// Equal returns true if the given PathStep is a PathStepAttributeName and the +// attribute name is equivalent. +func (s PathStepElementKeyInt) Equal(o PathStep) bool { + other, ok := o.(PathStepElementKeyInt) + + if !ok { + return false + } + + return int64(s) == int64(other) +} + +// ExpressionStep returns the ExpressionStep for the PathStep. +func (s PathStepElementKeyInt) ExpressionStep() ExpressionStep { + return ExpressionStepElementKeyIntExact(s) +} + +// String returns the human-readable representation of the element key. +// It is intended for logging and error messages and is not protected by +// compatibility guarantees. +func (s PathStepElementKeyInt) String() string { + return fmt.Sprintf("[%d]", s) +} + +// unexported satisfies the PathStep interface. +func (s PathStepElementKeyInt) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_string.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_string.go new file mode 100644 index 00000000..2a0f0ded --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_string.go @@ -0,0 +1,44 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import "fmt" + +// Ensure PathStepElementKeyString satisfies the PathStep interface. +var _ PathStep = PathStepElementKeyString("") + +// PathStepElementKeyString is an attribute path transversal for a string +// key of a map. Map keys are always strings. +// +// List elements must be transversed by PathStepElementKeyInt. +// Object attributes must be transversed by PathStepAttributeName. +// Set elements must be transversed by PathStepElementKeyValue. +type PathStepElementKeyString string + +// Equal returns true if the given PathStep is a PathStepAttributeName and the +// attribute name is equivalent. +func (s PathStepElementKeyString) Equal(o PathStep) bool { + other, ok := o.(PathStepElementKeyString) + + if !ok { + return false + } + + return string(s) == string(other) +} + +// ExpressionStep returns the ExpressionStep for the PathStep. +func (s PathStepElementKeyString) ExpressionStep() ExpressionStep { + return ExpressionStepElementKeyStringExact(s) +} + +// String returns the human-readable representation of the element key. +// It is intended for logging and error messages and is not protected by +// compatibility guarantees. +func (s PathStepElementKeyString) String() string { + return fmt.Sprintf("[%q]", string(s)) +} + +// unexported satisfies the PathStep interface. +func (s PathStepElementKeyString) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_value.go new file mode 100644 index 00000000..58c9fa2d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_step_element_key_value.go @@ -0,0 +1,51 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" +) + +// Ensure PathStepElementKeyValue satisfies the PathStep interface. +// var _ PathStep = PathStepElementKeyValue(/* ... */) + +// PathStepElementKeyValue is an attribute path transversal for a Value element +// of a set. Sets do not use integer-based indexing. +// +// List elements must be transversed by PathStepElementKeyInt. +// Map elements must be transversed by PathStepElementKeyString. +// Object attributes must be transversed by PathStepAttributeName. +type PathStepElementKeyValue struct { + // Value is an interface, so it cannot be type aliased with methods. + attr.Value +} + +// Equal returns true if the given PathStep is a PathStepAttributeName and the +// attribute name is equivalent. +func (s PathStepElementKeyValue) Equal(o PathStep) bool { + other, ok := o.(PathStepElementKeyValue) + + if !ok { + return false + } + + return s.Value.Equal(other.Value) +} + +// ExpressionStep returns the ExpressionStep for the PathStep. +func (s PathStepElementKeyValue) ExpressionStep() ExpressionStep { + return ExpressionStepElementKeyValueExact(s) +} + +// String returns the human-readable representation of the element key. +// It is intended for logging and error messages and is not protected by +// compatibility guarantees. +func (s PathStepElementKeyValue) String() string { + return fmt.Sprintf("[Value(%s)]", s.Value.String()) +} + +// unexported satisfies the PathStep interface. +func (s PathStepElementKeyValue) unexported() {} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_steps.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_steps.go new file mode 100644 index 00000000..adac94e9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/path_steps.go @@ -0,0 +1,101 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import "strings" + +// PathSteps represents an ordered collection of attribute path transversals. +type PathSteps []PathStep + +// Append adds the given PathSteps to the end of the previous PathSteps and +// returns the combined result. +func (s *PathSteps) Append(steps ...PathStep) PathSteps { + if s == nil { + return steps + } + + *s = append(*s, steps...) + + return *s +} + +// Copy returns a duplicate of the steps that is safe to modify without +// affecting the original. Returns nil if the original steps is nil. +func (s PathSteps) Copy() PathSteps { + if s == nil { + return nil + } + + copiedPathSteps := make(PathSteps, len(s)) + + copy(copiedPathSteps, s) + + return copiedPathSteps +} + +// Equal returns true if the given PathSteps are equivalent. +func (s PathSteps) Equal(o PathSteps) bool { + if len(s) != len(o) { + return false + } + + for stepIndex, step := range s { + if !step.Equal(o[stepIndex]) { + return false + } + } + + return true +} + +// LastStep returns the final PathStep and the remaining PathSteps. +func (s PathSteps) LastStep() (PathStep, PathSteps) { + if len(s) == 0 { + return nil, PathSteps{} + } + + if len(s) == 1 { + return s[0], PathSteps{} + } + + return s[len(s)-1], s[:len(s)-1] +} + +// NextStep returns the first PathStep and the remaining PathSteps. +func (s PathSteps) NextStep() (PathStep, PathSteps) { + if len(s) == 0 { + return nil, s + } + + return s[0], s[1:] +} + +// String returns the human-readable representation of the PathSteps. +// It is intended for logging and error messages and is not protected by +// compatibility guarantees. +func (s PathSteps) String() string { + var result strings.Builder + + for stepIndex, step := range s { + if _, ok := step.(PathStepAttributeName); ok && stepIndex != 0 { + result.WriteString(".") + } + + result.WriteString(step.String()) + } + + return result.String() +} + +// ExpressionSteps returns the ordered collection of expression steps which +// exactly matches the PathSteps. +func (s PathSteps) ExpressionSteps() ExpressionSteps { + result := make(ExpressionSteps, len(s)) + + for stepIndex, pathStep := range s { + result[stepIndex] = pathStep.ExpressionStep() + } + + return result +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/path/paths.go b/vendor/github.com/hashicorp/terraform-plugin-framework/path/paths.go new file mode 100644 index 00000000..994f8506 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/path/paths.go @@ -0,0 +1,67 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package path + +import "strings" + +// Paths is a collection of exact attribute paths. +// +// Refer to the Path documentation for more details about intended usage. +type Paths []Path + +// Append adds the given Paths to the collection without duplication and +// returns the combined result. +func (p *Paths) Append(paths ...Path) Paths { + if p == nil { + return paths + } + + for _, newPath := range paths { + if p.Contains(newPath) { + continue + } + + *p = append(*p, newPath) + } + + return *p +} + +// Contains returns true if the collection of paths includes the given path. +func (p Paths) Contains(checkPath Path) bool { + for _, path := range p { + if path.Equal(checkPath) { + return true + } + } + + return false +} + +// String returns the human-readable representation of the path collection. +// It is intended for logging and error messages and is not protected by +// compatibility guarantees. +// +// Empty paths are skipped. +func (p Paths) String() string { + var result strings.Builder + + result.WriteString("[") + + for pathIndex, path := range p { + if path.Equal(Empty()) { + continue + } + + if pathIndex != 0 { + result.WriteString(",") + } + + result.WriteString(path.String()) + } + + result.WriteString("]") + + return result.String() +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/config_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/config_validator.go new file mode 100644 index 00000000..11d5337d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/config_validator.go @@ -0,0 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package provider + +import "context" + +// ConfigValidator describes reusable Provider configuration validation functionality. +type ConfigValidator interface { + // Description describes the validation in plain text formatting. + // + // This information may be automatically added to provider plain text + // descriptions by external tooling. + Description(context.Context) string + + // MarkdownDescription describes the validation in Markdown formatting. + // + // This information may be automatically added to provider Markdown + // descriptions by external tooling. + MarkdownDescription(context.Context) string + + // ValidateProvider performs the validation. + // + // This method name is separate from the ConfigValidator + // interface ValidateDataSource method name and ResourceConfigValidator + // interface ValidateResource method name to allow generic validators. + ValidateProvider(context.Context, ValidateConfigRequest, *ValidateConfigResponse) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/configure.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/configure.go new file mode 100644 index 00000000..600f402f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/configure.go @@ -0,0 +1,48 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package provider + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ConfigureRequest represents a request containing the values the user +// specified for the provider configuration block, along with other runtime +// information from Terraform or the Plugin SDK. An instance of this request +// struct is supplied as an argument to the provider's Configure function. +type ConfigureRequest struct { + // TerraformVersion is the version of Terraform executing the request. + // This is supplied for logging, analytics, and User-Agent purposes + // only. Providers should not try to gate provider behavior on + // Terraform versions. + TerraformVersion string + + // Config is the configuration the user supplied for the provider. This + // information should usually be persisted to the underlying type + // that's implementing the Provider interface, for use in later + // resource CRUD operations. + Config tfsdk.Config +} + +// ConfigureResponse represents a response to a +// ConfigureRequest. An instance of this response struct is supplied as +// an argument to the provider's Configure function, in which the provider +// should set values on the ConfigureResponse as appropriate. +type ConfigureResponse struct { + // DataSourceData is provider-defined data, clients, etc. that is passed + // to [datasource.ConfigureRequest.ProviderData] for each DataSource type + // that implements the Configure method. + DataSourceData any + + // Diagnostics report errors or warnings related to configuring the + // provider. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics + + // ResourceData is provider-defined data, clients, etc. that is passed + // to [resource.ConfigureRequest.ProviderData] for each Resource type + // that implements the Configure method. + ResourceData any +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/doc.go new file mode 100644 index 00000000..dc5c3434 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/doc.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package provider contains all interfaces, request types, and response +// types for a provider implementation. +// +// In Terraform, a provider is a concept which enables provider developers +// to offer practitioners data sources and managed resources. Those concepts +// are described in more detail in their respective datasource and resource +// packages. +// +// Providers generally store any infrastructure clients or shared data that is +// applicable across data sources and managed resources. Providers are +// generally configured early in Terraform operations, such as plan and apply, +// before data source and managed resource logic is called. However, this early +// provider configuration is not guaranteed in the case there are unknown +// Terraform configuration values, so additional logic checks may be required +// throughout an implementation to handle this case. Providers may contain a +// schema representing the structure and data types of Terraform-based +// configuration. +// +// The main starting point for implementations in this package is the +// Provider type which represents an instance of a provider that has +// its own configuration. +package provider diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metadata.go new file mode 100644 index 00000000..f298e2f4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metadata.go @@ -0,0 +1,24 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package provider + +// MetadataRequest represents a request for the Provider to return its type +// name. An instance of this request struct is supplied as an argument to the +// Provider type Metadata method. +type MetadataRequest struct{} + +// MetadataResponse represents a response to a MetadataRequest. An +// instance of this response struct is supplied as an argument to the +// Provider type Metadata method. +type MetadataResponse struct { + // TypeName should be the provider type. For example, examplecloud, if + // the intended resource or data source types are examplecloud_thing, etc. + TypeName string + + // Version should be the provider version, such as 1.2.3. + // + // This is not connected to any framework functionality currently, but may + // be in the future. + Version string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema.go new file mode 100644 index 00000000..f3234850 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package provider + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/provider/metaschema" +) + +// MetaSchemaRequest represents a request for the Provider to return its schema. +// An instance of this request struct is supplied as an argument to the +// Provider type Schema method. +type MetaSchemaRequest struct{} + +// MetaSchemaResponse represents a response to a MetaSchemaRequest. An instance of this +// response struct is supplied as an argument to the Provider type Schema +// method. +type MetaSchemaResponse struct { + // Schema is the meta schema of the provider. + Schema metaschema.Schema + + // Diagnostics report errors or warnings related to validating the data + // source configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/attribute.go new file mode 100644 index 00000000..beba30fb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/attribute.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Attribute define a value field inside the Schema. Implementations in this +// package include: +// - BoolAttribute +// - Float64Attribute +// - Int64Attribute +// - ListAttribute +// - MapAttribute +// - NumberAttribute +// - ObjectAttribute +// - SetAttribute +// - StringAttribute +// +// Additionally, the NestedAttribute interface extends Attribute with nested +// attributes. Only supported in protocol version 6. Implementations in this +// package include: +// - ListNestedAttribute +// - MapNestedAttribute +// - SetNestedAttribute +// - SingleNestedAttribute +// +// In practitioner configurations, an equals sign (=) is required to set +// the value. [Configuration Reference] +// +// [Configuration Reference]: https://developer.hashicorp.com/terraform/language/syntax/configuration +type Attribute interface { + fwschema.Attribute +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/bool_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/bool_attribute.go new file mode 100644 index 00000000..6d96a516 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/bool_attribute.go @@ -0,0 +1,119 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = BoolAttribute{} +) + +// BoolAttribute represents a schema attribute that is a boolean. When +// retrieving the value for this attribute, use types.Bool as the value type +// unless the CustomType field is set. +// +// Terraform configurations configure this attribute using expressions that +// return a boolean or directly via the true/false keywords. +// +// example_attribute = true +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type BoolAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.BoolType. When retrieving data, the basetypes.BoolValuable + // associated with this custom type must be used in place of types.Bool. + CustomType basetypes.BoolTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a BoolAttribute. +func (a BoolAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a BoolAttribute +// and all fields are equal. +func (a BoolAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(BoolAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a BoolAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a BoolAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a BoolAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.StringType or the CustomType field value if defined. +func (a BoolAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.BoolType +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a BoolAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a BoolAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a BoolAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a BoolAttribute) IsSensitive() bool { + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/doc.go new file mode 100644 index 00000000..1e225407 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/doc.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package metaschema contains all available meta schema functionality for +// providers. Provider meta schemas define the structure and value types for +// provider_meta configuration data. Meta schemas are implemented via the +// provider.ProviderWithMetaSchema type MetaSchema method. +package metaschema diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/float64_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/float64_attribute.go new file mode 100644 index 00000000..8a447865 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/float64_attribute.go @@ -0,0 +1,122 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = Float64Attribute{} +) + +// Float64Attribute represents a schema attribute that is a 64-bit floating +// point number. When retrieving the value for this attribute, use +// types.Float64 as the value type unless the CustomType field is set. +// +// Use Int64Attribute for 64-bit integer attributes or NumberAttribute for +// 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via a floating point value. +// +// example_attribute = 123.45 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type Float64Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Float64Type. When retrieving data, the basetypes.Float64Valuable + // associated with this custom type must be used in place of types.Float64. + CustomType basetypes.Float64Typable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Float64Attribute. +func (a Float64Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Float64Attribute +// and all fields are equal. +func (a Float64Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Float64Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a Float64Attribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a Float64Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a Float64Attribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.Float64Type or the CustomType field value if defined. +func (a Float64Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Float64Type +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a Float64Attribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a Float64Attribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a Float64Attribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a Float64Attribute) IsSensitive() bool { + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/int64_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/int64_attribute.go new file mode 100644 index 00000000..8751d574 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/int64_attribute.go @@ -0,0 +1,122 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = Int64Attribute{} +) + +// Int64Attribute represents a schema attribute that is a 64-bit integer. +// When retrieving the value for this attribute, use types.Int64 as the value +// type unless the CustomType field is set. +// +// Use Float64Attribute for 64-bit floating point number attributes or +// NumberAttribute for 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via an integer value. +// +// example_attribute = 123 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type Int64Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Int64Type. When retrieving data, the basetypes.Int64Valuable + // associated with this custom type must be used in place of types.Int64. + CustomType basetypes.Int64Typable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Int64Attribute. +func (a Int64Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Int64Attribute +// and all fields are equal. +func (a Int64Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Int64Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a Int64Attribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a Int64Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a Int64Attribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.Int64Type or the CustomType field value if defined. +func (a Int64Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Int64Type +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a Int64Attribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a Int64Attribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a Int64Attribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a Int64Attribute) IsSensitive() bool { + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/list_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/list_attribute.go new file mode 100644 index 00000000..a3ff30e6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/list_attribute.go @@ -0,0 +1,145 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = ListAttribute{} + _ fwschema.AttributeWithValidateImplementation = ListAttribute{} +) + +// ListAttribute represents a schema attribute that is a list with a single +// element type. When retrieving the value for this attribute, use types.List +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use ListNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list or directly via square brace syntax. +// +// # list of strings +// example_attribute = ["first", "second"] +// +// Terraform configurations reference this attribute using expressions that +// accept a list or an element directly via square brace 0-based index syntax: +// +// # first known element +// .example_attribute[0] +type ListAttribute struct { + // ElementType is the type for all elements of the list. This field must be + // set. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ListType. When retrieving data, the basetypes.ListValuable + // associated with this custom type must be used in place of types.List. + CustomType basetypes.ListTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a list +// index or an error. +func (a ListAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a ListAttribute +// and all fields are equal. +func (a ListAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(ListAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a ListAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a ListAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ListAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.ListType or the CustomType field value if defined. +func (a ListAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ListType{ + ElemType: a.ElementType, + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a ListAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a ListAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ListAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a ListAttribute) IsSensitive() bool { + return false +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a ListAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/list_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/list_nested_attribute.go new file mode 100644 index 00000000..a6b4f875 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/list_nested_attribute.go @@ -0,0 +1,161 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = ListNestedAttribute{} +) + +// ListNestedAttribute represents an attribute that is a list of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.List +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use ListAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list of objects or directly via square and curly brace syntax. +// +// # list of objects +// example_attribute = [ +// { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a list of objects or an element directly via square brace 0-based +// index syntax: +// +// # first known object +// .example_attribute[0] +// # first known object nested_attribute value +// .example_attribute[0].nested_attribute +type ListNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.ListType of types.ObjectType. When retrieving data, the + // basetypes.ListValuable associated with this custom type must be used in + // place of types.List. + CustomType basetypes.ListTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyInt, otherwise returns an error. +func (a ListNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyInt) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to ListNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a ListNestedAttribute +// and all fields are equal. +func (a ListNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(ListNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a ListNestedAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a ListNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ListNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a ListNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a ListNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeList +} + +// GetType returns ListType of ObjectType or CustomType. +func (a ListNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ListType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a ListNestedAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a ListNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ListNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a ListNestedAttribute) IsSensitive() bool { + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/map_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/map_attribute.go new file mode 100644 index 00000000..d75cec98 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/map_attribute.go @@ -0,0 +1,148 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = MapAttribute{} + _ fwschema.AttributeWithValidateImplementation = MapAttribute{} +) + +// MapAttribute represents a schema attribute that is a list with a single +// element type. When retrieving the value for this attribute, use types.Map +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use MapNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list or directly via curly brace syntax. +// +// # map of strings +// example_attribute = { +// key1 = "first", +// key2 = "second", +// } +// +// Terraform configurations reference this attribute using expressions that +// accept a map or an element directly via square brace string syntax: +// +// # key1 known element +// .example_attribute["key1"] +type MapAttribute struct { + // ElementType is the type for all elements of the map. This field must be + // set. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.MapType. When retrieving data, the basetypes.MapValuable + // associated with this custom type must be used in place of types.Map. + CustomType basetypes.MapTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a map +// index or an error. +func (a MapAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a MapAttribute +// and all fields are equal. +func (a MapAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(MapAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a MapAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a MapAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a MapAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.MapType or the CustomType field value if defined. +func (a MapAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.MapType{ + ElemType: a.ElementType, + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a MapAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a MapAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a MapAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a MapAttribute) IsSensitive() bool { + return false +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a MapAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/map_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/map_nested_attribute.go new file mode 100644 index 00000000..a8809b7a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/map_nested_attribute.go @@ -0,0 +1,161 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = MapNestedAttribute{} +) + +// MapNestedAttribute represents an attribute that is a set of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Map +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use MapAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set of objects or directly via curly brace syntax. +// +// # map of objects +// example_attribute = { +// key = { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a map of objects or an element directly via square brace string +// syntax: +// +// # known object at key +// .example_attribute["key"] +// # known object nested_attribute value at key +// .example_attribute["key"].nested_attribute +type MapNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.MapType of types.ObjectType. When retrieving data, the + // basetypes.MapValuable associated with this custom type must be used in + // place of types.Map. + CustomType basetypes.MapTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyString, otherwise returns an error. +func (a MapNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyString) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to MapNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a MapNestedAttribute +// and all fields are equal. +func (a MapNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(MapNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a MapNestedAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a MapNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a MapNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a MapNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a MapNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeMap +} + +// GetType returns MapType of ObjectType or CustomType. +func (a MapNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.MapType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a MapNestedAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a MapNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a MapNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a MapNestedAttribute) IsSensitive() bool { + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/nested_attribute.go new file mode 100644 index 00000000..5b94ceed --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/nested_attribute.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Nested attributes are only compatible with protocol version 6. +type NestedAttribute interface { + Attribute + fwschema.NestedAttribute +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/nested_attribute_object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/nested_attribute_object.go new file mode 100644 index 00000000..e10aa2d7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/nested_attribute_object.go @@ -0,0 +1,63 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ fwschema.NestedAttributeObject = NestedAttributeObject{} + +// NestedAttributeObject is the object containing the underlying attributes +// for a ListNestedAttribute, MapNestedAttribute, SetNestedAttribute, or +// SingleNestedAttribute (automatically generated). When retrieving the value +// for this attribute, use types.Object as the value type unless the CustomType +// field is set. The Attributes field must be set. Nested attributes are only +// compatible with protocol version 6. +// +// This object enables customizing and simplifying details within its parent +// NestedAttribute, therefore it cannot have Terraform schema fields such as +// Required, Description, etc. +type NestedAttributeObject struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. This field must be set. + Attributes map[string]Attribute + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable +} + +// ApplyTerraform5AttributePathStep performs an AttributeName step on the +// underlying attributes or returns an error. +func (o NestedAttributeObject) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.NestedAttributeObjectApplyTerraform5AttributePathStep(o, step) +} + +// Equal returns true if the given NestedAttributeObject is equivalent. +func (o NestedAttributeObject) Equal(other fwschema.NestedAttributeObject) bool { + if _, ok := other.(NestedAttributeObject); !ok { + return false + } + + return fwschema.NestedAttributeObjectEqual(o, other) +} + +// GetAttributes returns the Attributes field value. +func (o NestedAttributeObject) GetAttributes() fwschema.UnderlyingAttributes { + return schemaAttributes(o.Attributes) +} + +// Type returns the framework type of the NestedAttributeObject. +func (o NestedAttributeObject) Type() basetypes.ObjectTypable { + if o.CustomType != nil { + return o.CustomType + } + + return fwschema.NestedAttributeObjectType(o) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/number_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/number_attribute.go new file mode 100644 index 00000000..86e45b8a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/number_attribute.go @@ -0,0 +1,123 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = NumberAttribute{} +) + +// NumberAttribute represents a schema attribute that is a generic number with +// up to 512 bits of floating point or integer precision. When retrieving the +// value for this attribute, use types.Number as the value type unless the +// CustomType field is set. +// +// Use Float64Attribute for 64-bit floating point number attributes or +// Int64Attribute for 64-bit integer number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via a floating point or integer value. +// +// example_attribute = 123 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type NumberAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.NumberType. When retrieving data, the basetypes.NumberValuable + // associated with this custom type must be used in place of types.Number. + CustomType basetypes.NumberTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a NumberAttribute. +func (a NumberAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a NumberAttribute +// and all fields are equal. +func (a NumberAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(NumberAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a NumberAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a NumberAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a NumberAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.NumberType or the CustomType field value if defined. +func (a NumberAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.NumberType +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a NumberAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a NumberAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a NumberAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a NumberAttribute) IsSensitive() bool { + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/object_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/object_attribute.go new file mode 100644 index 00000000..aa4c67be --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/object_attribute.go @@ -0,0 +1,147 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = ObjectAttribute{} + _ fwschema.AttributeWithValidateImplementation = ObjectAttribute{} +) + +// ObjectAttribute represents a schema attribute that is an object with only +// type information for underlying attributes. When retrieving the value for +// this attribute, use types.Object as the value type unless the CustomType +// field is set. The AttributeTypes field must be set. +// +// Prefer SingleNestedAttribute over ObjectAttribute if the provider is +// using protocol version 6 and full attribute functionality is needed. +// +// Terraform configurations configure this attribute using expressions that +// return an object or directly via curly brace syntax. +// +// # object with one attribute +// example_attribute = { +// underlying_attribute = #... +// } +// +// Terraform configurations reference this attribute using expressions that +// accept an object or an attribute directly via period syntax: +// +// # underlying attribute +// .example_attribute.underlying_attribute +type ObjectAttribute struct { + // AttributeTypes is the mapping of underlying attribute names to attribute + // types. This field must be set. + AttributeTypes map[string]attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into an +// attribute name or an error. +func (a ObjectAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a ObjectAttribute +// and all fields are equal. +func (a ObjectAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(ObjectAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a ObjectAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a ObjectAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ObjectAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.ObjectType or the CustomType field value if defined. +func (a ObjectAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ObjectType{ + AttrTypes: a.AttributeTypes, + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a ObjectAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a ObjectAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ObjectAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a ObjectAttribute) IsSensitive() bool { + return false +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a ObjectAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.AttributeTypes == nil && a.CustomType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingAttributeTypesDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/schema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/schema.go new file mode 100644 index 00000000..b4382645 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/schema.go @@ -0,0 +1,139 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Schema must satify the fwschema.Schema interface. +var _ fwschema.Schema = Schema{} + +// Schema defines the structure and value types of provider_meta configuration +// data. This type is used as the provider.MetaSchemaResponse type Schema +// field, which is implemented by the provider.ProviderWithMetaSchema type +// MetaSchema method. +type Schema struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Blocks names. + Attributes map[string]Attribute +} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// schema. +func (s Schema) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.SchemaApplyTerraform5AttributePathStep(s, step) +} + +// AttributeAtPath returns the Attribute at the passed path. If the path points +// to an element or attribute of a complex type, rather than to an Attribute, +// it will return an ErrPathInsideAtomicAttribute error. +func (s Schema) AttributeAtPath(ctx context.Context, p path.Path) (fwschema.Attribute, diag.Diagnostics) { + return fwschema.SchemaAttributeAtPath(ctx, s, p) +} + +// AttributeAtPath returns the Attribute at the passed path. If the path points +// to an element or attribute of a complex type, rather than to an Attribute, +// it will return an ErrPathInsideAtomicAttribute error. +func (s Schema) AttributeAtTerraformPath(ctx context.Context, p *tftypes.AttributePath) (fwschema.Attribute, error) { + return fwschema.SchemaAttributeAtTerraformPath(ctx, s, p) +} + +// GetAttributes returns the Attributes field value. +func (s Schema) GetAttributes() map[string]fwschema.Attribute { + return schemaAttributes(s.Attributes) +} + +// GetBlocks always returns nil as meta schemas cannot contain blocks. +func (s Schema) GetBlocks() map[string]fwschema.Block { + return nil +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for meta schemas. +func (s Schema) GetDeprecationMessage() string { + return "" +} + +// GetDescription always returns an empty string as there is no purpose for +// a meta schema description. The provider schema description should describe +// the provider itself. +func (s Schema) GetDescription() string { + return "" +} + +// GetMarkdownDescription always returns an empty string as there is no purpose +// for a meta schema description. The provider schema description should +// describe the provider itself. +func (s Schema) GetMarkdownDescription() string { + return "" +} + +// GetVersion always returns 0 as provider meta schemas cannot be versioned. +func (s Schema) GetVersion() int64 { + return 0 +} + +// Type returns the framework type of the schema. +func (s Schema) Type() attr.Type { + return fwschema.SchemaType(s) +} + +// TypeAtPath returns the framework type at the given schema path. +func (s Schema) TypeAtPath(ctx context.Context, p path.Path) (attr.Type, diag.Diagnostics) { + return fwschema.SchemaTypeAtPath(ctx, s, p) +} + +// TypeAtTerraformPath returns the framework type at the given tftypes path. +func (s Schema) TypeAtTerraformPath(ctx context.Context, p *tftypes.AttributePath) (attr.Type, error) { + return fwschema.SchemaTypeAtTerraformPath(ctx, s, p) +} + +// Validate verifies that the schema is not using a reserved field name for a top-level attribute. +// +// Deprecated: Use the ValidateImplementation method instead. +func (s Schema) Validate() diag.Diagnostics { + return s.ValidateImplementation(context.Background()) +} + +// ValidateImplementation contains logic for validating the provider-defined +// implementation of the schema and underlying attributes and blocks to prevent +// unexpected errors or panics. This logic runs during the GetProviderSchema +// RPC, or via provider-defined unit testing, and should never include false +// positives. +func (s Schema) ValidateImplementation(ctx context.Context) diag.Diagnostics { + var diags diag.Diagnostics + + for attributeName, attribute := range s.GetAttributes() { + req := fwschema.ValidateImplementationRequest{ + Name: attributeName, + Path: path.Root(attributeName), + } + + diags.Append(fwschema.ValidateAttributeImplementation(ctx, attribute, req)...) + } + + return diags +} + +// schemaAttributes is a provider to fwschema type conversion function. +func schemaAttributes(attributes map[string]Attribute) map[string]fwschema.Attribute { + result := make(map[string]fwschema.Attribute, len(attributes)) + + for name, attribute := range attributes { + result[name] = attribute + } + + return result +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/set_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/set_attribute.go new file mode 100644 index 00000000..91971307 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/set_attribute.go @@ -0,0 +1,143 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = SetAttribute{} + _ fwschema.AttributeWithValidateImplementation = SetAttribute{} +) + +// SetAttribute represents a schema attribute that is a set with a single +// element type. When retrieving the value for this attribute, use types.Set +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use SetNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set or directly via square brace syntax. +// +// # set of strings +// example_attribute = ["first", "second"] +// +// Terraform configurations reference this attribute using expressions that +// accept a set. Sets cannot be indexed in Terraform, therefore an expression +// is required to access an explicit element. +type SetAttribute struct { + // ElementType is the type for all elements of the set. This field must be + // set. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.SetType. When retrieving data, the basetypes.SetValuable + // associated with this custom type must be used in place of types.Set. + CustomType basetypes.SetTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a set +// index or an error. +func (a SetAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a SetAttribute +// and all fields are equal. +func (a SetAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(SetAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a SetAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a SetAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SetAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.SetType or the CustomType field value if defined. +func (a SetAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.SetType{ + ElemType: a.ElementType, + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a SetAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a SetAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SetAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a SetAttribute) IsSensitive() bool { + return false +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a SetAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/set_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/set_nested_attribute.go new file mode 100644 index 00000000..8bbcf125 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/set_nested_attribute.go @@ -0,0 +1,156 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = SetNestedAttribute{} +) + +// SetNestedAttribute represents an attribute that is a set of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Set +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use SetAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set of objects or directly via square and curly brace syntax. +// +// # set of objects +// example_attribute = [ +// { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a set of objects. Sets cannot be indexed in Terraform, therefore +// an expression is required to access an explicit element. +type SetNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.SetType of types.ObjectType. When retrieving data, the + // basetypes.SetValuable associated with this custom type must be used in + // place of types.Set. + CustomType basetypes.SetTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyValue, otherwise returns an error. +func (a SetNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyValue) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SetNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a SetNestedAttribute +// and all fields are equal. +func (a SetNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(SetNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a SetNestedAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a SetNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SetNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a SetNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a SetNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeSet +} + +// GetType returns SetType of ObjectType or CustomType. +func (a SetNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.SetType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a SetNestedAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a SetNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SetNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a SetNestedAttribute) IsSensitive() bool { + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/single_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/single_nested_attribute.go new file mode 100644 index 00000000..de4dc07a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/single_nested_attribute.go @@ -0,0 +1,176 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = SingleNestedAttribute{} +) + +// SingleNestedAttribute represents an attribute that is a single object where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Object +// as the value type unless the CustomType field is set. The Attributes field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use ObjectAttribute if the underlying attributes do not require definition +// beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return an object or directly via curly brace syntax. +// +// # single object +// example_attribute = { +// nested_attribute = #... +// } +// +// Terraform configurations reference this attribute using expressions that +// accept an object or an attribute name directly via period syntax: +// +// # object nested_attribute value +// .example_attribute.nested_attribute +type SingleNestedAttribute struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. This field must be set. + Attributes map[string]Attribute + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is AttributeName, otherwise returns an error. +func (a SingleNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + name, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SingleNestedAttribute", step) + } + + attribute, ok := a.Attributes[string(name)] + + if !ok { + return nil, fmt.Errorf("no attribute %q on SingleNestedAttribute", name) + } + + return attribute, nil +} + +// Equal returns true if the given Attribute is a SingleNestedAttribute +// and all fields are equal. +func (a SingleNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(SingleNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetAttributes returns the Attributes field value. +func (a SingleNestedAttribute) GetAttributes() fwschema.UnderlyingAttributes { + return schemaAttributes(a.Attributes) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a SingleNestedAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a SingleNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SingleNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns a generated NestedAttributeObject from the +// Attributes and CustomType field values. +func (a SingleNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return NestedAttributeObject{ + Attributes: a.Attributes, + CustomType: a.CustomType, + } +} + +// GetNestingMode always returns NestingModeList. +func (a SingleNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeSingle +} + +// GetType returns ListType of ObjectType or CustomType. +func (a SingleNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + attrTypes := make(map[string]attr.Type, len(a.Attributes)) + + for name, attribute := range a.Attributes { + attrTypes[name] = attribute.GetType() + } + + return types.ObjectType{ + AttrTypes: attrTypes, + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a SingleNestedAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a SingleNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SingleNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a SingleNestedAttribute) IsSensitive() bool { + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/string_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/string_attribute.go new file mode 100644 index 00000000..3a14d072 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/metaschema/string_attribute.go @@ -0,0 +1,119 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package metaschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = StringAttribute{} +) + +// StringAttribute represents a schema attribute that is a string. When +// retrieving the value for this attribute, use types.String as the value type +// unless the CustomType field is set. +// +// Terraform configurations configure this attribute using expressions that +// return a string or directly via double quote syntax. +// +// example_attribute = "value" +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type StringAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.StringType. When retrieving data, the basetypes.StringValuable + // associated with this custom type must be used in place of types.String. + CustomType basetypes.StringTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a StringAttribute. +func (a StringAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a StringAttribute +// and all fields are equal. +func (a StringAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(StringAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage always returns an empty string as there is no +// deprecation validation support for provider meta schemas. +func (a StringAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. +func (a StringAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a StringAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.StringType or the CustomType field value if defined. +func (a StringAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.StringType +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a StringAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a StringAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a StringAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive always returns false as there is no plan for provider meta +// schema data. +func (a StringAttribute) IsSensitive() bool { + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/provider.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/provider.go new file mode 100644 index 00000000..ff0d18e8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/provider.go @@ -0,0 +1,122 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package provider + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/function" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +// Provider is the core interface that all Terraform providers must implement. +// +// Providers can optionally implement these additional concepts: +// +// - Validation: Schema-based or entire configuration +// via ProviderWithConfigValidators or ProviderWithValidateConfig. +// - Functions: ProviderWithFunctions +// - Meta Schema: ProviderWithMetaSchema +type Provider interface { + // Metadata should return the metadata for the provider, such as + // a type name and version data. + // + // Implementing the MetadataResponse.TypeName will populate the + // datasource.MetadataRequest.ProviderTypeName and + // resource.MetadataRequest.ProviderTypeName fields automatically. + Metadata(context.Context, MetadataRequest, *MetadataResponse) + + // Schema should return the schema for this provider. + Schema(context.Context, SchemaRequest, *SchemaResponse) + + // Configure is called at the beginning of the provider lifecycle, when + // Terraform sends to the provider the values the user specified in the + // provider configuration block. These are supplied in the + // ConfigureProviderRequest argument. + // Values from provider configuration are often used to initialise an + // API client, which should be stored on the struct implementing the + // Provider interface. + Configure(context.Context, ConfigureRequest, *ConfigureResponse) + + // DataSources returns a slice of functions to instantiate each DataSource + // implementation. + // + // The data source type name is determined by the DataSource implementing + // the Metadata method. All data sources must have unique names. + DataSources(context.Context) []func() datasource.DataSource + + // Resources returns a slice of functions to instantiate each Resource + // implementation. + // + // The resource type name is determined by the Resource implementing + // the Metadata method. All resources must have unique names. + Resources(context.Context) []func() resource.Resource +} + +// ProviderWithConfigValidators is an interface type that extends Provider to include declarative validations. +// +// Declaring validation using this methodology simplifies implementation of +// reusable functionality. These also include descriptions, which can be used +// for automating documentation. +// +// Validation will include ConfigValidators and ValidateConfig, if both are +// implemented, in addition to any Attribute or Type validation. +type ProviderWithConfigValidators interface { + Provider + + // ConfigValidators returns a list of functions which will all be performed during validation. + ConfigValidators(context.Context) []ConfigValidator +} + +// ProviderWithFunctions is an interface type that extends Provider to +// include provider defined functions for usage in practitioner configurations. +// +// Provider-defined functions are supported in Terraform version 1.8 and later. +type ProviderWithFunctions interface { + Provider + + // Functions returns a slice of functions to instantiate each Function + // implementation. + // + // The function name is determined by the Function implementing its Metadata + // method. All functions must have unique names. + Functions(context.Context) []func() function.Function +} + +// ProviderWithMetaSchema is a provider with a provider meta schema, which +// is configured by practitioners via the provider_meta configuration block +// and the configuration data is included with certain data source and resource +// operations. The intended use case is to enable Terraform module authors +// within the same organization of the provider to track module usage in +// requests. Other use cases are explicitly not supported. All provider +// instances (aliases) receive the same data. +// +// This functionality is currently experimental and subject to change or break +// without warning. It is not protected by version compatibility guarantees. +type ProviderWithMetaSchema interface { + Provider + + // MetaSchema should return the meta schema for this provider. + // + // This functionality is currently experimental and subject to change or + // break without warning. It is not protected by version compatibility + // guarantees. + MetaSchema(context.Context, MetaSchemaRequest, *MetaSchemaResponse) +} + +// ProviderWithValidateConfig is an interface type that extends Provider to include imperative validation. +// +// Declaring validation using this methodology simplifies one-off +// functionality that typically applies to a single provider. Any documentation +// of this functionality must be manually added into schema descriptions. +// +// Validation will include ConfigValidators and ValidateConfig, if both are +// implemented, in addition to any Attribute or Type validation. +type ProviderWithValidateConfig interface { + Provider + + // ValidateConfig performs the validation. + ValidateConfig(context.Context, ValidateConfigRequest, *ValidateConfigResponse) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema.go new file mode 100644 index 00000000..7b333972 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package provider + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/provider/schema" +) + +// SchemaRequest represents a request for the Provider to return its schema. +// An instance of this request struct is supplied as an argument to the +// Provider type Schema method. +type SchemaRequest struct{} + +// SchemaResponse represents a response to a SchemaRequest. An instance of this +// response struct is supplied as an argument to the Provider type Schema +// method. +type SchemaResponse struct { + // Schema is the schema of the provider. + Schema schema.Schema + + // Diagnostics report errors or warnings related to validating the data + // source configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/attribute.go new file mode 100644 index 00000000..4a0fecee --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/attribute.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Attribute define a value field inside the Schema. Implementations in this +// package include: +// - BoolAttribute +// - Float64Attribute +// - Int64Attribute +// - ListAttribute +// - MapAttribute +// - NumberAttribute +// - ObjectAttribute +// - SetAttribute +// - StringAttribute +// +// Additionally, the NestedAttribute interface extends Attribute with nested +// attributes. Only supported in protocol version 6. Implementations in this +// package include: +// - ListNestedAttribute +// - MapNestedAttribute +// - SetNestedAttribute +// - SingleNestedAttribute +// +// In practitioner configurations, an equals sign (=) is required to set +// the value. [Configuration Reference] +// +// [Configuration Reference]: https://developer.hashicorp.com/terraform/language/syntax/configuration +type Attribute interface { + fwschema.Attribute +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/block.go new file mode 100644 index 00000000..f741d8f8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/block.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Block defines a structural field inside a Schema. Implementations in this +// package include: +// - ListNestedBlock +// - SetNestedBlock +// - SingleNestedBlock +// +// In practitioner configurations, an equals sign (=) cannot be used to set the +// value. Blocks are instead repeated as necessary, or require the use of +// [Dynamic Block Expressions]. +// +// Prefer NestedAttribute over Block. Blocks should typically be used for +// configuration compatibility with previously existing schemas from an older +// Terraform Plugin SDK. Efforts should be made to convert from Block to +// NestedAttribute as a breaking change for practitioners. +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +// +// [Configuration Reference]: https://developer.hashicorp.com/terraform/language/syntax/configuration +type Block interface { + fwschema.Block +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/bool_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/bool_attribute.go new file mode 100644 index 00000000..c411062e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/bool_attribute.go @@ -0,0 +1,180 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = BoolAttribute{} + _ fwxschema.AttributeWithBoolValidators = BoolAttribute{} +) + +// BoolAttribute represents a schema attribute that is a boolean. When +// retrieving the value for this attribute, use types.Bool as the value type +// unless the CustomType field is set. +// +// Terraform configurations configure this attribute using expressions that +// return a boolean or directly via the true/false keywords. +// +// example_attribute = true +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type BoolAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.BoolType. When retrieving data, the basetypes.BoolValuable + // associated with this custom type must be used in place of types.Bool. + CustomType basetypes.BoolTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Bool +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a BoolAttribute. +func (a BoolAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// BoolValidators returns the Validators field value. +func (a BoolAttribute) BoolValidators() []validator.Bool { + return a.Validators +} + +// Equal returns true if the given Attribute is a BoolAttribute +// and all fields are equal. +func (a BoolAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(BoolAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a BoolAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a BoolAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a BoolAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.StringType or the CustomType field value if defined. +func (a BoolAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.BoolType +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a BoolAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a BoolAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a BoolAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a BoolAttribute) IsSensitive() bool { + return a.Sensitive +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/doc.go new file mode 100644 index 00000000..64993307 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/doc.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package schema contains all available schema functionality for data sources. +// Data source schemas define the structure and value types for configuration +// and state data. Schemas are implemented via the datasource.DataSource type +// Schema method. +package schema diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/dynamic_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/dynamic_attribute.go new file mode 100644 index 00000000..c738d348 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/dynamic_attribute.go @@ -0,0 +1,177 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = DynamicAttribute{} + _ fwxschema.AttributeWithDynamicValidators = DynamicAttribute{} +) + +// DynamicAttribute represents a schema attribute that is a dynamic, rather +// than a single static type. Static types are always preferable over dynamic +// types in Terraform as practitioners will receive less helpful configuration +// assistance from validation error diagnostics and editor integrations. When +// retrieving the value for this attribute, use types.Dynamic as the value type +// unless the CustomType field is set. +// +// The concrete value type for a dynamic is determined at runtime by Terraform, +// if defined in the configuration. +type DynamicAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.DynamicType. When retrieving data, the basetypes.DynamicValuable + // associated with this custom type must be used in place of types.Dynamic. + CustomType basetypes.DynamicTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Dynamic +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a DynamicAttribute. +func (a DynamicAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a DynamicAttribute +// and all fields are equal. +func (a DynamicAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(DynamicAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a DynamicAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a DynamicAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a DynamicAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.DynamicType or the CustomType field value if defined. +func (a DynamicAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.DynamicType +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a DynamicAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a DynamicAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a DynamicAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a DynamicAttribute) IsSensitive() bool { + return a.Sensitive +} + +// DynamicValidators returns the Validators field value. +func (a DynamicAttribute) DynamicValidators() []validator.Dynamic { + return a.Validators +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/float64_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/float64_attribute.go new file mode 100644 index 00000000..786965e3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/float64_attribute.go @@ -0,0 +1,183 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = Float64Attribute{} + _ fwxschema.AttributeWithFloat64Validators = Float64Attribute{} +) + +// Float64Attribute represents a schema attribute that is a 64-bit floating +// point number. When retrieving the value for this attribute, use +// types.Float64 as the value type unless the CustomType field is set. +// +// Use Int64Attribute for 64-bit integer attributes or NumberAttribute for +// 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via a floating point value. +// +// example_attribute = 123.45 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type Float64Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Float64Type. When retrieving data, the basetypes.Float64Valuable + // associated with this custom type must be used in place of types.Float64. + CustomType basetypes.Float64Typable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Float64 +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Float64Attribute. +func (a Float64Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Float64Attribute +// and all fields are equal. +func (a Float64Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Float64Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// Float64Validators returns the Validators field value. +func (a Float64Attribute) Float64Validators() []validator.Float64 { + return a.Validators +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a Float64Attribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a Float64Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a Float64Attribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.Float64Type or the CustomType field value if defined. +func (a Float64Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Float64Type +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a Float64Attribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a Float64Attribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a Float64Attribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a Float64Attribute) IsSensitive() bool { + return a.Sensitive +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/int64_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/int64_attribute.go new file mode 100644 index 00000000..3fd9713f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/int64_attribute.go @@ -0,0 +1,183 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = Int64Attribute{} + _ fwxschema.AttributeWithInt64Validators = Int64Attribute{} +) + +// Int64Attribute represents a schema attribute that is a 64-bit integer. +// When retrieving the value for this attribute, use types.Int64 as the value +// type unless the CustomType field is set. +// +// Use Float64Attribute for 64-bit floating point number attributes or +// NumberAttribute for 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via an integer value. +// +// example_attribute = 123 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type Int64Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Int64Type. When retrieving data, the basetypes.Int64Valuable + // associated with this custom type must be used in place of types.Int64. + CustomType basetypes.Int64Typable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Int64 +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Int64Attribute. +func (a Int64Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Int64Attribute +// and all fields are equal. +func (a Int64Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Int64Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a Int64Attribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a Int64Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a Int64Attribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.Int64Type or the CustomType field value if defined. +func (a Int64Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Int64Type +} + +// Int64Validators returns the Validators field value. +func (a Int64Attribute) Int64Validators() []validator.Int64 { + return a.Validators +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a Int64Attribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a Int64Attribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a Int64Attribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a Int64Attribute) IsSensitive() bool { + return a.Sensitive +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_attribute.go new file mode 100644 index 00000000..e733b297 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_attribute.go @@ -0,0 +1,215 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = ListAttribute{} + _ fwschema.AttributeWithValidateImplementation = ListAttribute{} + _ fwxschema.AttributeWithListValidators = ListAttribute{} +) + +// ListAttribute represents a schema attribute that is a list with a single +// element type. When retrieving the value for this attribute, use types.List +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use ListNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list or directly via square brace syntax. +// +// # list of strings +// example_attribute = ["first", "second"] +// +// Terraform configurations reference this attribute using expressions that +// accept a list or an element directly via square brace 0-based index syntax: +// +// # first known element +// .example_attribute[0] +type ListAttribute struct { + // ElementType is the type for all elements of the list. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ListType. When retrieving data, the basetypes.ListValuable + // associated with this custom type must be used in place of types.List. + CustomType basetypes.ListTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.List +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a list +// index or an error. +func (a ListAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a ListAttribute +// and all fields are equal. +func (a ListAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(ListAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a ListAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a ListAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ListAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.ListType or the CustomType field value if defined. +func (a ListAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ListType{ + ElemType: a.ElementType, + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a ListAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a ListAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ListAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a ListAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ListValidators returns the Validators field value. +func (a ListAttribute) ListValidators() []validator.List { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a ListAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_nested_attribute.go new file mode 100644 index 00000000..0c82da4a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_nested_attribute.go @@ -0,0 +1,239 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = ListNestedAttribute{} + _ fwschema.AttributeWithValidateImplementation = ListNestedAttribute{} + _ fwxschema.AttributeWithListValidators = ListNestedAttribute{} +) + +// ListNestedAttribute represents an attribute that is a list of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.List +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use ListAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list of objects or directly via square and curly brace syntax. +// +// # list of objects +// example_attribute = [ +// { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a list of objects or an element directly via square brace 0-based +// index syntax: +// +// # first known object +// .example_attribute[0] +// # first known object nested_attribute value +// .example_attribute[0].nested_attribute +type ListNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.ListType of types.ObjectType. When retrieving data, the + // basetypes.ListValuable associated with this custom type must be used in + // place of types.List. + CustomType basetypes.ListTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.List +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyInt, otherwise returns an error. +func (a ListNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyInt) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to ListNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a ListNestedAttribute +// and all fields are equal. +func (a ListNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(ListNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a ListNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a ListNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ListNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a ListNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a ListNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeList +} + +// GetType returns ListType of ObjectType or CustomType. +func (a ListNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ListType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a ListNestedAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a ListNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ListNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a ListNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ListValidators returns the Validators field value. +func (a ListNestedAttribute) ListValidators() []validator.List { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a ListNestedAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_nested_block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_nested_block.go new file mode 100644 index 00000000..4d098bc2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/list_nested_block.go @@ -0,0 +1,205 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Block = ListNestedBlock{} + _ fwschema.BlockWithValidateImplementation = ListNestedBlock{} + _ fwxschema.BlockWithListValidators = ListNestedBlock{} +) + +// ListNestedBlock represents a block that is a list of objects where +// the object attributes can be fully defined, including further attributes +// or blocks. When retrieving the value for this block, use types.List +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. +// +// Prefer ListNestedAttribute over ListNestedBlock if the provider is +// using protocol version 6. Nested attributes allow practitioners to configure +// values directly with expressions. +// +// Terraform configurations configure this block repeatedly using curly brace +// syntax without an equals (=) sign or [Dynamic Block Expressions]. +// +// # list of blocks with two elements +// example_block { +// nested_attribute = #... +// } +// example_block { +// nested_attribute = #... +// } +// +// Terraform configurations reference this block using expressions that +// accept a list of objects or an element directly via square brace 0-based +// index syntax: +// +// # first known object +// .example_block[0] +// # first known object nested_attribute value +// .example_block[0].nested_attribute +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +type ListNestedBlock struct { + // NestedObject is the underlying object that contains nested attributes or + // blocks. This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this block definition with + // a DynamicAttribute. + NestedObject NestedBlockObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.ListType of types.ObjectType. When retrieving data, the + // basetypes.ListValuable associated with this custom type must be used in + // place of types.List. + CustomType basetypes.ListTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.List +} + +// ApplyTerraform5AttributePathStep returns the NestedObject field value if step +// is ElementKeyInt, otherwise returns an error. +func (b ListNestedBlock) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyInt) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to ListNestedBlock", step) + } + + return b.NestedObject, nil +} + +// Equal returns true if the given Block is ListNestedBlock +// and all fields are equal. +func (b ListNestedBlock) Equal(o fwschema.Block) bool { + if _, ok := o.(ListNestedBlock); !ok { + return false + } + + return fwschema.BlocksEqual(b, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (b ListNestedBlock) GetDeprecationMessage() string { + return b.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (b ListNestedBlock) GetDescription() string { + return b.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (b ListNestedBlock) GetMarkdownDescription() string { + return b.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (b ListNestedBlock) GetNestedObject() fwschema.NestedBlockObject { + return b.NestedObject +} + +// GetNestingMode always returns BlockNestingModeList. +func (b ListNestedBlock) GetNestingMode() fwschema.BlockNestingMode { + return fwschema.BlockNestingModeList +} + +// ListValidators returns the Validators field value. +func (b ListNestedBlock) ListValidators() []validator.List { + return b.Validators +} + +// Type returns ListType of ObjectType or CustomType. +func (b ListNestedBlock) Type() attr.Type { + if b.CustomType != nil { + return b.CustomType + } + + return types.ListType{ + ElemType: b.NestedObject.Type(), + } +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the block to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (b ListNestedBlock) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if b.CustomType == nil && fwtype.ContainsCollectionWithDynamic(b.Type()) { + resp.Diagnostics.Append(fwtype.BlockCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/map_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/map_attribute.go new file mode 100644 index 00000000..079535e7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/map_attribute.go @@ -0,0 +1,218 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = MapAttribute{} + _ fwschema.AttributeWithValidateImplementation = MapAttribute{} + _ fwxschema.AttributeWithMapValidators = MapAttribute{} +) + +// MapAttribute represents a schema attribute that is a list with a single +// element type. When retrieving the value for this attribute, use types.Map +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use MapNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list or directly via curly brace syntax. +// +// # map of strings +// example_attribute = { +// key1 = "first", +// key2 = "second", +// } +// +// Terraform configurations reference this attribute using expressions that +// accept a map or an element directly via square brace string syntax: +// +// # key1 known element +// .example_attribute["key1"] +type MapAttribute struct { + // ElementType is the type for all elements of the map. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.MapType. When retrieving data, the basetypes.MapValuable + // associated with this custom type must be used in place of types.Map. + CustomType basetypes.MapTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Map +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a map +// index or an error. +func (a MapAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a MapAttribute +// and all fields are equal. +func (a MapAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(MapAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a MapAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a MapAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a MapAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.MapType or the CustomType field value if defined. +func (a MapAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.MapType{ + ElemType: a.ElementType, + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a MapAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a MapAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a MapAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a MapAttribute) IsSensitive() bool { + return a.Sensitive +} + +// MapValidators returns the Validators field value. +func (a MapAttribute) MapValidators() []validator.Map { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a MapAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/map_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/map_nested_attribute.go new file mode 100644 index 00000000..0cdc9b5e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/map_nested_attribute.go @@ -0,0 +1,239 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = MapNestedAttribute{} + _ fwxschema.AttributeWithMapValidators = MapNestedAttribute{} +) + +// MapNestedAttribute represents an attribute that is a set of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Map +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use MapAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set of objects or directly via curly brace syntax. +// +// # map of objects +// example_attribute = { +// key = { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a map of objects or an element directly via square brace string +// syntax: +// +// # known object at key +// .example_attribute["key"] +// # known object nested_attribute value at key +// .example_attribute["key"].nested_attribute +type MapNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.MapType of types.ObjectType. When retrieving data, the + // basetypes.MapValuable associated with this custom type must be used in + // place of types.Map. + CustomType basetypes.MapTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Map +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyString, otherwise returns an error. +func (a MapNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyString) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to MapNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a MapNestedAttribute +// and all fields are equal. +func (a MapNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(MapNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a MapNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a MapNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a MapNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a MapNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a MapNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeMap +} + +// GetType returns MapType of ObjectType or CustomType. +func (a MapNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.MapType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a MapNestedAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a MapNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a MapNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a MapNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// MapValidators returns the Validators field value. +func (a MapNestedAttribute) MapValidators() []validator.Map { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a MapNestedAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_attribute.go new file mode 100644 index 00000000..31d2ee15 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_attribute.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Nested attributes are only compatible with protocol version 6. +type NestedAttribute interface { + Attribute + fwschema.NestedAttribute +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_attribute_object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_attribute_object.go new file mode 100644 index 00000000..3719a239 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_attribute_object.go @@ -0,0 +1,82 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ fwxschema.NestedAttributeObjectWithValidators = NestedAttributeObject{} + +// NestedAttributeObject is the object containing the underlying attributes +// for a ListNestedAttribute, MapNestedAttribute, SetNestedAttribute, or +// SingleNestedAttribute (automatically generated). When retrieving the value +// for this attribute, use types.Object as the value type unless the CustomType +// field is set. The Attributes field must be set. Nested attributes are only +// compatible with protocol version 6. +// +// This object enables customizing and simplifying details within its parent +// NestedAttribute, therefore it cannot have Terraform schema fields such as +// Required, Description, etc. +type NestedAttributeObject struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. This field must be set. + Attributes map[string]Attribute + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object +} + +// ApplyTerraform5AttributePathStep performs an AttributeName step on the +// underlying attributes or returns an error. +func (o NestedAttributeObject) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.NestedAttributeObjectApplyTerraform5AttributePathStep(o, step) +} + +// Equal returns true if the given NestedAttributeObject is equivalent. +func (o NestedAttributeObject) Equal(other fwschema.NestedAttributeObject) bool { + if _, ok := other.(NestedAttributeObject); !ok { + return false + } + + return fwschema.NestedAttributeObjectEqual(o, other) +} + +// GetAttributes returns the Attributes field value. +func (o NestedAttributeObject) GetAttributes() fwschema.UnderlyingAttributes { + return schemaAttributes(o.Attributes) +} + +// ObjectValidators returns the Validators field value. +func (o NestedAttributeObject) ObjectValidators() []validator.Object { + return o.Validators +} + +// Type returns the framework type of the NestedAttributeObject. +func (o NestedAttributeObject) Type() basetypes.ObjectTypable { + if o.CustomType != nil { + return o.CustomType + } + + return fwschema.NestedAttributeObjectType(o) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_block_object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_block_object.go new file mode 100644 index 00000000..2b560b60 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/nested_block_object.go @@ -0,0 +1,94 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var _ fwxschema.NestedBlockObjectWithValidators = NestedBlockObject{} + +// NestedBlockObject is the object containing the underlying attributes and +// blocks for a ListNestedBlock or SetNestedBlock. When retrieving the value +// for this attribute, use types.Object as the value type unless the CustomType +// field is set. +// +// This object enables customizing and simplifying details within its parent +// Block, therefore it cannot have Terraform schema fields such as Description, +// etc. +type NestedBlockObject struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Blocks names. + Attributes map[string]Attribute + + // Blocks is the mapping of underlying block names to block definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Attributes names. + Blocks map[string]Block + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object +} + +// ApplyTerraform5AttributePathStep performs an AttributeName step on the +// underlying attributes or returns an error. +func (o NestedBlockObject) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.NestedBlockObjectApplyTerraform5AttributePathStep(o, step) +} + +// Equal returns true if the given NestedBlockObject is equivalent. +func (o NestedBlockObject) Equal(other fwschema.NestedBlockObject) bool { + if _, ok := other.(NestedBlockObject); !ok { + return false + } + + return fwschema.NestedBlockObjectEqual(o, other) +} + +// GetAttributes returns the Attributes field value. +func (o NestedBlockObject) GetAttributes() fwschema.UnderlyingAttributes { + return schemaAttributes(o.Attributes) +} + +// GetAttributes returns the Blocks field value. +func (o NestedBlockObject) GetBlocks() map[string]fwschema.Block { + return schemaBlocks(o.Blocks) +} + +// ObjectValidators returns the Validators field value. +func (o NestedBlockObject) ObjectValidators() []validator.Object { + return o.Validators +} + +// Type returns the framework type of the NestedBlockObject. +func (o NestedBlockObject) Type() basetypes.ObjectTypable { + if o.CustomType != nil { + return o.CustomType + } + + return fwschema.NestedBlockObjectType(o) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/number_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/number_attribute.go new file mode 100644 index 00000000..f3e90e2b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/number_attribute.go @@ -0,0 +1,184 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = NumberAttribute{} + _ fwxschema.AttributeWithNumberValidators = NumberAttribute{} +) + +// NumberAttribute represents a schema attribute that is a generic number with +// up to 512 bits of floating point or integer precision. When retrieving the +// value for this attribute, use types.Number as the value type unless the +// CustomType field is set. +// +// Use Float64Attribute for 64-bit floating point number attributes or +// Int64Attribute for 64-bit integer number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via a floating point or integer value. +// +// example_attribute = 123 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type NumberAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.NumberType. When retrieving data, the basetypes.NumberValuable + // associated with this custom type must be used in place of types.Number. + CustomType basetypes.NumberTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Number +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a NumberAttribute. +func (a NumberAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a NumberAttribute +// and all fields are equal. +func (a NumberAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(NumberAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a NumberAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a NumberAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a NumberAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.NumberType or the CustomType field value if defined. +func (a NumberAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.NumberType +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a NumberAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a NumberAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a NumberAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a NumberAttribute) IsSensitive() bool { + return a.Sensitive +} + +// NumberValidators returns the Validators field value. +func (a NumberAttribute) NumberValidators() []validator.Number { + return a.Validators +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/object_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/object_attribute.go new file mode 100644 index 00000000..3041f5a7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/object_attribute.go @@ -0,0 +1,217 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = ObjectAttribute{} + _ fwschema.AttributeWithValidateImplementation = ObjectAttribute{} + _ fwxschema.AttributeWithObjectValidators = ObjectAttribute{} +) + +// ObjectAttribute represents a schema attribute that is an object with only +// type information for underlying attributes. When retrieving the value for +// this attribute, use types.Object as the value type unless the CustomType +// field is set. The AttributeTypes field must be set. +// +// Prefer SingleNestedAttribute over ObjectAttribute if the provider is +// using protocol version 6 and full attribute functionality is needed. +// +// Terraform configurations configure this attribute using expressions that +// return an object or directly via curly brace syntax. +// +// # object with one attribute +// example_attribute = { +// underlying_attribute = #... +// } +// +// Terraform configurations reference this attribute using expressions that +// accept an object or an attribute directly via period syntax: +// +// # underlying attribute +// .example_attribute.underlying_attribute +type ObjectAttribute struct { + // AttributeTypes is the mapping of underlying attribute names to attribute + // types. This field must be set. + // + // Attribute types that contain a collection with a nested dynamic type (i.e. types.List[types.Dynamic]) are not supported. + // If underlying dynamic collection values are required, replace this attribute definition with + // DynamicAttribute instead. + AttributeTypes map[string]attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into an +// attribute name or an error. +func (a ObjectAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a ObjectAttribute +// and all fields are equal. +func (a ObjectAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(ObjectAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a ObjectAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a ObjectAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ObjectAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.ObjectType or the CustomType field value if defined. +func (a ObjectAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ObjectType{ + AttrTypes: a.AttributeTypes, + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a ObjectAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a ObjectAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ObjectAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a ObjectAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ObjectValidators returns the Validators field value. +func (a ObjectAttribute) ObjectValidators() []validator.Object { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a ObjectAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.AttributeTypes == nil && a.CustomType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingAttributeTypesDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/schema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/schema.go new file mode 100644 index 00000000..91cb1781 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/schema.go @@ -0,0 +1,185 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Schema must satify the fwschema.Schema interface. +var _ fwschema.Schema = Schema{} + +// Schema defines the structure and value types of provider configuration data. +// This type is used as the provider.SchemaResponse type Schema field, which is +// implemented by the provider.Provider type Schema method. +type Schema struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Blocks names. + Attributes map[string]Attribute + + // Blocks is the mapping of underlying block names to block definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Attributes names. + Blocks map[string]Block + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this provider is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this provider is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this provider. The warning diagnostic + // summary is automatically set to "Provider Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Use examplenewcloud provider instead." + // - "Remove this provider as it no longer is valid." + // + DeprecationMessage string +} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// schema. +func (s Schema) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.SchemaApplyTerraform5AttributePathStep(s, step) +} + +// AttributeAtPath returns the Attribute at the passed path. If the path points +// to an element or attribute of a complex type, rather than to an Attribute, +// it will return an ErrPathInsideAtomicAttribute error. +func (s Schema) AttributeAtPath(ctx context.Context, p path.Path) (fwschema.Attribute, diag.Diagnostics) { + return fwschema.SchemaAttributeAtPath(ctx, s, p) +} + +// AttributeAtPath returns the Attribute at the passed path. If the path points +// to an element or attribute of a complex type, rather than to an Attribute, +// it will return an ErrPathInsideAtomicAttribute error. +func (s Schema) AttributeAtTerraformPath(ctx context.Context, p *tftypes.AttributePath) (fwschema.Attribute, error) { + return fwschema.SchemaAttributeAtTerraformPath(ctx, s, p) +} + +// GetAttributes returns the Attributes field value. +func (s Schema) GetAttributes() map[string]fwschema.Attribute { + return schemaAttributes(s.Attributes) +} + +// GetBlocks returns the Blocks field value. +func (s Schema) GetBlocks() map[string]fwschema.Block { + return schemaBlocks(s.Blocks) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (s Schema) GetDeprecationMessage() string { + return s.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (s Schema) GetDescription() string { + return s.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (s Schema) GetMarkdownDescription() string { + return s.MarkdownDescription +} + +// GetVersion always returns 0 as provider schemas cannot be versioned. +func (s Schema) GetVersion() int64 { + return 0 +} + +// Type returns the framework type of the schema. +func (s Schema) Type() attr.Type { + return fwschema.SchemaType(s) +} + +// TypeAtPath returns the framework type at the given schema path. +func (s Schema) TypeAtPath(ctx context.Context, p path.Path) (attr.Type, diag.Diagnostics) { + return fwschema.SchemaTypeAtPath(ctx, s, p) +} + +// TypeAtTerraformPath returns the framework type at the given tftypes path. +func (s Schema) TypeAtTerraformPath(ctx context.Context, p *tftypes.AttributePath) (attr.Type, error) { + return fwschema.SchemaTypeAtTerraformPath(ctx, s, p) +} + +// Validate verifies that the schema is not using a reserved field name for a top-level attribute. +// +// Deprecated: Use the ValidateImplementation method instead. +func (s Schema) Validate() diag.Diagnostics { + return s.ValidateImplementation(context.Background()) +} + +// ValidateImplementation contains logic for validating the provider-defined +// implementation of the schema and underlying attributes and blocks to prevent +// unexpected errors or panics. This logic runs during the GetProviderSchema +// RPC, or via provider-defined unit testing, and should never include false +// positives. +func (s Schema) ValidateImplementation(ctx context.Context) diag.Diagnostics { + var diags diag.Diagnostics + + for attributeName, attribute := range s.GetAttributes() { + req := fwschema.ValidateImplementationRequest{ + Name: attributeName, + Path: path.Root(attributeName), + } + + diags.Append(fwschema.IsReservedProviderAttributeName(req.Name, req.Path)...) + diags.Append(fwschema.ValidateAttributeImplementation(ctx, attribute, req)...) + } + + for blockName, block := range s.GetBlocks() { + req := fwschema.ValidateImplementationRequest{ + Name: blockName, + Path: path.Root(blockName), + } + + diags.Append(fwschema.IsReservedProviderAttributeName(req.Name, req.Path)...) + diags.Append(fwschema.ValidateBlockImplementation(ctx, block, req)...) + } + + return diags +} + +// schemaAttributes is a provider to fwschema type conversion function. +func schemaAttributes(attributes map[string]Attribute) map[string]fwschema.Attribute { + result := make(map[string]fwschema.Attribute, len(attributes)) + + for name, attribute := range attributes { + result[name] = attribute + } + + return result +} + +// schemaBlocks is a provider to fwschema type conversion function. +func schemaBlocks(blocks map[string]Block) map[string]fwschema.Block { + result := make(map[string]fwschema.Block, len(blocks)) + + for name, block := range blocks { + result[name] = block + } + + return result +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_attribute.go new file mode 100644 index 00000000..3297452b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_attribute.go @@ -0,0 +1,213 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = SetAttribute{} + _ fwschema.AttributeWithValidateImplementation = SetAttribute{} + _ fwxschema.AttributeWithSetValidators = SetAttribute{} +) + +// SetAttribute represents a schema attribute that is a set with a single +// element type. When retrieving the value for this attribute, use types.Set +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use SetNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set or directly via square brace syntax. +// +// # set of strings +// example_attribute = ["first", "second"] +// +// Terraform configurations reference this attribute using expressions that +// accept a set. Sets cannot be indexed in Terraform, therefore an expression +// is required to access an explicit element. +type SetAttribute struct { + // ElementType is the type for all elements of the set. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.SetType. When retrieving data, the basetypes.SetValuable + // associated with this custom type must be used in place of types.Set. + CustomType basetypes.SetTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Set +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a set +// index or an error. +func (a SetAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a SetAttribute +// and all fields are equal. +func (a SetAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(SetAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a SetAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a SetAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SetAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.SetType or the CustomType field value if defined. +func (a SetAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.SetType{ + ElemType: a.ElementType, + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a SetAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a SetAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SetAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a SetAttribute) IsSensitive() bool { + return a.Sensitive +} + +// SetValidators returns the Validators field value. +func (a SetAttribute) SetValidators() []validator.Set { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC +// and should never include false positives. +func (a SetAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_nested_attribute.go new file mode 100644 index 00000000..64fed1ea --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_nested_attribute.go @@ -0,0 +1,235 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = SetNestedAttribute{} + _ fwschema.AttributeWithValidateImplementation = SetNestedAttribute{} + _ fwxschema.AttributeWithSetValidators = SetNestedAttribute{} +) + +// SetNestedAttribute represents an attribute that is a set of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Set +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use SetAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set of objects or directly via square and curly brace syntax. +// +// # set of objects +// example_attribute = [ +// { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a set of objects. Sets cannot be indexed in Terraform, therefore +// an expression is required to access an explicit element. +type SetNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.SetType of types.ObjectType. When retrieving data, the + // basetypes.SetValuable associated with this custom type must be used in + // place of types.Set. + CustomType basetypes.SetTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Set +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyValue, otherwise returns an error. +func (a SetNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyValue) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SetNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a SetNestedAttribute +// and all fields are equal. +func (a SetNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(SetNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a SetNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a SetNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SetNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a SetNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a SetNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeSet +} + +// GetType returns SetType of ObjectType or CustomType. +func (a SetNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.SetType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a SetNestedAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a SetNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SetNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a SetNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// SetValidators returns the Validators field value. +func (a SetNestedAttribute) SetValidators() []validator.Set { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a SetNestedAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_nested_block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_nested_block.go new file mode 100644 index 00000000..085163f3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/set_nested_block.go @@ -0,0 +1,205 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Block = SetNestedBlock{} + _ fwschema.BlockWithValidateImplementation = SetNestedBlock{} + _ fwxschema.BlockWithSetValidators = SetNestedBlock{} +) + +// SetNestedBlock represents a block that is a set of objects where +// the object attributes can be fully defined, including further attributes +// or blocks. When retrieving the value for this block, use types.Set +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. +// +// Prefer SetNestedAttribute over SetNestedBlock if the provider is +// using protocol version 6. Nested attributes allow practitioners to configure +// values directly with expressions. +// +// Terraform configurations configure this block repeatedly using curly brace +// syntax without an equals (=) sign or [Dynamic Block Expressions]. +// +// # set of blocks with two elements +// example_block { +// nested_attribute = #... +// } +// example_block { +// nested_attribute = #... +// } +// +// Terraform configurations reference this block using expressions that +// accept a set of objects or an element directly via square brace 0-based +// index syntax: +// +// # first known object +// .example_block[0] +// # first known object nested_attribute value +// .example_block[0].nested_attribute +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +type SetNestedBlock struct { + // NestedObject is the underlying object that contains nested attributes or + // blocks. This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this block definition with + // a DynamicAttribute. + NestedObject NestedBlockObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.SetType of types.ObjectType. When retrieving data, the + // basetypes.SetValuable associated with this custom type must be used in + // place of types.Set. + CustomType basetypes.SetTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Set +} + +// ApplyTerraform5AttributePathStep returns the NestedObject field value if step +// is ElementKeyValue, otherwise returns an error. +func (b SetNestedBlock) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyValue) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SetNestedBlock", step) + } + + return b.NestedObject, nil +} + +// Equal returns true if the given Block is SetNestedBlock +// and all fields are equal. +func (b SetNestedBlock) Equal(o fwschema.Block) bool { + if _, ok := o.(SetNestedBlock); !ok { + return false + } + + return fwschema.BlocksEqual(b, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (b SetNestedBlock) GetDeprecationMessage() string { + return b.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (b SetNestedBlock) GetDescription() string { + return b.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (b SetNestedBlock) GetMarkdownDescription() string { + return b.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (b SetNestedBlock) GetNestedObject() fwschema.NestedBlockObject { + return b.NestedObject +} + +// GetNestingMode always returns BlockNestingModeSet. +func (b SetNestedBlock) GetNestingMode() fwschema.BlockNestingMode { + return fwschema.BlockNestingModeSet +} + +// SetValidators returns the Validators field value. +func (b SetNestedBlock) SetValidators() []validator.Set { + return b.Validators +} + +// Type returns SetType of ObjectType or CustomType. +func (b SetNestedBlock) Type() attr.Type { + if b.CustomType != nil { + return b.CustomType + } + + return types.SetType{ + ElemType: b.NestedObject.Type(), + } +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the block to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (b SetNestedBlock) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if b.CustomType == nil && fwtype.ContainsCollectionWithDynamic(b.Type()) { + resp.Diagnostics.Append(fwtype.BlockCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/single_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/single_nested_attribute.go new file mode 100644 index 00000000..aac9875a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/single_nested_attribute.go @@ -0,0 +1,239 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = SingleNestedAttribute{} + _ fwxschema.AttributeWithObjectValidators = SingleNestedAttribute{} +) + +// SingleNestedAttribute represents an attribute that is a single object where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Object +// as the value type unless the CustomType field is set. The Attributes field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use ObjectAttribute if the underlying attributes do not require definition +// beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return an object or directly via curly brace syntax. +// +// # single object +// example_attribute = { +// nested_attribute = #... +// } +// +// Terraform configurations reference this attribute using expressions that +// accept an object or an attribute name directly via period syntax: +// +// # object nested_attribute value +// .example_attribute.nested_attribute +type SingleNestedAttribute struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. This field must be set. + Attributes map[string]Attribute + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is AttributeName, otherwise returns an error. +func (a SingleNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + name, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SingleNestedAttribute", step) + } + + attribute, ok := a.Attributes[string(name)] + + if !ok { + return nil, fmt.Errorf("no attribute %q on SingleNestedAttribute", name) + } + + return attribute, nil +} + +// Equal returns true if the given Attribute is a SingleNestedAttribute +// and all fields are equal. +func (a SingleNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(SingleNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetAttributes returns the Attributes field value. +func (a SingleNestedAttribute) GetAttributes() fwschema.UnderlyingAttributes { + return schemaAttributes(a.Attributes) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a SingleNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a SingleNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SingleNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns a generated NestedAttributeObject from the +// Attributes, CustomType, and Validators field values. +func (a SingleNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return NestedAttributeObject{ + Attributes: a.Attributes, + CustomType: a.CustomType, + Validators: a.Validators, + } +} + +// GetNestingMode always returns NestingModeList. +func (a SingleNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeSingle +} + +// GetType returns ListType of ObjectType or CustomType. +func (a SingleNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + attrTypes := make(map[string]attr.Type, len(a.Attributes)) + + for name, attribute := range a.Attributes { + attrTypes[name] = attribute.GetType() + } + + return types.ObjectType{ + AttrTypes: attrTypes, + } +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a SingleNestedAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a SingleNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SingleNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a SingleNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ObjectValidators returns the Validators field value. +func (a SingleNestedAttribute) ObjectValidators() []validator.Object { + return a.Validators +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/single_nested_block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/single_nested_block.go new file mode 100644 index 00000000..926825a0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/single_nested_block.go @@ -0,0 +1,213 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Block = SingleNestedBlock{} + _ fwxschema.BlockWithObjectValidators = SingleNestedBlock{} +) + +// SingleNestedBlock represents a block that is a single object where +// the object attributes can be fully defined, including further attributes +// or blocks. When retrieving the value for this block, use types.Object +// as the value type unless the CustomType field is set. +// +// Prefer SingleNestedAttribute over SingleNestedBlock if the provider is +// using protocol version 6. Nested attributes allow practitioners to configure +// values directly with expressions. +// +// Terraform configurations configure this block only once using curly brace +// syntax without an equals (=) sign or [Dynamic Block Expressions]. +// +// # single block +// example_block { +// nested_attribute = #... +// } +// +// Terraform configurations reference this block using expressions that +// accept an object or an attribute name directly via period syntax: +// +// # object nested_attribute value +// .example_block.nested_attribute +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +type SingleNestedBlock struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Blocks names. + Attributes map[string]Attribute + + // Blocks is the mapping of underlying block names to block definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Attributes names. + Blocks map[string]Block + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is AttributeName, otherwise returns an error. +func (b SingleNestedBlock) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + name, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SingleNestedBlock", step) + } + + if attribute, ok := b.Attributes[string(name)]; ok { + return attribute, nil + } + + if block, ok := b.Blocks[string(name)]; ok { + return block, nil + } + + return nil, fmt.Errorf("no attribute or block %q on SingleNestedBlock", name) +} + +// Equal returns true if the given Attribute is b SingleNestedBlock +// and all fields are equal. +func (b SingleNestedBlock) Equal(o fwschema.Block) bool { + if _, ok := o.(SingleNestedBlock); !ok { + return false + } + + return fwschema.BlocksEqual(b, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (b SingleNestedBlock) GetDeprecationMessage() string { + return b.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (b SingleNestedBlock) GetDescription() string { + return b.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (b SingleNestedBlock) GetMarkdownDescription() string { + return b.MarkdownDescription +} + +// GetNestedObject returns a generated NestedBlockObject from the +// Attributes, CustomType, and Validators field values. +func (b SingleNestedBlock) GetNestedObject() fwschema.NestedBlockObject { + return NestedBlockObject{ + Attributes: b.Attributes, + Blocks: b.Blocks, + CustomType: b.CustomType, + Validators: b.Validators, + } +} + +// GetNestingMode always returns BlockNestingModeSingle. +func (b SingleNestedBlock) GetNestingMode() fwschema.BlockNestingMode { + return fwschema.BlockNestingModeSingle +} + +// ObjectValidators returns the Validators field value. +func (b SingleNestedBlock) ObjectValidators() []validator.Object { + return b.Validators +} + +// Type returns ObjectType or CustomType. +func (b SingleNestedBlock) Type() attr.Type { + if b.CustomType != nil { + return b.CustomType + } + + attrTypes := make(map[string]attr.Type, len(b.Attributes)+len(b.Blocks)) + + for name, attribute := range b.Attributes { + attrTypes[name] = attribute.GetType() + } + + for name, block := range b.Blocks { + attrTypes[name] = block.Type() + } + + return types.ObjectType{ + AttrTypes: attrTypes, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/string_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/string_attribute.go new file mode 100644 index 00000000..7ab7a0c4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/schema/string_attribute.go @@ -0,0 +1,180 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Attribute = StringAttribute{} + _ fwxschema.AttributeWithStringValidators = StringAttribute{} +) + +// StringAttribute represents a schema attribute that is a string. When +// retrieving the value for this attribute, use types.String as the value type +// unless the CustomType field is set. +// +// Terraform configurations configure this attribute using expressions that +// return a string or directly via double quote syntax. +// +// example_attribute = "value" +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type StringAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.StringType. When retrieving data, the basetypes.StringValuable + // associated with this custom type must be used in place of types.String. + CustomType basetypes.StringTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.String +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a StringAttribute. +func (a StringAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a StringAttribute +// and all fields are equal. +func (a StringAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(StringAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a StringAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a StringAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a StringAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.StringType or the CustomType field value if defined. +func (a StringAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.StringType +} + +// IsComputed always returns false as provider schemas cannot be Computed. +func (a StringAttribute) IsComputed() bool { + return false +} + +// IsOptional returns the Optional field value. +func (a StringAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a StringAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a StringAttribute) IsSensitive() bool { + return a.Sensitive +} + +// StringValidators returns the Validators field value. +func (a StringAttribute) StringValidators() []validator.String { + return a.Validators +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/provider/validate_config.go b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/validate_config.go new file mode 100644 index 00000000..70939002 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/provider/validate_config.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package provider + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ValidateConfigRequest represents a request to validate the +// configuration of a provider. An instance of this request struct is +// supplied as an argument to the Provider ValidateConfig receiver method +// or automatically passed through to each ConfigValidator. +type ValidateConfigRequest struct { + // Config is the configuration the user supplied for the provider. + // + // This configuration may contain unknown values if a user uses + // interpolation or other functionality that would prevent Terraform + // from knowing the value at request time. + Config tfsdk.Config +} + +// ValidateConfigResponse represents a response to a +// ValidateConfigRequest. An instance of this response struct is +// supplied as an argument to the Provider ValidateConfig receiver method +// or automatically passed through to each ConfigValidator. +type ValidateConfigResponse struct { + // Diagnostics report errors or warnings related to validating the provider + // configuration. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/doc.go new file mode 100644 index 00000000..cb427c87 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/doc.go @@ -0,0 +1,17 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package providerserver implements functionality for serving a provider, +// such as directly starting a server in a production binary and conversion +// functions for testing. +// +// For production usage, call the Serve function from binary startup, such as +// from the provider codebase main package. If multiplexing the provider server +// via terraform-plugin-mux functionality, use the NewProtocol* functions and +// call the Serve function from that Go module. For testing usage, call the +// NewProtocol* functions. +// +// All functionality in this package requires the provider.Provider type, which +// contains the provider implementation including all managed resources and +// data sources. +package providerserver diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/providerserver.go b/vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/providerserver.go new file mode 100644 index 00000000..2352f4e5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/providerserver.go @@ -0,0 +1,128 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package providerserver + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/proto5server" + "github.com/hashicorp/terraform-plugin-framework/internal/proto6server" + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server" +) + +// NewProtocol5 returns a protocol version 5 ProviderServer implementation +// based on the given Provider and suitable for usage with the +// github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.Serve() +// function and various terraform-plugin-mux functions. +func NewProtocol5(p provider.Provider) func() tfprotov5.ProviderServer { + return func() tfprotov5.ProviderServer { + return &proto5server.Server{ + FrameworkServer: fwserver.Server{ + Provider: p, + }, + } + } +} + +// NewProtocol5WithError returns a protocol version 5 ProviderServer +// implementation based on the given Provider and suitable for usage with +// github.com/hashicorp/terraform-plugin-testing/helper/resource.TestCase.ProtoV5ProviderFactories. +// +// The error return is not currently used, but it may be in the future. +func NewProtocol5WithError(p provider.Provider) func() (tfprotov5.ProviderServer, error) { + return func() (tfprotov5.ProviderServer, error) { + return &proto5server.Server{ + FrameworkServer: fwserver.Server{ + Provider: p, + }, + }, nil + } +} + +// NewProtocol6 returns a protocol version 6 ProviderServer implementation +// based on the given Provider and suitable for usage with the +// github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server.Serve() +// function and various terraform-plugin-mux functions. +func NewProtocol6(p provider.Provider) func() tfprotov6.ProviderServer { + return func() tfprotov6.ProviderServer { + return &proto6server.Server{ + FrameworkServer: fwserver.Server{ + Provider: p, + }, + } + } +} + +// NewProtocol6WithError returns a protocol version 6 ProviderServer +// implementation based on the given Provider and suitable for usage with +// github.com/hashicorp/terraform-plugin-testing/helper/resource.TestCase.ProtoV6ProviderFactories. +// +// The error return is not currently used, but it may be in the future. +func NewProtocol6WithError(p provider.Provider) func() (tfprotov6.ProviderServer, error) { + return func() (tfprotov6.ProviderServer, error) { + return &proto6server.Server{ + FrameworkServer: fwserver.Server{ + Provider: p, + }, + }, nil + } +} + +// Serve serves a provider, blocking until the context is canceled. +func Serve(ctx context.Context, providerFunc func() provider.Provider, opts ServeOpts) error { + err := opts.validate(ctx) + + if err != nil { + return fmt.Errorf("unable to validate ServeOpts: %w", err) + } + + switch opts.ProtocolVersion { + case 5: + var tf5serverOpts []tf5server.ServeOpt + + if opts.Debug { + tf5serverOpts = append(tf5serverOpts, tf5server.WithManagedDebug()) + } + + return tf5server.Serve( + opts.Address, + func() tfprotov5.ProviderServer { + provider := providerFunc() + + return &proto5server.Server{ + FrameworkServer: fwserver.Server{ + Provider: provider, + }, + } + }, + tf5serverOpts..., + ) + default: + var tf6serverOpts []tf6server.ServeOpt + + if opts.Debug { + tf6serverOpts = append(tf6serverOpts, tf6server.WithManagedDebug()) + } + + return tf6server.Serve( + opts.Address, + func() tfprotov6.ProviderServer { + provider := providerFunc() + + return &proto6server.Server{ + FrameworkServer: fwserver.Server{ + Provider: provider, + }, + } + }, + tf6serverOpts..., + ) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/serve_opts.go b/vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/serve_opts.go new file mode 100644 index 00000000..19678be1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/providerserver/serve_opts.go @@ -0,0 +1,87 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package providerserver + +import ( + "context" + "fmt" + "strings" +) + +// ServeOpts are options for serving the provider. +type ServeOpts struct { + // Address is the full address of the provider. Full address form has three + // parts separated by forward slashes (/): Hostname, namespace, and + // provider type ("name"). + // + // For example: registry.terraform.io/hashicorp/random. + Address string + + // Debug runs the provider in a mode acceptable for debugging and testing + // processes, such as delve, by managing the process lifecycle. Information + // needed for Terraform CLI to connect to the provider is output to stdout. + // os.Interrupt (Ctrl-c) can be used to stop the provider. + Debug bool + + // ProtocolVersion is the protocol version that should be used when serving + // the provider. Either protocol version 5 or protocol version 6 can be + // used. Defaults to protocol version 6. + // + // Protocol version 5 has the following functionality limitations, which + // will raise an error during the GetProviderSchema or other RPCs: + // + // - tfsdk.Attribute cannot use Attributes field (nested attributes). + // + ProtocolVersion int +} + +// Validate a given provider address. This is only used for the Address field +// to preserve backwards compatibility for the Name field. +// +// This logic is manually implemented over importing +// github.com/hashicorp/terraform-registry-address as its functionality such as +// ParseAndInferProviderSourceString and ParseRawProviderSourceString allow +// shorter address formats, which would then require post-validation anyways. +func (opts ServeOpts) validateAddress(_ context.Context) error { + addressParts := strings.Split(opts.Address, "/") + formatErr := fmt.Errorf("expected hostname/namespace/type format, got: %s", opts.Address) + + if len(addressParts) != 3 { + return formatErr + } + + if addressParts[0] == "" || addressParts[1] == "" || addressParts[2] == "" { + return formatErr + } + + return nil +} + +// Validation checks for provider defined ServeOpts. +// +// Current checks which return errors: +// +// - If Address is not set +// - Address is a valid full provider address +// - ProtocolVersion, if set, is 5 or 6 +func (opts ServeOpts) validate(ctx context.Context) error { + if opts.Address == "" { + return fmt.Errorf("Address must be provided") + } + + err := opts.validateAddress(ctx) + + if err != nil { + return fmt.Errorf("unable to validate Address: %w", err) + } + + switch opts.ProtocolVersion { + // 0 represents unset, which Serve will use default. + case 0, 5, 6: + default: + return fmt.Errorf("ProtocolVersion, if set, must be 5 or 6") + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/config_validator.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/config_validator.go new file mode 100644 index 00000000..775ca7fe --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/config_validator.go @@ -0,0 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import "context" + +// ConfigValidator describes reusable Resource configuration validation functionality. +type ConfigValidator interface { + // Description describes the validation in plain text formatting. + // + // This information may be automatically added to resource plain text + // descriptions by external tooling. + Description(context.Context) string + + // MarkdownDescription describes the validation in Markdown formatting. + // + // This information may be automatically added to resource Markdown + // descriptions by external tooling. + MarkdownDescription(context.Context) string + + // ValidateResource performs the validation. + // + // This method name is separate from the datasource.ConfigValidator + // interface ValidateDataSource method name and provider.ConfigValidator + // interface ValidateProvider method name to allow generic validators. + ValidateResource(context.Context, ValidateConfigRequest, *ValidateConfigResponse) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/configure.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/configure.go new file mode 100644 index 00000000..4935d3be --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/configure.go @@ -0,0 +1,34 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +// ConfigureRequest represents a request for the provider to configure a +// resource, i.e., set provider-level data or clients. An instance of this +// request struct is supplied as an argument to the Resource type Configure +// method. +type ConfigureRequest struct { + // ProviderData is the data set in the + // [provider.ConfigureResponse.ResourceData] field. This data is + // provider-specifc and therefore can contain any necessary remote system + // clients, custom provider data, or anything else pertinent to the + // functionality of the Resource. + // + // This data is only set after the ConfigureProvider RPC has been called + // by Terraform. + ProviderData any +} + +// ConfigureResponse represents a response to a ConfigureRequest. An +// instance of this response struct is supplied as an argument to the +// Resource type Configure method. +type ConfigureResponse struct { + // Diagnostics report errors or warnings related to configuring of the + // Datasource. An empty slice indicates a successful operation with no + // warnings or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/create.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/create.go new file mode 100644 index 00000000..8831f837 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/create.go @@ -0,0 +1,49 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// CreateRequest represents a request for the provider to create a +// resource. An instance of this request struct is supplied as an argument to +// the resource's Create function. +type CreateRequest struct { + // Config is the configuration the user supplied for the resource. + // + // This configuration may contain unknown values if a user uses + // interpolation or other functionality that would prevent Terraform + // from knowing the value at request time. + Config tfsdk.Config + + // Plan is the planned state for the resource. + Plan tfsdk.Plan + + // ProviderMeta is metadata from the provider_meta block of the module. + ProviderMeta tfsdk.Config +} + +// CreateResponse represents a response to a CreateRequest. An +// instance of this response struct is supplied as +// an argument to the resource's Create function, in which the provider +// should set values on the CreateResponse as appropriate. +type CreateResponse struct { + // State is the state of the resource following the Create operation. + // This field is pre-populated from CreateRequest.Plan and + // should be set during the resource's Create operation. + State tfsdk.State + + // Private is the private state resource data following the Create operation. + // This field is not pre-populated as there is no pre-existing private state + // data during the resource's Create operation. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to creating the + // resource. An empty slice indicates a successful operation with no + // warnings or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/delete.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/delete.go new file mode 100644 index 00000000..ab81a6c9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/delete.go @@ -0,0 +1,52 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// DeleteRequest represents a request for the provider to delete a +// resource. An instance of this request struct is supplied as an argument to +// the resource's Delete function. +type DeleteRequest struct { + // State is the current state of the resource prior to the Delete + // operation. + State tfsdk.State + + // ProviderMeta is metadata from the provider_meta block of the module. + ProviderMeta tfsdk.Config + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. + // + // Use the GetKey method to read data. + Private *privatestate.ProviderData +} + +// DeleteResponse represents a response to a DeleteRequest. An +// instance of this response struct is supplied as +// an argument to the resource's Delete function, in which the provider +// should set values on the DeleteResponse as appropriate. +type DeleteResponse struct { + // State is the state of the resource following the Delete operation. + // This field is pre-populated from UpdateResourceRequest.Plan and + // should be set during the resource's Update operation. + State tfsdk.State + + // Private is the private state resource data following the Delete + // operation. This field is pre-populated from DeleteRequest.Private and + // can be modified during the resource's Delete operation in cases where + // an error diagnostic is being returned. Otherwise if no error diagnostic + // is being returned, indicating that the resource was successfully deleted, + // this data will be automatically cleared to prevent Terraform errors. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to deleting the + // resource. An empty slice indicates a successful operation with no + // warnings or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/doc.go new file mode 100644 index 00000000..7bf5c0c0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/doc.go @@ -0,0 +1,24 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package resource contains all interfaces, request types, and response types +// for a managed resource implementation. +// +// In Terraform, a managed resource is a concept which enables provider +// developers to offer practitioners full lifecycle management (create, read, +// update, and delete) of a infrastructure component. Managed resources can +// also stand in for one-time infrastructure operations that require tracking, +// by implementing create logic, while omitting update and delete logic. +// +// Resources are saved into the Terraform state and can be referenced by other +// parts of a configuration. Resources are defined by a resource type/name, +// such as "examplecloud_thing", a schema representing the structure and data +// types of configuration, plan, and state, and lifecycle logic. +// +// The main starting point for implementations in this package is the +// Resource type which represents an instance of a resource type that has +// its own configuration, plan, state, and lifecycle logic. The +// [resource.Resource] implementations are referenced by the +// [provider.Provider] type Resources method, which enables the resource +// practitioner and testing usage. +package resource diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/import_state.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/import_state.go new file mode 100644 index 00000000..c0825574 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/import_state.go @@ -0,0 +1,62 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ImportStateRequest represents a request for the provider to import a +// resource. An instance of this request struct is supplied as an argument to +// the Resource's ImportState method. +type ImportStateRequest struct { + // ID represents the import identifier supplied by the practitioner when + // calling the import command. In many cases, this may align with the + // unique identifier for the resource, which can optionally be stored + // as an Attribute. However, this identifier can also be treated as + // its own type of value and parsed during import. This value + // is not stored in the state unless the provider explicitly stores it. + ID string +} + +// ImportStateResponse represents a response to a ImportStateRequest. +// An instance of this response struct is supplied as an argument to the +// Resource's ImportState method, in which the provider should set values on +// the ImportStateResponse as appropriate. +type ImportStateResponse struct { + // Diagnostics report errors or warnings related to importing the + // resource. An empty slice indicates a successful operation with no + // warnings or errors generated. + Diagnostics diag.Diagnostics + + // State is the state of the resource following the import operation. + // It must contain enough information so Terraform can successfully + // refresh the resource, e.g. call the Resource Read method. + State tfsdk.State + + // Private is the private state resource data following the Import operation. + // This field is not pre-populated as there is no pre-existing private state + // data during the resource's Import operation. + Private *privatestate.ProviderData +} + +// ImportStatePassthroughID is a helper function to set the import +// identifier to a given state attribute path. The attribute must accept a +// string value. +func ImportStatePassthroughID(ctx context.Context, attrPath path.Path, req ImportStateRequest, resp *ImportStateResponse) { + if attrPath.Equal(path.Empty()) { + resp.Diagnostics.AddError( + "Resource Import Passthrough Missing Attribute Path", + "This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + "Resource ImportState method call to ImportStatePassthroughID path must be set to a valid attribute path that can accept a string value.", + ) + } + + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, attrPath, req.ID)...) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/metadata.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/metadata.go new file mode 100644 index 00000000..9750a46c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/metadata.go @@ -0,0 +1,24 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +// MetadataRequest represents a request for the Resource to return metadata, +// such as its type name. An instance of this request struct is supplied as +// an argument to the Resource type Metadata method. +type MetadataRequest struct { + // ProviderTypeName is the string returned from + // [provider.MetadataResponse.TypeName], if the Provider type implements + // the Metadata method. This string should prefix the Resource type name + // with an underscore in the response. + ProviderTypeName string +} + +// MetadataResponse represents a response to a MetadataRequest. An +// instance of this response struct is supplied as an argument to the +// Resource type Metadata method. +type MetadataResponse struct { + // TypeName should be the full resource type, including the provider + // type prefix and an underscore. For example, examplecloud_thing. + TypeName string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/modify_plan.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/modify_plan.go new file mode 100644 index 00000000..76be450d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/modify_plan.go @@ -0,0 +1,68 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ModifyPlanRequest represents a request for the provider to modify the +// planned new state that Terraform has generated for the resource. +type ModifyPlanRequest struct { + // Config is the configuration the user supplied for the resource. + // + // This configuration may contain unknown values if a user uses + // interpolation or other functionality that would prevent Terraform + // from knowing the value at request time. + Config tfsdk.Config + + // State is the current state of the resource. + State tfsdk.State + + // Plan is the planned new state for the resource. Terraform 1.3 and later + // supports resource destroy planning, in which this will contain a null + // value. + Plan tfsdk.Plan + + // ProviderMeta is metadata from the provider_meta block of the module. + ProviderMeta tfsdk.Config + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // ModifyPlanResponse.Private to prevent accidental private state data loss. + // + // Use the GetKey method to read data. Use the SetKey method on + // ModifyPlanResponse.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// ModifyPlanResponse represents a response to a +// ModifyPlanRequest. An instance of this response struct is supplied +// as an argument to the resource's ModifyPlan function, in which the provider +// should modify the Plan and populate the RequiresReplace field as appropriate. +type ModifyPlanResponse struct { + // Plan is the planned new state for the resource. + Plan tfsdk.Plan + + // RequiresReplace is a list of attribute paths that require the + // resource to be replaced. They should point to the specific field + // that changed that requires the resource to be destroyed and + // recreated. + RequiresReplace path.Paths + + // Private is the private state resource data following the ModifyPlan operation. + // This field is pre-populated from ModifyPlanRequest.Private and + // can be modified during the resource's ModifyPlan operation. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to determining the + // planned state of the requested resource. Returning an empty slice + // indicates a successful plan modification with no warnings or errors + // generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/move_state.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/move_state.go new file mode 100644 index 00000000..6918f5b7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/move_state.go @@ -0,0 +1,110 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// MoveStateRequest represents a request for the provider to move a source +// resource state into the target resource state with any necessary data +// transformation logic. An instance of this request struct is supplied as an +// argument to each [StateMover.StateMover]. +type MoveStateRequest struct { + // SourcePrivate is the source resource private state data. If this source + // data is important for the target resource, the implementation should set + // the data via [MoveStateResponse.TargetPrivate] as it is intentionally not + // copied automatically. + SourcePrivate *privatestate.ProviderData + + // SourceProviderAddress is the address of the provider for the source + // resource type. It is the full address in HOSTNAME/NAMESPACE/TYPE format. + // For example, registry.terraform.io/hashicorp/random. + // + // Implementations should consider using this value to determine whether the + // request should be handled by this particular implementation. It is + // recommended to ignore the hostname unless necessary for disambiguation. + SourceProviderAddress string + + // SourceRawState is the raw state of the source resource. This data is + // always available, regardless whether the [StateMover.SourceSchema] field + // was set. If SourceSchema is present, the [SourceState] field will be + // populated and it is recommended to use that field instead. + // + // If this request matches the intended implementation, the implementation + // logic must set [MoveStateResponse.State] as it is intentionally not + // copied automatically. + // + // This is advanced functionality for providers wanting to skip the full + // redeclaration of source schemas and instead use lower level handlers to + // transform data. A typical implementation for working with this data will + // call the Unmarshal() method. + SourceRawState *tfprotov6.RawState + + // SourceSchemaVersion is the schema version of the source resource. It is + // important for implementations to account for the schema version when + // handling the source state data, since differing schema versions typically + // have differing data structures and types. + SourceSchemaVersion int64 + + // SourceState is the source resource state if the [StateMover.SourceSchema] + // was set. When available, this allows for easier data handling such as + // calling Get() or GetAttribute(). + // + // If this request matches the intended implementation, the implementation + // logic must set [MoveStateResponse.TargetState] as it is intentionally not + // copied automatically. + // + // State conversion errors based on [StateMover.SourceSchema] not matching + // the source state are only intentionally logged at DEBUG level as there + // may be multiple [StateMover] implementations on the same target resource + // for differing source resources. The [StateMover] implementation will + // still be called even with these errors, so it is important that + // implementations verify the request via the SourceTypeName and other + // fields before attempting to use this data. + SourceState *tfsdk.State + + // SourceTypeName is the type name of the source resource. For example, + // aws_vpc or random_string. + // + // Implementations should always use this value, in addition to potentially + // other request fields, to determine whether the request should be handled + // by this particular implementation. + SourceTypeName string +} + +// MoveStateResponse represents a response to a MoveStateRequest. +// An instance of this response struct is supplied as an argument to +// [StateMover] implementations. The provider should set response values only +// within the implementation that aligns with a supported request, or put +// differently, a response that contains no error diagnostics nor state is +// considered as skipped by the framework. Any fulfilling response, whether via +// error diagnostics or state data, will cause the framework to not call other +// implementations and immediately return that response. The framework will +// return an implementation not found error if all implementations return +// responses without error diagnostics and state. +type MoveStateResponse struct { + // Diagnostics report errors or warnings related to moving the resource. + // An unset or empty value indicates a successful operation or skipped + // implementation if [TargetState] is also not set. + Diagnostics diag.Diagnostics + + // TargetState is the resource state following the move operation. This + // value is intentionally not pre-populated by the framework. The provider + // must set state values to indicate a successful move operation. + // + // If this value is unset and there are no diagnostics, the framework will + // consider this implementation to have not matched the request and move on + // to the next implementation, if any. If no implementation returns a state + // then the framework will return an implementation not found error. + TargetState tfsdk.State + + // TargetPrivate is the resource private state data following the move + // operation. This field is not pre-populated as it is up to implementations + // whether the source private data is relevant for the target resource. + TargetPrivate *privatestate.ProviderData +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/read.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/read.go new file mode 100644 index 00000000..0cc13543 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/read.go @@ -0,0 +1,53 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ReadRequest represents a request for the provider to read a +// resource, i.e., update values in state according to the real state of the +// resource. An instance of this request struct is supplied as an argument to +// the resource's Read function. +type ReadRequest struct { + // State is the current state of the resource prior to the Read + // operation. + State tfsdk.State + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // ReadResourceResponse.Private to prevent accidental private state data loss. + // + // Use the GetKey method to read data. Use the SetKey method on + // ReadResourceResponse.Private to update or remove a value. + Private *privatestate.ProviderData + + // ProviderMeta is metadata from the provider_meta block of the module. + ProviderMeta tfsdk.Config +} + +// ReadResponse represents a response to a ReadRequest. An +// instance of this response struct is supplied as +// an argument to the resource's Read function, in which the provider +// should set values on the ReadResponse as appropriate. +type ReadResponse struct { + // State is the state of the resource following the Read operation. + // This field is pre-populated from ReadRequest.State and + // should be set during the resource's Read operation. + State tfsdk.State + + // Private is the private state resource data following the Read operation. + // This field is pre-populated from ReadResourceRequest.Private and + // can be modified during the resource's Read operation. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to reading the + // resource. An empty slice indicates a successful operation with no + // warnings or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/resource.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/resource.go new file mode 100644 index 00000000..7113d4bf --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/resource.go @@ -0,0 +1,198 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" +) + +// Resource represents an instance of a managed resource type. This is the core +// interface that all resources must implement. +// +// Resources can optionally implement these additional concepts: +// +// - Configure: Include provider-level data or clients. +// - Import: ResourceWithImportState +// - Validation: Schema-based or entire configuration +// via ResourceWithConfigValidators or ResourceWithValidateConfig. +// - Plan Modification: Schema-based or entire plan +// via ResourceWithModifyPlan. +// - State Upgrades: ResourceWithUpgradeState +// +// Although not required, it is conventional for resources to implement the +// ResourceWithImportState interface. +type Resource interface { + // Metadata should return the full name of the resource, such as + // examplecloud_thing. + Metadata(context.Context, MetadataRequest, *MetadataResponse) + + // Schema should return the schema for this resource. + Schema(context.Context, SchemaRequest, *SchemaResponse) + + // Create is called when the provider must create a new resource. Config + // and planned state values should be read from the + // CreateRequest and new state values set on the CreateResponse. + Create(context.Context, CreateRequest, *CreateResponse) + + // Read is called when the provider must read resource values in order + // to update state. Planned state values should be read from the + // ReadRequest and new state values set on the ReadResponse. + Read(context.Context, ReadRequest, *ReadResponse) + + // Update is called to update the state of the resource. Config, planned + // state, and prior state values should be read from the + // UpdateRequest and new state values set on the UpdateResponse. + Update(context.Context, UpdateRequest, *UpdateResponse) + + // Delete is called when the provider must delete the resource. Config + // values may be read from the DeleteRequest. + // + // If execution completes without error, the framework will automatically + // call DeleteResponse.State.RemoveResource(), so it can be omitted + // from provider logic. + Delete(context.Context, DeleteRequest, *DeleteResponse) +} + +// ResourceWithConfigure is an interface type that extends Resource to +// include a method which the framework will automatically call so provider +// developers have the opportunity to setup any necessary provider-level data +// or clients in the Resource type. +// +// This method is intended to replace the provider.ResourceType type +// NewResource method in a future release. +type ResourceWithConfigure interface { + Resource + + // Configure enables provider-level data or clients to be set in the + // provider-defined Resource type. It is separately executed for each + // ReadResource RPC. + Configure(context.Context, ConfigureRequest, *ConfigureResponse) +} + +// ResourceWithConfigValidators is an interface type that extends Resource to include declarative validations. +// +// Declaring validation using this methodology simplifies implmentation of +// reusable functionality. These also include descriptions, which can be used +// for automating documentation. +// +// Validation will include ConfigValidators and ValidateConfig, if both are +// implemented, in addition to any Attribute or Type validation. +type ResourceWithConfigValidators interface { + Resource + + // ConfigValidators returns a list of functions which will all be performed during validation. + ConfigValidators(context.Context) []ConfigValidator +} + +// Optional interface on top of Resource that enables provider control over +// the ImportResourceState RPC. This RPC is called by Terraform when the +// `terraform import` command is executed. Afterwards, the ReadResource RPC +// is executed to allow providers to fully populate the resource state. +type ResourceWithImportState interface { + Resource + + // ImportState is called when the provider must import the state of a + // resource instance. This method must return enough state so the Read + // method can properly refresh the full resource. + // + // If setting an attribute with the import identifier, it is recommended + // to use the ImportStatePassthroughID() call in this method. + ImportState(context.Context, ImportStateRequest, *ImportStateResponse) +} + +// ResourceWithModifyPlan represents a resource instance with a ModifyPlan +// function. +type ResourceWithModifyPlan interface { + Resource + + // ModifyPlan is called when the provider has an opportunity to modify + // the plan: once during the plan phase when Terraform is determining + // the diff that should be shown to the user for approval, and once + // during the apply phase with any unknown values from configuration + // filled in with their final values. + // + // The planned new state is represented by + // ModifyPlanResponse.Plan. It must meet the following + // constraints: + // 1. Any non-Computed attribute set in config must preserve the exact + // config value or return the corresponding attribute value from the + // prior state (ModifyPlanRequest.State). + // 2. Any attribute with a known value must not have its value changed + // in subsequent calls to ModifyPlan or Create/Read/Update. + // 3. Any attribute with an unknown value may either remain unknown + // or take on any value of the expected type. + // + // Any errors will prevent further resource-level plan modifications. + ModifyPlan(context.Context, ModifyPlanRequest, *ModifyPlanResponse) +} + +// Optional interface on top of [Resource] that enables provider control over +// the MoveResourceState RPC. This RPC is called by Terraform when there is a +// `moved` configuration block that changes the resource type and where this +// [Resource] is the target resource type. Since state data operations can cause +// data loss for practitioners, this support is explicitly opt-in to ensure that +// all data transformation logic is explicitly defined by the provider. +// +// If the [Resource] does not implement this interface and Terraform sends a +// MoveResourceState request, the framework will automatically return an error +// diagnostic notifying the practitioner that this resource does not support the +// requested operation. +// +// This functionality is only supported in Terraform 1.8 and later. +type ResourceWithMoveState interface { + Resource + + // An ordered list of source resource to current schema version state move + // implementations. Only the first [StateMover] implementation that returns + // state data or error diagnostics will be used, otherwise the framework + // considers the [StateMover] as skipped and will try the next [StateMover]. + // If all implementations return without state and error diagnostics, the + // framework will return an implementation not found error. + // + // It is strongly recommended that implementations be overly cautious and + // return no state data if the source provider address, resource type, + // or schema version is not fully implemented. + MoveState(context.Context) []StateMover +} + +// Optional interface on top of Resource that enables provider control over +// the UpgradeResourceState RPC. This RPC is automatically called by Terraform +// when the current Schema type Version field is greater than the stored state. +// Terraform does not store previous Schema information, so any breaking +// changes to state data types must be handled by providers. +// +// Terraform CLI can execute the UpgradeResourceState RPC even when the prior +// state version matches the current schema version. The framework will +// automatically intercept this request and attempt to respond with the +// existing state. In this situation the framework will not execute any +// provider defined logic, so declaring it for this version is extraneous. +type ResourceWithUpgradeState interface { + Resource + + // A mapping of prior state version to current schema version state upgrade + // implementations. Only the specified state upgrader for the prior state + // version is called, rather than each version in between, so it must + // encapsulate all logic to convert the prior state to the current schema + // version. + // + // Version keys begin at 0, which is the default schema version when + // undefined. The framework will return an error diagnostic should the + // requested state version not be implemented. + UpgradeState(context.Context) map[int64]StateUpgrader +} + +// ResourceWithValidateConfig is an interface type that extends Resource to include imperative validation. +// +// Declaring validation using this methodology simplifies one-off +// functionality that typically applies to a single resource. Any documentation +// of this functionality must be manually added into schema descriptions. +// +// Validation will include ConfigValidators and ValidateConfig, if both are +// implemented, in addition to any Attribute or Type validation. +type ResourceWithValidateConfig interface { + Resource + + // ValidateConfig performs the validation. + ValidateConfig(context.Context, ValidateConfigRequest, *ValidateConfigResponse) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema.go new file mode 100644 index 00000000..cbf506f0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" +) + +// SchemaRequest represents a request for the Resource to return its schema. +// An instance of this request struct is supplied as an argument to the +// Resource type Schema method. +type SchemaRequest struct{} + +// SchemaResponse represents a response to a SchemaRequest. An instance of this +// response struct is supplied as an argument to the Resource type Schema +// method. +type SchemaResponse struct { + // Schema is the schema of the data source. + Schema schema.Schema + + // Diagnostics report errors or warnings related to validating the data + // source configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/attribute.go new file mode 100644 index 00000000..4a0fecee --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/attribute.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Attribute define a value field inside the Schema. Implementations in this +// package include: +// - BoolAttribute +// - Float64Attribute +// - Int64Attribute +// - ListAttribute +// - MapAttribute +// - NumberAttribute +// - ObjectAttribute +// - SetAttribute +// - StringAttribute +// +// Additionally, the NestedAttribute interface extends Attribute with nested +// attributes. Only supported in protocol version 6. Implementations in this +// package include: +// - ListNestedAttribute +// - MapNestedAttribute +// - SetNestedAttribute +// - SingleNestedAttribute +// +// In practitioner configurations, an equals sign (=) is required to set +// the value. [Configuration Reference] +// +// [Configuration Reference]: https://developer.hashicorp.com/terraform/language/syntax/configuration +type Attribute interface { + fwschema.Attribute +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/block.go new file mode 100644 index 00000000..f741d8f8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/block.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Block defines a structural field inside a Schema. Implementations in this +// package include: +// - ListNestedBlock +// - SetNestedBlock +// - SingleNestedBlock +// +// In practitioner configurations, an equals sign (=) cannot be used to set the +// value. Blocks are instead repeated as necessary, or require the use of +// [Dynamic Block Expressions]. +// +// Prefer NestedAttribute over Block. Blocks should typically be used for +// configuration compatibility with previously existing schemas from an older +// Terraform Plugin SDK. Efforts should be made to convert from Block to +// NestedAttribute as a breaking change for practitioners. +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +// +// [Configuration Reference]: https://developer.hashicorp.com/terraform/language/syntax/configuration +type Block interface { + fwschema.Block +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/bool_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/bool_attribute.go new file mode 100644 index 00000000..abb0b870 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/bool_attribute.go @@ -0,0 +1,240 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = BoolAttribute{} + _ fwschema.AttributeWithValidateImplementation = BoolAttribute{} + _ fwschema.AttributeWithBoolDefaultValue = BoolAttribute{} + _ fwxschema.AttributeWithBoolPlanModifiers = BoolAttribute{} + _ fwxschema.AttributeWithBoolValidators = BoolAttribute{} +) + +// BoolAttribute represents a schema attribute that is a boolean. When +// retrieving the value for this attribute, use types.Bool as the value type +// unless the CustomType field is set. +// +// Terraform configurations configure this attribute using expressions that +// return a boolean or directly via the true/false keywords. +// +// example_attribute = true +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type BoolAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.BoolType. When retrieving data, the basetypes.BoolValuable + // associated with this custom type must be used in place of types.Bool. + CustomType basetypes.BoolTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Bool + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Bool + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.Bool +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a BoolAttribute. +func (a BoolAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// BoolDefaultValue returns the Default field value. +func (a BoolAttribute) BoolDefaultValue() defaults.Bool { + return a.Default +} + +// BoolPlanModifiers returns the PlanModifiers field value. +func (a BoolAttribute) BoolPlanModifiers() []planmodifier.Bool { + return a.PlanModifiers +} + +// BoolValidators returns the Validators field value. +func (a BoolAttribute) BoolValidators() []validator.Bool { + return a.Validators +} + +// Equal returns true if the given Attribute is a BoolAttribute +// and all fields are equal. +func (a BoolAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(BoolAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a BoolAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a BoolAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a BoolAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.StringType or the CustomType field value if defined. +func (a BoolAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.BoolType +} + +// IsComputed returns the Computed field value. +func (a BoolAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a BoolAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a BoolAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a BoolAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a BoolAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if !a.IsComputed() && a.BoolDefaultValue() != nil { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/bool.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/bool.go new file mode 100644 index 00000000..cd16b91b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/bool.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package defaults + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Bool is a schema default value for types.Bool attributes. +type Bool interface { + Describer + + // DefaultBool should set the default value. + DefaultBool(context.Context, BoolRequest, *BoolResponse) +} + +type BoolRequest struct { + // Path contains the path of the attribute for setting the + // default value. Use this path for any response diagnostics. + Path path.Path +} + +type BoolResponse struct { + // Diagnostics report errors or warnings related to setting the + // default value resource configuration. An empty slice + // indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics + + // PlanValue is the planned new state for the attribute. + PlanValue types.Bool +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/describer.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/describer.go new file mode 100644 index 00000000..64b80987 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/describer.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package defaults + +import "context" + +// Describer is the common documentation interface for extensible schema +// default value functionality. +type Describer interface { + // Description should describe the default in plain text formatting. + // This information is used by provider logging and provider tooling such + // as documentation generation. + // + // The description should: + // - Begin with a lowercase or other character suitable for the middle of + // a sentence. + // - End without punctuation. + Description(ctx context.Context) string + + // MarkdownDescription should describe the default in Markdown + // formatting. This information is used by provider logging and provider + // tooling such as documentation generation. + // + // The description should: + // - Begin with a lowercase or other character suitable for the middle of + // a sentence. + // - End without punctuation. + MarkdownDescription(ctx context.Context) string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/doc.go new file mode 100644 index 00000000..8f4f8e8a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/doc.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package defaults contains schema default value interfaces and +// request/response implementations. These default value interfaces +// are used by resource/schema and internally in the framework. +// Refer to the typed default packages, such as stringdefault, +// for framework-defined default values that can be used in +// provider-defined schemas. +// +// Each attr.Type has a corresponding {TYPE} interface which +// implements concretely typed Default{TYPE} methods, such as +// StringDefault and DefaultString. +// +// The framework has to choose between default value developers handling a +// concrete framework value type, such as types.Bool, or the framework +// interface for custom value basetypes, such as basetypes.BoolValuable. +// +// In the framework type model, the developer can immediately use the value. +// If the value was associated with a custom type and using the custom value +// type is desired, the developer must use the type's ValueFrom{TYPE} method. +// +// In the custom type model, the developer must always convert to a concrete +// type before using the value unless checking for null or unknown. Since any +// custom type may be passed due to the schema, it is possible, if not likely, +// that unknown concrete types will be passed to the default. +// +// The framework chooses to pass the framework value type. This prevents the +// potential for unexpected runtime panics and simplifies development for +// easier use cases where the framework type is sufficient. More advanced +// developers can choose to call the type's ValueFrom{TYPE} method to get the +// desired custom type in a plan modifier. +// +// Defaults that are not type dependent need to implement all interfaces, +// but can use shared logic to reduce implementation code. +package defaults diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/dynamic.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/dynamic.go new file mode 100644 index 00000000..313a3d69 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/dynamic.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package defaults + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Dynamic is a schema default value for types.Dynamic attributes. +type Dynamic interface { + Describer + + // DefaultDynamic should set the default value. + DefaultDynamic(context.Context, DynamicRequest, *DynamicResponse) +} + +type DynamicRequest struct { + // Path contains the path of the attribute for setting the + // default value. Use this path for any response diagnostics. + Path path.Path +} + +type DynamicResponse struct { + // Diagnostics report errors or warnings related to setting the + // default value resource configuration. An empty slice + // indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics + + // PlanValue is the planned new state for the attribute. + PlanValue types.Dynamic +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/float64.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/float64.go new file mode 100644 index 00000000..4c20fbe4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/float64.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package defaults + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Float64 is a schema default value for types.Float64 attributes. +type Float64 interface { + Describer + + // DefaultFloat64 should set the default value. + DefaultFloat64(context.Context, Float64Request, *Float64Response) +} + +type Float64Request struct { + // Path contains the path of the attribute for setting the + // default value. Use this path for any response diagnostics. + Path path.Path +} + +type Float64Response struct { + // Diagnostics report errors or warnings related to setting the + // default value resource configuration. An empty slice + // indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics + + // PlanValue is the planned new state for the attribute. + PlanValue types.Float64 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/int64.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/int64.go new file mode 100644 index 00000000..186ecd78 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/int64.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package defaults + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Int64 is a schema default value for types.Int64 attributes. +type Int64 interface { + Describer + + // DefaultInt64 should set the default value. + DefaultInt64(context.Context, Int64Request, *Int64Response) +} + +type Int64Request struct { + // Path contains the path of the attribute for setting the + // default value. Use this path for any response diagnostics. + Path path.Path +} + +type Int64Response struct { + // Diagnostics report errors or warnings related to setting the + // default value resource configuration. An empty slice + // indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics + + // PlanValue is the planned new state for the attribute. + PlanValue types.Int64 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/list.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/list.go new file mode 100644 index 00000000..0e5509ce --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/list.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package defaults + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// List is a schema default value for types.List attributes. +type List interface { + Describer + + // DefaultList should set the default value. + DefaultList(context.Context, ListRequest, *ListResponse) +} + +type ListRequest struct { + // Path contains the path of the attribute for setting the + // default value. Use this path for any response diagnostics. + Path path.Path +} + +type ListResponse struct { + // Diagnostics report errors or warnings related to setting the + // default value resource configuration. An empty slice + // indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics + + // PlanValue is the planned new state for the attribute. + PlanValue types.List +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/map.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/map.go new file mode 100644 index 00000000..8b53ee77 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/map.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package defaults + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Map is a schema default value for types.Map attributes. +type Map interface { + Describer + + // DefaultMap should set the default value. + DefaultMap(context.Context, MapRequest, *MapResponse) +} + +type MapRequest struct { + // Path contains the path of the attribute for setting the + // default value. Use this path for any response diagnostics. + Path path.Path +} + +type MapResponse struct { + // Diagnostics report errors or warnings related to setting the + // default value resource configuration. An empty slice + // indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics + + // PlanValue is the planned new state for the attribute. + PlanValue types.Map +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/number.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/number.go new file mode 100644 index 00000000..d07a86f1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/number.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package defaults + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Number is a schema default value for types.Number attributes. +type Number interface { + Describer + + // DefaultNumber should set the default value. + DefaultNumber(context.Context, NumberRequest, *NumberResponse) +} + +type NumberRequest struct { + // Path contains the path of the attribute for setting the + // default value. Use this path for any response diagnostics. + Path path.Path +} + +type NumberResponse struct { + // Diagnostics report errors or warnings related to setting the + // default value resource configuration. An empty slice + // indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics + + // PlanValue is the planned new state for the attribute. + PlanValue types.Number +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/object.go new file mode 100644 index 00000000..0c5d2ce7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/object.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package defaults + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Object is a schema default value for types.Object attributes. +type Object interface { + Describer + + // DefaultObject should set the default value. + DefaultObject(context.Context, ObjectRequest, *ObjectResponse) +} + +type ObjectRequest struct { + // Path contains the path of the attribute for setting the + // default value. Use this path for any response diagnostics. + Path path.Path +} + +type ObjectResponse struct { + // Diagnostics report errors or warnings related to setting the + // default value resource configuration. An empty slice + // indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics + + // PlanValue is the planned new state for the attribute. + PlanValue types.Object +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/set.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/set.go new file mode 100644 index 00000000..2e15b3cf --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/set.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package defaults + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Set is a schema default value for types.Set attributes. +type Set interface { + Describer + + // DefaultSet should set the default value. + DefaultSet(context.Context, SetRequest, *SetResponse) +} + +type SetRequest struct { + // Path contains the path of the attribute for setting the + // default value. Use this path for any response diagnostics. + Path path.Path +} + +type SetResponse struct { + // Diagnostics report errors or warnings related to setting the + // default value resource configuration. An empty slice + // indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics + + // PlanValue is the planned new state for the attribute. + PlanValue types.Set +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/string.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/string.go new file mode 100644 index 00000000..90aa822a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults/string.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package defaults + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// String is a schema default value for types.String attributes. +type String interface { + Describer + + // DefaultString should set the default value. + DefaultString(context.Context, StringRequest, *StringResponse) +} + +type StringRequest struct { + // Path contains the path of the attribute for setting the + // default value. Use this path for any response diagnostics. + Path path.Path +} + +type StringResponse struct { + // Diagnostics report errors or warnings related to setting the + // default value resource configuration. An empty slice + // indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics + + // PlanValue is the planned new state for the attribute. + PlanValue types.String +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/doc.go new file mode 100644 index 00000000..797fe0b1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/doc.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package schema contains all available schema functionality for resources. +// Resource schemas define the structure and value types for configuration, +// plan, and state data. Schemas are implemented via the resource.Resource type +// Schema method. +package schema diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/dynamic_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/dynamic_attribute.go new file mode 100644 index 00000000..7b97625d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/dynamic_attribute.go @@ -0,0 +1,241 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = DynamicAttribute{} + _ fwschema.AttributeWithValidateImplementation = DynamicAttribute{} + _ fwschema.AttributeWithDynamicDefaultValue = DynamicAttribute{} + _ fwxschema.AttributeWithDynamicPlanModifiers = DynamicAttribute{} + _ fwxschema.AttributeWithDynamicValidators = DynamicAttribute{} +) + +// DynamicAttribute represents a schema attribute that is a dynamic, rather +// than a single static type. Static types are always preferable over dynamic +// types in Terraform as practitioners will receive less helpful configuration +// assistance from validation error diagnostics and editor integrations. When +// retrieving the value for this attribute, use types.Dynamic as the value type +// unless the CustomType field is set. +// +// The concrete value type for a dynamic is determined at runtime in this order: +// 1. By Terraform, if defined in the configuration (if Required or Optional). +// 2. By the provider (if Computed). +// +// Once the concrete value type has been determined, it must remain consistent between +// plan and apply or Terraform will return an error. +type DynamicAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.DynamicType. When retrieving data, the basetypes.DynamicValuable + // associated with this custom type must be used in place of types.Dynamic. + CustomType basetypes.DynamicTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Dynamic + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Dynamic + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.Dynamic +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a DynamicAttribute. +func (a DynamicAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a DynamicAttribute +// and all fields are equal. +func (a DynamicAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(DynamicAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a DynamicAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a DynamicAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a DynamicAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.DynamicType or the CustomType field value if defined. +func (a DynamicAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.DynamicType +} + +// IsComputed returns the Computed field value. +func (a DynamicAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a DynamicAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a DynamicAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a DynamicAttribute) IsSensitive() bool { + return a.Sensitive +} + +// DynamicDefaultValue returns the Default field value. +func (a DynamicAttribute) DynamicDefaultValue() defaults.Dynamic { + return a.Default +} + +// DynamicPlanModifiers returns the PlanModifiers field value. +func (a DynamicAttribute) DynamicPlanModifiers() []planmodifier.Dynamic { + return a.PlanModifiers +} + +// DynamicValidators returns the Validators field value. +func (a DynamicAttribute) DynamicValidators() []validator.Dynamic { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a DynamicAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if !a.IsComputed() && a.DynamicDefaultValue() != nil { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/float64_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/float64_attribute.go new file mode 100644 index 00000000..7d762a4a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/float64_attribute.go @@ -0,0 +1,243 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = Float64Attribute{} + _ fwschema.AttributeWithValidateImplementation = Float64Attribute{} + _ fwschema.AttributeWithFloat64DefaultValue = Float64Attribute{} + _ fwxschema.AttributeWithFloat64PlanModifiers = Float64Attribute{} + _ fwxschema.AttributeWithFloat64Validators = Float64Attribute{} +) + +// Float64Attribute represents a schema attribute that is a 64-bit floating +// point number. When retrieving the value for this attribute, use +// types.Float64 as the value type unless the CustomType field is set. +// +// Use Int64Attribute for 64-bit integer attributes or NumberAttribute for +// 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via a floating point value. +// +// example_attribute = 123.45 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type Float64Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Float64Type. When retrieving data, the basetypes.Float64Valuable + // associated with this custom type must be used in place of types.Float64. + CustomType basetypes.Float64Typable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Float64 + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Float64 + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.Float64 +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Float64Attribute. +func (a Float64Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Float64Attribute +// and all fields are equal. +func (a Float64Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Float64Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// Float64DefaultValue returns the Default field value. +func (a Float64Attribute) Float64DefaultValue() defaults.Float64 { + return a.Default +} + +// Float64PlanModifiers returns the PlanModifiers field value. +func (a Float64Attribute) Float64PlanModifiers() []planmodifier.Float64 { + return a.PlanModifiers +} + +// Float64Validators returns the Validators field value. +func (a Float64Attribute) Float64Validators() []validator.Float64 { + return a.Validators +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a Float64Attribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a Float64Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a Float64Attribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.Float64Type or the CustomType field value if defined. +func (a Float64Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Float64Type +} + +// IsComputed returns the Computed field value. +func (a Float64Attribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a Float64Attribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a Float64Attribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a Float64Attribute) IsSensitive() bool { + return a.Sensitive +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a Float64Attribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if !a.IsComputed() && a.Float64DefaultValue() != nil { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/int64_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/int64_attribute.go new file mode 100644 index 00000000..65ec795e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/int64_attribute.go @@ -0,0 +1,243 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = Int64Attribute{} + _ fwschema.AttributeWithValidateImplementation = Int64Attribute{} + _ fwschema.AttributeWithInt64DefaultValue = Int64Attribute{} + _ fwxschema.AttributeWithInt64PlanModifiers = Int64Attribute{} + _ fwxschema.AttributeWithInt64Validators = Int64Attribute{} +) + +// Int64Attribute represents a schema attribute that is a 64-bit integer. +// When retrieving the value for this attribute, use types.Int64 as the value +// type unless the CustomType field is set. +// +// Use Float64Attribute for 64-bit floating point number attributes or +// NumberAttribute for 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via an integer value. +// +// example_attribute = 123 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type Int64Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Int64Type. When retrieving data, the basetypes.Int64Valuable + // associated with this custom type must be used in place of types.Int64. + CustomType basetypes.Int64Typable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Int64 + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Int64 + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.Int64 +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Int64Attribute. +func (a Int64Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Int64Attribute +// and all fields are equal. +func (a Int64Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Int64Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a Int64Attribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a Int64Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a Int64Attribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.Int64Type or the CustomType field value if defined. +func (a Int64Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Int64Type +} + +// Int64DefaultValue returns the Default field value. +func (a Int64Attribute) Int64DefaultValue() defaults.Int64 { + return a.Default +} + +// Int64PlanModifiers returns the PlanModifiers field value. +func (a Int64Attribute) Int64PlanModifiers() []planmodifier.Int64 { + return a.PlanModifiers +} + +// Int64Validators returns the Validators field value. +func (a Int64Attribute) Int64Validators() []validator.Int64 { + return a.Validators +} + +// IsComputed returns the Computed field value. +func (a Int64Attribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a Int64Attribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a Int64Attribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a Int64Attribute) IsSensitive() bool { + return a.Sensitive +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a Int64Attribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if !a.IsComputed() && a.Int64DefaultValue() != nil { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_attribute.go new file mode 100644 index 00000000..1dc0e0e8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_attribute.go @@ -0,0 +1,289 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = ListAttribute{} + _ fwschema.AttributeWithValidateImplementation = ListAttribute{} + _ fwschema.AttributeWithListDefaultValue = ListAttribute{} + _ fwxschema.AttributeWithListPlanModifiers = ListAttribute{} + _ fwxschema.AttributeWithListValidators = ListAttribute{} +) + +// ListAttribute represents a schema attribute that is a list with a single +// element type. When retrieving the value for this attribute, use types.List +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use ListNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list or directly via square brace syntax. +// +// # list of strings +// example_attribute = ["first", "second"] +// +// Terraform configurations reference this attribute using expressions that +// accept a list or an element directly via square brace 0-based index syntax: +// +// # first known element +// .example_attribute[0] +type ListAttribute struct { + // ElementType is the type for all elements of the list. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ListType. When retrieving data, the basetypes.ListValuable + // associated with this custom type must be used in place of types.List. + CustomType basetypes.ListTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.List + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.List + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.List +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a list +// index or an error. +func (a ListAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a ListAttribute +// and all fields are equal. +func (a ListAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(ListAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a ListAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a ListAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ListAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.ListType or the CustomType field value if defined. +func (a ListAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ListType{ + ElemType: a.ElementType, + } +} + +// IsComputed returns the Computed field value. +func (a ListAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a ListAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ListAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a ListAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ListDefaultValue returns the Default field value. +func (a ListAttribute) ListDefaultValue() defaults.List { + return a.Default +} + +// ListPlanModifiers returns the PlanModifiers field value. +func (a ListAttribute) ListPlanModifiers() []planmodifier.List { + return a.PlanModifiers +} + +// ListValidators returns the Validators field value. +func (a ListAttribute) ListValidators() []validator.List { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a ListAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } + + if a.ListDefaultValue() != nil { + if !a.IsComputed() { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } + + // Validate Default implementation. This is safe unless the framework + // ever allows more dynamic Default implementations at which the + // implementation would be required to be validated at runtime. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/930 + defaultReq := defaults.ListRequest{ + Path: req.Path, + } + defaultResp := &defaults.ListResponse{} + + a.ListDefaultValue().DefaultList(ctx, defaultReq, defaultResp) + + resp.Diagnostics.Append(defaultResp.Diagnostics...) + + if defaultResp.Diagnostics.HasError() { + return + } + + if a.ElementType != nil && !a.ElementType.Equal(defaultResp.PlanValue.ElementType(ctx)) { + resp.Diagnostics.Append(fwschema.AttributeDefaultElementTypeMismatchDiag(req.Path, a.ElementType, defaultResp.PlanValue.ElementType(ctx))) + } + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_nested_attribute.go new file mode 100644 index 00000000..95fd2ba0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_nested_attribute.go @@ -0,0 +1,313 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = ListNestedAttribute{} + _ fwschema.AttributeWithValidateImplementation = ListNestedAttribute{} + _ fwschema.AttributeWithListDefaultValue = ListNestedAttribute{} + _ fwxschema.AttributeWithListPlanModifiers = ListNestedAttribute{} + _ fwxschema.AttributeWithListValidators = ListNestedAttribute{} +) + +// ListNestedAttribute represents an attribute that is a list of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.List +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use ListAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list of objects or directly via square and curly brace syntax. +// +// # list of objects +// example_attribute = [ +// { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a list of objects or an element directly via square brace 0-based +// index syntax: +// +// # first known object +// .example_attribute[0] +// # first known object nested_attribute value +// .example_attribute[0].nested_attribute +type ListNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.ListType of types.ObjectType. When retrieving data, the + // basetypes.ListValuable associated with this custom type must be used in + // place of types.List. + CustomType basetypes.ListTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.List + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.List + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.List +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyInt, otherwise returns an error. +func (a ListNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyInt) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to ListNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a ListNestedAttribute +// and all fields are equal. +func (a ListNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(ListNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a ListNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a ListNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ListNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a ListNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a ListNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeList +} + +// GetType returns ListType of ObjectType or CustomType. +func (a ListNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ListType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed returns the Computed field value. +func (a ListNestedAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a ListNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ListNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a ListNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ListDefaultValue returns the Default field value. +func (a ListNestedAttribute) ListDefaultValue() defaults.List { + return a.Default +} + +// ListPlanModifiers returns the PlanModifiers field value. +func (a ListNestedAttribute) ListPlanModifiers() []planmodifier.List { + return a.PlanModifiers +} + +// ListValidators returns the Validators field value. +func (a ListNestedAttribute) ListValidators() []validator.List { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a ListNestedAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } + + if a.ListDefaultValue() != nil { + if !a.IsComputed() { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } + + // Validate Default implementation. This is safe unless the framework + // ever allows more dynamic Default implementations at which the + // implementation would be required to be validated at runtime. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/930 + defaultReq := defaults.ListRequest{ + Path: req.Path, + } + defaultResp := &defaults.ListResponse{} + + a.ListDefaultValue().DefaultList(ctx, defaultReq, defaultResp) + + resp.Diagnostics.Append(defaultResp.Diagnostics...) + + if defaultResp.Diagnostics.HasError() { + return + } + + if a.CustomType == nil && a.NestedObject.CustomType == nil && !a.NestedObject.Type().Equal(defaultResp.PlanValue.ElementType(ctx)) { + resp.Diagnostics.Append(fwschema.AttributeDefaultElementTypeMismatchDiag(req.Path, a.NestedObject.Type(), defaultResp.PlanValue.ElementType(ctx))) + } + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_nested_block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_nested_block.go new file mode 100644 index 00000000..b82cfea6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/list_nested_block.go @@ -0,0 +1,229 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Block = ListNestedBlock{} + _ fwschema.BlockWithValidateImplementation = ListNestedBlock{} + _ fwxschema.BlockWithListPlanModifiers = ListNestedBlock{} + _ fwxschema.BlockWithListValidators = ListNestedBlock{} +) + +// ListNestedBlock represents a block that is a list of objects where +// the object attributes can be fully defined, including further attributes +// or blocks. When retrieving the value for this block, use types.List +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. +// +// Prefer ListNestedAttribute over ListNestedBlock if the provider is +// using protocol version 6. Nested attributes allow practitioners to configure +// values directly with expressions. +// +// Terraform configurations configure this block repeatedly using curly brace +// syntax without an equals (=) sign or [Dynamic Block Expressions]. +// +// # list of blocks with two elements +// example_block { +// nested_attribute = #... +// } +// example_block { +// nested_attribute = #... +// } +// +// Terraform configurations reference this block using expressions that +// accept a list of objects or an element directly via square brace 0-based +// index syntax: +// +// # first known object +// .example_block[0] +// # first known object nested_attribute value +// .example_block[0].nested_attribute +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +type ListNestedBlock struct { + // NestedObject is the underlying object that contains nested attributes or + // blocks. This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this block definition with + // a DynamicAttribute. + NestedObject NestedBlockObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.ListType of types.ObjectType. When retrieving data, the + // basetypes.ListValuable associated with this custom type must be used in + // place of types.List. + CustomType basetypes.ListTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.List + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.List +} + +// ApplyTerraform5AttributePathStep returns the NestedObject field value if step +// is ElementKeyInt, otherwise returns an error. +func (b ListNestedBlock) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyInt) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to ListNestedBlock", step) + } + + return b.NestedObject, nil +} + +// Equal returns true if the given Block is ListNestedBlock +// and all fields are equal. +func (b ListNestedBlock) Equal(o fwschema.Block) bool { + if _, ok := o.(ListNestedBlock); !ok { + return false + } + + return fwschema.BlocksEqual(b, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (b ListNestedBlock) GetDeprecationMessage() string { + return b.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (b ListNestedBlock) GetDescription() string { + return b.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (b ListNestedBlock) GetMarkdownDescription() string { + return b.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (b ListNestedBlock) GetNestedObject() fwschema.NestedBlockObject { + return b.NestedObject +} + +// GetNestingMode always returns BlockNestingModeList. +func (b ListNestedBlock) GetNestingMode() fwschema.BlockNestingMode { + return fwschema.BlockNestingModeList +} + +// ListPlanModifiers returns the PlanModifiers field value. +func (b ListNestedBlock) ListPlanModifiers() []planmodifier.List { + return b.PlanModifiers +} + +// ListValidators returns the Validators field value. +func (b ListNestedBlock) ListValidators() []validator.List { + return b.Validators +} + +// Type returns ListType of ObjectType or CustomType. +func (b ListNestedBlock) Type() attr.Type { + if b.CustomType != nil { + return b.CustomType + } + + return types.ListType{ + ElemType: b.NestedObject.Type(), + } +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the block to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (b ListNestedBlock) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if b.CustomType == nil && fwtype.ContainsCollectionWithDynamic(b.Type()) { + resp.Diagnostics.Append(fwtype.BlockCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/map_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/map_attribute.go new file mode 100644 index 00000000..ea08fa7b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/map_attribute.go @@ -0,0 +1,292 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = MapAttribute{} + _ fwschema.AttributeWithValidateImplementation = MapAttribute{} + _ fwschema.AttributeWithMapDefaultValue = MapAttribute{} + _ fwxschema.AttributeWithMapPlanModifiers = MapAttribute{} + _ fwxschema.AttributeWithMapValidators = MapAttribute{} +) + +// MapAttribute represents a schema attribute that is a list with a single +// element type. When retrieving the value for this attribute, use types.Map +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use MapNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a list or directly via curly brace syntax. +// +// # map of strings +// example_attribute = { +// key1 = "first", +// key2 = "second", +// } +// +// Terraform configurations reference this attribute using expressions that +// accept a map or an element directly via square brace string syntax: +// +// # key1 known element +// .example_attribute["key1"] +type MapAttribute struct { + // ElementType is the type for all elements of the map. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.MapType. When retrieving data, the basetypes.MapValuable + // associated with this custom type must be used in place of types.Map. + CustomType basetypes.MapTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Map + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Map + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.Map +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a map +// index or an error. +func (a MapAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a MapAttribute +// and all fields are equal. +func (a MapAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(MapAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a MapAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a MapAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a MapAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.MapType or the CustomType field value if defined. +func (a MapAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.MapType{ + ElemType: a.ElementType, + } +} + +// IsComputed returns the Computed field value. +func (a MapAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a MapAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a MapAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a MapAttribute) IsSensitive() bool { + return a.Sensitive +} + +// MapDefaultValue returns the Default field value. +func (a MapAttribute) MapDefaultValue() defaults.Map { + return a.Default +} + +// MapPlanModifiers returns the PlanModifiers field value. +func (a MapAttribute) MapPlanModifiers() []planmodifier.Map { + return a.PlanModifiers +} + +// MapValidators returns the Validators field value. +func (a MapAttribute) MapValidators() []validator.Map { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a MapAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } + + if a.MapDefaultValue() != nil { + if !a.IsComputed() { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } + + // Validate Default implementation. This is safe unless the framework + // ever allows more dynamic Default implementations at which the + // implementation would be required to be validated at runtime. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/930 + defaultReq := defaults.MapRequest{ + Path: req.Path, + } + defaultResp := &defaults.MapResponse{} + + a.MapDefaultValue().DefaultMap(ctx, defaultReq, defaultResp) + + resp.Diagnostics.Append(defaultResp.Diagnostics...) + + if defaultResp.Diagnostics.HasError() { + return + } + + if a.ElementType != nil && !a.ElementType.Equal(defaultResp.PlanValue.ElementType(ctx)) { + resp.Diagnostics.Append(fwschema.AttributeDefaultElementTypeMismatchDiag(req.Path, a.ElementType, defaultResp.PlanValue.ElementType(ctx))) + } + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/map_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/map_nested_attribute.go new file mode 100644 index 00000000..faa1f327 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/map_nested_attribute.go @@ -0,0 +1,313 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = MapNestedAttribute{} + _ fwschema.AttributeWithValidateImplementation = MapNestedAttribute{} + _ fwschema.AttributeWithMapDefaultValue = MapNestedAttribute{} + _ fwxschema.AttributeWithMapPlanModifiers = MapNestedAttribute{} + _ fwxschema.AttributeWithMapValidators = MapNestedAttribute{} +) + +// MapNestedAttribute represents an attribute that is a set of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Map +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use MapAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set of objects or directly via curly brace syntax. +// +// # map of objects +// example_attribute = { +// key = { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a map of objects or an element directly via square brace string +// syntax: +// +// # known object at key +// .example_attribute["key"] +// # known object nested_attribute value at key +// .example_attribute["key"].nested_attribute +type MapNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.MapType of types.ObjectType. When retrieving data, the + // basetypes.MapValuable associated with this custom type must be used in + // place of types.Map. + CustomType basetypes.MapTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Map + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Map + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.Map +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyString, otherwise returns an error. +func (a MapNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyString) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to MapNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a MapNestedAttribute +// and all fields are equal. +func (a MapNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(MapNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a MapNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a MapNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a MapNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a MapNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a MapNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeMap +} + +// GetType returns MapType of ObjectType or CustomType. +func (a MapNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.MapType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed returns the Computed field value. +func (a MapNestedAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a MapNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a MapNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a MapNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// MapDefaultValue returns the Default field value. +func (a MapNestedAttribute) MapDefaultValue() defaults.Map { + return a.Default +} + +// MapPlanModifiers returns the PlanModifiers field value. +func (a MapNestedAttribute) MapPlanModifiers() []planmodifier.Map { + return a.PlanModifiers +} + +// MapValidators returns the Validators field value. +func (a MapNestedAttribute) MapValidators() []validator.Map { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a MapNestedAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } + + if a.MapDefaultValue() != nil { + if !a.IsComputed() { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } + + // Validate Default implementation. This is safe unless the framework + // ever allows more dynamic Default implementations at which the + // implementation would be required to be validated at runtime. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/930 + defaultReq := defaults.MapRequest{ + Path: req.Path, + } + defaultResp := &defaults.MapResponse{} + + a.MapDefaultValue().DefaultMap(ctx, defaultReq, defaultResp) + + resp.Diagnostics.Append(defaultResp.Diagnostics...) + + if defaultResp.Diagnostics.HasError() { + return + } + + if a.CustomType == nil && a.NestedObject.CustomType == nil && !a.NestedObject.Type().Equal(defaultResp.PlanValue.ElementType(ctx)) { + resp.Diagnostics.Append(fwschema.AttributeDefaultElementTypeMismatchDiag(req.Path, a.NestedObject.Type(), defaultResp.PlanValue.ElementType(ctx))) + } + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_attribute.go new file mode 100644 index 00000000..31d2ee15 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_attribute.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Nested attributes are only compatible with protocol version 6. +type NestedAttribute interface { + Attribute + fwschema.NestedAttribute +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_attribute_object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_attribute_object.go new file mode 100644 index 00000000..ac7f3549 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_attribute_object.go @@ -0,0 +1,108 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ fwxschema.NestedAttributeObjectWithPlanModifiers = NestedAttributeObject{} + _ fwxschema.NestedAttributeObjectWithValidators = NestedAttributeObject{} +) + +// NestedAttributeObject is the object containing the underlying attributes +// for a ListNestedAttribute, MapNestedAttribute, SetNestedAttribute, or +// SingleNestedAttribute (automatically generated). When retrieving the value +// for this attribute, use types.Object as the value type unless the CustomType +// field is set. The Attributes field must be set. Nested attributes are only +// compatible with protocol version 6. +// +// This object enables customizing and simplifying details within its parent +// NestedAttribute, therefore it cannot have Terraform schema fields such as +// Required, Description, etc. +type NestedAttributeObject struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. This field must be set. + Attributes map[string]Attribute + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Object +} + +// ApplyTerraform5AttributePathStep performs an AttributeName step on the +// underlying attributes or returns an error. +func (o NestedAttributeObject) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.NestedAttributeObjectApplyTerraform5AttributePathStep(o, step) +} + +// Equal returns true if the given NestedAttributeObject is equivalent. +func (o NestedAttributeObject) Equal(other fwschema.NestedAttributeObject) bool { + if _, ok := other.(NestedAttributeObject); !ok { + return false + } + + return fwschema.NestedAttributeObjectEqual(o, other) +} + +// GetAttributes returns the Attributes field value. +func (o NestedAttributeObject) GetAttributes() fwschema.UnderlyingAttributes { + return schemaAttributes(o.Attributes) +} + +// ObjectPlanModifiers returns the PlanModifiers field value. +func (o NestedAttributeObject) ObjectPlanModifiers() []planmodifier.Object { + return o.PlanModifiers +} + +// ObjectValidators returns the Validators field value. +func (o NestedAttributeObject) ObjectValidators() []validator.Object { + return o.Validators +} + +// Type returns the framework type of the NestedAttributeObject. +func (o NestedAttributeObject) Type() basetypes.ObjectTypable { + if o.CustomType != nil { + return o.CustomType + } + + return fwschema.NestedAttributeObjectType(o) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_block_object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_block_object.go new file mode 100644 index 00000000..92dc494d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/nested_block_object.go @@ -0,0 +1,120 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ fwxschema.NestedBlockObjectWithPlanModifiers = NestedBlockObject{} + _ fwxschema.NestedBlockObjectWithValidators = NestedBlockObject{} +) + +// NestedBlockObject is the object containing the underlying attributes and +// blocks for a ListNestedBlock or SetNestedBlock. When retrieving the value +// for this attribute, use types.Object as the value type unless the CustomType +// field is set. +// +// This object enables customizing and simplifying details within its parent +// Block, therefore it cannot have Terraform schema fields such as Description, +// etc. +type NestedBlockObject struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Blocks names. + Attributes map[string]Attribute + + // Blocks is the mapping of underlying block names to block definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Attributes names. + Blocks map[string]Block + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Object +} + +// ApplyTerraform5AttributePathStep performs an AttributeName step on the +// underlying attributes or returns an error. +func (o NestedBlockObject) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.NestedBlockObjectApplyTerraform5AttributePathStep(o, step) +} + +// Equal returns true if the given NestedBlockObject is equivalent. +func (o NestedBlockObject) Equal(other fwschema.NestedBlockObject) bool { + if _, ok := other.(NestedBlockObject); !ok { + return false + } + + return fwschema.NestedBlockObjectEqual(o, other) +} + +// GetAttributes returns the Attributes field value. +func (o NestedBlockObject) GetAttributes() fwschema.UnderlyingAttributes { + return schemaAttributes(o.Attributes) +} + +// GetAttributes returns the Blocks field value. +func (o NestedBlockObject) GetBlocks() map[string]fwschema.Block { + return schemaBlocks(o.Blocks) +} + +// ObjectPlanModifiers returns the PlanModifiers field value. +func (o NestedBlockObject) ObjectPlanModifiers() []planmodifier.Object { + return o.PlanModifiers +} + +// ObjectValidators returns the Validators field value. +func (o NestedBlockObject) ObjectValidators() []validator.Object { + return o.Validators +} + +// Type returns the framework type of the NestedBlockObject. +func (o NestedBlockObject) Type() basetypes.ObjectTypable { + if o.CustomType != nil { + return o.CustomType + } + + return fwschema.NestedBlockObjectType(o) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/number_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/number_attribute.go new file mode 100644 index 00000000..d2b9c59a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/number_attribute.go @@ -0,0 +1,244 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = NumberAttribute{} + _ fwschema.AttributeWithValidateImplementation = NumberAttribute{} + _ fwschema.AttributeWithNumberDefaultValue = NumberAttribute{} + _ fwxschema.AttributeWithNumberPlanModifiers = NumberAttribute{} + _ fwxschema.AttributeWithNumberValidators = NumberAttribute{} +) + +// NumberAttribute represents a schema attribute that is a generic number with +// up to 512 bits of floating point or integer precision. When retrieving the +// value for this attribute, use types.Number as the value type unless the +// CustomType field is set. +// +// Use Float64Attribute for 64-bit floating point number attributes or +// Int64Attribute for 64-bit integer number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via a floating point or integer value. +// +// example_attribute = 123 +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type NumberAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.NumberType. When retrieving data, the basetypes.NumberValuable + // associated with this custom type must be used in place of types.Number. + CustomType basetypes.NumberTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Number + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Number + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.Number +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a NumberAttribute. +func (a NumberAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a NumberAttribute +// and all fields are equal. +func (a NumberAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(NumberAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a NumberAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a NumberAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a NumberAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.NumberType or the CustomType field value if defined. +func (a NumberAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.NumberType +} + +// IsComputed returns the Computed field value. +func (a NumberAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a NumberAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a NumberAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a NumberAttribute) IsSensitive() bool { + return a.Sensitive +} + +// NumberDefaultValue returns the Default field value. +func (a NumberAttribute) NumberDefaultValue() defaults.Number { + return a.Default +} + +// NumberPlanModifiers returns the PlanModifiers field value. +func (a NumberAttribute) NumberPlanModifiers() []planmodifier.Number { + return a.PlanModifiers +} + +// NumberValidators returns the Validators field value. +func (a NumberAttribute) NumberValidators() []validator.Number { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a NumberAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if !a.IsComputed() && a.NumberDefaultValue() != nil { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/object_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/object_attribute.go new file mode 100644 index 00000000..7b9fe6a5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/object_attribute.go @@ -0,0 +1,291 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = ObjectAttribute{} + _ fwschema.AttributeWithValidateImplementation = ObjectAttribute{} + _ fwschema.AttributeWithObjectDefaultValue = ObjectAttribute{} + _ fwxschema.AttributeWithObjectPlanModifiers = ObjectAttribute{} + _ fwxschema.AttributeWithObjectValidators = ObjectAttribute{} +) + +// ObjectAttribute represents a schema attribute that is an object with only +// type information for underlying attributes. When retrieving the value for +// this attribute, use types.Object as the value type unless the CustomType +// field is set. The AttributeTypes field must be set. +// +// Prefer SingleNestedAttribute over ObjectAttribute if the provider is +// using protocol version 6 and full attribute functionality is needed. +// +// Terraform configurations configure this attribute using expressions that +// return an object or directly via curly brace syntax. +// +// # object with one attribute +// example_attribute = { +// underlying_attribute = #... +// } +// +// Terraform configurations reference this attribute using expressions that +// accept an object or an attribute directly via period syntax: +// +// # underlying attribute +// .example_attribute.underlying_attribute +type ObjectAttribute struct { + // AttributeTypes is the mapping of underlying attribute names to attribute + // types. This field must be set. + // + // Attribute types that contain a collection with a nested dynamic type (i.e. types.List[types.Dynamic]) are not supported. + // If underlying dynamic collection values are required, replace this attribute definition with + // DynamicAttribute instead. + AttributeTypes map[string]attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Object + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.Object +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into an +// attribute name or an error. +func (a ObjectAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a ObjectAttribute +// and all fields are equal. +func (a ObjectAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(ObjectAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a ObjectAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a ObjectAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a ObjectAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.ObjectType or the CustomType field value if defined. +func (a ObjectAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ObjectType{ + AttrTypes: a.AttributeTypes, + } +} + +// IsComputed returns the Computed field value. +func (a ObjectAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a ObjectAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a ObjectAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a ObjectAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ObjectDefaultValue returns the Default field value. +func (a ObjectAttribute) ObjectDefaultValue() defaults.Object { + return a.Default +} + +// ObjectPlanModifiers returns the PlanModifiers field value. +func (a ObjectAttribute) ObjectPlanModifiers() []planmodifier.Object { + return a.PlanModifiers +} + +// ObjectValidators returns the Validators field value. +func (a ObjectAttribute) ObjectValidators() []validator.Object { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a ObjectAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.AttributeTypes == nil && a.CustomType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingAttributeTypesDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } + + if a.ObjectDefaultValue() != nil { + if !a.IsComputed() { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } + + // Validate Default implementation. This is safe unless the framework + // ever allows more dynamic Default implementations at which the + // implementation would be required to be validated at runtime. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/930 + defaultReq := defaults.ObjectRequest{ + Path: req.Path, + } + defaultResp := &defaults.ObjectResponse{} + + a.ObjectDefaultValue().DefaultObject(ctx, defaultReq, defaultResp) + + resp.Diagnostics.Append(defaultResp.Diagnostics...) + + if defaultResp.Diagnostics.HasError() { + return + } + + if a.AttributeTypes != nil && !a.GetType().Equal(defaultResp.PlanValue.Type(ctx)) { + resp.Diagnostics.Append(fwschema.AttributeDefaultTypeMismatchDiag(req.Path, a.GetType(), defaultResp.PlanValue.Type(ctx))) + } + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/bool.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/bool.go new file mode 100644 index 00000000..9b60038b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/bool.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package planmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Bool is a schema plan modifier for types.Bool attributes. +type Bool interface { + Describer + + // PlanModifyBool should perform the modification. + PlanModifyBool(context.Context, BoolRequest, *BoolResponse) +} + +// BoolRequest is a request for types.Bool schema plan modification. +type BoolRequest struct { + // Path contains the path of the attribute for modification. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for modification. + PathExpression path.Expression + + // Config contains the entire configuration of the resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for modification from the configuration. + ConfigValue types.Bool + + // Plan contains the entire proposed new state of the resource. + Plan tfsdk.Plan + + // PlanValue contains the value of the attribute for modification from the proposed new state. + PlanValue types.Bool + + // State contains the entire prior state of the resource. + State tfsdk.State + + // StateValue contains the value of the attribute for modification from the prior state. + StateValue types.Bool + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // BoolResponse.Private to prevent accidental private state data loss. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + // + // Use the GetKey method to read data. Use the SetKey method on + // BoolResponse.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// BoolResponse is a response to a BoolRequest. +type BoolResponse struct { + // PlanValue is the planned new state for the attribute. + PlanValue types.Bool + + // RequiresReplace indicates whether a change in the attribute + // requires replacement of the whole resource. + RequiresReplace bool + + // Private is the private state resource data following the PlanModifyBool operation. + // This field is pre-populated from BoolRequest.Private and + // can be modified during the resource's PlanModifyBool operation. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to modifying the resource + // plan. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/describer.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/describer.go new file mode 100644 index 00000000..4bd6f3c2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/describer.go @@ -0,0 +1,32 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package planmodifier + +import ( + "context" +) + +// Describer is the common documentation interface for extensible schema +// plan modifier functionality. +type Describer interface { + // Description should describe the plan modifier in plain text formatting. + // This information is used by provider logging and provider tooling such + // as documentation generation. + // + // The description should: + // - Begin with a lowercase or other character suitable for the middle of + // a sentence. + // - End without punctuation. + Description(context.Context) string + + // MarkdownDescription should describe the plan modifier in Markdown + // formatting. This information is used by provider logging and provider + // tooling such as documentation generation. + // + // The description should: + // - Begin with a lowercase or other character suitable for the middle of + // a sentence. + // - End without punctuation. + MarkdownDescription(context.Context) string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/doc.go new file mode 100644 index 00000000..c75ffb98 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/doc.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package planmodifier contains schema plan modifier interfaces and +// request/response implementations. These plan modifier interfaces +// are used by resource/schema and internally in the framework. +// Refer to the typed plan modifier packages, such as stringplanmodifier, +// for framework-defined plan modifiers that can be used in +// provider-defined schemas. +// +// Each attr.Type has a corresponding {TYPE} interface which +// implements concretely typed PlanModify{TYPE} methods, such as +// StringPlanModifier and PlanModifyString. +// +// The framework has to choose between plan modifier developers handling a +// concrete framework value type, such as types.Bool, or the framework +// interface for custom value basetypes, such as basetypes.BoolValuable. +// +// In the framework type model, the developer can immediately use the value. +// If the value was associated with a custom type and using the custom value +// type is desired, the developer must use the type's ValueFrom{TYPE} method. +// +// In the custom type model, the developer must always convert to a concrete +// type before using the value unless checking for null or unknown. Since any +// custom type may be passed due to the schema, it is possible, if not likely, +// that unknown concrete types will be passed to the plan modifier. +// +// The framework chooses to pass the framework value type. This prevents the +// potential for unexpected runtime panics and simplifies development for +// easier use cases where the framework type is sufficient. More advanced +// developers can choose to call the type's ValueFrom{TYPE} method to get the +// desired custom type in a plan modifier. +// +// PlanModifers that are not type dependent need to implement all interfaces, +// but can use shared logic to reduce implementation code. +package planmodifier diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/dynamic.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/dynamic.go new file mode 100644 index 00000000..cbf9a775 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/dynamic.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package planmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Dynamic is a schema plan modifier for types.Dynamic attributes. +type Dynamic interface { + Describer + + // PlanModifyDynamic should perform the modification. + PlanModifyDynamic(context.Context, DynamicRequest, *DynamicResponse) +} + +// DynamicRequest is a request for types.Dynamic schema plan modification. +type DynamicRequest struct { + // Path contains the path of the attribute for modification. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for modification. + PathExpression path.Expression + + // Config contains the entire configuration of the resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for modification from the configuration. + ConfigValue types.Dynamic + + // Plan contains the entire proposed new state of the resource. + Plan tfsdk.Plan + + // PlanValue contains the value of the attribute for modification from the proposed new state. + PlanValue types.Dynamic + + // State contains the entire prior state of the resource. + State tfsdk.State + + // StateValue contains the value of the attribute for modification from the prior state. + StateValue types.Dynamic + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // DynamicResponse.Private to prevent accidental private state data loss. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + // + // Use the GetKey method to read data. Use the SetKey method on + // DynamicResponse.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// DynamicResponse is a response to a DynamicRequest. +type DynamicResponse struct { + // PlanValue is the planned new state for the attribute. + PlanValue types.Dynamic + + // RequiresReplace indicates whether a change in the attribute + // requires replacement of the whole resource. + RequiresReplace bool + + // Private is the private state resource data following the PlanModifyDynamic operation. + // This field is pre-populated from DynamicRequest.Private and + // can be modified during the resource's PlanModifyDynamic operation. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to modifying the resource + // plan. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/float64.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/float64.go new file mode 100644 index 00000000..971586b3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/float64.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package planmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Float64 is a schema plan modifier for types.Float64 attributes. +type Float64 interface { + Describer + + // PlanModifyFloat64 should perform the modification. + PlanModifyFloat64(context.Context, Float64Request, *Float64Response) +} + +// Float64Request is a request for types.Float64 schema plan modification. +type Float64Request struct { + // Path contains the path of the attribute for modification. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for modification. + PathExpression path.Expression + + // Config contains the entire configuration of the resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for modification from the configuration. + ConfigValue types.Float64 + + // Plan contains the entire proposed new state of the resource. + Plan tfsdk.Plan + + // PlanValue contains the value of the attribute for modification from the proposed new state. + PlanValue types.Float64 + + // State contains the entire prior state of the resource. + State tfsdk.State + + // StateValue contains the value of the attribute for modification from the prior state. + StateValue types.Float64 + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // Float64Response.Private to prevent accidental private state data loss. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + // + // Use the GetKey method to read data. Use the SetKey method on + // Float64Response.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// Float64Response is a response to a Float64Request. +type Float64Response struct { + // PlanValue is the planned new state for the attribute. + PlanValue types.Float64 + + // RequiresReplace indicates whether a change in the attribute + // requires replacement of the whole resource. + RequiresReplace bool + + // Private is the private state resource data following the PlanModifyFloat64 operation. + // This field is pre-populated from Float64Request.Private and + // can be modified during the resource's PlanModifyFloat64 operation. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to modifying the resource + // plan. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/int64.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/int64.go new file mode 100644 index 00000000..f65d63b5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/int64.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package planmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Int64 is a schema plan modifier for types.Int64 attributes. +type Int64 interface { + Describer + + // PlanModifyInt64 should perform the modification. + PlanModifyInt64(context.Context, Int64Request, *Int64Response) +} + +// Int64Request is a request for types.Int64 schema plan modification. +type Int64Request struct { + // Path contains the path of the attribute for modification. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for modification. + PathExpression path.Expression + + // Config contains the entire configuration of the resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for modification from the configuration. + ConfigValue types.Int64 + + // Plan contains the entire proposed new state of the resource. + Plan tfsdk.Plan + + // PlanValue contains the value of the attribute for modification from the proposed new state. + PlanValue types.Int64 + + // State contains the entire prior state of the resource. + State tfsdk.State + + // StateValue contains the value of the attribute for modification from the prior state. + StateValue types.Int64 + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // Int64Response.Private to prevent accidental private state data loss. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + // + // Use the GetKey method to read data. Use the SetKey method on + // Int64Response.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// Int64Response is a response to a Int64Request. +type Int64Response struct { + // PlanValue is the planned new state for the attribute. + PlanValue types.Int64 + + // RequiresReplace indicates whether a change in the attribute + // requires replacement of the whole resource. + RequiresReplace bool + + // Private is the private state resource data following the PlanModifyInt64 operation. + // This field is pre-populated from Int64Request.Private and + // can be modified during the resource's PlanModifyInt64 operation. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to modifying the resource + // plan. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/list.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/list.go new file mode 100644 index 00000000..dfbff6a8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/list.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package planmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// List is a schema plan modifier for types.List attributes. +type List interface { + Describer + + // PlanModifyList should perform the modification. + PlanModifyList(context.Context, ListRequest, *ListResponse) +} + +// ListRequest is a request for types.List schema plan modification. +type ListRequest struct { + // Path contains the path of the attribute for modification. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for modification. + PathExpression path.Expression + + // Config contains the entire configuration of the resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for modification from the configuration. + ConfigValue types.List + + // Plan contains the entire proposed new state of the resource. + Plan tfsdk.Plan + + // PlanValue contains the value of the attribute for modification from the proposed new state. + PlanValue types.List + + // State contains the entire prior state of the resource. + State tfsdk.State + + // StateValue contains the value of the attribute for modification from the prior state. + StateValue types.List + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // ListResponse.Private to prevent accidental private state data loss. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + // + // Use the GetKey method to read data. Use the SetKey method on + // ListResponse.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// ListResponse is a response to a ListRequest. +type ListResponse struct { + // PlanValue is the planned new state for the attribute. + PlanValue types.List + + // RequiresReplace indicates whether a change in the attribute + // requires replacement of the whole resource. + RequiresReplace bool + + // Private is the private state resource data following the PlanModifyList operation. + // This field is pre-populated from ListRequest.Private and + // can be modified during the resource's PlanModifyList operation. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to modifying the resource + // plan. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/map.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/map.go new file mode 100644 index 00000000..5969d5de --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/map.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package planmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Map is a schema plan modifier for types.Map attributes. +type Map interface { + Describer + + // PlanModifyMap should perform the modification. + PlanModifyMap(context.Context, MapRequest, *MapResponse) +} + +// MapRequest is a request for types.Map schema plan modification. +type MapRequest struct { + // Path contains the path of the attribute for modification. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for modification. + PathExpression path.Expression + + // Config contains the entire configuration of the resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for modification from the configuration. + ConfigValue types.Map + + // Plan contains the entire proposed new state of the resource. + Plan tfsdk.Plan + + // PlanValue contains the value of the attribute for modification from the proposed new state. + PlanValue types.Map + + // State contains the entire prior state of the resource. + State tfsdk.State + + // StateValue contains the value of the attribute for modification from the prior state. + StateValue types.Map + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // MapResponse.Private to prevent accidental private state data loss. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + // + // Use the GetKey method to read data. Use the SetKey method on + // MapResponse.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// MapResponse is a response to a MapRequest. +type MapResponse struct { + // PlanValue is the planned new state for the attribute. + PlanValue types.Map + + // RequiresReplace indicates whether a change in the attribute + // requires replacement of the whole resource. + RequiresReplace bool + + // Private is the private state resource data following the PlanModifyMap operation. + // This field is pre-populated from MapRequest.Private and + // can be modified during the resource's PlanModifyMap operation. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to modifying the resource + // plan. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/number.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/number.go new file mode 100644 index 00000000..44978912 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/number.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package planmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Number is a schema plan modifier for types.Number attributes. +type Number interface { + Describer + + // PlanModifyNumber should perform the modification. + PlanModifyNumber(context.Context, NumberRequest, *NumberResponse) +} + +// NumberRequest is a request for types.Number schema plan modification. +type NumberRequest struct { + // Path contains the path of the attribute for modification. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for modification. + PathExpression path.Expression + + // Config contains the entire configuration of the resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for modification from the configuration. + ConfigValue types.Number + + // Plan contains the entire proposed new state of the resource. + Plan tfsdk.Plan + + // PlanValue contains the value of the attribute for modification from the proposed new state. + PlanValue types.Number + + // State contains the entire prior state of the resource. + State tfsdk.State + + // StateValue contains the value of the attribute for modification from the prior state. + StateValue types.Number + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // NumberResponse.Private to prevent accidental private state data loss. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + // + // Use the GetKey method to read data. Use the SetKey method on + // NumberResponse.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// NumberResponse is a response to a NumberRequest. +type NumberResponse struct { + // PlanValue is the planned new state for the attribute. + PlanValue types.Number + + // RequiresReplace indicates whether a change in the attribute + // requires replacement of the whole resource. + RequiresReplace bool + + // Private is the private state resource data following the PlanModifyNumber operation. + // This field is pre-populated from NumberRequest.Private and + // can be modified during the resource's PlanModifyNumber operation. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to modifying the resource + // plan. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/object.go new file mode 100644 index 00000000..1f426d73 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/object.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package planmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Object is a schema plan modifier for types.Object attributes. +type Object interface { + Describer + + // PlanModifyObject should perform the modification. + PlanModifyObject(context.Context, ObjectRequest, *ObjectResponse) +} + +// ObjectRequest is a request for types.Object schema plan modification. +type ObjectRequest struct { + // Path contains the path of the attribute for modification. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for modification. + PathExpression path.Expression + + // Config contains the entire configuration of the resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for modification from the configuration. + ConfigValue types.Object + + // Plan contains the entire proposed new state of the resource. + Plan tfsdk.Plan + + // PlanValue contains the value of the attribute for modification from the proposed new state. + PlanValue types.Object + + // State contains the entire prior state of the resource. + State tfsdk.State + + // StateValue contains the value of the attribute for modification from the prior state. + StateValue types.Object + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // ObjectResponse.Private to prevent accidental private state data loss. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + // + // Use the GetKey method to read data. Use the SetKey method on + // ObjectResponse.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// ObjectResponse is a response to a ObjectRequest. +type ObjectResponse struct { + // PlanValue is the planned new state for the attribute. + PlanValue types.Object + + // RequiresReplace indicates whether a change in the attribute + // requires replacement of the whole resource. + RequiresReplace bool + + // Private is the private state resource data following the PlanModifyObject operation. + // This field is pre-populated from ObjectRequest.Private and + // can be modified during the resource's PlanModifyObject operation. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to modifying the resource + // plan. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/set.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/set.go new file mode 100644 index 00000000..21e157a7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/set.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package planmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Set is a schema plan modifier for types.Set attributes. +type Set interface { + Describer + + // PlanModifySet should perform the modification. + PlanModifySet(context.Context, SetRequest, *SetResponse) +} + +// SetRequest is a request for types.Set schema plan modification. +type SetRequest struct { + // Path contains the path of the attribute for modification. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for modification. + PathExpression path.Expression + + // Config contains the entire configuration of the resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for modification from the configuration. + ConfigValue types.Set + + // Plan contains the entire proposed new state of the resource. + Plan tfsdk.Plan + + // PlanValue contains the value of the attribute for modification from the proposed new state. + PlanValue types.Set + + // State contains the entire prior state of the resource. + State tfsdk.State + + // StateValue contains the value of the attribute for modification from the prior state. + StateValue types.Set + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // SetResponse.Private to prevent accidental private state data loss. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + // + // Use the GetKey method to read data. Use the SetKey method on + // SetResponse.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// SetResponse is a response to a SetRequest. +type SetResponse struct { + // PlanValue is the planned new state for the attribute. + PlanValue types.Set + + // RequiresReplace indicates whether a change in the attribute + // requires replacement of the whole resource. + RequiresReplace bool + + // Private is the private state resource data following the PlanModifySet operation. + // This field is pre-populated from SetRequest.Private and + // can be modified during the resource's PlanModifySet operation. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to modifying the resource + // plan. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/string.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/string.go new file mode 100644 index 00000000..b8c938c8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier/string.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package planmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// String is a schema plan modifier for types.String attributes. +type String interface { + Describer + + // PlanModifyString should perform the modification. + PlanModifyString(context.Context, StringRequest, *StringResponse) +} + +// StringRequest is a request for types.String schema plan modification. +type StringRequest struct { + // Path contains the path of the attribute for modification. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for modification. + PathExpression path.Expression + + // Config contains the entire configuration of the resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for modification from the configuration. + ConfigValue types.String + + // Plan contains the entire proposed new state of the resource. + Plan tfsdk.Plan + + // PlanValue contains the value of the attribute for modification from the proposed new state. + PlanValue types.String + + // State contains the entire prior state of the resource. + State tfsdk.State + + // StateValue contains the value of the attribute for modification from the prior state. + StateValue types.String + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. This data is opaque to Terraform and does + // not affect plan output. Any existing data is copied to + // StringResponse.Private to prevent accidental private state data loss. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + // + // Use the GetKey method to read data. Use the SetKey method on + // StringResponse.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// StringResponse is a response to a StringRequest. +type StringResponse struct { + // PlanValue is the planned new state for the attribute. + PlanValue types.String + + // RequiresReplace indicates whether a change in the attribute + // requires replacement of the whole resource. + RequiresReplace bool + + // Private is the private state resource data following the PlanModifyString operation. + // This field is pre-populated from StringRequest.Private and + // can be modified during the resource's PlanModifyString operation. + // + // The private state data is always the original data when the schema-based plan + // modification began or, is updated as the logic traverses deeper into underlying + // attributes. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to modifying the resource + // plan. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/schema.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/schema.go new file mode 100644 index 00000000..0f280662 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/schema.go @@ -0,0 +1,211 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Schema must satify the fwschema.Schema interface. +var _ fwschema.Schema = Schema{} + +// Schema defines the structure and value types of resource data. This type +// is used as the resource.SchemaResponse type Schema field, which is +// implemented by the resource.DataSource type Schema method. +type Schema struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Blocks names. + Attributes map[string]Attribute + + // Blocks is the mapping of underlying block names to block definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Attributes names. + Blocks map[string]Block + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this resource is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this resource is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this resource. The warning diagnostic + // summary is automatically set to "Resource Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Use examplecloud_other resource instead. This resource + // will be removed in the next major version of the provider." + // - "Remove this resource as it no longer is valid and + // will be removed in the next major version of the provider." + // + DeprecationMessage string + + // Version indicates the current version of the resource schema. Resource + // schema versioning enables state upgrades in conjunction with the + // [resource.ResourceWithStateUpgrades] interface. Versioning is only + // required if there is a breaking change involving existing state data, + // such as changing an attribute or block type in a manner that is + // incompatible with the Terraform type. + // + // Versions are conventionally only incremented by one each release. + Version int64 +} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// schema. +func (s Schema) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.SchemaApplyTerraform5AttributePathStep(s, step) +} + +// AttributeAtPath returns the Attribute at the passed path. If the path points +// to an element or attribute of a complex type, rather than to an Attribute, +// it will return an ErrPathInsideAtomicAttribute error. +func (s Schema) AttributeAtPath(ctx context.Context, p path.Path) (fwschema.Attribute, diag.Diagnostics) { + return fwschema.SchemaAttributeAtPath(ctx, s, p) +} + +// AttributeAtPath returns the Attribute at the passed path. If the path points +// to an element or attribute of a complex type, rather than to an Attribute, +// it will return an ErrPathInsideAtomicAttribute error. +func (s Schema) AttributeAtTerraformPath(ctx context.Context, p *tftypes.AttributePath) (fwschema.Attribute, error) { + return fwschema.SchemaAttributeAtTerraformPath(ctx, s, p) +} + +// GetAttributes returns the Attributes field value. +func (s Schema) GetAttributes() map[string]fwschema.Attribute { + return schemaAttributes(s.Attributes) +} + +// GetBlocks returns the Blocks field value. +func (s Schema) GetBlocks() map[string]fwschema.Block { + return schemaBlocks(s.Blocks) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (s Schema) GetDeprecationMessage() string { + return s.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (s Schema) GetDescription() string { + return s.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (s Schema) GetMarkdownDescription() string { + return s.MarkdownDescription +} + +// GetVersion returns the Version field value. +func (s Schema) GetVersion() int64 { + return s.Version +} + +// Type returns the framework type of the schema. +func (s Schema) Type() attr.Type { + return fwschema.SchemaType(s) +} + +// TypeAtPath returns the framework type at the given schema path. +func (s Schema) TypeAtPath(ctx context.Context, p path.Path) (attr.Type, diag.Diagnostics) { + return fwschema.SchemaTypeAtPath(ctx, s, p) +} + +// TypeAtTerraformPath returns the framework type at the given tftypes path. +func (s Schema) TypeAtTerraformPath(ctx context.Context, p *tftypes.AttributePath) (attr.Type, error) { + return fwschema.SchemaTypeAtTerraformPath(ctx, s, p) +} + +// Validate verifies that the schema is not using a reserved field name for a top-level attribute. +// +// Deprecated: Use the ValidateImplementation method instead. +func (s Schema) Validate() diag.Diagnostics { + return s.ValidateImplementation(context.Background()) +} + +// ValidateImplementation contains logic for validating the provider-defined +// implementation of the schema and underlying attributes and blocks to prevent +// unexpected errors or panics. This logic runs during the +// ValidateResourceConfig RPC, or via provider-defined unit testing, and should +// never include false positives. +func (s Schema) ValidateImplementation(ctx context.Context) diag.Diagnostics { + var diags diag.Diagnostics + + for attributeName, attribute := range s.GetAttributes() { + req := fwschema.ValidateImplementationRequest{ + Name: attributeName, + Path: path.Root(attributeName), + } + + diags.Append(fwschema.IsReservedResourceAttributeName(req.Name, req.Path)...) + diags.Append(fwschema.ValidateAttributeImplementation(ctx, attribute, req)...) + } + + for blockName, block := range s.GetBlocks() { + req := fwschema.ValidateImplementationRequest{ + Name: blockName, + Path: path.Root(blockName), + } + + diags.Append(fwschema.IsReservedResourceAttributeName(req.Name, req.Path)...) + diags.Append(fwschema.ValidateBlockImplementation(ctx, block, req)...) + } + + return diags +} + +// schemaAttributes is a resource to fwschema type conversion function. +func schemaAttributes(attributes map[string]Attribute) map[string]fwschema.Attribute { + result := make(map[string]fwschema.Attribute, len(attributes)) + + for name, attribute := range attributes { + result[name] = attribute + } + + return result +} + +// schemaBlocks is a resource to fwschema type conversion function. +func schemaBlocks(blocks map[string]Block) map[string]fwschema.Block { + result := make(map[string]fwschema.Block, len(blocks)) + + for name, block := range blocks { + result[name] = block + } + + return result +} + +// nonComputedAttributeWithDefaultDiag returns a diagnostic for use when a non-computed +// attribute is using a default value. +func nonComputedAttributeWithDefaultDiag(path path.Path) diag.Diagnostic { + // The diagnostic path is intentionally omitted as it is invalid in this + // context. Diagnostic paths are intended to be mapped to actual data, + // while this path information must be synthesized. + return diag.NewErrorDiagnostic( + "Schema Using Attribute Default For Non-Computed Attribute", + fmt.Sprintf("Attribute %q must be computed when using default. ", path.String())+ + "This is an issue with the provider and should be reported to the provider developers.", + ) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_attribute.go new file mode 100644 index 00000000..7a54221b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_attribute.go @@ -0,0 +1,287 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = SetAttribute{} + _ fwschema.AttributeWithValidateImplementation = SetAttribute{} + _ fwschema.AttributeWithSetDefaultValue = SetAttribute{} + _ fwxschema.AttributeWithSetPlanModifiers = SetAttribute{} + _ fwxschema.AttributeWithSetValidators = SetAttribute{} +) + +// SetAttribute represents a schema attribute that is a set with a single +// element type. When retrieving the value for this attribute, use types.Set +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// Use SetNestedAttribute if the underlying elements should be objects and +// require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set or directly via square brace syntax. +// +// # set of strings +// example_attribute = ["first", "second"] +// +// Terraform configurations reference this attribute using expressions that +// accept a set. Sets cannot be indexed in Terraform, therefore an expression +// is required to access an explicit element. +type SetAttribute struct { + // ElementType is the type for all elements of the set. This field must be + // set. + // + // Element types that contain a dynamic type (i.e. types.Dynamic) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.SetType. When retrieving data, the basetypes.SetValuable + // associated with this custom type must be used in place of types.Set. + CustomType basetypes.SetTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Set + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Set + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.Set +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a set +// index or an error. +func (a SetAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a SetAttribute +// and all fields are equal. +func (a SetAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(SetAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a SetAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a SetAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SetAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.SetType or the CustomType field value if defined. +func (a SetAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.SetType{ + ElemType: a.ElementType, + } +} + +// IsComputed returns the Computed field value. +func (a SetAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a SetAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SetAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a SetAttribute) IsSensitive() bool { + return a.Sensitive +} + +// SetDefaultValue returns the Default field value. +func (a SetAttribute) SetDefaultValue() defaults.Set { + return a.Default +} + +// SetPlanModifiers returns the PlanModifiers field value. +func (a SetAttribute) SetPlanModifiers() []planmodifier.Set { + return a.PlanModifiers +} + +// SetValidators returns the Validators field value. +func (a SetAttribute) SetValidators() []validator.Set { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a SetAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } + + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } + + if a.SetDefaultValue() != nil { + if !a.IsComputed() { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } + + // Validate Default implementation. This is safe unless the framework + // ever allows more dynamic Default implementations at which the + // implementation would be required to be validated at runtime. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/930 + defaultReq := defaults.SetRequest{ + Path: req.Path, + } + defaultResp := &defaults.SetResponse{} + + a.SetDefaultValue().DefaultSet(ctx, defaultReq, defaultResp) + + resp.Diagnostics.Append(defaultResp.Diagnostics...) + + if defaultResp.Diagnostics.HasError() { + return + } + + if a.ElementType != nil && !a.ElementType.Equal(defaultResp.PlanValue.ElementType(ctx)) { + resp.Diagnostics.Append(fwschema.AttributeDefaultElementTypeMismatchDiag(req.Path, a.ElementType, defaultResp.PlanValue.ElementType(ctx))) + } + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_nested_attribute.go new file mode 100644 index 00000000..3f2b3d1b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_nested_attribute.go @@ -0,0 +1,308 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = SetNestedAttribute{} + _ fwschema.AttributeWithValidateImplementation = SetNestedAttribute{} + _ fwschema.AttributeWithSetDefaultValue = SetNestedAttribute{} + _ fwxschema.AttributeWithSetPlanModifiers = SetNestedAttribute{} + _ fwxschema.AttributeWithSetValidators = SetNestedAttribute{} +) + +// SetNestedAttribute represents an attribute that is a set of objects where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Set +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use SetAttribute if the underlying elements are of a single type and do +// not require definition beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return a set of objects or directly via square and curly brace syntax. +// +// # set of objects +// example_attribute = [ +// { +// nested_attribute = #... +// }, +// ] +// +// Terraform configurations reference this attribute using expressions that +// accept a set of objects. Sets cannot be indexed in Terraform, therefore +// an expression is required to access an explicit element. +type SetNestedAttribute struct { + // NestedObject is the underlying object that contains nested attributes. + // This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this attribute definition with + // DynamicAttribute instead. + NestedObject NestedAttributeObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.SetType of types.ObjectType. When retrieving data, the + // basetypes.SetValuable associated with this custom type must be used in + // place of types.Set. + CustomType basetypes.SetTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Set + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Set + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.Set +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is ElementKeyValue, otherwise returns an error. +func (a SetNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyValue) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SetNestedAttribute", step) + } + + return a.NestedObject, nil +} + +// Equal returns true if the given Attribute is a SetNestedAttribute +// and all fields are equal. +func (a SetNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(SetNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a SetNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a SetNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SetNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (a SetNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return a.NestedObject +} + +// GetNestingMode always returns NestingModeList. +func (a SetNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeSet +} + +// GetType returns SetType of ObjectType or CustomType. +func (a SetNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.SetType{ + ElemType: a.NestedObject.Type(), + } +} + +// IsComputed returns the Computed field value. +func (a SetNestedAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a SetNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SetNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a SetNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// SetDefaultValue returns the Default field value. +func (a SetNestedAttribute) SetDefaultValue() defaults.Set { + return a.Default +} + +// SetPlanModifiers returns the PlanModifiers field value. +func (a SetNestedAttribute) SetPlanModifiers() []planmodifier.Set { + return a.PlanModifiers +} + +// SetValidators returns the Validators field value. +func (a SetNestedAttribute) SetValidators() []validator.Set { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a SetNestedAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + } + + if a.SetDefaultValue() != nil { + if !a.IsComputed() { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } + + // Validate Default implementation. This is safe unless the framework + // ever allows more dynamic Default implementations at which the + // implementation would be required to be validated at runtime. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/930 + defaultReq := defaults.SetRequest{ + Path: req.Path, + } + defaultResp := &defaults.SetResponse{} + + a.SetDefaultValue().DefaultSet(ctx, defaultReq, defaultResp) + + resp.Diagnostics.Append(defaultResp.Diagnostics...) + + if defaultResp.Diagnostics.HasError() { + return + } + + if a.CustomType == nil && a.NestedObject.CustomType == nil && !a.NestedObject.Type().Equal(defaultResp.PlanValue.ElementType(ctx)) { + resp.Diagnostics.Append(fwschema.AttributeDefaultElementTypeMismatchDiag(req.Path, a.NestedObject.Type(), defaultResp.PlanValue.ElementType(ctx))) + } + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_nested_block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_nested_block.go new file mode 100644 index 00000000..78de8afb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/set_nested_block.go @@ -0,0 +1,229 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwtype" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Block = SetNestedBlock{} + _ fwschema.BlockWithValidateImplementation = SetNestedBlock{} + _ fwxschema.BlockWithSetPlanModifiers = SetNestedBlock{} + _ fwxschema.BlockWithSetValidators = SetNestedBlock{} +) + +// SetNestedBlock represents a block that is a set of objects where +// the object attributes can be fully defined, including further attributes +// or blocks. When retrieving the value for this block, use types.Set +// as the value type unless the CustomType field is set. The NestedObject field +// must be set. +// +// Prefer SetNestedAttribute over SetNestedBlock if the provider is +// using protocol version 6. Nested attributes allow practitioners to configure +// values directly with expressions. +// +// Terraform configurations configure this block repeatedly using curly brace +// syntax without an equals (=) sign or [Dynamic Block Expressions]. +// +// # set of blocks with two elements +// example_block { +// nested_attribute = #... +// } +// example_block { +// nested_attribute = #... +// } +// +// Terraform configurations reference this block using expressions that +// accept a set of objects or an element directly via square brace 0-based +// index syntax: +// +// # first known object +// .example_block[0] +// # first known object nested_attribute value +// .example_block[0].nested_attribute +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +type SetNestedBlock struct { + // NestedObject is the underlying object that contains nested attributes or + // blocks. This field must be set. + // + // Nested attributes that contain a dynamic type (i.e. DynamicAttribute) are not supported. + // If underlying dynamic values are required, replace this block definition with + // a DynamicAttribute. + NestedObject NestedBlockObject + + // CustomType enables the use of a custom attribute type in place of the + // default types.SetType of types.ObjectType. When retrieving data, the + // basetypes.SetValuable associated with this custom type must be used in + // place of types.Set. + CustomType basetypes.SetTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Set + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Set +} + +// ApplyTerraform5AttributePathStep returns the NestedObject field value if step +// is ElementKeyValue, otherwise returns an error. +func (b SetNestedBlock) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + _, ok := step.(tftypes.ElementKeyValue) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SetNestedBlock", step) + } + + return b.NestedObject, nil +} + +// Equal returns true if the given Block is SetNestedBlock +// and all fields are equal. +func (b SetNestedBlock) Equal(o fwschema.Block) bool { + if _, ok := o.(SetNestedBlock); !ok { + return false + } + + return fwschema.BlocksEqual(b, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (b SetNestedBlock) GetDeprecationMessage() string { + return b.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (b SetNestedBlock) GetDescription() string { + return b.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (b SetNestedBlock) GetMarkdownDescription() string { + return b.MarkdownDescription +} + +// GetNestedObject returns the NestedObject field value. +func (b SetNestedBlock) GetNestedObject() fwschema.NestedBlockObject { + return b.NestedObject +} + +// GetNestingMode always returns BlockNestingModeSet. +func (b SetNestedBlock) GetNestingMode() fwschema.BlockNestingMode { + return fwschema.BlockNestingModeSet +} + +// SetPlanModifiers returns the PlanModifiers field value. +func (b SetNestedBlock) SetPlanModifiers() []planmodifier.Set { + return b.PlanModifiers +} + +// SetValidators returns the Validators field value. +func (b SetNestedBlock) SetValidators() []validator.Set { + return b.Validators +} + +// Type returns SetType of ObjectType or CustomType. +func (b SetNestedBlock) Type() attr.Type { + if b.CustomType != nil { + return b.CustomType + } + + return types.SetType{ + ElemType: b.NestedObject.Type(), + } +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the block to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (b SetNestedBlock) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if b.CustomType == nil && fwtype.ContainsCollectionWithDynamic(b.Type()) { + resp.Diagnostics.Append(fwtype.BlockCollectionWithDynamicTypeDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/single_nested_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/single_nested_attribute.go new file mode 100644 index 00000000..a47ef654 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/single_nested_attribute.go @@ -0,0 +1,324 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ NestedAttribute = SingleNestedAttribute{} + _ fwschema.AttributeWithValidateImplementation = SingleNestedAttribute{} + _ fwschema.AttributeWithObjectDefaultValue = SingleNestedAttribute{} + _ fwxschema.AttributeWithObjectPlanModifiers = SingleNestedAttribute{} + _ fwxschema.AttributeWithObjectValidators = SingleNestedAttribute{} +) + +// SingleNestedAttribute represents an attribute that is a single object where +// the object attributes can be fully defined, including further nested +// attributes. When retrieving the value for this attribute, use types.Object +// as the value type unless the CustomType field is set. The Attributes field +// must be set. Nested attributes are only compatible with protocol version 6. +// +// Use ObjectAttribute if the underlying attributes do not require definition +// beyond type information. +// +// Terraform configurations configure this attribute using expressions that +// return an object or directly via curly brace syntax. +// +// # single object +// example_attribute = { +// nested_attribute = #... +// } +// +// Terraform configurations reference this attribute using expressions that +// accept an object or an attribute name directly via period syntax: +// +// # object nested_attribute value +// .example_attribute.nested_attribute +type SingleNestedAttribute struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. This field must be set. + Attributes map[string]Attribute + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Object + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.Object +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is AttributeName, otherwise returns an error. +func (a SingleNestedAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + name, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SingleNestedAttribute", step) + } + + attribute, ok := a.Attributes[string(name)] + + if !ok { + return nil, fmt.Errorf("no attribute %q on SingleNestedAttribute", name) + } + + return attribute, nil +} + +// Equal returns true if the given Attribute is a SingleNestedAttribute +// and all fields are equal. +func (a SingleNestedAttribute) Equal(o fwschema.Attribute) bool { + other, ok := o.(SingleNestedAttribute) + + if !ok { + return false + } + + return fwschema.NestedAttributesEqual(a, other) +} + +// GetAttributes returns the Attributes field value. +func (a SingleNestedAttribute) GetAttributes() fwschema.UnderlyingAttributes { + return schemaAttributes(a.Attributes) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a SingleNestedAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a SingleNestedAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a SingleNestedAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetNestedObject returns a generated NestedAttributeObject from the +// Attributes, CustomType, and Validators field values. +func (a SingleNestedAttribute) GetNestedObject() fwschema.NestedAttributeObject { + return NestedAttributeObject{ + Attributes: a.Attributes, + CustomType: a.CustomType, + Validators: a.Validators, + } +} + +// GetNestingMode always returns NestingModeList. +func (a SingleNestedAttribute) GetNestingMode() fwschema.NestingMode { + return fwschema.NestingModeSingle +} + +// GetType returns ListType of ObjectType or CustomType. +func (a SingleNestedAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + attrTypes := make(map[string]attr.Type, len(a.Attributes)) + + for name, attribute := range a.Attributes { + attrTypes[name] = attribute.GetType() + } + + return types.ObjectType{ + AttrTypes: attrTypes, + } +} + +// IsComputed returns the Computed field value. +func (a SingleNestedAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a SingleNestedAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a SingleNestedAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a SingleNestedAttribute) IsSensitive() bool { + return a.Sensitive +} + +// ObjectDefaultValue returns the Default field value. +func (a SingleNestedAttribute) ObjectDefaultValue() defaults.Object { + return a.Default +} + +// ObjectPlanModifiers returns the PlanModifiers field value. +func (a SingleNestedAttribute) ObjectPlanModifiers() []planmodifier.Object { + return a.PlanModifiers +} + +// ObjectValidators returns the Validators field value. +func (a SingleNestedAttribute) ObjectValidators() []validator.Object { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a SingleNestedAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if !a.IsComputed() && a.ObjectDefaultValue() != nil { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } + + if a.ObjectDefaultValue() != nil { + if !a.IsComputed() { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } + + // Validate Default implementation. This is safe unless the framework + // ever allows more dynamic Default implementations at which the + // implementation would be required to be validated at runtime. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/930 + defaultReq := defaults.ObjectRequest{ + Path: req.Path, + } + defaultResp := &defaults.ObjectResponse{} + + a.ObjectDefaultValue().DefaultObject(ctx, defaultReq, defaultResp) + + resp.Diagnostics.Append(defaultResp.Diagnostics...) + + if defaultResp.Diagnostics.HasError() { + return + } + + if a.CustomType == nil && !a.GetType().Equal(defaultResp.PlanValue.Type(ctx)) { + resp.Diagnostics.Append(fwschema.AttributeDefaultTypeMismatchDiag(req.Path, a.GetType(), defaultResp.PlanValue.Type(ctx))) + } + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/single_nested_block.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/single_nested_block.go new file mode 100644 index 00000000..d44530cc --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/single_nested_block.go @@ -0,0 +1,237 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Ensure the implementation satisifies the desired interfaces. +var ( + _ Block = SingleNestedBlock{} + _ fwxschema.BlockWithObjectPlanModifiers = SingleNestedBlock{} + _ fwxschema.BlockWithObjectValidators = SingleNestedBlock{} +) + +// SingleNestedBlock represents a block that is a single object where +// the object attributes can be fully defined, including further attributes +// or blocks. When retrieving the value for this block, use types.Object +// as the value type unless the CustomType field is set. +// +// Prefer SingleNestedAttribute over SingleNestedBlock if the provider is +// using protocol version 6. Nested attributes allow practitioners to configure +// values directly with expressions. +// +// Terraform configurations configure this block only once using curly brace +// syntax without an equals (=) sign or [Dynamic Block Expressions]. +// +// # single block +// example_block { +// nested_attribute = #... +// } +// +// Terraform configurations reference this block using expressions that +// accept an object or an attribute name directly via period syntax: +// +// # object nested_attribute value +// .example_block.nested_attribute +// +// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks +type SingleNestedBlock struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Blocks names. + Attributes map[string]Attribute + + // Blocks is the mapping of underlying block names to block definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + // Names must not collide with any Attributes names. + Blocks map[string]Block + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable + // associated with this custom type must be used in place of types.Object. + CustomType basetypes.ObjectTypable + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.Object + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.Object +} + +// ApplyTerraform5AttributePathStep returns the Attributes field value if step +// is AttributeName, otherwise returns an error. +func (b SingleNestedBlock) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + name, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to SingleNestedBlock", step) + } + + if attribute, ok := b.Attributes[string(name)]; ok { + return attribute, nil + } + + if block, ok := b.Blocks[string(name)]; ok { + return block, nil + } + + return nil, fmt.Errorf("no attribute or block %q on SingleNestedBlock", name) +} + +// Equal returns true if the given Attribute is b SingleNestedBlock +// and all fields are equal. +func (b SingleNestedBlock) Equal(o fwschema.Block) bool { + if _, ok := o.(SingleNestedBlock); !ok { + return false + } + + return fwschema.BlocksEqual(b, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (b SingleNestedBlock) GetDeprecationMessage() string { + return b.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (b SingleNestedBlock) GetDescription() string { + return b.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (b SingleNestedBlock) GetMarkdownDescription() string { + return b.MarkdownDescription +} + +// GetNestedObject returns a generated NestedBlockObject from the +// Attributes, CustomType, and Validators field values. +func (b SingleNestedBlock) GetNestedObject() fwschema.NestedBlockObject { + return NestedBlockObject{ + Attributes: b.Attributes, + Blocks: b.Blocks, + CustomType: b.CustomType, + Validators: b.Validators, + } +} + +// GetNestingMode always returns BlockNestingModeSingle. +func (b SingleNestedBlock) GetNestingMode() fwschema.BlockNestingMode { + return fwschema.BlockNestingModeSingle +} + +// ObjectPlanModifiers returns the PlanModifiers field value. +func (b SingleNestedBlock) ObjectPlanModifiers() []planmodifier.Object { + return b.PlanModifiers +} + +// ObjectValidators returns the Validators field value. +func (b SingleNestedBlock) ObjectValidators() []validator.Object { + return b.Validators +} + +// Type returns ObjectType or CustomType. +func (b SingleNestedBlock) Type() attr.Type { + if b.CustomType != nil { + return b.CustomType + } + + attrTypes := make(map[string]attr.Type, len(b.Attributes)+len(b.Blocks)) + + for name, attribute := range b.Attributes { + attrTypes[name] = attribute.GetType() + } + + for name, block := range b.Blocks { + attrTypes[name] = block.Type() + } + + return types.ObjectType{ + AttrTypes: attrTypes, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/string_attribute.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/string_attribute.go new file mode 100644 index 00000000..7e3b8a1c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/string_attribute.go @@ -0,0 +1,240 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = StringAttribute{} + _ fwschema.AttributeWithValidateImplementation = StringAttribute{} + _ fwschema.AttributeWithStringDefaultValue = StringAttribute{} + _ fwxschema.AttributeWithStringPlanModifiers = StringAttribute{} + _ fwxschema.AttributeWithStringValidators = StringAttribute{} +) + +// StringAttribute represents a schema attribute that is a string. When +// retrieving the value for this attribute, use types.String as the value type +// unless the CustomType field is set. +// +// Terraform configurations configure this attribute using expressions that +// return a string or directly via double quote syntax. +// +// example_attribute = "value" +// +// Terraform configurations reference this attribute using the attribute name. +// +// .example_attribute +type StringAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.StringType. When retrieving data, the basetypes.StringValuable + // associated with this custom type must be used in place of types.String. + CustomType basetypes.StringTypable + + // Required indicates whether the practitioner must enter a value for + // this attribute or not. Required and Optional cannot both be true, + // and Required and Computed cannot both be true. + Required bool + + // Optional indicates whether the practitioner can choose to enter a value + // for this attribute or not. Optional and Required cannot both be true. + Optional bool + + // Computed indicates whether the provider may return its own value for + // this Attribute or not. Required and Computed cannot both be true. If + // Required and Optional are both false, Computed must be true, and the + // attribute will be considered "read only" for the practitioner, with + // only the provider able to set its value. + Computed bool + + // Sensitive indicates whether the value of this attribute should be + // considered sensitive data. Setting it to true will obscure the value + // in CLI output. Sensitive does not impact how values are stored, and + // practitioners are encouraged to store their state as if the entire + // file is sensitive. + Sensitive bool + + // Description is used in various tooling, like the language server, to + // give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It should be written as + // plain text, with no special formatting. + Description string + + // MarkdownDescription is used in various tooling, like the + // documentation generator, to give practitioners more information + // about what this attribute is, what it's for, and how it should be + // used. It should be formatted using Markdown. + MarkdownDescription string + + // DeprecationMessage defines warning diagnostic details to display when + // practitioner configurations use this Attribute. The warning diagnostic + // summary is automatically set to "Attribute Deprecated" along with + // configuration source file and line information. + // + // Set this field to a practitioner actionable message such as: + // + // - "Configure other_attribute instead. This attribute will be removed + // in the next major version of the provider." + // - "Remove this attribute's configuration as it no longer is used and + // the attribute will be removed in the next major version of the + // provider." + // + // In Terraform 1.2.7 and later, this warning diagnostic is displayed any + // time a practitioner attempts to configure a value for this attribute and + // certain scenarios where this attribute is referenced. + // + // In Terraform 1.2.6 and earlier, this warning diagnostic is only + // displayed when the Attribute is Required or Optional, and if the + // practitioner configuration sets the value to a known or unknown value + // (which may eventually be null). It has no effect when the Attribute is + // Computed-only (read-only; not Required or Optional). + // + // Across any Terraform version, there are no warnings raised for + // practitioner configuration values set directly to null, as there is no + // way for the framework to differentiate between an unset and null + // configuration due to how Terraform sends configuration information + // across the protocol. + // + // Additional information about deprecation enhancements for read-only + // attributes can be found in: + // + // - https://github.com/hashicorp/terraform/issues/7569 + // + DeprecationMessage string + + // Validators define value validation functionality for the attribute. All + // elements of the slice of AttributeValidator are run, regardless of any + // previous error diagnostics. + // + // Many common use case validators can be found in the + // github.com/hashicorp/terraform-plugin-framework-validators Go module. + // + // If the Type field points to a custom type that implements the + // xattr.TypeWithValidate interface, the validators defined in this field + // are run in addition to the validation defined by the type. + Validators []validator.String + + // PlanModifiers defines a sequence of modifiers for this attribute at + // plan time. Schema-based plan modifications occur before any + // resource-level plan modifications. + // + // Schema-based plan modifications can adjust Terraform's plan by: + // + // - Requiring resource recreation. Typically used for configuration + // updates which cannot be done in-place. + // - Setting the planned value. Typically used for enhancing the plan + // to replace unknown values. Computed must be true or Terraform will + // return an error. If the plan value is known due to a known + // configuration value, the plan value cannot be changed or Terraform + // will return an error. + // + // Any errors will prevent further execution of this sequence or modifiers. + PlanModifiers []planmodifier.String + + // Default defines a proposed new state (plan) value for the attribute + // if the configuration value is null. Default prevents the framework + // from automatically marking the value as unknown during planning when + // other proposed new state changes are detected. If the attribute is + // computed and the value could be altered by other changes then a default + // should be avoided and a plan modifier should be used instead. + Default defaults.String +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a StringAttribute. +func (a StringAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a StringAttribute +// and all fields are equal. +func (a StringAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(StringAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns the DeprecationMessage field value. +func (a StringAttribute) GetDeprecationMessage() string { + return a.DeprecationMessage +} + +// GetDescription returns the Description field value. +func (a StringAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the MarkdownDescription field value. +func (a StringAttribute) GetMarkdownDescription() string { + return a.MarkdownDescription +} + +// GetType returns types.StringType or the CustomType field value if defined. +func (a StringAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.StringType +} + +// IsComputed returns the Computed field value. +func (a StringAttribute) IsComputed() bool { + return a.Computed +} + +// IsOptional returns the Optional field value. +func (a StringAttribute) IsOptional() bool { + return a.Optional +} + +// IsRequired returns the Required field value. +func (a StringAttribute) IsRequired() bool { + return a.Required +} + +// IsSensitive returns the Sensitive field value. +func (a StringAttribute) IsSensitive() bool { + return a.Sensitive +} + +// StringDefaultValue returns the Default field value. +func (a StringAttribute) StringDefaultValue() defaults.String { + return a.Default +} + +// StringPlanModifiers returns the PlanModifiers field value. +func (a StringAttribute) StringPlanModifiers() []planmodifier.String { + return a.PlanModifiers +} + +// StringValidators returns the Validators field value. +func (a StringAttribute) StringValidators() []validator.String { + return a.Validators +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetProviderSchema RPC and +// should never include false positives. +func (a StringAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if !a.IsComputed() && a.StringDefaultValue() != nil { + resp.Diagnostics.Append(nonComputedAttributeWithDefaultDiag(req.Path)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault/doc.go new file mode 100644 index 00000000..c1ca3989 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault/doc.go @@ -0,0 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package stringdefault provides default values for types.String attributes. +package stringdefault diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault/static_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault/static_value.go new file mode 100644 index 00000000..deb2965b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault/static_value.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringdefault + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// StaticString returns a static string value default handler. +// +// Use StaticString if a static default value for a string should be set. +func StaticString(defaultVal string) defaults.String { + return staticStringDefault{ + defaultVal: defaultVal, + } +} + +// staticStringDefault is static value default handler that +// sets a value on a string attribute. +type staticStringDefault struct { + defaultVal string +} + +// Description returns a human-readable description of the default value handler. +func (d staticStringDefault) Description(_ context.Context) string { + return fmt.Sprintf("value defaults to %s", d.defaultVal) +} + +// MarkdownDescription returns a markdown description of the default value handler. +func (d staticStringDefault) MarkdownDescription(_ context.Context) string { + return fmt.Sprintf("value defaults to `%s`", d.defaultVal) +} + +// DefaultString implements the static default value logic. +func (d staticStringDefault) DefaultString(_ context.Context, req defaults.StringRequest, resp *defaults.StringResponse) { + resp.PlanValue = types.StringValue(d.defaultVal) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/doc.go new file mode 100644 index 00000000..6bbbb660 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/doc.go @@ -0,0 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package stringplanmodifier provides plan modifiers for types.String attributes. +package stringplanmodifier diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace.go new file mode 100644 index 00000000..e3adb4b9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringplanmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// RequiresReplace returns a plan modifier that conditionally requires +// resource replacement if: +// +// - The resource is planned for update. +// - The plan and state values are not equal. +// +// Use RequiresReplaceIfConfigured if the resource replacement should +// only occur if there is a configuration value (ignore unconfigured drift +// detection changes). Use RequiresReplaceIf if the resource replacement +// should check provider-defined conditional logic. +func RequiresReplace() planmodifier.String { + return RequiresReplaceIf( + func(_ context.Context, _ planmodifier.StringRequest, resp *RequiresReplaceIfFuncResponse) { + resp.RequiresReplace = true + }, + "If the value of this attribute changes, Terraform will destroy and recreate the resource.", + "If the value of this attribute changes, Terraform will destroy and recreate the resource.", + ) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if.go new file mode 100644 index 00000000..0afe6ceb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if.go @@ -0,0 +1,73 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringplanmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// RequiresReplaceIf returns a plan modifier that conditionally requires +// resource replacement if: +// +// - The resource is planned for update. +// - The plan and state values are not equal. +// - The given function returns true. Returning false will not unset any +// prior resource replacement. +// +// Use RequiresReplace if the resource replacement should always occur on value +// changes. Use RequiresReplaceIfConfigured if the resource replacement should +// occur on value changes, but only if there is a configuration value (ignore +// unconfigured drift detection changes). +func RequiresReplaceIf(f RequiresReplaceIfFunc, description, markdownDescription string) planmodifier.String { + return requiresReplaceIfModifier{ + ifFunc: f, + description: description, + markdownDescription: markdownDescription, + } +} + +// requiresReplaceIfModifier is an plan modifier that sets RequiresReplace +// on the attribute if a given function is true. +type requiresReplaceIfModifier struct { + ifFunc RequiresReplaceIfFunc + description string + markdownDescription string +} + +// Description returns a human-readable description of the plan modifier. +func (m requiresReplaceIfModifier) Description(_ context.Context) string { + return m.description +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m requiresReplaceIfModifier) MarkdownDescription(_ context.Context) string { + return m.markdownDescription +} + +// PlanModifyString implements the plan modification logic. +func (m requiresReplaceIfModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { + // Do not replace on resource creation. + if req.State.Raw.IsNull() { + return + } + + // Do not replace on resource destroy. + if req.Plan.Raw.IsNull() { + return + } + + // Do not replace if the plan and state values are equal. + if req.PlanValue.Equal(req.StateValue) { + return + } + + ifFuncResp := &RequiresReplaceIfFuncResponse{} + + m.ifFunc(ctx, req, ifFuncResp) + + resp.Diagnostics.Append(ifFuncResp.Diagnostics...) + resp.RequiresReplace = ifFuncResp.RequiresReplace +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if_configured.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if_configured.go new file mode 100644 index 00000000..e1bf461d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if_configured.go @@ -0,0 +1,34 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringplanmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// RequiresReplaceIfConfigured returns a plan modifier that conditionally requires +// resource replacement if: +// +// - The resource is planned for update. +// - The plan and state values are not equal. +// - The configuration value is not null. +// +// Use RequiresReplace if the resource replacement should occur regardless of +// the presence of a configuration value. Use RequiresReplaceIf if the resource +// replacement should check provider-defined conditional logic. +func RequiresReplaceIfConfigured() planmodifier.String { + return RequiresReplaceIf( + func(_ context.Context, req planmodifier.StringRequest, resp *RequiresReplaceIfFuncResponse) { + if req.ConfigValue.IsNull() { + return + } + + resp.RequiresReplace = true + }, + "If the value of this attribute is configured and changes, Terraform will destroy and recreate the resource.", + "If the value of this attribute is configured and changes, Terraform will destroy and recreate the resource.", + ) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if_func.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if_func.go new file mode 100644 index 00000000..bde13cb3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/requires_replace_if_func.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringplanmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// RequiresReplaceIfFunc is a conditional function used in the RequiresReplaceIf +// plan modifier to determine whether the attribute requires replacement. +type RequiresReplaceIfFunc func(context.Context, planmodifier.StringRequest, *RequiresReplaceIfFuncResponse) + +// RequiresReplaceIfFuncResponse is the response type for a RequiresReplaceIfFunc. +type RequiresReplaceIfFuncResponse struct { + // Diagnostics report errors or warnings related to this logic. An empty + // or unset slice indicates success, with no warnings or errors generated. + Diagnostics diag.Diagnostics + + // RequiresReplace should be enabled if the resource should be replaced. + RequiresReplace bool +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/use_state_for_unknown.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/use_state_for_unknown.go new file mode 100644 index 00000000..983bc5cb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier/use_state_for_unknown.go @@ -0,0 +1,55 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringplanmodifier + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// UseStateForUnknown returns a plan modifier that copies a known prior state +// value into the planned value. Use this when it is known that an unconfigured +// value will remain the same after a resource update. +// +// To prevent Terraform errors, the framework automatically sets unconfigured +// and Computed attributes to an unknown value "(known after apply)" on update. +// Using this plan modifier will instead display the prior state value in the +// plan, unless a prior plan modifier adjusts the value. +func UseStateForUnknown() planmodifier.String { + return useStateForUnknownModifier{} +} + +// useStateForUnknownModifier implements the plan modifier. +type useStateForUnknownModifier struct{} + +// Description returns a human-readable description of the plan modifier. +func (m useStateForUnknownModifier) Description(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m useStateForUnknownModifier) MarkdownDescription(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// PlanModifyString implements the plan modification logic. +func (m useStateForUnknownModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { + // Do nothing if there is no state value. + if req.StateValue.IsNull() { + return + } + + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up. + if req.ConfigValue.IsUnknown() { + return + } + + resp.PlanValue = req.StateValue +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/state_mover.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/state_mover.go new file mode 100644 index 00000000..d7fec01c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/state_mover.go @@ -0,0 +1,69 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema" +) + +// Implementation handler for a state move operation. After determining the +// source resource is supported, this should encapsulate all data transformation +// logic from a source resource to the current schema version of this +// [Resource]. The [Resource] is connected to these implementations by +// implementing the [ResourceWithMoveState] interface. +// +// This functionality is only available in Terraform 1.8 or later. It is invoked +// when a configuration contains a `moved` configuration block where the source +// resource type in the `from` argument differs from the target resource type in +// the `to` argument, causing Terraform to call this provider operation and the +// framework to route the request to this [Resource] as the target. +// +// Each implementation is responsible for determining whether the request should +// be handled or skipped. The implementation is considered skipped by the +// framework when the response contains no error diagnostics or state. +// Otherwise, any error diagnostics or state data, will cause the framework to +// consider the request completed and not call other [StateMover] +// implementations. The framework will return an implementation not found error +// if all implementations return responses without error diagnostics or state. +type StateMover struct { + // SourceSchema is an optional schema for the intended source resource state + // and schema version. While not required, setting this will populate + // [MoveStateRequest.SourceState] when possible similar to other [Resource] + // types. + // + // State conversion errors based on this schema are only logged at DEBUG + // level as there may be multiple [StateMover] implementations on the same + // target resource for differing source resources. The [StateMover] + // implementation will still be called even with these errors, so it is + // important that implementations verify the request via the + // [MoveStateRequest.SourceTypeName] and other fields before attempting + // to use [MoveStateRequest.SourceState]. + // + // If not set, source state data is only available in + // [MoveStateRequest.SourceRawState]. + SourceSchema *schema.Schema + + // StateMove defines the logic for determining whether the request source + // resource information should match this implementation, and if so, the + // data transformation of the source resource state to the current schema + // version state of this [Resource]. + // + // The [context.Context] parameter contains framework-defined loggers and + // supports request cancellation. + // + // The [MoveStateRequest] parameter contains source resource information. + // If [SourceSchema] was set, the [MoveStateRequest.SourceState] field will + // be available. Otherwise, the [MoveStateRequest.SourceRawState] must be + // used. + // + // The [MoveStateResponse] parameter can either remain unmodified to signal + // to the framework that this implementation should be considered skipped or + // must contain the transformed state data to signal a successful move. Any + // returned error diagnostics will cause the framework to immediately + // respond with those errors and without calling other [StateMover] + // implementations. + StateMover func(context.Context, MoveStateRequest, *MoveStateResponse) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/state_upgrader.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/state_upgrader.go new file mode 100644 index 00000000..11ba5000 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/state_upgrader.go @@ -0,0 +1,39 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" +) + +// Implementation handler for a UpgradeState operation. +// +// This is used to encapsulate all upgrade logic from a prior state to the +// current schema version when a Resource implements the +// ResourceWithUpgradeState interface. +type StateUpgrader struct { + // Schema information for the prior state version. While not required, + // setting this will populate the UpgradeStateRequest type State + // field similar to other Resource data types. This allows for easier data + // handling such as calling Get() or GetAttribute(). + // + // If not set, prior state data is available in the + // UpgradeResourceStateRequest type RawState field. + PriorSchema *schema.Schema + + // Provider defined logic for upgrading a resource state from the prior + // state version to the current schema version. + // + // The context.Context parameter contains framework-defined loggers and + // supports request cancellation. + // + // The UpgradeStateRequest parameter contains the prior state data. + // If PriorSchema was set, the State field will be available. Otherwise, + // the RawState must be used. + // + // The UpgradeStateResponse parameter should contain the upgraded + // state data and can be used to signal any logic warnings or errors. + StateUpgrader func(context.Context, UpgradeStateRequest, *UpgradeStateResponse) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/update.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/update.go new file mode 100644 index 00000000..0dceaf8a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/update.go @@ -0,0 +1,61 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/privatestate" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// UpdateRequest represents a request for the provider to update a +// resource. An instance of this request struct is supplied as an argument to +// the resource's Update function. +type UpdateRequest struct { + // Config is the configuration the user supplied for the resource. + // + // This configuration may contain unknown values if a user uses + // interpolation or other functionality that would prevent Terraform + // from knowing the value at request time. + Config tfsdk.Config + + // Plan is the planned state for the resource. + Plan tfsdk.Plan + + // State is the current state of the resource prior to the Update + // operation. + State tfsdk.State + + // ProviderMeta is metadata from the provider_meta block of the module. + ProviderMeta tfsdk.Config + + // Private is provider-defined resource private state data which was previously + // stored with the resource state. Any existing data is copied to + // UpdateResponse.Private to prevent accidental private state data loss. + // + // Use the GetKey method to read data. Use the SetKey method on + // UpdateResponse.Private to update or remove a value. + Private *privatestate.ProviderData +} + +// UpdateResponse represents a response to an UpdateRequest. An +// instance of this response struct is supplied as +// an argument to the resource's Update function, in which the provider +// should set values on the UpdateResponse as appropriate. +type UpdateResponse struct { + // State is the state of the resource following the Update operation. + // This field is pre-populated from UpdateResourceRequest.Plan and + // should be set during the resource's Update operation. + State tfsdk.State + + // Private is the private state resource data following the Update operation. + // This field is pre-populated from UpdateRequest.Private and + // can be modified during the resource's Update operation. + Private *privatestate.ProviderData + + // Diagnostics report errors or warnings related to updating the + // resource. An empty slice indicates a successful operation with no + // warnings or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/upgrade_state.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/upgrade_state.go new file mode 100644 index 00000000..ffcd2ae3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/upgrade_state.go @@ -0,0 +1,74 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// Request information for the provider logic to update a resource state +// from a prior state version to the current schema version. An instance of +// this is supplied as a parameter to a StateUpgrader, which ultimately comes +// from a Resource's UpgradeState method. +type UpgradeStateRequest struct { + // Previous state of the resource in JSON (Terraform CLI 0.12 and later) + // or flatmap format, depending on which version of Terraform CLI last + // wrote the resource state. This data is always available, regardless + // whether the wrapping StateUpgrader type PriorSchema field was + // present. + // + // This is advanced functionality for providers wanting to skip the full + // redeclaration of older schemas and instead use lower level handlers to + // transform data. A typical implementation for working with this data will + // call the Unmarshal() method. + // + // TODO: Create framework defined type that is not protocol specific. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/340 + RawState *tfprotov6.RawState + + // Previous state of the resource if the wrapping StateUpgrader + // type PriorSchema field was present. When available, this allows for + // easier data handling such as calling Get() or GetAttribute(). + State *tfsdk.State +} + +// Response information for the provider logic to update a resource state +// from a prior state version to the current schema version. An instance of +// this is supplied as a parameter to a StateUpgrader, which ultimately came +// from a Resource's UpgradeState method. +type UpgradeStateResponse struct { + // Diagnostics report errors or warnings related to upgrading the resource + // state. An empty slice indicates a successful operation with no warnings + // or errors generated. + Diagnostics diag.Diagnostics + + // Upgraded state of the resource, which should match the current schema + // version. If set, this will override State. + // + // This field is intended only for advanced provider functionality, such as + // skipping the full redeclaration of older schemas or using lower level + // handlers to transform data. Call tfprotov6.NewDynamicValue() to set this + // value. + // + // All data must be populated to prevent data loss during the upgrade + // operation. No prior state data is copied automatically. + // + // TODO: Remove in preference of requiring State, rather than using either + // a new framework defined type or keeping this protocol specific type. + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/340 + DynamicValue *tfprotov6.DynamicValue + + // Upgraded state of the resource, which should match the current schema + // version. If DynamicValue is set, it will override this value. + // + // This field allows for easier data handling such as calling Set() or + // SetAttribute(). It is generally recommended over working with the lower + // level types and functionality required for DynamicValue. + // + // All data must be populated to prevent data loss during the upgrade + // operation. No prior state data is copied automatically. + State tfsdk.State +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/resource/validate_config.go b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/validate_config.go new file mode 100644 index 00000000..40e1213b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/resource/validate_config.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// ValidateConfigRequest represents a request to validate the +// configuration of a resource. An instance of this request struct is +// supplied as an argument to the Resource ValidateConfig receiver method +// or automatically passed through to each ConfigValidator. +type ValidateConfigRequest struct { + // Config is the configuration the user supplied for the resource. + // + // This configuration may contain unknown values if a user uses + // interpolation or other functionality that would prevent Terraform + // from knowing the value at request time. + Config tfsdk.Config +} + +// ValidateConfigResponse represents a response to a +// ValidateConfigRequest. An instance of this response struct is +// supplied as an argument to the Resource ValidateConfig receiver method +// or automatically passed through to each ConfigValidator. +type ValidateConfigResponse struct { + // Diagnostics report errors or warnings related to validating the resource + // configuration. An empty slice indicates success, with no warnings or + // errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/bool.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/bool.go new file mode 100644 index 00000000..64115e71 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/bool.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Bool is a schema validator for types.Bool attributes. +type Bool interface { + Describer + + // ValidateBool should perform the validation. + ValidateBool(context.Context, BoolRequest, *BoolResponse) +} + +// BoolRequest is a request for types.Bool schema validation. +type BoolRequest struct { + // Path contains the path of the attribute for validation. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for validation. + PathExpression path.Expression + + // Config contains the entire configuration of the data source, provider, or resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for validation from the configuration. + ConfigValue types.Bool +} + +// BoolResponse is a response to a BoolRequest. +type BoolResponse struct { + // Diagnostics report errors or warnings related to validating the data source, provider, or resource + // configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/describer.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/describer.go new file mode 100644 index 00000000..7b448558 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/describer.go @@ -0,0 +1,40 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validator + +import ( + "context" +) + +// Describer is the common documentation interface for extensible schema +// validation functionality. +type Describer interface { + // Description should describe the validation in plain text formatting. + // This information is used by provider logging and provider tooling such + // as documentation generation. + // + // The description should: + // - Begin with a lowercase or other character suitable for the middle of + // a sentence. + // - End without punctuation. + // - Use actionable language, such as "must" or "cannot". + // - Avoid newlines. Prefer separate validators instead. + // + // For example, "size must be less than 50 elements". + Description(context.Context) string + + // MarkdownDescription should describe the validation in Markdown + // formatting. This information is used by provider logging and provider + // tooling such as documentation generation. + // + // The description should: + // - Begin with a lowercase or other character suitable for the middle of + // a sentence. + // - End without punctuation. + // - Use actionable language, such as "must" or "cannot". + // - Avoid newlines. Prefer separate validators instead. + // + // For example, "value must be `one` or `two`". + MarkdownDescription(context.Context) string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/doc.go new file mode 100644 index 00000000..f59ada44 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/doc.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package validator contains common schema validator interfaces and +// implementations. These validators are used by concept specific packages +// such as datasource/schema, provider/schema, and resource/schema. +// +// Each attr.Type has a corresponding {TYPE}Validator interface which +// implements concretely typed Validate{TYPE} methods, such as +// StringValidator and ValidateString. Custom attr.Type can also consider +// implementing native type validation via the attr/xattr.TypeWithValidate +// interface instead of schema validators. +// +// The framework has to choose between validator developers handling a concrete +// framework value type, such as types.Bool, or the framework interface for +// custom value basetypes. such as basetypes.BoolValuable. +// +// In the framework type model, the developer can immediately use the value. +// If the value was associated with a custom type and using the custom value +// type is desired, the developer must use the type's ValueFrom{TYPE} method. +// +// In the custom type model, the developer must always convert to a concreate +// type before using the value unless checking for null or unknown. Since any +// custom type may be passed due to the schema, it is possible, if not likely, +// that unknown concrete types will be passed to the validator. +// +// The framework chooses to pass the framework value type. This prevents the +// potential for unexpected runtime panics and simplifies development for +// easier use cases where the framework type is sufficient. More advanced +// developers can choose to implement native type validation for custom +// types or call the type's ValueFrom{TYPE} method to get the desired +// desired custom type in a validator. +// +// Validators that are not type dependent need to implement all interfaces, +// but can use shared logic to reduce implementation code. +package validator diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/dynamic.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/dynamic.go new file mode 100644 index 00000000..b035175a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/dynamic.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Dynamic is a schema validator for types.Dynamic attributes. +type Dynamic interface { + Describer + + // ValidateDynamic should perform the validation. + ValidateDynamic(context.Context, DynamicRequest, *DynamicResponse) +} + +// DynamicRequest is a request for types.Dynamic schema validation. +type DynamicRequest struct { + // Path contains the path of the attribute for validation. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for validation. + PathExpression path.Expression + + // Config contains the entire configuration of the data source, provider, or resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for validation from the configuration. + ConfigValue types.Dynamic +} + +// DynamicResponse is a response to a DynamicRequest. +type DynamicResponse struct { + // Diagnostics report errors or warnings related to validating the data source, provider, or resource + // configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/float64.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/float64.go new file mode 100644 index 00000000..f09111ac --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/float64.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Float64 is a schema validator for types.Float64 attributes. +type Float64 interface { + Describer + + // ValidateFloat64 should perform the validation. + ValidateFloat64(context.Context, Float64Request, *Float64Response) +} + +// Float64Request is a request for types.Float64 schema validation. +type Float64Request struct { + // Path contains the path of the attribute for validation. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for validation. + PathExpression path.Expression + + // Config contains the entire configuration of the data source, provider, or resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for validation from the configuration. + ConfigValue types.Float64 +} + +// Float64Response is a response to a Float64Request. +type Float64Response struct { + // Diagnostics report errors or warnings related to validating the data source, provider, or resource + // configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/int64.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/int64.go new file mode 100644 index 00000000..8e8accdc --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/int64.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Int64 is a schema validator for types.Int64 attributes. +type Int64 interface { + Describer + + // ValidateInt64 should perform the validation. + ValidateInt64(context.Context, Int64Request, *Int64Response) +} + +// Int64Request is a request for types.Int64 schema validation. +type Int64Request struct { + // Path contains the path of the attribute for validation. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for validation. + PathExpression path.Expression + + // Config contains the entire configuration of the data source, provider, or resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for validation from the configuration. + ConfigValue types.Int64 +} + +// Int64Response is a response to a Int64Request. +type Int64Response struct { + // Diagnostics report errors or warnings related to validating the data source, provider, or resource + // configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/list.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/list.go new file mode 100644 index 00000000..e5b6083d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/list.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// List is a schema validator for types.List attributes. +type List interface { + Describer + + // ValidateList should perform the validation. + ValidateList(context.Context, ListRequest, *ListResponse) +} + +// ListRequest is a request for types.List schema validation. +type ListRequest struct { + // Path contains the path of the attribute for validation. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for validation. + PathExpression path.Expression + + // Config contains the entire configuration of the data source, provider, or resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for validation from the configuration. + ConfigValue types.List +} + +// ListResponse is a response to a ListRequest. +type ListResponse struct { + // Diagnostics report errors or warnings related to validating the data source, provider, or resource + // configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/map.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/map.go new file mode 100644 index 00000000..2a41cc7a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/map.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Map is a schema validator for types.Map attributes. +type Map interface { + Describer + + // ValidateMap should perform the validation. + ValidateMap(context.Context, MapRequest, *MapResponse) +} + +// MapRequest is a request for types.Map schema validation. +type MapRequest struct { + // Path contains the path of the attribute for validation. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for validation. + PathExpression path.Expression + + // Config contains the entire configuration of the data source, provider, or resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for validation from the configuration. + ConfigValue types.Map +} + +// MapResponse is a response to a MapRequest. +type MapResponse struct { + // Diagnostics report errors or warnings related to validating the data source, provider, or resource + // configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/number.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/number.go new file mode 100644 index 00000000..ef7692c2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/number.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Number is a schema validator for types.Number attributes. +type Number interface { + Describer + + // ValidateNumber should perform the validation. + ValidateNumber(context.Context, NumberRequest, *NumberResponse) +} + +// NumberRequest is a request for types.Number schema validation. +type NumberRequest struct { + // Path contains the path of the attribute for validation. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for validation. + PathExpression path.Expression + + // Config contains the entire configuration of the data source, provider, or resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for validation from the configuration. + ConfigValue types.Number +} + +// NumberResponse is a response to a NumberRequest. +type NumberResponse struct { + // Diagnostics report errors or warnings related to validating the data source, provider, or resource + // configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/object.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/object.go new file mode 100644 index 00000000..88029e0a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/object.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Object is a schema validator for types.Object attributes. +type Object interface { + Describer + + // ValidateObject should perform the validation. + ValidateObject(context.Context, ObjectRequest, *ObjectResponse) +} + +// ObjectRequest is a request for types.Object schema validation. +type ObjectRequest struct { + // Path contains the path of the attribute for validation. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for validation. + PathExpression path.Expression + + // Config contains the entire configuration of the data source, provider, or resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for validation from the configuration. + ConfigValue types.Object +} + +// ObjectResponse is a response to a ObjectRequest. +type ObjectResponse struct { + // Diagnostics report errors or warnings related to validating the data source, provider, or resource + // configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/set.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/set.go new file mode 100644 index 00000000..ce7cdea3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/set.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Set is a schema validator for types.Set attributes. +type Set interface { + Describer + + // ValidateSet should perform the validation. + ValidateSet(context.Context, SetRequest, *SetResponse) +} + +// SetRequest is a request for types.Set schema validation. +type SetRequest struct { + // Path contains the path of the attribute for validation. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for validation. + PathExpression path.Expression + + // Config contains the entire configuration of the data source, provider, or resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for validation from the configuration. + ConfigValue types.Set +} + +// SetResponse is a response to a SetRequest. +type SetResponse struct { + // Diagnostics report errors or warnings related to validating the data source, provider, or resource + // configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/string.go b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/string.go new file mode 100644 index 00000000..b453a7bf --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/schema/validator/string.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// String is a schema validator for types.String attributes. +type String interface { + Describer + + // ValidateString should perform the validation. + ValidateString(context.Context, StringRequest, *StringResponse) +} + +// StringRequest is a request for types.String schema validation. +type StringRequest struct { + // Path contains the path of the attribute for validation. Use this path + // for any response diagnostics. + Path path.Path + + // PathExpression contains the expression matching the exact path + // of the attribute for validation. + PathExpression path.Expression + + // Config contains the entire configuration of the data source, provider, or resource. + Config tfsdk.Config + + // ConfigValue contains the value of the attribute for validation from the configuration. + ConfigValue types.String +} + +// StringResponse is a response to a StringRequest. +type StringResponse struct { + // Diagnostics report errors or warnings related to validating the data source, provider, or resource + // configuration. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/config.go b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/config.go new file mode 100644 index 00000000..156b8401 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/config.go @@ -0,0 +1,53 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfsdk + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Config represents a Terraform config. +type Config struct { + Raw tftypes.Value + Schema fwschema.Schema +} + +// Get populates the struct passed as `target` with the entire config. +func (c Config) Get(ctx context.Context, target interface{}) diag.Diagnostics { + return c.data().Get(ctx, target) +} + +// GetAttribute retrieves the attribute or block found at `path` and populates +// the `target` with the value. This method is intended for top level schema +// attributes or blocks. Use `types` package methods or custom types to step +// into collections. +// +// Attributes or elements under null or unknown collections return null +// values, however this behavior is not protected by compatibility promises. +func (c Config) GetAttribute(ctx context.Context, path path.Path, target interface{}) diag.Diagnostics { + return c.data().GetAtPath(ctx, path, target) +} + +// PathMatches returns all matching path.Paths from the given path.Expression. +// +// If a parent path is null or unknown, which would prevent a full expression +// from matching, the parent path is returned rather than no match to prevent +// false positives. +func (c Config) PathMatches(ctx context.Context, pathExpr path.Expression) (path.Paths, diag.Diagnostics) { + return c.data().PathMatches(ctx, pathExpr) +} + +func (c Config) data() fwschemadata.Data { + return fwschemadata.Data{ + Description: fwschemadata.DataDescriptionConfiguration, + Schema: c.Schema, + TerraformValue: c.Raw, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/convert.go b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/convert.go new file mode 100644 index 00000000..9147a388 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/convert.go @@ -0,0 +1,31 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfsdk + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +// ConvertValue creates a new attr.Value of the attr.Type `typ`, using the data +// in `val`, which can be of any attr.Type so long as its TerraformType method +// returns a tftypes.Type that `typ`'s ValueFromTerraform method can accept. +func ConvertValue(ctx context.Context, val attr.Value, typ attr.Type) (attr.Value, diag.Diagnostics) { + newVal, err := val.ToTerraformValue(ctx) + if err != nil { + return nil, diag.Diagnostics{diag.NewErrorDiagnostic("Error converting value", + fmt.Sprintf("An unexpected error was encountered converting a %T to a %s. This is always a problem with the provider. Please tell the provider developers that %T ran into the following error during ToTerraformValue: %s", val, typ, val, err), + )} + } + res, err := typ.ValueFromTerraform(ctx, newVal) + if err != nil { + return nil, diag.Diagnostics{diag.NewErrorDiagnostic("Error converting value", + fmt.Sprintf("An unexpected error was encountered converting a %T to a %s. This is always a problem with the provider. Please tell the provider developers that %s returned the following error when calling ValueFromTerraform: %s", val, typ, typ, err), + )} + } + return res, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/doc.go new file mode 100644 index 00000000..6bd90eb1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/doc.go @@ -0,0 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package tfsdk contains core framework functionality for schema data. +package tfsdk diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/plan.go b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/plan.go new file mode 100644 index 00000000..bb76eee9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/plan.go @@ -0,0 +1,94 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfsdk + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Plan represents a Terraform plan. +type Plan struct { + Raw tftypes.Value + Schema fwschema.Schema +} + +// Get populates the struct passed as `target` with the entire plan. +func (p Plan) Get(ctx context.Context, target interface{}) diag.Diagnostics { + return p.data().Get(ctx, target) +} + +// GetAttribute retrieves the attribute or block found at `path` and populates +// the `target` with the value. This method is intended for top level schema +// attributes or blocks. Use `types` package methods or custom types to step +// into collections. +// +// Attributes or elements under null or unknown collections return null +// values, however this behavior is not protected by compatibility promises. +func (p Plan) GetAttribute(ctx context.Context, path path.Path, target interface{}) diag.Diagnostics { + return p.data().GetAtPath(ctx, path, target) +} + +// PathMatches returns all matching path.Paths from the given path.Expression. +// +// If a parent path is null or unknown, which would prevent a full expression +// from matching, the parent path is returned rather than no match to prevent +// false positives. +func (p Plan) PathMatches(ctx context.Context, pathExpr path.Expression) (path.Paths, diag.Diagnostics) { + return p.data().PathMatches(ctx, pathExpr) +} + +// Set populates the entire plan using the supplied Go value. The value `val` +// should be a struct whose values have one of the attr.Value types. Each field +// must be tagged with the corresponding schema field. +func (p *Plan) Set(ctx context.Context, val interface{}) diag.Diagnostics { + data := p.data() + diags := data.Set(ctx, val) + + if diags.HasError() { + return diags + } + + p.Raw = data.TerraformValue + + return diags +} + +// SetAttribute sets the attribute at `path` using the supplied Go value. +// +// The attribute path and value must be valid with the current schema. If the +// attribute path already has a value, it will be overwritten. If the attribute +// path does not have a value, it will be added, including any parent attribute +// paths as necessary. +// +// The value must not be an untyped nil. Use a typed nil or types package null +// value function instead. For example with a types.StringType attribute, +// use (*string)(nil) or types.StringNull(). +// +// Lists can only have the next element added according to the current length. +func (p *Plan) SetAttribute(ctx context.Context, path path.Path, val interface{}) diag.Diagnostics { + data := p.data() + diags := data.SetAtPath(ctx, path, val) + + if diags.HasError() { + return diags + } + + p.Raw = data.TerraformValue + + return diags +} + +func (p Plan) data() *fwschemadata.Data { + return &fwschemadata.Data{ + Description: fwschemadata.DataDescriptionPlan, + Schema: p.Schema, + TerraformValue: p.Raw, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/state.go b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/state.go new file mode 100644 index 00000000..a2ce4762 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/state.go @@ -0,0 +1,114 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfsdk + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// State represents a Terraform state. +type State struct { + Raw tftypes.Value + Schema fwschema.Schema +} + +// Get populates the struct passed as `target` with the entire state. +func (s State) Get(ctx context.Context, target interface{}) diag.Diagnostics { + return s.data().Get(ctx, target) +} + +// GetAttribute retrieves the attribute or block found at `path` and populates +// the `target` with the value. This method is intended for top level schema +// attributes or blocks. Use `types` package methods or custom types to step +// into collections. +// +// Attributes or elements under null or unknown collections return null +// values, however this behavior is not protected by compatibility promises. +func (s State) GetAttribute(ctx context.Context, path path.Path, target interface{}) diag.Diagnostics { + return s.data().GetAtPath(ctx, path, target) +} + +// PathMatches returns all matching path.Paths from the given path.Expression. +// +// If a parent path is null or unknown, which would prevent a full expression +// from matching, the parent path is returned rather than no match to prevent +// false positives. +func (s State) PathMatches(ctx context.Context, pathExpr path.Expression) (path.Paths, diag.Diagnostics) { + return s.data().PathMatches(ctx, pathExpr) +} + +// Set populates the entire state using the supplied Go value. The value `val` +// should be a struct whose values have one of the attr.Value types. Each field +// must be tagged with the corresponding schema field. +func (s *State) Set(ctx context.Context, val interface{}) diag.Diagnostics { + if val == nil { + err := fmt.Errorf("cannot set nil as entire state; to remove a resource from state, call State.RemoveResource, instead") + return diag.Diagnostics{ + diag.NewErrorDiagnostic( + "State Read Error", + "An unexpected error was encountered trying to write the state. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ), + } + } + + data := s.data() + diags := data.Set(ctx, val) + + if diags.HasError() { + return diags + } + + s.Raw = data.TerraformValue + + return diags +} + +// SetAttribute sets the attribute at `path` using the supplied Go value. +// +// The attribute path and value must be valid with the current schema. If the +// attribute path already has a value, it will be overwritten. If the attribute +// path does not have a value, it will be added, including any parent attribute +// paths as necessary. +// +// The value must not be an untyped nil. Use a typed nil or types package null +// value function instead. For example with a types.StringType attribute, +// use (*string)(nil) or types.StringNull(). +// +// Lists can only have the next element added according to the current length. +func (s *State) SetAttribute(ctx context.Context, path path.Path, val interface{}) diag.Diagnostics { + data := s.data() + diags := data.SetAtPath(ctx, path, val) + + if diags.HasError() { + return diags + } + + s.Raw = data.TerraformValue + + return diags +} + +// RemoveResource removes the entire resource from state. +// +// If a Resource type Delete method is completed without error, this is +// automatically called on the DeleteResourceResponse.State. +func (s *State) RemoveResource(ctx context.Context) { + s.Raw = tftypes.NewValue(s.Schema.Type().TerraformType(ctx), nil) +} + +func (s State) data() fwschemadata.Data { + return fwschemadata.Data{ + Description: fwschemadata.DataDescriptionState, + Schema: s.Schema, + TerraformValue: s.Raw, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/value_as.go b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/value_as.go new file mode 100644 index 00000000..b5d85182 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/value_as.go @@ -0,0 +1,31 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfsdk + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// ValueAs takes the attr.Value `val` and populates the Go value `target` with its content. +// +// This is achieved using reflection rules provided by the internal/reflect package. +func ValueAs(ctx context.Context, val attr.Value, target interface{}) diag.Diagnostics { + if reflect.IsGenericAttrValue(ctx, target) { + //nolint:forcetypeassert // Type assertion is guaranteed by the above `reflect.IsGenericAttrValue` function + *(target.(*attr.Value)) = val + return nil + } + raw, err := val.ToTerraformValue(ctx) + if err != nil { + return diag.Diagnostics{diag.NewErrorDiagnostic("Error converting value", + fmt.Sprintf("An unexpected error was encountered converting a %T to its equivalent Terraform representation. This is always a bug in the provider.\n\nError: %s", val, err))} + } + return reflect.Into(ctx, val.Type(ctx), raw, target, reflect.Options{}, path.Empty()) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/value_from.go b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/value_from.go new file mode 100644 index 00000000..3f5c9092 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/tfsdk/value_from.go @@ -0,0 +1,26 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfsdk + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// ValueFrom takes the Go value `val` and populates `target` with an attr.Value, +// based on the type definition provided in `targetType`. +// +// This is achieved using reflection rules provided by the internal/reflect package. +func ValueFrom(ctx context.Context, val interface{}, targetType attr.Type, target interface{}) diag.Diagnostics { + v, diags := reflect.FromValue(ctx, targetType, val, path.Empty()) + if diags.HasError() { + return diags + } + + return ValueAs(ctx, v, target) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/bool_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/bool_type.go new file mode 100644 index 00000000..9bdc30bb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/bool_type.go @@ -0,0 +1,86 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// BoolTypable extends attr.Type for bool types. +// Implement this interface to create a custom BoolType type. +type BoolTypable interface { + attr.Type + + // ValueFromBool should convert the Bool to a BoolValuable type. + ValueFromBool(context.Context, BoolValue) (BoolValuable, diag.Diagnostics) +} + +var _ BoolTypable = BoolType{} + +// BoolType is the base framework type for a boolean. BoolValue is the +// associated value type. +type BoolType struct{} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// type. +func (t BoolType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +func (t BoolType) Equal(o attr.Type) bool { + _, ok := o.(BoolType) + + return ok +} + +// String returns a human readable string of the type name. +func (t BoolType) String() string { + return "basetypes.BoolType" +} + +// TerraformType returns the tftypes.Type that should be used to represent this +// framework type. +func (t BoolType) TerraformType(_ context.Context) tftypes.Type { + return tftypes.Bool +} + +// ValueFromBool returns a BoolValuable type given a BoolValue. +func (t BoolType) ValueFromBool(_ context.Context, v BoolValue) (BoolValuable, diag.Diagnostics) { + return v, nil +} + +// ValueFromTerraform returns a Value given a tftypes.Value. This is meant to +// convert the tftypes.Value into a more convenient Go type for the provider to +// consume the data with. +func (t BoolType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if !in.IsKnown() { + return NewBoolUnknown(), nil + } + + if in.IsNull() { + return NewBoolNull(), nil + } + + var v bool + + err := in.As(&v) + + if err != nil { + return nil, err + } + + return NewBoolValue(v), nil +} + +// ValueType returns the Value type. +func (t BoolType) ValueType(_ context.Context) attr.Value { + // This Value does not need to be valid. + return BoolValue{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/bool_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/bool_value.go new file mode 100644 index 00000000..aa10b398 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/bool_value.go @@ -0,0 +1,175 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +var ( + _ BoolValuable = BoolValue{} +) + +// BoolValuable extends attr.Value for boolean value types. +// Implement this interface to create a custom Bool value type. +type BoolValuable interface { + attr.Value + + // ToBoolValue should convert the value type to a Bool. + ToBoolValue(ctx context.Context) (BoolValue, diag.Diagnostics) +} + +// BoolValuableWithSemanticEquals extends BoolValuable with semantic +// equality logic. +type BoolValuableWithSemanticEquals interface { + BoolValuable + + // BoolSemanticEquals should return true if the given value is + // semantically equal to the current value. This logic is used to prevent + // Terraform data consistency errors and resource drift where a value change + // may have inconsequential differences. + // + // Only known values are compared with this method as changing a value's + // state implicitly represents a different value. + BoolSemanticEquals(context.Context, BoolValuable) (bool, diag.Diagnostics) +} + +// NewBoolNull creates a Bool with a null value. Determine whether the value is +// null via the Bool type IsNull method. +func NewBoolNull() BoolValue { + return BoolValue{ + state: attr.ValueStateNull, + } +} + +// NewBoolUnknown creates a Bool with an unknown value. Determine whether the +// value is unknown via the Bool type IsUnknown method. +func NewBoolUnknown() BoolValue { + return BoolValue{ + state: attr.ValueStateUnknown, + } +} + +// NewBoolValue creates a Bool with a known value. Access the value via the Bool +// type ValueBool method. +func NewBoolValue(value bool) BoolValue { + return BoolValue{ + state: attr.ValueStateKnown, + value: value, + } +} + +// NewBoolPointerValue creates a Bool with a null value if nil or a known +// value. Access the value via the Bool type ValueBoolPointer method. +func NewBoolPointerValue(value *bool) BoolValue { + if value == nil { + return NewBoolNull() + } + + return NewBoolValue(*value) +} + +// BoolValue represents a boolean value. +type BoolValue struct { + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState + + // value contains the known value, if not null or unknown. + value bool +} + +// Type returns a BoolType. +func (b BoolValue) Type(_ context.Context) attr.Type { + return BoolType{} +} + +// ToTerraformValue returns the data contained in the Bool as a tftypes.Value. +func (b BoolValue) ToTerraformValue(_ context.Context) (tftypes.Value, error) { + switch b.state { + case attr.ValueStateKnown: + if err := tftypes.ValidateValue(tftypes.Bool, b.value); err != nil { + return tftypes.NewValue(tftypes.Bool, tftypes.UnknownValue), err + } + + return tftypes.NewValue(tftypes.Bool, b.value), nil + case attr.ValueStateNull: + return tftypes.NewValue(tftypes.Bool, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(tftypes.Bool, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Bool state in ToTerraformValue: %s", b.state)) + } +} + +// Equal returns true if `other` is a *Bool and has the same value as `b`. +func (b BoolValue) Equal(other attr.Value) bool { + o, ok := other.(BoolValue) + + if !ok { + return false + } + + if b.state != o.state { + return false + } + + if b.state != attr.ValueStateKnown { + return true + } + + return b.value == o.value +} + +// IsNull returns true if the Bool represents a null value. +func (b BoolValue) IsNull() bool { + return b.state == attr.ValueStateNull +} + +// IsUnknown returns true if the Bool represents a currently unknown value. +func (b BoolValue) IsUnknown() bool { + return b.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the Bool value. +// The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (b BoolValue) String() string { + if b.IsUnknown() { + return attr.UnknownValueString + } + + if b.IsNull() { + return attr.NullValueString + } + + return fmt.Sprintf("%t", b.value) +} + +// ValueBool returns the known bool value. If Bool is null or unknown, returns +// false. +func (b BoolValue) ValueBool() bool { + return b.value +} + +// ValueBoolPointer returns a pointer to the known bool value, nil for a null +// value, or a pointer to false for an unknown value. +func (b BoolValue) ValueBoolPointer() *bool { + if b.IsNull() { + return nil + } + + return &b.value +} + +// ToBoolValue returns Bool. +func (b BoolValue) ToBoolValue(context.Context) (BoolValue, diag.Diagnostics) { + return b, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/doc.go new file mode 100644 index 00000000..674b0627 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/doc.go @@ -0,0 +1,7 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package basetypes contains the implementations for framework-defined data +// types and values, such as boolean, floating point, integer, list, map, +// object, set, and string. Embed these implementations to create custom types. +package basetypes diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/dynamic_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/dynamic_type.go new file mode 100644 index 00000000..87138984 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/dynamic_type.go @@ -0,0 +1,198 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "errors" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// DynamicTypable extends attr.Type for dynamic types. Implement this interface to create a custom DynamicType type. +type DynamicTypable interface { + attr.Type + + // ValueFromDynamic should convert the DynamicValue to a DynamicValuable type. + ValueFromDynamic(context.Context, DynamicValue) (DynamicValuable, diag.Diagnostics) +} + +var _ DynamicTypable = DynamicType{} + +// DynamicType is the base framework type for a dynamic. Static types are always +// preferable over dynamic types in Terraform as practitioners will receive less +// helpful configuration assistance from validation error diagnostics and editor +// integrations. +// +// DynamicValue is the associated value type and, when known, contains a concrete +// value of another framework type. (StringValue, ListValue, ObjectValue, MapValue, etc.) +type DynamicType struct{} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the type. +func (t DynamicType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + // MAINTAINER NOTE: Based on dynamic type alone, there is no alternative type information to return related to a path step. + // When working with dynamics, we should always use DynamicValue to determine underlying type information. + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +// +// Dynamic types do not contain a reference to the underlying `attr.Value` type, so this equality check +// only asserts that both types are DynamicType. +func (t DynamicType) Equal(o attr.Type) bool { + _, ok := o.(DynamicType) + + return ok +} + +// String returns a human-friendly description of the DynamicType. +func (t DynamicType) String() string { + return "basetypes.DynamicType" +} + +// TerraformType returns the tftypes.Type that should be used to represent this type. +func (t DynamicType) TerraformType(ctx context.Context) tftypes.Type { + return tftypes.DynamicPseudoType +} + +// ValueFromDynamic returns a DynamicValuable type given a DynamicValue. +func (t DynamicType) ValueFromDynamic(ctx context.Context, v DynamicValue) (DynamicValuable, diag.Diagnostics) { + return v, nil +} + +// ValueFromTerraform returns an attr.Value given a tftypes.Value. This is meant to convert +// the tftypes.Value into a more convenient Go type for the provider to consume the data with. +func (t DynamicType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewDynamicNull(), nil + } + + // For dynamic values, it's possible the incoming value is unknown but the concrete type itself is known. In this + // situation, we can't return a dynamic unknown as we will lose that concrete type information. If the type here + // is not dynamic, then we use the concrete `(attr.Type).ValueFromTerraform` below to produce the unknown value. + if !in.IsKnown() && in.Type().Is(tftypes.DynamicPseudoType) { + return NewDynamicUnknown(), nil + } + + // For dynamic values, it's possible the incoming value is null but the concrete type itself is known. In this + // situation, we can't return a dynamic null as we will lose that concrete type information. If the type here + // is not dynamic, then we use the concrete `(attr.Type).ValueFromTerraform` below to produce the null value. + if in.IsNull() && in.Type().Is(tftypes.DynamicPseudoType) { + return NewDynamicNull(), nil + } + + // MAINTAINER NOTE: It should not be possible for Terraform core to send a known value of `tftypes.DynamicPseudoType`. + // This check prevents an infinite recursion that would result if this scenario occurs when attempting to create a dynamic value. + if in.Type().Is(tftypes.DynamicPseudoType) { + return nil, errors.New("ambiguous known value for `tftypes.DynamicPseudoType` detected") + } + + attrType, err := tftypeToFrameworkType(in.Type()) + if err != nil { + return nil, err + } + + val, err := attrType.ValueFromTerraform(ctx, in) + if err != nil { + return nil, err + } + + return NewDynamicValue(val), nil +} + +// ValueType returns the Value type. +func (t DynamicType) ValueType(_ context.Context) attr.Value { + return DynamicValue{} +} + +// tftypeToFrameworkType is a helper function that returns the framework type equivalent for a given Terraform type. +// +// Custom dynamic type implementations shouldn't need to override this method, but if needed, they can implement similar logic +// in their `ValueFromTerraform` implementation. +func tftypeToFrameworkType(in tftypes.Type) (attr.Type, error) { + // Primitive types + if in.Is(tftypes.Bool) { + return BoolType{}, nil + } + if in.Is(tftypes.Number) { + return NumberType{}, nil + } + if in.Is(tftypes.String) { + return StringType{}, nil + } + + if in.Is(tftypes.DynamicPseudoType) { + // Null and Unknown values that do not have a type determined will have a type of DynamicPseudoType + return DynamicType{}, nil + } + + // Collection types + if in.Is(tftypes.List{}) { + //nolint:forcetypeassert // Type assertion is guaranteed by the above `(tftypes.Type).Is` function + l := in.(tftypes.List) + + elemType, err := tftypeToFrameworkType(l.ElementType) + if err != nil { + return nil, err + } + return ListType{ElemType: elemType}, nil + } + if in.Is(tftypes.Map{}) { + //nolint:forcetypeassert // Type assertion is guaranteed by the above `(tftypes.Type).Is` function + m := in.(tftypes.Map) + + elemType, err := tftypeToFrameworkType(m.ElementType) + if err != nil { + return nil, err + } + + return MapType{ElemType: elemType}, nil + } + if in.Is(tftypes.Set{}) { + //nolint:forcetypeassert // Type assertion is guaranteed by the above `(tftypes.Type).Is` function + s := in.(tftypes.Set) + + elemType, err := tftypeToFrameworkType(s.ElementType) + if err != nil { + return nil, err + } + + return SetType{ElemType: elemType}, nil + } + + // Structural types + if in.Is(tftypes.Object{}) { + //nolint:forcetypeassert // Type assertion is guaranteed by the above `(tftypes.Type).Is` function + o := in.(tftypes.Object) + + attrTypes := make(map[string]attr.Type, len(o.AttributeTypes)) + for name, tfType := range o.AttributeTypes { + t, err := tftypeToFrameworkType(tfType) + if err != nil { + return nil, err + } + attrTypes[name] = t + } + return ObjectType{AttrTypes: attrTypes}, nil + } + if in.Is(tftypes.Tuple{}) { + //nolint:forcetypeassert // Type assertion is guaranteed by the above `(tftypes.Type).Is` function + tup := in.(tftypes.Tuple) + + elemTypes := make([]attr.Type, len(tup.ElementTypes)) + for i, tfType := range tup.ElementTypes { + t, err := tftypeToFrameworkType(tfType) + if err != nil { + return nil, err + } + elemTypes[i] = t + } + return TupleType{ElemTypes: elemTypes}, nil + } + + return nil, fmt.Errorf("unsupported tftypes.Type detected: %T", in) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/dynamic_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/dynamic_value.go new file mode 100644 index 00000000..07946e18 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/dynamic_value.go @@ -0,0 +1,197 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "errors" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +var ( + _ DynamicValuable = DynamicValue{} +) + +// DynamicValuable extends attr.Value for dynamic value types. Implement this interface +// to create a custom Dynamic value type. +type DynamicValuable interface { + attr.Value + + // ToDynamicValue should convert the value type to a DynamicValue. + ToDynamicValue(context.Context) (DynamicValue, diag.Diagnostics) +} + +// DynamicValuableWithSemanticEquals extends DynamicValuable with semantic equality logic. +type DynamicValuableWithSemanticEquals interface { + DynamicValuable + + // DynamicSemanticEquals should return true if the given value is + // semantically equal to the current value. This logic is used to prevent + // Terraform data consistency errors and resource drift where a value change + // may have inconsequential differences. + // + // Only known values are compared with this method as changing a value's + // state implicitly represents a different value. + DynamicSemanticEquals(context.Context, DynamicValuable) (bool, diag.Diagnostics) +} + +// NewDynamicValue creates a Dynamic with a known value. Access the value via the Dynamic +// type UnderlyingValue method. The concrete value type returned to Terraform from this value +// will be determined by the provided `(attr.Value).ToTerraformValue` function. +func NewDynamicValue(value attr.Value) DynamicValue { + if value == nil { + return NewDynamicNull() + } + + return DynamicValue{ + value: value, + state: attr.ValueStateKnown, + } +} + +// NewDynamicNull creates a Dynamic with a null value. The concrete value type returned to Terraform +// from this value will be tftypes.DynamicPseudoType. +func NewDynamicNull() DynamicValue { + return DynamicValue{ + state: attr.ValueStateNull, + } +} + +// NewDynamicUnknown creates a Dynamic with an unknown value. The concrete value type returned to Terraform +// from this value will be tftypes.DynamicPseudoType. +func NewDynamicUnknown() DynamicValue { + return DynamicValue{ + state: attr.ValueStateUnknown, + } +} + +// DynamicValue represents a dynamic value. Static types are always +// preferable over dynamic types in Terraform as practitioners will receive less +// helpful configuration assistance from validation error diagnostics and editor +// integrations. +type DynamicValue struct { + // value contains the known value, if not null or unknown. + value attr.Value + + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState +} + +// Type returns DynamicType. +func (v DynamicValue) Type(ctx context.Context) attr.Type { + return DynamicType{} +} + +// ToTerraformValue returns the equivalent tftypes.Value for the DynamicValue. +func (v DynamicValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + switch v.state { + case attr.ValueStateKnown: + if v.value == nil { + return tftypes.NewValue(tftypes.DynamicPseudoType, tftypes.UnknownValue), + errors.New("invalid Dynamic state in ToTerraformValue: DynamicValue is known but the underlying value is unset") + } + + return v.value.ToTerraformValue(ctx) + case attr.ValueStateNull: + return tftypes.NewValue(tftypes.DynamicPseudoType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(tftypes.DynamicPseudoType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Dynamic state in ToTerraformValue: %s", v.state)) + } +} + +// Equal returns true if the given attr.Value is also a DynamicValue and contains an equal underlying value as defined by its Equal method. +func (v DynamicValue) Equal(o attr.Value) bool { + other, ok := o.(DynamicValue) + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + // Prevent panic and force inequality if either underlying value is nil + if v.value == nil || other.value == nil { + return false + } + + return v.value.Equal(other.value) +} + +// IsNull returns true if the DynamicValue represents a null value. +func (v DynamicValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +// IsUnknown returns true if the DynamicValue represents an unknown value. +func (v DynamicValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the DynamicValue. The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (v DynamicValue) String() string { + if v.IsUnknown() { + return attr.UnknownValueString + } + + if v.IsNull() { + return attr.NullValueString + } + + if v.value == nil { + return attr.UnsetValueString + } + + return v.value.String() +} + +// ToDynamicValue returns DynamicValue. +func (v DynamicValue) ToDynamicValue(ctx context.Context) (DynamicValue, diag.Diagnostics) { + return v, nil +} + +// UnderlyingValue returns the concrete underlying value in the DynamicValue. This will return `nil` +// if DynamicValue is null or unknown. +// +// A known DynamicValue can have an underlying value that is in null or unknown state in the +// scenario that the underlying value type has been refined by Terraform. +func (v DynamicValue) UnderlyingValue() attr.Value { + return v.value +} + +// IsUnderlyingValueNull is a helper method that return true only in the case where the underlying value has a +// known type but the value is null. This method will return false if the underlying type is not known. +// +// IsNull should be used to determine if the dynamic value does not have a known type and the value is null. +// +// An example of a known type with a null underlying value would be: +// +// types.DynamicValue(types.StringNull()) +func (v DynamicValue) IsUnderlyingValueNull() bool { + return v.value != nil && v.value.IsNull() +} + +// IsUnderlyingValueUnknown is a helper method that return true only in the case where the underlying value has a +// known type but the value is unknown. This method will return false if the underlying type is not known. +// +// IsUnknown should be used to determine if the dynamic value does not have a known type and the value is unknown. +// +// An example of a known type with an unknown underlying value would be: +// +// types.DynamicValue(types.StringUnknown()) +func (v DynamicValue) IsUnderlyingValueUnknown() bool { + return v.value != nil && v.value.IsUnknown() +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/float64_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/float64_type.go new file mode 100644 index 00000000..a783201e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/float64_type.go @@ -0,0 +1,171 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "math" + "math/big" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Float64Typable extends attr.Type for float64 types. +// Implement this interface to create a custom Float64Type type. +type Float64Typable interface { + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + xattr.TypeWithValidate + + // ValueFromFloat64 should convert the Float64 to a Float64Valuable type. + ValueFromFloat64(context.Context, Float64Value) (Float64Valuable, diag.Diagnostics) +} + +var _ Float64Typable = Float64Type{} + +// Float64Type is the base framework type for a floating point number. +// Float64Value is the associated value type. +type Float64Type struct{} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// type. +func (t Float64Type) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +func (t Float64Type) Equal(o attr.Type) bool { + _, ok := o.(Float64Type) + + return ok +} + +// String returns a human readable string of the type name. +func (t Float64Type) String() string { + return "basetypes.Float64Type" +} + +// TerraformType returns the tftypes.Type that should be used to represent this +// framework type. +func (t Float64Type) TerraformType(_ context.Context) tftypes.Type { + return tftypes.Number +} + +// Validate implements type validation. +func (t Float64Type) Validate(ctx context.Context, in tftypes.Value, path path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + if in.Type() == nil { + return diags + } + + if !in.Type().Equal(tftypes.Number) { + diags.AddAttributeError( + path, + "Float64 Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Expected Number value, received %T with value: %v", in, in), + ) + return diags + } + + if !in.IsKnown() || in.IsNull() { + return diags + } + + var value *big.Float + err := in.As(&value) + + if err != nil { + diags.AddAttributeError( + path, + "Float64 Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Cannot convert value to big.Float: %s", err), + ) + return diags + } + + float64Value, accuracy := value.Float64() + + // Underflow + // Reference: https://pkg.go.dev/math/big#Float.Float64 + if float64Value == 0 && accuracy != big.Exact { + diags.AddAttributeError( + path, + "Float64 Type Validation Error", + fmt.Sprintf("Value %s cannot be represented as a 64-bit floating point.", value), + ) + return diags + } + + // Overflow + // Reference: https://pkg.go.dev/math/big#Float.Float64 + if math.IsInf(float64Value, 0) { + diags.AddAttributeError( + path, + "Float64 Type Validation Error", + fmt.Sprintf("Value %s cannot be represented as a 64-bit floating point.", value), + ) + return diags + } + + return diags +} + +// ValueFromFloat64 returns a Float64Valuable type given a Float64Value. +func (t Float64Type) ValueFromFloat64(_ context.Context, v Float64Value) (Float64Valuable, diag.Diagnostics) { + return v, nil +} + +// ValueFromTerraform returns a Value given a tftypes.Value. This is meant to +// convert the tftypes.Value into a more convenient Go type for the provider to +// consume the data with. +func (t Float64Type) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if !in.IsKnown() { + return NewFloat64Unknown(), nil + } + + if in.IsNull() { + return NewFloat64Null(), nil + } + + var bigF *big.Float + err := in.As(&bigF) + + if err != nil { + return nil, err + } + + f, accuracy := bigF.Float64() + + // Underflow + // Reference: https://pkg.go.dev/math/big#Float.Float64 + if f == 0 && accuracy != big.Exact { + return nil, fmt.Errorf("Value %s cannot be represented as a 64-bit floating point.", bigF) + } + + // Overflow + // Reference: https://pkg.go.dev/math/big#Float.Float64 + if math.IsInf(f, 0) { + return nil, fmt.Errorf("Value %s cannot be represented as a 64-bit floating point.", bigF) + } + + // Underlying *big.Float values are not exposed with helper functions, so creating Float64Value via struct literal + return Float64Value{ + state: attr.ValueStateKnown, + value: bigF, + }, nil +} + +// ValueType returns the Value type. +func (t Float64Type) ValueType(_ context.Context) attr.Value { + // This Value does not need to be valid. + return Float64Value{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/float64_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/float64_value.go new file mode 100644 index 00000000..fb9c19a5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/float64_value.go @@ -0,0 +1,223 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "math/big" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +var ( + _ Float64Valuable = Float64Value{} + _ Float64ValuableWithSemanticEquals = Float64Value{} +) + +// Float64Valuable extends attr.Value for float64 value types. +// Implement this interface to create a custom Float64 value type. +type Float64Valuable interface { + attr.Value + + // ToFloat64Value should convert the value type to a Float64. + ToFloat64Value(ctx context.Context) (Float64Value, diag.Diagnostics) +} + +// Float64ValuableWithSemanticEquals extends Float64Valuable with semantic +// equality logic. +type Float64ValuableWithSemanticEquals interface { + Float64Valuable + + // Float64SemanticEquals should return true if the given value is + // semantically equal to the current value. This logic is used to prevent + // Terraform data consistency errors and resource drift where a value change + // may have inconsequential differences, such as rounding. + // + // Only known values are compared with this method as changing a value's + // state implicitly represents a different value. + Float64SemanticEquals(context.Context, Float64Valuable) (bool, diag.Diagnostics) +} + +// Float64Null creates a Float64 with a null value. Determine whether the value is +// null via the Float64 type IsNull method. +func NewFloat64Null() Float64Value { + return Float64Value{ + state: attr.ValueStateNull, + } +} + +// Float64Unknown creates a Float64 with an unknown value. Determine whether the +// value is unknown via the Float64 type IsUnknown method. +// +// Setting the deprecated Float64 type Null, Unknown, or Value fields after +// creating a Float64 with this function has no effect. +func NewFloat64Unknown() Float64Value { + return Float64Value{ + state: attr.ValueStateUnknown, + } +} + +// Float64Value creates a Float64 with a known value. Access the value via the Float64 +// type ValueFloat64 method. Passing a value of `NaN` will result in a panic. +// +// Setting the deprecated Float64 type Null, Unknown, or Value fields after +// creating a Float64 with this function has no effect. +func NewFloat64Value(value float64) Float64Value { + return Float64Value{ + state: attr.ValueStateKnown, + value: big.NewFloat(value), + } +} + +// NewFloat64PointerValue creates a Float64 with a null value if nil or a known +// value. Access the value via the Float64 type ValueFloat64Pointer method. +// Passing a value of `NaN` will result in a panic. +func NewFloat64PointerValue(value *float64) Float64Value { + if value == nil { + return NewFloat64Null() + } + + return NewFloat64Value(*value) +} + +// Float64Value represents a 64-bit floating point value, exposed as a float64. +type Float64Value struct { + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState + + // value contains the known value, if not null or unknown. + value *big.Float +} + +// Float64SemanticEquals returns true if the given Float64Value is semantically equal to the current Float64Value. +// The underlying value *big.Float can store more precise float values then the Go built-in float64 type. This only +// compares the precision of the value that can be represented as the Go built-in float64, which is 53 bits of precision. +func (f Float64Value) Float64SemanticEquals(ctx context.Context, newValuable Float64Valuable) (bool, diag.Diagnostics) { + var diags diag.Diagnostics + + newValue, ok := newValuable.(Float64Value) + if !ok { + diags.AddError( + "Semantic Equality Check Error", + "An unexpected value type was received while performing semantic equality checks. "+ + "Please report this to the provider developers.\n\n"+ + "Expected Value Type: "+fmt.Sprintf("%T", f)+"\n"+ + "Got Value Type: "+fmt.Sprintf("%T", newValuable), + ) + + return false, diags + } + + return f.ValueFloat64() == newValue.ValueFloat64(), diags +} + +// Equal returns true if `other` is a Float64 and has the same value as `f`. +func (f Float64Value) Equal(other attr.Value) bool { + o, ok := other.(Float64Value) + + if !ok { + return false + } + + if f.state != o.state { + return false + } + + if f.state != attr.ValueStateKnown { + return true + } + + // Not possible to create a known Float64Value with a nil value, but check anyways + if f.value == nil || o.value == nil { + return f.value == o.value + } + + return f.value.Cmp(o.value) == 0 +} + +// ToTerraformValue returns the data contained in the Float64 as a tftypes.Value. +func (f Float64Value) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + switch f.state { + case attr.ValueStateKnown: + if err := tftypes.ValidateValue(tftypes.Number, f.value); err != nil { + return tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), err + } + + return tftypes.NewValue(tftypes.Number, f.value), nil + case attr.ValueStateNull: + return tftypes.NewValue(tftypes.Number, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Float64 state in ToTerraformValue: %s", f.state)) + } +} + +// Type returns a Float64Type. +func (f Float64Value) Type(ctx context.Context) attr.Type { + return Float64Type{} +} + +// IsNull returns true if the Float64 represents a null value. +func (f Float64Value) IsNull() bool { + return f.state == attr.ValueStateNull +} + +// IsUnknown returns true if the Float64 represents a currently unknown value. +func (f Float64Value) IsUnknown() bool { + return f.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the Float64 value. +// The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (f Float64Value) String() string { + if f.IsUnknown() { + return attr.UnknownValueString + } + + if f.IsNull() { + return attr.NullValueString + } + + f64 := f.ValueFloat64() + return fmt.Sprintf("%f", f64) +} + +// ValueFloat64 returns the known float64 value. If Float64 is null or unknown, returns +// 0.0. +func (f Float64Value) ValueFloat64() float64 { + if f.IsNull() || f.IsUnknown() { + return float64(0.0) + } + + f64, _ := f.value.Float64() + return f64 +} + +// ValueFloat64Pointer returns a pointer to the known float64 value, nil for a +// null value, or a pointer to 0.0 for an unknown value. +func (f Float64Value) ValueFloat64Pointer() *float64 { + if f.IsNull() { + return nil + } + + if f.IsUnknown() { + f64 := float64(0.0) + return &f64 + } + + f64, _ := f.value.Float64() + return &f64 +} + +// ToFloat64Value returns Float64. +func (f Float64Value) ToFloat64Value(context.Context) (Float64Value, diag.Diagnostics) { + return f, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/int64_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/int64_type.go new file mode 100644 index 00000000..93fa1b9e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/int64_type.go @@ -0,0 +1,158 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "math/big" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Int64Typable extends attr.Type for int64 types. +// Implement this interface to create a custom Int64Type type. +type Int64Typable interface { + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + xattr.TypeWithValidate + + // ValueFromInt64 should convert the Int64 to a Int64Valuable type. + ValueFromInt64(context.Context, Int64Value) (Int64Valuable, diag.Diagnostics) +} + +var _ Int64Typable = Int64Type{} + +// Int64Type is the base framework type for an integer number. +// Int64Value is the associated value type. +type Int64Type struct{} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// type. +func (t Int64Type) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +func (t Int64Type) Equal(o attr.Type) bool { + _, ok := o.(Int64Type) + + return ok +} + +// String returns a human readable string of the type name. +func (t Int64Type) String() string { + return "basetypes.Int64Type" +} + +// TerraformType returns the tftypes.Type that should be used to represent this +// framework type. +func (t Int64Type) TerraformType(_ context.Context) tftypes.Type { + return tftypes.Number +} + +// Validate implements type validation. +func (t Int64Type) Validate(ctx context.Context, in tftypes.Value, path path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + if in.Type() == nil { + return diags + } + + if !in.Type().Equal(tftypes.Number) { + diags.AddAttributeError( + path, + "Int64 Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Expected Number value, received %T with value: %v", in, in), + ) + return diags + } + + if !in.IsKnown() || in.IsNull() { + return diags + } + + var value *big.Float + err := in.As(&value) + + if err != nil { + diags.AddAttributeError( + path, + "Int64 Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Cannot convert value to big.Float: %s", err), + ) + return diags + } + + if !value.IsInt() { + diags.AddAttributeError( + path, + "Int64 Type Validation Error", + fmt.Sprintf("Value %s is not an integer.", value), + ) + return diags + } + + _, accuracy := value.Int64() + + if accuracy != 0 { + diags.AddAttributeError( + path, + "Int64 Type Validation Error", + fmt.Sprintf("Value %s cannot be represented as a 64-bit integer.", value), + ) + return diags + } + + return diags +} + +// ValueFromInt64 returns a Int64Valuable type given a Int64Value. +func (t Int64Type) ValueFromInt64(_ context.Context, v Int64Value) (Int64Valuable, diag.Diagnostics) { + return v, nil +} + +// ValueFromTerraform returns a Value given a tftypes.Value. This is meant to +// convert the tftypes.Value into a more convenient Go type for the provider to +// consume the data with. +func (t Int64Type) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if !in.IsKnown() { + return NewInt64Unknown(), nil + } + + if in.IsNull() { + return NewInt64Null(), nil + } + + var bigF *big.Float + err := in.As(&bigF) + + if err != nil { + return nil, err + } + + if !bigF.IsInt() { + return nil, fmt.Errorf("Value %s is not an integer.", bigF) + } + + i, accuracy := bigF.Int64() + + if accuracy != 0 { + return nil, fmt.Errorf("Value %s cannot be represented as a 64-bit integer.", bigF) + } + + return NewInt64Value(i), nil +} + +// ValueType returns the Value type. +func (t Int64Type) ValueType(_ context.Context) attr.Value { + // This Value does not need to be valid. + return Int64Value{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/int64_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/int64_value.go new file mode 100644 index 00000000..bf8b3bd5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/int64_value.go @@ -0,0 +1,175 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +var ( + _ Int64Valuable = Int64Value{} +) + +// Int64Valuable extends attr.Value for int64 value types. +// Implement this interface to create a custom Int64 value type. +type Int64Valuable interface { + attr.Value + + // ToInt64Value should convert the value type to an Int64. + ToInt64Value(ctx context.Context) (Int64Value, diag.Diagnostics) +} + +// Int64ValuableWithSemanticEquals extends Int64Valuable with semantic +// equality logic. +type Int64ValuableWithSemanticEquals interface { + Int64Valuable + + // Int64SemanticEquals should return true if the given value is + // semantically equal to the current value. This logic is used to prevent + // Terraform data consistency errors and resource drift where a value change + // may have inconsequential differences, such as rounding. + // + // Only known values are compared with this method as changing a value's + // state implicitly represents a different value. + Int64SemanticEquals(context.Context, Int64Valuable) (bool, diag.Diagnostics) +} + +// NewInt64Null creates a Int64 with a null value. Determine whether the value is +// null via the Int64 type IsNull method. +func NewInt64Null() Int64Value { + return Int64Value{ + state: attr.ValueStateNull, + } +} + +// NewInt64Unknown creates a Int64 with an unknown value. Determine whether the +// value is unknown via the Int64 type IsUnknown method. +func NewInt64Unknown() Int64Value { + return Int64Value{ + state: attr.ValueStateUnknown, + } +} + +// NewInt64Value creates a Int64 with a known value. Access the value via the Int64 +// type ValueInt64 method. +func NewInt64Value(value int64) Int64Value { + return Int64Value{ + state: attr.ValueStateKnown, + value: value, + } +} + +// NewInt64PointerValue creates a Int64 with a null value if nil or a known +// value. Access the value via the Int64 type ValueInt64Pointer method. +func NewInt64PointerValue(value *int64) Int64Value { + if value == nil { + return NewInt64Null() + } + + return NewInt64Value(*value) +} + +// Int64Value represents a 64-bit integer value, exposed as an int64. +type Int64Value struct { + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState + + // value contains the known value, if not null or unknown. + value int64 +} + +// Equal returns true if `other` is an Int64 and has the same value as `i`. +func (i Int64Value) Equal(other attr.Value) bool { + o, ok := other.(Int64Value) + + if !ok { + return false + } + + if i.state != o.state { + return false + } + + if i.state != attr.ValueStateKnown { + return true + } + + return i.value == o.value +} + +// ToTerraformValue returns the data contained in the Int64 as a tftypes.Value. +func (i Int64Value) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + switch i.state { + case attr.ValueStateKnown: + if err := tftypes.ValidateValue(tftypes.Number, i.value); err != nil { + return tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), err + } + + return tftypes.NewValue(tftypes.Number, i.value), nil + case attr.ValueStateNull: + return tftypes.NewValue(tftypes.Number, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Int64 state in ToTerraformValue: %s", i.state)) + } +} + +// Type returns a Int64Type. +func (i Int64Value) Type(ctx context.Context) attr.Type { + return Int64Type{} +} + +// IsNull returns true if the Int64 represents a null value. +func (i Int64Value) IsNull() bool { + return i.state == attr.ValueStateNull +} + +// IsUnknown returns true if the Int64 represents a currently unknown value. +func (i Int64Value) IsUnknown() bool { + return i.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the Int64 value. +// The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (i Int64Value) String() string { + if i.IsUnknown() { + return attr.UnknownValueString + } + + if i.IsNull() { + return attr.NullValueString + } + + return fmt.Sprintf("%d", i.value) +} + +// ValueInt64 returns the known int64 value. If Int64 is null or unknown, returns +// 0. +func (i Int64Value) ValueInt64() int64 { + return i.value +} + +// ValueInt64Pointer returns a pointer to the known int64 value, nil for a +// null value, or a pointer to 0 for an unknown value. +func (i Int64Value) ValueInt64Pointer() *int64 { + if i.IsNull() { + return nil + } + + return &i.value +} + +// ToInt64Value returns Int64. +func (i Int64Value) ToInt64Value(context.Context) (Int64Value, diag.Diagnostics) { + return i, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/list_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/list_type.go new file mode 100644 index 00000000..ef1b8a13 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/list_type.go @@ -0,0 +1,201 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +var _ ListTypable = ListType{} + +// ListTypable extends attr.Type for list types. +// Implement this interface to create a custom ListType type. +type ListTypable interface { + attr.Type + + // ValueFromList should convert the List to a ListValuable type. + ValueFromList(context.Context, ListValue) (ListValuable, diag.Diagnostics) +} + +// ListType is an AttributeType representing a list of values. All values must +// be of the same type, which the provider must specify as the ElemType +// property. +type ListType struct { + ElemType attr.Type +} + +// ElementType returns the attr.Type elements will be created from. +func (l ListType) ElementType() attr.Type { + if l.ElemType == nil { + return missingType{} + } + + return l.ElemType +} + +// WithElementType returns a ListType that is identical to `l`, but with the +// element type set to `typ`. +func (l ListType) WithElementType(typ attr.Type) attr.TypeWithElementType { + return ListType{ElemType: typ} +} + +// TerraformType returns the tftypes.Type that should be used to +// represent this type. This constrains what user input will be +// accepted and what kind of data can be set in state. The framework +// will use this to translate the AttributeType to something Terraform +// can understand. +func (l ListType) TerraformType(ctx context.Context) tftypes.Type { + return tftypes.List{ + ElementType: l.ElementType().TerraformType(ctx), + } +} + +// ValueFromTerraform returns an attr.Value given a tftypes.Value. +// This is meant to convert the tftypes.Value into a more convenient Go +// type for the provider to consume the data with. +func (l ListType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewListNull(l.ElementType()), nil + } + + // MAINTAINER NOTE: + // ListType does not support DynamicType as an element type. It is not explicitly prevented from being created with the + // Framework type system, but the Framework-supported ListAttribute, ListNestedAttribute, and ListNestedBlock all prevent DynamicType + // from being used as an element type. An attempt to use DynamicType as the element type will eventually lead you to an error on this line :) + // + // In the future, if we ever need to support a list of dynamic element types, this type equality check will need to be modified to allow + // dynamic types to not return an error, as the tftypes.Value coming in (if known) will be a concrete value, for example: + // + // - l.TerraformType(ctx): tftypes.List[tftypes.DynamicPseudoType] + // - in.Type(): tftypes.List[tftypes.String] + // + // The `ValueFromTerraform` function for a dynamic type will be able create the correct concrete dynamic value with this modification in place. + // + if !in.Type().Equal(l.TerraformType(ctx)) { + return nil, fmt.Errorf("can't use %s as value of List with ElementType %T, can only use %s values", in.String(), l.ElementType(), l.ElementType().TerraformType(ctx).String()) + } + if !in.IsKnown() { + return NewListUnknown(l.ElementType()), nil + } + if in.IsNull() { + return NewListNull(l.ElementType()), nil + } + val := []tftypes.Value{} + err := in.As(&val) + if err != nil { + return nil, err + } + elems := make([]attr.Value, 0, len(val)) + for _, elem := range val { + av, err := l.ElementType().ValueFromTerraform(ctx, elem) + if err != nil { + return nil, err + } + elems = append(elems, av) + } + // ValueFromTerraform above on each element should make this safe. + // Otherwise, this will need to do some Diagnostics to error conversion. + return NewListValueMust(l.ElementType(), elems), nil +} + +// Equal returns true if `o` is also a ListType and has the same ElemType. +func (l ListType) Equal(o attr.Type) bool { + // Preserve prior ElemType nil check behavior + if l.ElementType().Equal(missingType{}) { + return false + } + + other, ok := o.(ListType) + + if !ok { + return false + } + + return l.ElementType().Equal(other.ElementType()) +} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// list. +func (l ListType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + if _, ok := step.(tftypes.ElementKeyInt); !ok { + return nil, fmt.Errorf("cannot apply step %T to ListType", step) + } + + return l.ElementType(), nil +} + +// String returns a human-friendly description of the ListType. +func (l ListType) String() string { + return "types.ListType[" + l.ElementType().String() + "]" +} + +// Validate validates all elements of the list that are of type +// xattr.TypeWithValidate. +func (l ListType) Validate(ctx context.Context, in tftypes.Value, path path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + if in.Type() == nil { + return diags + } + + if !in.Type().Is(tftypes.List{}) { + err := fmt.Errorf("expected List value, received %T with value: %v", in, in) + diags.AddAttributeError( + path, + "List Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return diags + } + + if !in.IsKnown() || in.IsNull() { + return diags + } + + var elems []tftypes.Value + + if err := in.As(&elems); err != nil { + diags.AddAttributeError( + path, + "List Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return diags + } + + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + validatableType, isValidatable := l.ElementType().(xattr.TypeWithValidate) + if !isValidatable { + return diags + } + + for index, elem := range elems { + if !elem.IsFullyKnown() { + continue + } + diags = append(diags, validatableType.Validate(ctx, elem, path.AtListIndex(index))...) + } + + return diags +} + +// ValueType returns the Value type. +func (l ListType) ValueType(_ context.Context) attr.Value { + return ListValue{ + elementType: l.ElementType(), + } +} + +// ValueFromList returns a ListValuable type given a List. +func (l ListType) ValueFromList(_ context.Context, list ListValue) (ListValuable, diag.Diagnostics) { + return list, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/list_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/list_value.go new file mode 100644 index 00000000..d0ec0302 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/list_value.go @@ -0,0 +1,334 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +var _ ListValuable = &ListValue{} + +// ListValuable extends attr.Value for list value types. +// Implement this interface to create a custom List value type. +type ListValuable interface { + attr.Value + + // ToListValue should convert the value type to a List. + ToListValue(ctx context.Context) (ListValue, diag.Diagnostics) +} + +// ListValuableWithSemanticEquals extends ListValuable with semantic equality +// logic. +type ListValuableWithSemanticEquals interface { + ListValuable + + // ListSemanticEquals should return true if the given value is + // semantically equal to the current value. This logic is used to prevent + // Terraform data consistency errors and resource drift where a value change + // may have inconsequential differences, such as computed elements added by + // a remote system. + // + // Only known values are compared with this method as changing a value's + // state implicitly represents a different value. + ListSemanticEquals(context.Context, ListValuable) (bool, diag.Diagnostics) +} + +// NewListNull creates a List with a null value. Determine whether the value is +// null via the List type IsNull method. +func NewListNull(elementType attr.Type) ListValue { + return ListValue{ + elementType: elementType, + state: attr.ValueStateNull, + } +} + +// NewListUnknown creates a List with an unknown value. Determine whether the +// value is unknown via the List type IsUnknown method. +func NewListUnknown(elementType attr.Type) ListValue { + return ListValue{ + elementType: elementType, + state: attr.ValueStateUnknown, + } +} + +// NewListValue creates a List with a known value. Access the value via the List +// type Elements or ElementsAs methods. +func NewListValue(elementType attr.Type, elements []attr.Value) (ListValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for idx, element := range elements { + if !elementType.Equal(element.Type(ctx)) { + diags.AddError( + "Invalid List Element Type", + "While creating a List value, an invalid element was detected. "+ + "A List must use the single, given element type. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("List Element Type: %s\n", elementType.String())+ + fmt.Sprintf("List Index (%d) Element Type: %s", idx, element.Type(ctx)), + ) + } + } + + if diags.HasError() { + return NewListUnknown(elementType), diags + } + + return ListValue{ + elementType: elementType, + elements: elements, + state: attr.ValueStateKnown, + }, nil +} + +// NewListValueFrom creates a List with a known value, using reflection rules. +// The elements must be a slice which can convert into the given element type. +// Access the value via the List type Elements or ElementsAs methods. +func NewListValueFrom(ctx context.Context, elementType attr.Type, elements any) (ListValue, diag.Diagnostics) { + attrValue, diags := reflect.FromValue( + ctx, + ListType{ElemType: elementType}, + elements, + path.Empty(), + ) + + if diags.HasError() { + return NewListUnknown(elementType), diags + } + + list, ok := attrValue.(ListValue) + + // This should not happen, but ensure there is an error if it does. + if !ok { + diags.AddError( + "Unable to Convert List Value", + "An unexpected result occurred when creating a List using NewListValueFrom. "+ + "This is an issue with terraform-plugin-framework and should be reported to the provider developers.", + ) + } + + return list, diags +} + +// NewListValueMust creates a List with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the List +// type Elements or ElementsAs methods. +// +// This creation function is only recommended to create List values which will +// not potentially affect practitioners, such as testing, or exhaustively +// tested provider logic. +func NewListValueMust(elementType attr.Type, elements []attr.Value) ListValue { + list, diags := NewListValue(elementType, elements) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewListValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return list +} + +// ListValue represents a list of attr.Values, all of the same type, indicated +// by ElemType. +type ListValue struct { + // elements is the collection of known values in the List. + elements []attr.Value + + // elementType is the type of the elements in the List. + elementType attr.Type + + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState +} + +// Elements returns a copy of the collection of elements for the List. +func (l ListValue) Elements() []attr.Value { + // Ensure callers cannot mutate the internal elements + result := make([]attr.Value, 0, len(l.elements)) + result = append(result, l.elements...) + + return result +} + +// ElementsAs populates `target` with the elements of the ListValue, throwing an +// error if the elements cannot be stored in `target`. +func (l ListValue) ElementsAs(ctx context.Context, target interface{}, allowUnhandled bool) diag.Diagnostics { + // we need a tftypes.Value for this List to be able to use it with our + // reflection code + values, err := l.ToTerraformValue(ctx) + if err != nil { + return diag.Diagnostics{ + diag.NewErrorDiagnostic( + "List Element Conversion Error", + "An unexpected error was encountered trying to convert list elements. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ), + } + } + return reflect.Into(ctx, ListType{ElemType: l.elementType}, values, target, reflect.Options{ + UnhandledNullAsEmpty: allowUnhandled, + UnhandledUnknownAsEmpty: allowUnhandled, + }, path.Empty()) +} + +// ElementType returns the element type for the List. +func (l ListValue) ElementType(_ context.Context) attr.Type { + return l.elementType +} + +// Type returns a ListType with the same element type as `l`. +func (l ListValue) Type(ctx context.Context) attr.Type { + return ListType{ElemType: l.ElementType(ctx)} +} + +// ToTerraformValue returns the data contained in the List as a tftypes.Value. +func (l ListValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + listType := tftypes.List{ElementType: l.ElementType(ctx).TerraformType(ctx)} + + switch l.state { + case attr.ValueStateKnown: + // MAINTAINER NOTE: + // ListValue does not support DynamicType as an element type. It is not explicitly prevented from being created with the + // Framework type system, but the Framework-supported ListAttribute, ListNestedAttribute, and ListNestedBlock all prevent DynamicType + // from being used as an element type. + // + // In the future, if we ever need to support a list of dynamic element types, this tftypes.List creation logic will need to be modified to ensure + // that known values contain the exact same concrete element type, specifically with unknown and null values. Dynamic values will return the correct concrete + // element type for known values from `elem.ToTerraformValue`, but unknown and null values will be tftypes.DynamicPseudoType, causing an error due to multiple element + // types in a tftypes.List. + // + // Unknown and null element types of tftypes.DynamicPseudoType must be recreated as the concrete element type unknown/null value. This can be done by checking `l.elements` + // for a single concrete type (i.e. not tftypes.DynamicPseudoType), and using that concrete type to create unknown and null dynamic values later. + // + vals := make([]tftypes.Value, 0, len(l.elements)) + + for _, elem := range l.elements { + val, err := elem.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(listType, tftypes.UnknownValue), err + } + + vals = append(vals, val) + } + + if err := tftypes.ValidateValue(listType, vals); err != nil { + return tftypes.NewValue(listType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(listType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(listType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(listType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled List state in ToTerraformValue: %s", l.state)) + } +} + +// Equal returns true if the given attr.Value is also a ListValue, has the +// same element type, same value state, and contains exactly the element values +// as defined by the Equal method of the element type. +func (l ListValue) Equal(o attr.Value) bool { + other, ok := o.(ListValue) + + if !ok { + return false + } + + // A list with no elementType is an invalid state + if l.elementType == nil || other.elementType == nil { + return false + } + + if !l.elementType.Equal(other.elementType) { + return false + } + + if l.state != other.state { + return false + } + + if l.state != attr.ValueStateKnown { + return true + } + + if len(l.elements) != len(other.elements) { + return false + } + + for idx, lElem := range l.elements { + otherElem := other.elements[idx] + + if !lElem.Equal(otherElem) { + return false + } + } + + return true +} + +// IsNull returns true if the List represents a null value. +func (l ListValue) IsNull() bool { + return l.state == attr.ValueStateNull +} + +// IsUnknown returns true if the List represents a currently unknown value. +// Returns false if the List has a known number of elements, even if all are +// unknown values. +func (l ListValue) IsUnknown() bool { + return l.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the List value. +// The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (l ListValue) String() string { + if l.IsUnknown() { + return attr.UnknownValueString + } + + if l.IsNull() { + return attr.NullValueString + } + + var res strings.Builder + + res.WriteString("[") + for i, e := range l.Elements() { + if i != 0 { + res.WriteString(",") + } + res.WriteString(e.String()) + } + res.WriteString("]") + + return res.String() +} + +// ToListValue returns the List. +func (l ListValue) ToListValue(context.Context) (ListValue, diag.Diagnostics) { + return l, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/map_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/map_type.go new file mode 100644 index 00000000..d7997a68 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/map_type.go @@ -0,0 +1,204 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +var _ MapTypable = MapType{} + +// MapTypable extends attr.Type for map types. +// Implement this interface to create a custom MapType type. +type MapTypable interface { + attr.Type + + // ValueFromMap should convert the Map to a MapValuable type. + ValueFromMap(context.Context, MapValue) (MapValuable, diag.Diagnostics) +} + +// MapType is an AttributeType representing a map of values. All values must +// be of the same type, which the provider must specify as the ElemType +// property. Keys will always be strings. +type MapType struct { + ElemType attr.Type +} + +// WithElementType returns a new copy of the type with its element type set. +func (m MapType) WithElementType(typ attr.Type) attr.TypeWithElementType { + return MapType{ + ElemType: typ, + } +} + +// ElementType returns the type's element type. +func (m MapType) ElementType() attr.Type { + if m.ElemType == nil { + return missingType{} + } + + return m.ElemType +} + +// TerraformType returns the tftypes.Type that should be used to represent this +// type. This constrains what user input will be accepted and what kind of data +// can be set in state. The framework will use this to translate the +// AttributeType to something Terraform can understand. +func (m MapType) TerraformType(ctx context.Context) tftypes.Type { + return tftypes.Map{ + ElementType: m.ElementType().TerraformType(ctx), + } +} + +// ValueFromTerraform returns an attr.Value given a tftypes.Value. This is +// meant to convert the tftypes.Value into a more convenient Go type for the +// provider to consume the data with. +func (m MapType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewMapNull(m.ElementType()), nil + } + if !in.Type().Is(tftypes.Map{}) { + return nil, fmt.Errorf("can't use %s as value of MapValue, can only use tftypes.Map values", in.String()) + } + + // MAINTAINER NOTE: + // MapType does not support DynamicType as an element type. It is not explicitly prevented from being created with the + // Framework type system, but the Framework-supported MapAttribute and MapNestedAttribute prevent DynamicType + // from being used as an element type. An attempt to use DynamicType as the element type will eventually lead you to an error on this line :) + // + // In the future, if we ever need to support a map of dynamic element types, this type equality check will need to be modified to allow + // dynamic types to not return an error, as the tftypes.Value coming in (if known) will be a concrete value, for example: + // + // - m.TerraformType(ctx): tftypes.Map[tftypes.DynamicPseudoType] + // - in.Type(): tftypes.Map[tftypes.String] + // + // The `ValueFromTerraform` function for a dynamic type will be able create the correct concrete dynamic value with this modification in place. + // + if !in.Type().Equal(tftypes.Map{ElementType: m.ElementType().TerraformType(ctx)}) { + return nil, fmt.Errorf("can't use %s as value of Map with ElementType %T, can only use %s values", in.String(), m.ElementType(), m.ElementType().TerraformType(ctx).String()) + } + if !in.IsKnown() { + return NewMapUnknown(m.ElementType()), nil + } + if in.IsNull() { + return NewMapNull(m.ElementType()), nil + } + val := map[string]tftypes.Value{} + err := in.As(&val) + if err != nil { + return nil, err + } + elems := make(map[string]attr.Value, len(val)) + for key, elem := range val { + av, err := m.ElementType().ValueFromTerraform(ctx, elem) + if err != nil { + return nil, err + } + elems[key] = av + } + // ValueFromTerraform above on each element should make this safe. + // Otherwise, this will need to do some Diagnostics to error conversion. + return NewMapValueMust(m.ElementType(), elems), nil +} + +// Equal returns true if `o` is also a MapType and has the same ElemType. +func (m MapType) Equal(o attr.Type) bool { + // Preserve prior ElemType nil check behavior + if m.ElementType().Equal(missingType{}) { + return false + } + + other, ok := o.(MapType) + + if !ok { + return false + } + + return m.ElementType().Equal(other.ElementType()) +} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// map. +func (m MapType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + if _, ok := step.(tftypes.ElementKeyString); !ok { + return nil, fmt.Errorf("cannot apply step %T to MapType", step) + } + + return m.ElementType(), nil +} + +// String returns a human-friendly description of the MapType. +func (m MapType) String() string { + return "types.MapType[" + m.ElementType().String() + "]" +} + +// Validate validates all elements of the map that are of type +// xattr.TypeWithValidate. +func (m MapType) Validate(ctx context.Context, in tftypes.Value, path path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + if in.Type() == nil { + return diags + } + + if !in.Type().Is(tftypes.Map{}) { + err := fmt.Errorf("expected Map value, received %T with value: %v", in, in) + diags.AddAttributeError( + path, + "Map Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return diags + } + + if !in.IsKnown() || in.IsNull() { + return diags + } + + var elems map[string]tftypes.Value + + if err := in.As(&elems); err != nil { + diags.AddAttributeError( + path, + "Map Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return diags + } + + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + validatableType, isValidatable := m.ElementType().(xattr.TypeWithValidate) + if !isValidatable { + return diags + } + + for index, elem := range elems { + if !elem.IsFullyKnown() { + continue + } + diags = append(diags, validatableType.Validate(ctx, elem, path.AtMapKey(index))...) + } + + return diags +} + +// ValueType returns the Value type. +func (m MapType) ValueType(_ context.Context) attr.Value { + return MapValue{ + elementType: m.ElementType(), + } +} + +// ValueFromMap returns a MapValuable type given a Map. +func (m MapType) ValueFromMap(_ context.Context, ma MapValue) (MapValuable, diag.Diagnostics) { + return ma, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/map_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/map_value.go new file mode 100644 index 00000000..7d819eca --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/map_value.go @@ -0,0 +1,348 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "sort" + "strings" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +var _ MapValuable = &MapValue{} + +// MapValuable extends attr.Value for map value types. +// Implement this interface to create a custom Map value type. +type MapValuable interface { + attr.Value + + // ToMapValue should convert the value type to a Map. + ToMapValue(ctx context.Context) (MapValue, diag.Diagnostics) +} + +// MapValuableWithSemanticEquals extends MapValuable with semantic equality +// logic. +type MapValuableWithSemanticEquals interface { + MapValuable + + // MapSemanticEquals should return true if the given value is + // semantically equal to the current value. This logic is used to prevent + // Terraform data consistency errors and resource drift where a value change + // may have inconsequential differences, such as computed elements added by + // a remote system. + // + // Only known values are compared with this method as changing a value's + // state implicitly represents a different value. + MapSemanticEquals(context.Context, MapValuable) (bool, diag.Diagnostics) +} + +// NewMapNull creates a Map with a null value. Determine whether the value is +// null via the Map type IsNull method. +func NewMapNull(elementType attr.Type) MapValue { + return MapValue{ + elementType: elementType, + state: attr.ValueStateNull, + } +} + +// NewMapUnknown creates a Map with an unknown value. Determine whether the +// value is unknown via the Map type IsUnknown method. +func NewMapUnknown(elementType attr.Type) MapValue { + return MapValue{ + elementType: elementType, + state: attr.ValueStateUnknown, + } +} + +// NewMapValue creates a Map with a known value. Access the value via the Map +// type Elements or ElementsAs methods. +func NewMapValue(elementType attr.Type, elements map[string]attr.Value) (MapValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for key, element := range elements { + if !elementType.Equal(element.Type(ctx)) { + diags.AddError( + "Invalid Map Element Type", + "While creating a Map value, an invalid element was detected. "+ + "A Map must use the single, given element type. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Map Element Type: %s\n", elementType.String())+ + fmt.Sprintf("Map Key (%s) Element Type: %s", key, element.Type(ctx)), + ) + } + } + + if diags.HasError() { + return NewMapUnknown(elementType), diags + } + + return MapValue{ + elementType: elementType, + elements: elements, + state: attr.ValueStateKnown, + }, nil +} + +// NewMapValueFrom creates a Map with a known value, using reflection rules. +// The elements must be a map of string keys to values which can convert into +// the given element type. Access the value via the Map type Elements or +// ElementsAs methods. +func NewMapValueFrom(ctx context.Context, elementType attr.Type, elements any) (MapValue, diag.Diagnostics) { + attrValue, diags := reflect.FromValue( + ctx, + MapType{ElemType: elementType}, + elements, + path.Empty(), + ) + + if diags.HasError() { + return NewMapUnknown(elementType), diags + } + + m, ok := attrValue.(MapValue) + + // This should not happen, but ensure there is an error if it does. + if !ok { + diags.AddError( + "Unable to Convert Map Value", + "An unexpected result occurred when creating a Map using MapValueFrom. "+ + "This is an issue with terraform-plugin-framework and should be reported to the provider developers.", + ) + } + + return m, diags +} + +// NewMapValueMust creates a Map with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the Map +// type Elements or ElementsAs methods. +// +// This creation function is only recommended to create Map values which will +// not potentially effect practitioners, such as testing, or exhaustively +// tested provider logic. +func NewMapValueMust(elementType attr.Type, elements map[string]attr.Value) MapValue { + m, diags := NewMapValue(elementType, elements) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("MapValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return m +} + +// MapValue represents a mapping of string keys to attr.Value values of a single +// type. +type MapValue struct { + // elements is the mapping of known values in the Map. + elements map[string]attr.Value + + // elementType is the type of the elements in the Map. + elementType attr.Type + + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState +} + +// Elements returns a copy of the mapping of elements for the Map. +func (m MapValue) Elements() map[string]attr.Value { + // Ensure callers cannot mutate the internal elements + result := make(map[string]attr.Value, len(m.elements)) + + for key, value := range m.elements { + result[key] = value + } + + return result +} + +// ElementsAs populates `target` with the elements of the MapValue, throwing an +// error if the elements cannot be stored in `target`. +func (m MapValue) ElementsAs(ctx context.Context, target interface{}, allowUnhandled bool) diag.Diagnostics { + // we need a tftypes.Value for this Map to be able to use it with our + // reflection code + val, err := m.ToTerraformValue(ctx) + if err != nil { + err := fmt.Errorf("error getting Terraform value for map: %w", err) + return diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Map Conversion Error", + "An unexpected error was encountered trying to convert the map into an equivalent Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ), + } + } + + return reflect.Into(ctx, MapType{ElemType: m.elementType}, val, target, reflect.Options{ + UnhandledNullAsEmpty: allowUnhandled, + UnhandledUnknownAsEmpty: allowUnhandled, + }, path.Empty()) +} + +// ElementType returns the element type for the Map. +func (m MapValue) ElementType(_ context.Context) attr.Type { + return m.elementType +} + +// Type returns a MapType with the same element type as `m`. +func (m MapValue) Type(ctx context.Context) attr.Type { + return MapType{ElemType: m.ElementType(ctx)} +} + +// ToTerraformValue returns the data contained in the Map as a tftypes.Value. +func (m MapValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + mapType := tftypes.Map{ElementType: m.ElementType(ctx).TerraformType(ctx)} + + switch m.state { + case attr.ValueStateKnown: + // MAINTAINER NOTE: + // MapValue does not support DynamicType as an element type. It is not explicitly prevented from being created with the + // Framework type system, but the Framework-supported MapAttribute and MapNestedAttribute prevent DynamicType + // from being used as an element type. + // + // In the future, if we ever need to support a map of dynamic element types, this tftypes.Map creation logic will need to be modified to ensure + // that known values contain the exact same concrete element type, specifically with unknown and null values. Dynamic values will return the correct concrete + // element type for known values from `elem.ToTerraformValue`, but unknown and null values will be tftypes.DynamicPseudoType, causing an error due to multiple element + // types in a tftypes.Map. + // + // Unknown and null element types of tftypes.DynamicPseudoType must be recreated as the concrete element type unknown/null value. This can be done by checking `m.elements` + // for a single concrete type (i.e. not tftypes.DynamicPseudoType), and using that concrete type to create unknown and null dynamic values later. + // + vals := make(map[string]tftypes.Value, len(m.elements)) + + for key, elem := range m.elements { + val, err := elem.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(mapType, tftypes.UnknownValue), err + } + + vals[key] = val + } + + if err := tftypes.ValidateValue(mapType, vals); err != nil { + return tftypes.NewValue(mapType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(mapType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(mapType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(mapType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Map state in ToTerraformValue: %s", m.state)) + } +} + +// Equal returns true if the given attr.Value is also a MapValue, has the +// same element type, same value state, and contains exactly the element values +// as defined by the Equal method of the element type. +func (m MapValue) Equal(o attr.Value) bool { + other, ok := o.(MapValue) + + if !ok { + return false + } + + // A map with no elementType is an invalid state + if m.elementType == nil || other.elementType == nil { + return false + } + + if !m.elementType.Equal(other.elementType) { + return false + } + + if m.state != other.state { + return false + } + + if m.state != attr.ValueStateKnown { + return true + } + + if len(m.elements) != len(other.elements) { + return false + } + + for key, mElem := range m.elements { + otherElem := other.elements[key] + + if !mElem.Equal(otherElem) { + return false + } + } + + return true +} + +// IsNull returns true if the Map represents a null value. +func (m MapValue) IsNull() bool { + return m.state == attr.ValueStateNull +} + +// IsUnknown returns true if the Map represents a currently unknown value. +// Returns false if the Map has a known number of elements, even if all are +// unknown values. +func (m MapValue) IsUnknown() bool { + return m.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the Map value. +// The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (m MapValue) String() string { + if m.IsUnknown() { + return attr.UnknownValueString + } + + if m.IsNull() { + return attr.NullValueString + } + + // We want the output to be consistent, so we sort the output by key + keys := make([]string, 0, len(m.Elements())) + for k := range m.Elements() { + keys = append(keys, k) + } + sort.Strings(keys) + + var res strings.Builder + + res.WriteString("{") + for i, k := range keys { + if i != 0 { + res.WriteString(",") + } + res.WriteString(fmt.Sprintf("%q:%s", k, m.Elements()[k].String())) + } + res.WriteString("}") + + return res.String() +} + +// ToMapValue returns the Map. +func (m MapValue) ToMapValue(context.Context) (MapValue, diag.Diagnostics) { + return m, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/missing_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/missing_type.go new file mode 100644 index 00000000..96079478 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/missing_type.go @@ -0,0 +1,59 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +var _ attr.Type = missingType{} + +// missingType is a placeholder attr.Type implementation for when type +// information is missing. This type is never valid for real usage, which is why +// it is unexported, but it is primarily used by other base types when an +// expected attr.Type field is nil for panic prevention and troubleshooting. +// Ideally those other base type implementations would make it impossible to +// create a situation which needs this, but those exported APIs are protected by +// compatibility promises until a major version. +type missingType struct{} + +// ApplyTerraform5AttributePathStep always returns an error. +func (t missingType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +func (t missingType) Equal(o attr.Type) bool { + _, ok := o.(missingType) + + return ok +} + +// String returns a human readable string of the type. +func (t missingType) String() string { + return "!!! MISSING TYPE !!!" +} + +// TerraformType returns DynamicPseudoType. +func (t missingType) TerraformType(_ context.Context) tftypes.Type { + // Ideally, upstream would implement an "invalid" primitive type for this + // situation, but DynamicPseudoType is an alternative unexpected type in + // the framework until it potentially implements its own dynamic type + // handling. + return tftypes.DynamicPseudoType +} + +// ValueFromTerraform always returns an error. +func (t missingType) ValueFromTerraform(_ context.Context, _ tftypes.Value) (attr.Value, error) { + return missingValue{}, fmt.Errorf("missing type information; cannot create value") +} + +// ValueType returns the missingValue type. +func (t missingType) ValueType(_ context.Context) attr.Value { + return missingValue{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/missing_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/missing_value.go new file mode 100644 index 00000000..37f600d7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/missing_value.go @@ -0,0 +1,61 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +var _ attr.Value = missingValue{} + +// missingValue is a placeholder attr.Value implementation for when type +// information is missing. This type is never valid for real usage, which is why +// it is unexported, but it is primarily used by other base types when an +// expected attr.Value field is nil for panic prevention and troubleshooting. +// Ideally those other base type implementations would make it impossible to +// create a situation which needs this, but those exported APIs are protected by +// compatibility promises until a major version. +type missingValue struct{} + +// Equal returns true if the given value is a missingValue. +func (v missingValue) Equal(o attr.Value) bool { + _, ok := o.(missingValue) + + return ok +} + +// IsNull returns false. +func (v missingValue) IsNull() bool { + // Short of causing a panic, this method must choose a return value and + // false was chosen so it is always "known". + return false +} + +// IsUnknown returns false. +func (v missingValue) IsUnknown() bool { + // Short of causing a panic, this method must choose a return value and + // false was chosen so it is always "known". + return false +} + +// String returns a human-readable representation of the value. +// +// The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (v missingValue) String() string { + return "!!! MISSING VALUE !!!" +} + +// ToTerraformValue always returns an error. +func (v missingValue) ToTerraformValue(_ context.Context) (tftypes.Value, error) { + return tftypes.Value{}, nil +} + +// Type returns missingType. +func (v missingValue) Type(_ context.Context) attr.Type { + return missingType{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/number_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/number_type.go new file mode 100644 index 00000000..3cd2a92f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/number_type.go @@ -0,0 +1,87 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "math/big" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// NumberTypable extends attr.Type for number types. +// Implement this interface to create a custom NumberType type. +type NumberTypable interface { + attr.Type + + // ValueFromNumber should convert the Number to a NumberValuable type. + ValueFromNumber(context.Context, NumberValue) (NumberValuable, diag.Diagnostics) +} + +var _ NumberTypable = NumberType{} + +// NumberType is the base framework type for a floating point number. +// NumberValue is the associated value type. +type NumberType struct{} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// type. +func (t NumberType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +func (t NumberType) Equal(o attr.Type) bool { + _, ok := o.(NumberType) + + return ok +} + +// String returns a human readable string of the type name. +func (t NumberType) String() string { + return "basetypes.NumberType" +} + +// TerraformType returns the tftypes.Type that should be used to represent this +// framework type. +func (t NumberType) TerraformType(_ context.Context) tftypes.Type { + return tftypes.Number +} + +// ValueFromNumber returns a NumberValuable type given a NumberValue. +func (t NumberType) ValueFromNumber(_ context.Context, v NumberValue) (NumberValuable, diag.Diagnostics) { + return v, nil +} + +// ValueFromTerraform returns a Value given a tftypes.Value. This is meant to +// convert the tftypes.Value into a more convenient Go type for the provider to +// consume the data with. +func (t NumberType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if !in.IsKnown() { + return NewNumberUnknown(), nil + } + + if in.IsNull() { + return NewNumberNull(), nil + } + + n := big.NewFloat(0) + + err := in.As(&n) + + if err != nil { + return nil, err + } + + return NewNumberValue(n), nil +} + +// ValueType returns the Value type. +func (t NumberType) ValueType(_ context.Context) attr.Value { + // This Value does not need to be valid. + return NumberValue{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/number_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/number_value.go new file mode 100644 index 00000000..28c89de5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/number_value.go @@ -0,0 +1,165 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "math/big" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +var ( + _ NumberValuable = NumberValue{} +) + +// NumberValuable extends attr.Value for number value types. +// Implement this interface to create a custom Number value type. +type NumberValuable interface { + attr.Value + + // ToNumberValue should convert the value type to a Number. + ToNumberValue(ctx context.Context) (NumberValue, diag.Diagnostics) +} + +// NumberValuableWithSemanticEquals extends NumberValuable with semantic +// equality logic. +type NumberValuableWithSemanticEquals interface { + NumberValuable + + // NumberSemanticEquals should return true if the given value is + // semantically equal to the current value. This logic is used to prevent + // Terraform data consistency errors and resource drift where a value change + // may have inconsequential differences, such as rounding. + // + // Only known values are compared with this method as changing a value's + // state implicitly represents a different value. + NumberSemanticEquals(context.Context, NumberValuable) (bool, diag.Diagnostics) +} + +// NewNumberNull creates a Number with a null value. Determine whether the value is +// null via the Number type IsNull method. +func NewNumberNull() NumberValue { + return NumberValue{ + state: attr.ValueStateNull, + } +} + +// NewNumberUnknown creates a Number with an unknown value. Determine whether the +// value is unknown via the Number type IsUnknown method. +func NewNumberUnknown() NumberValue { + return NumberValue{ + state: attr.ValueStateUnknown, + } +} + +// NewNumberValue creates a Number with a known value. Access the value via the Number +// type ValueBigFloat method. If the given value is nil, a null Number is created. +func NewNumberValue(value *big.Float) NumberValue { + if value == nil { + return NewNumberNull() + } + + return NumberValue{ + state: attr.ValueStateKnown, + value: value, + } +} + +// NumberValue represents a number value, exposed as a *big.Float. Numbers can be +// floats or integers. +type NumberValue struct { + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState + + // value contains the known value, if not null or unknown. + value *big.Float +} + +// Type returns a NumberType. +func (n NumberValue) Type(_ context.Context) attr.Type { + return NumberType{} +} + +// ToTerraformValue returns the data contained in the Number as a tftypes.Value. +func (n NumberValue) ToTerraformValue(_ context.Context) (tftypes.Value, error) { + switch n.state { + case attr.ValueStateKnown: + if n.value == nil { + return tftypes.NewValue(tftypes.Number, nil), nil + } + + if err := tftypes.ValidateValue(tftypes.Number, n.value); err != nil { + return tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), err + } + + return tftypes.NewValue(tftypes.Number, n.value), nil + case attr.ValueStateNull: + return tftypes.NewValue(tftypes.Number, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Number state in ToTerraformValue: %s", n.state)) + } +} + +// Equal returns true if `other` is a Number and has the same value as `n`. +func (n NumberValue) Equal(other attr.Value) bool { + o, ok := other.(NumberValue) + + if !ok { + return false + } + + if n.state != o.state { + return false + } + + if n.state != attr.ValueStateKnown { + return true + } + + return n.value.Cmp(o.value) == 0 +} + +// IsNull returns true if the Number represents a null value. +func (n NumberValue) IsNull() bool { + return n.state == attr.ValueStateNull +} + +// IsUnknown returns true if the Number represents a currently unknown value. +func (n NumberValue) IsUnknown() bool { + return n.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the Number value. +// The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (n NumberValue) String() string { + if n.IsUnknown() { + return attr.UnknownValueString + } + + if n.IsNull() { + return attr.NullValueString + } + + return n.value.String() +} + +// ValueBigFloat returns the known *big.Float value. If Number is null or unknown, returns +// 0.0. +func (n NumberValue) ValueBigFloat() *big.Float { + return n.value +} + +// ToNumberValue returns Number. +func (n NumberValue) ToNumberValue(context.Context) (NumberValue, diag.Diagnostics) { + return n, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/object_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/object_type.go new file mode 100644 index 00000000..9136a59b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/object_type.go @@ -0,0 +1,174 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "sort" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +var _ ObjectTypable = ObjectType{} + +// ObjectTypable extends attr.Type for object types. +// Implement this interface to create a custom ObjectType type. +type ObjectTypable interface { + attr.Type + + // ValueFromObject should convert the Object to an ObjectValuable type. + ValueFromObject(context.Context, ObjectValue) (ObjectValuable, diag.Diagnostics) +} + +// ObjectType is an AttributeType representing an object. +type ObjectType struct { + AttrTypes map[string]attr.Type +} + +// WithAttributeTypes returns a new copy of the type with its attribute types +// set. +func (o ObjectType) WithAttributeTypes(typs map[string]attr.Type) attr.TypeWithAttributeTypes { + return ObjectType{ + AttrTypes: typs, + } +} + +// AttributeTypes returns a copy of the type's attribute types. +func (o ObjectType) AttributeTypes() map[string]attr.Type { + // Ensure callers cannot mutate the value + result := make(map[string]attr.Type, len(o.AttrTypes)) + + for key, value := range o.AttrTypes { + result[key] = value + } + + return result +} + +// TerraformType returns the tftypes.Type that should be used to +// represent this type. This constrains what user input will be +// accepted and what kind of data can be set in state. The framework +// will use this to translate the AttributeType to something Terraform +// can understand. +func (o ObjectType) TerraformType(ctx context.Context) tftypes.Type { + attributeTypes := map[string]tftypes.Type{} + for k, v := range o.AttrTypes { + attributeTypes[k] = v.TerraformType(ctx) + } + return tftypes.Object{ + AttributeTypes: attributeTypes, + } +} + +// ValueFromTerraform returns an attr.Value given a tftypes.Value. +// This is meant to convert the tftypes.Value into a more convenient Go +// type for the provider to consume the data with. +func (o ObjectType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewObjectNull(o.AttrTypes), nil + } + if !in.Type().Equal(o.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", o.TerraformType(ctx), in.Type()) + } + if !in.IsKnown() { + return NewObjectUnknown(o.AttrTypes), nil + } + if in.IsNull() { + return NewObjectNull(o.AttrTypes), nil + } + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + err := in.As(&val) + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := o.AttrTypes[k].ValueFromTerraform(ctx, v) + if err != nil { + return nil, err + } + attributes[k] = a + } + // ValueFromTerraform above on each attribute should make this safe. + // Otherwise, this will need to do some Diagnostics to error conversion. + return NewObjectValueMust(o.AttrTypes, attributes), nil +} + +// Equal returns true if `candidate` is also an ObjectType and has the same +// AttributeTypes. +func (o ObjectType) Equal(candidate attr.Type) bool { + other, ok := candidate.(ObjectType) + if !ok { + return false + } + if len(other.AttrTypes) != len(o.AttrTypes) { + return false + } + for k, v := range o.AttrTypes { + attr, ok := other.AttrTypes[k] + if !ok { + return false + } + if !v.Equal(attr) { + return false + } + } + return true +} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// object. +func (o ObjectType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + attrName, ok := step.(tftypes.AttributeName) + + if !ok { + return nil, fmt.Errorf("cannot apply step %T to ObjectType", step) + } + + attrType, ok := o.AttrTypes[string(attrName)] + + if !ok { + return nil, fmt.Errorf("undefined attribute name %s in ObjectType", attrName) + } + + return attrType, nil +} + +// String returns a human-friendly description of the ObjectType. +func (o ObjectType) String() string { + var res strings.Builder + res.WriteString("types.ObjectType[") + keys := make([]string, 0, len(o.AttrTypes)) + for k := range o.AttrTypes { + keys = append(keys, k) + } + sort.Strings(keys) + for pos, key := range keys { + if pos != 0 { + res.WriteString(", ") + } + res.WriteString(`"` + key + `":`) + res.WriteString(o.AttrTypes[key].String()) + } + res.WriteString("]") + return res.String() +} + +// ValueType returns the Value type. +func (o ObjectType) ValueType(_ context.Context) attr.Value { + return ObjectValue{ + attributeTypes: o.AttrTypes, + } +} + +// ValueFromObject returns an ObjectValuable type given an Object. +func (o ObjectType) ValueFromObject(_ context.Context, obj ObjectValue) (ObjectValuable, diag.Diagnostics) { + return obj, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/object_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/object_value.go new file mode 100644 index 00000000..baeb8c0e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/object_value.go @@ -0,0 +1,400 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "sort" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/path" + + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +var _ ObjectValuable = &ObjectValue{} + +// ObjectValuable extends attr.Value for object value types. +// Implement this interface to create a custom Object value type. +type ObjectValuable interface { + attr.Value + + // ToObjectValue should convert the value type to an Object. + ToObjectValue(ctx context.Context) (ObjectValue, diag.Diagnostics) +} + +// ObjectValuableWithSemanticEquals extends ObjectValuable with semantic +// equality logic. +type ObjectValuableWithSemanticEquals interface { + ObjectValuable + + // ObjectSemanticEquals should return true if the given value is + // semantically equal to the current value. This logic is used to prevent + // Terraform data consistency errors and resource drift where a value change + // may have inconsequential differences, such as computed attribute values + // changed by a remote system. + // + // Only known values are compared with this method as changing a value's + // state implicitly represents a different value. + ObjectSemanticEquals(context.Context, ObjectValuable) (bool, diag.Diagnostics) +} + +// NewObjectNull creates a Object with a null value. Determine whether the value is +// null via the Object type IsNull method. +func NewObjectNull(attributeTypes map[string]attr.Type) ObjectValue { + return ObjectValue{ + attributeTypes: attributeTypes, + state: attr.ValueStateNull, + } +} + +// NewObjectUnknown creates a Object with an unknown value. Determine whether the +// value is unknown via the Object type IsUnknown method. +func NewObjectUnknown(attributeTypes map[string]attr.Type) ObjectValue { + return ObjectValue{ + attributeTypes: attributeTypes, + state: attr.ValueStateUnknown, + } +} + +// NewObjectValue creates a Object with a known value. Access the value via the Object +// type ElementsAs method. +func NewObjectValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing Object Attribute Value", + "While creating a Object value, a missing attribute value was detected. "+ + "A Object must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Object Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid Object Attribute Type", + "While creating a Object value, an invalid attribute value was detected. "+ + "A Object must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Object Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("Object Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra Object Attribute Value", + "While creating a Object value, an extra attribute value was detected. "+ + "A Object must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra Object Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewObjectUnknown(attributeTypes), diags + } + + return ObjectValue{ + attributeTypes: attributeTypes, + attributes: attributes, + state: attr.ValueStateKnown, + }, nil +} + +// NewObjectValueFrom creates a Object with a known value, using reflection rules. +// The attributes must be a map of string attribute names to attribute values +// which can convert into the given attribute type or a struct with tfsdk field +// tags. Access the value via the Object type Elements or ElementsAs methods. +func NewObjectValueFrom(ctx context.Context, attributeTypes map[string]attr.Type, attributes any) (ObjectValue, diag.Diagnostics) { + attrValue, diags := reflect.FromValue( + ctx, + ObjectType{AttrTypes: attributeTypes}, + attributes, + path.Empty(), + ) + + if diags.HasError() { + return NewObjectUnknown(attributeTypes), diags + } + + m, ok := attrValue.(ObjectValue) + + // This should not happen, but ensure there is an error if it does. + if !ok { + diags.AddError( + "Unable to Convert Object Value", + "An unexpected result occurred when creating a Object using ObjectValueFrom. "+ + "This is an issue with terraform-plugin-framework and should be reported to the provider developers.", + ) + } + + return m, diags +} + +// NewObjectValueMust creates a Object with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the Object +// type Elements or ElementsAs methods. +// +// This creation function is only recommended to create Object values which will +// not potentially effect practitioners, such as testing, or exhaustively +// tested provider logic. +func NewObjectValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) ObjectValue { + object, diags := NewObjectValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("ObjectValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +// ObjectValue represents an object +type ObjectValue struct { + // attributes is the mapping of known attribute values in the Object. + attributes map[string]attr.Value + + // attributeTypes is the type of the attributes in the Object. + attributeTypes map[string]attr.Type + + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState +} + +// ObjectAsOptions is a collection of toggles to control the behavior of +// Object.As. +type ObjectAsOptions struct { + // UnhandledNullAsEmpty controls what happens when As needs to put a + // null value in a type that has no way to preserve that distinction. + // When set to true, the type's empty value will be used. When set to + // false, an error will be returned. + UnhandledNullAsEmpty bool + + // UnhandledUnknownAsEmpty controls what happens when As needs to put + // an unknown value in a type that has no way to preserve that + // distinction. When set to true, the type's empty value will be used. + // When set to false, an error will be returned. + UnhandledUnknownAsEmpty bool +} + +// As populates `target` with the data in the ObjectValue, throwing an error if the +// data cannot be stored in `target`. +func (o ObjectValue) As(ctx context.Context, target interface{}, opts ObjectAsOptions) diag.Diagnostics { + // we need a tftypes.Value for this Object to be able to use it with + // our reflection code + obj := ObjectType{AttrTypes: o.attributeTypes} + val, err := o.ToTerraformValue(ctx) + if err != nil { + return diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Object Conversion Error", + "An unexpected error was encountered trying to convert object. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ), + } + } + return reflect.Into(ctx, obj, val, target, reflect.Options{ + UnhandledNullAsEmpty: opts.UnhandledNullAsEmpty, + UnhandledUnknownAsEmpty: opts.UnhandledUnknownAsEmpty, + }, path.Empty()) +} + +// Attributes returns a copy of the mapping of known attribute values for the Object. +func (o ObjectValue) Attributes() map[string]attr.Value { + // Ensure callers cannot mutate the internal attributes + result := make(map[string]attr.Value, len(o.attributes)) + + for name, value := range o.attributes { + result[name] = value + } + + return result +} + +// AttributeTypes returns a copy of the mapping of attribute types for the Object. +func (o ObjectValue) AttributeTypes(_ context.Context) map[string]attr.Type { + // Ensure callers cannot mutate the internal attribute types + result := make(map[string]attr.Type, len(o.attributeTypes)) + + for name, typ := range o.attributeTypes { + result[name] = typ + } + + return result +} + +// Type returns an ObjectType with the same attribute types as `o`. +func (o ObjectValue) Type(ctx context.Context) attr.Type { + return ObjectType{AttrTypes: o.AttributeTypes(ctx)} +} + +// ToTerraformValue returns the data contained in the attr.Value as +// a tftypes.Value. +func (o ObjectValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, len(o.attributeTypes)) + + for attr, typ := range o.attributeTypes { + attrTypes[attr] = typ.TerraformType(ctx) + } + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch o.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, len(o.attributes)) + + for name, v := range o.attributes { + val, err := v.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals[name] = val + } + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", o.state)) + } +} + +// Equal returns true if the given attr.Value is also an ObjectValue, has the +// same value state, and contains exactly the same attribute types/values as +// defined by the Equal method of those underlying types/values. +func (o ObjectValue) Equal(c attr.Value) bool { + other, ok := c.(ObjectValue) + + if !ok { + return false + } + + if o.state != other.state { + return false + } + + if o.state != attr.ValueStateKnown { + return true + } + + if len(o.attributeTypes) != len(other.attributeTypes) { + return false + } + + for name, oAttributeType := range o.attributeTypes { + otherAttributeType, ok := other.attributeTypes[name] + + if !ok { + return false + } + + if !oAttributeType.Equal(otherAttributeType) { + return false + } + } + + if len(o.attributes) != len(other.attributes) { + return false + } + + for name, oAttribute := range o.attributes { + otherAttribute, ok := other.attributes[name] + + if !ok { + return false + } + + if !oAttribute.Equal(otherAttribute) { + return false + } + } + + return true +} + +// IsNull returns true if the Object represents a null value. +func (o ObjectValue) IsNull() bool { + return o.state == attr.ValueStateNull +} + +// IsUnknown returns true if the Object represents a currently unknown value. +func (o ObjectValue) IsUnknown() bool { + return o.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the Object value. +// The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (o ObjectValue) String() string { + if o.IsUnknown() { + return attr.UnknownValueString + } + + if o.IsNull() { + return attr.NullValueString + } + + // We want the output to be consistent, so we sort the output by key + keys := make([]string, 0, len(o.Attributes())) + for k := range o.Attributes() { + keys = append(keys, k) + } + sort.Strings(keys) + + var res strings.Builder + + res.WriteString("{") + for i, k := range keys { + if i != 0 { + res.WriteString(",") + } + res.WriteString(fmt.Sprintf(`"%s":%s`, k, o.Attributes()[k].String())) + } + res.WriteString("}") + + return res.String() +} + +// ToObjectValue returns the Object. +func (o ObjectValue) ToObjectValue(context.Context) (ObjectValue, diag.Diagnostics) { + return o, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/set_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/set_type.go new file mode 100644 index 00000000..d6b033a8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/set_type.go @@ -0,0 +1,236 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +var ( + _ SetTypable = SetType{} + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + _ xattr.TypeWithValidate = SetType{} +) + +// SetTypable extends attr.Type for set types. +// Implement this interface to create a custom SetType type. +type SetTypable interface { + attr.Type + + // ValueFromSet should convert the Set to a SetValuable type. + ValueFromSet(context.Context, SetValue) (SetValuable, diag.Diagnostics) +} + +// SetType is an AttributeType representing a set of values. All values must +// be of the same type, which the provider must specify as the ElemType +// property. +type SetType struct { + ElemType attr.Type +} + +// ElementType returns the attr.Type elements will be created from. +func (st SetType) ElementType() attr.Type { + if st.ElemType == nil { + return missingType{} + } + + return st.ElemType +} + +// WithElementType returns a SetType that is identical to `l`, but with the +// element type set to `typ`. +func (st SetType) WithElementType(typ attr.Type) attr.TypeWithElementType { + return SetType{ElemType: typ} +} + +// TerraformType returns the tftypes.Type that should be used to +// represent this type. This constrains what user input will be +// accepted and what kind of data can be set in state. The framework +// will use this to translate the AttributeType to something Terraform +// can understand. +func (st SetType) TerraformType(ctx context.Context) tftypes.Type { + return tftypes.Set{ + ElementType: st.ElementType().TerraformType(ctx), + } +} + +// ValueFromTerraform returns an attr.Value given a tftypes.Value. +// This is meant to convert the tftypes.Value into a more convenient Go +// type for the provider to consume the data with. +func (st SetType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewSetNull(st.ElementType()), nil + } + + // MAINTAINER NOTE: + // SetType does not support DynamicType as an element type. It is not explicitly prevented from being created with the + // Framework type system, but the Framework-supported SetAttribute, SetNestedAttribute, and SetNestedBlock all prevent DynamicType + // from being used as an element type. An attempt to use DynamicType as the element type will eventually lead you to an error on this line :) + // + // In the future, if we ever need to support a set of dynamic element types, this type equality check will need to be modified to allow + // dynamic types to not return an error, as the tftypes.Value coming in (if known) will be a concrete value, for example: + // + // - st.TerraformType(ctx): tftypes.Set[tftypes.DynamicPseudoType] + // - in.Type(): tftypes.Set[tftypes.String] + // + // The `ValueFromTerraform` function for a dynamic type will be able create the correct concrete dynamic value with this modification in place. + // + if !in.Type().Equal(st.TerraformType(ctx)) { + return nil, fmt.Errorf("can't use %s as value of Set with ElementType %T, can only use %s values", in.String(), st.ElementType(), st.ElementType().TerraformType(ctx).String()) + } + if !in.IsKnown() { + return NewSetUnknown(st.ElementType()), nil + } + if in.IsNull() { + return NewSetNull(st.ElementType()), nil + } + val := []tftypes.Value{} + err := in.As(&val) + if err != nil { + return nil, err + } + elems := make([]attr.Value, 0, len(val)) + for _, elem := range val { + av, err := st.ElementType().ValueFromTerraform(ctx, elem) + if err != nil { + return nil, err + } + elems = append(elems, av) + } + // ValueFromTerraform above on each element should make this safe. + // Otherwise, this will need to do some Diagnostics to error conversion. + return NewSetValueMust(st.ElementType(), elems), nil +} + +// Equal returns true if `o` is also a SetType and has the same ElemType. +func (st SetType) Equal(o attr.Type) bool { + // Preserve prior ElemType nil check behavior + if st.ElementType().Equal(missingType{}) { + return false + } + + other, ok := o.(SetType) + + if !ok { + return false + } + + return st.ElementType().Equal(other.ElementType()) +} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// set. +func (st SetType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + if _, ok := step.(tftypes.ElementKeyValue); !ok { + return nil, fmt.Errorf("cannot apply step %T to SetType", step) + } + + return st.ElementType(), nil +} + +// String returns a human-friendly description of the SetType. +func (st SetType) String() string { + return "types.SetType[" + st.ElementType().String() + "]" +} + +// Validate implements type validation. This type requires all elements to be +// unique. +func (st SetType) Validate(ctx context.Context, in tftypes.Value, path path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + if in.Type() == nil { + return diags + } + + if !in.Type().Is(tftypes.Set{}) { + err := fmt.Errorf("expected Set value, received %T with value: %v", in, in) + diags.AddAttributeError( + path, + "Set Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return diags + } + + if !in.IsKnown() || in.IsNull() { + return diags + } + + var elems []tftypes.Value + + if err := in.As(&elems); err != nil { + diags.AddAttributeError( + path, + "Set Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return diags + } + + //nolint:staticcheck // xattr.TypeWithValidate is deprecated, but we still need to support it. + validatableType, isValidatable := st.ElementType().(xattr.TypeWithValidate) + + // Attempting to use map[tftypes.Value]struct{} for duplicate detection yields: + // panic: runtime error: hash of unhashable type tftypes.primitive + // Instead, use for loops. + for indexOuter, elemOuter := range elems { + // Only evaluate fully known values for duplicates and validation. + if !elemOuter.IsFullyKnown() { + continue + } + + // Validate the element first + if isValidatable { + elemValue, err := st.ElementType().ValueFromTerraform(ctx, elemOuter) + if err != nil { + diags.AddAttributeError( + path, + "Set Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return diags + } + diags = append(diags, validatableType.Validate(ctx, elemOuter, path.AtSetValue(elemValue))...) + } + + // Then check for duplicates + for indexInner := indexOuter + 1; indexInner < len(elems); indexInner++ { + elemInner := elems[indexInner] + + if !elemInner.Equal(elemOuter) { + continue + } + + // TODO: Point at element attr.Value when Validate method is converted to attr.Value + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/172 + diags.AddAttributeError( + path, + "Duplicate Set Element", + fmt.Sprintf("This attribute contains duplicate values of: %s", elemInner), + ) + } + } + + return diags +} + +// ValueType returns the Value type. +func (st SetType) ValueType(_ context.Context) attr.Value { + return SetValue{ + elementType: st.ElementType(), + } +} + +// ValueFromSet returns a SetValuable type given a Set. +func (st SetType) ValueFromSet(_ context.Context, set SetValue) (SetValuable, diag.Diagnostics) { + return set, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/set_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/set_value.go new file mode 100644 index 00000000..2064e8fb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/set_value.go @@ -0,0 +1,342 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/reflect" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +var _ SetValuable = &SetValue{} + +// SetValuable extends attr.Value for set value types. +// Implement this interface to create a custom Set value type. +type SetValuable interface { + attr.Value + + // ToSetValue should convert the value type to a Set. + ToSetValue(ctx context.Context) (SetValue, diag.Diagnostics) +} + +// SetValuableWithSemanticEquals extends SetValuable with semantic equality +// logic. +type SetValuableWithSemanticEquals interface { + SetValuable + + // SetSemanticEquals should return true if the given value is + // semantically equal to the current value. This logic is used to prevent + // Terraform data consistency errors and resource drift where a value change + // may have inconsequential differences, such as computed elements added by + // a remote system. + // + // Only known values are compared with this method as changing a value's + // state implicitly represents a different value. + SetSemanticEquals(context.Context, SetValuable) (bool, diag.Diagnostics) +} + +// NewSetNull creates a Set with a null value. Determine whether the value is +// null via the Set type IsNull method. +func NewSetNull(elementType attr.Type) SetValue { + return SetValue{ + elementType: elementType, + state: attr.ValueStateNull, + } +} + +// NewSetUnknown creates a Set with an unknown value. Determine whether the +// value is unknown via the Set type IsUnknown method. +func NewSetUnknown(elementType attr.Type) SetValue { + return SetValue{ + elementType: elementType, + state: attr.ValueStateUnknown, + } +} + +// NewSetValue creates a Set with a known value. Access the value via the Set +// type Elements or ElementsAs methods. +func NewSetValue(elementType attr.Type, elements []attr.Value) (SetValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for idx, element := range elements { + if !elementType.Equal(element.Type(ctx)) { + diags.AddError( + "Invalid Set Element Type", + "While creating a Set value, an invalid element was detected. "+ + "A Set must use the single, given element type. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Set Element Type: %s\n", elementType.String())+ + fmt.Sprintf("Set Index (%d) Element Type: %s", idx, element.Type(ctx)), + ) + } + } + + if diags.HasError() { + return NewSetUnknown(elementType), diags + } + + return SetValue{ + elementType: elementType, + elements: elements, + state: attr.ValueStateKnown, + }, nil +} + +// NewSetValueFrom creates a Set with a known value, using reflection rules. +// The elements must be a slice which can convert into the given element type. +// Access the value via the Set type Elements or ElementsAs methods. +func NewSetValueFrom(ctx context.Context, elementType attr.Type, elements any) (SetValue, diag.Diagnostics) { + attrValue, diags := reflect.FromValue( + ctx, + SetType{ElemType: elementType}, + elements, + path.Empty(), + ) + + if diags.HasError() { + return NewSetUnknown(elementType), diags + } + + set, ok := attrValue.(SetValue) + + // This should not happen, but ensure there is an error if it does. + if !ok { + diags.AddError( + "Unable to Convert Set Value", + "An unexpected result occurred when creating a Set using SetValueFrom. "+ + "This is an issue with terraform-plugin-framework and should be reported to the provider developers.", + ) + } + + return set, diags +} + +// NewSetValueMust creates a Set with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the Set +// type Elements or ElementsAs methods. +// +// This creation function is only recommended to create Set values which will +// not potentially effect practitioners, such as testing, or exhaustively +// tested provider logic. +func NewSetValueMust(elementType attr.Type, elements []attr.Value) SetValue { + set, diags := NewSetValue(elementType, elements) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("SetValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return set +} + +// SetValue represents a set of attr.Value, all of the same type, +// indicated by ElemType. +type SetValue struct { + // elements is the collection of known values in the Set. + elements []attr.Value + + // elementType is the type of the elements in the Set. + elementType attr.Type + + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState +} + +// Elements returns a copy of the collection of elements for the Set. +func (s SetValue) Elements() []attr.Value { + // Ensure callers cannot mutate the internal elements + result := make([]attr.Value, 0, len(s.elements)) + result = append(result, s.elements...) + + return result +} + +// ElementsAs populates `target` with the elements of the SetValue, throwing an +// error if the elements cannot be stored in `target`. +func (s SetValue) ElementsAs(ctx context.Context, target interface{}, allowUnhandled bool) diag.Diagnostics { + // we need a tftypes.Value for this Set to be able to use it with our + // reflection code + val, err := s.ToTerraformValue(ctx) + if err != nil { + return diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Set Element Conversion Error", + "An unexpected error was encountered trying to convert set elements. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ), + } + } + return reflect.Into(ctx, s.Type(ctx), val, target, reflect.Options{ + UnhandledNullAsEmpty: allowUnhandled, + UnhandledUnknownAsEmpty: allowUnhandled, + }, path.Empty()) +} + +// ElementType returns the element type for the Set. +func (s SetValue) ElementType(_ context.Context) attr.Type { + return s.elementType +} + +// Type returns a SetType with the same element type as `s`. +func (s SetValue) Type(ctx context.Context) attr.Type { + return SetType{ElemType: s.ElementType(ctx)} +} + +// ToTerraformValue returns the data contained in the Set as a tftypes.Value. +func (s SetValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + setType := tftypes.Set{ElementType: s.ElementType(ctx).TerraformType(ctx)} + + switch s.state { + case attr.ValueStateKnown: + // MAINTAINER NOTE: + // SetValue does not support DynamicType as an element type. It is not explicitly prevented from being created with the + // Framework type system, but the Framework-supported SetAttribute, SetNestedAttribute, and SetNestedBlock all prevent DynamicType + // from being used as an element type. + // + // In the future, if we ever need to support a set of dynamic element types, this tftypes.Set creation logic will need to be modified to ensure + // that known values contain the exact same concrete element type, specifically with unknown and null values. Dynamic values will return the correct concrete + // element type for known values from `elem.ToTerraformValue`, but unknown and null values will be tftypes.DynamicPseudoType, causing an error due to multiple element + // types in a tftypes.Set. + // + // Unknown and null element types of tftypes.DynamicPseudoType must be recreated as the concrete element type unknown/null value. This can be done by checking `s.elements` + // for a single concrete type (i.e. not tftypes.DynamicPseudoType), and using that concrete type to create unknown and null dynamic values later. + // + vals := make([]tftypes.Value, 0, len(s.elements)) + + for _, elem := range s.elements { + val, err := elem.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(setType, tftypes.UnknownValue), err + } + + vals = append(vals, val) + } + + if err := tftypes.ValidateValue(setType, vals); err != nil { + return tftypes.NewValue(setType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(setType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(setType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(setType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Set state in ToTerraformValue: %s", s.state)) + } +} + +// Equal returns true if the given attr.Value is also a SetValue, has the +// same element type, same value state, and contains exactly the element values +// as defined by the Equal method of the element type. +func (s SetValue) Equal(o attr.Value) bool { + other, ok := o.(SetValue) + + if !ok { + return false + } + + // A set with no elementType is an invalid state + if s.elementType == nil || other.elementType == nil { + return false + } + + if !s.elementType.Equal(other.elementType) { + return false + } + + if s.state != other.state { + return false + } + + if s.state != attr.ValueStateKnown { + return true + } + + if len(s.elements) != len(other.elements) { + return false + } + + for _, elem := range s.elements { + if !other.contains(elem) { + return false + } + } + + return true +} + +func (s SetValue) contains(v attr.Value) bool { + for _, elem := range s.Elements() { + if elem.Equal(v) { + return true + } + } + + return false +} + +// IsNull returns true if the Set represents a null value. +func (s SetValue) IsNull() bool { + return s.state == attr.ValueStateNull +} + +// IsUnknown returns true if the Set represents a currently unknown value. +// Returns false if the Set has a known number of elements, even if all are +// unknown values. +func (s SetValue) IsUnknown() bool { + return s.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the Set value. +// The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (s SetValue) String() string { + if s.IsUnknown() { + return attr.UnknownValueString + } + + if s.IsNull() { + return attr.NullValueString + } + + var res strings.Builder + + res.WriteString("[") + for i, e := range s.Elements() { + if i != 0 { + res.WriteString(",") + } + res.WriteString(e.String()) + } + res.WriteString("]") + + return res.String() +} + +// ToSetValue returns the Set. +func (s SetValue) ToSetValue(context.Context) (SetValue, diag.Diagnostics) { + return s, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/string_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/string_type.go new file mode 100644 index 00000000..319ae02b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/string_type.go @@ -0,0 +1,86 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// StringTypable extends attr.Type for string types. +// Implement this interface to create a custom StringType type. +type StringTypable interface { + attr.Type + + // ValueFromString should convert the String to a StringValuable type. + ValueFromString(context.Context, StringValue) (StringValuable, diag.Diagnostics) +} + +var _ StringTypable = StringType{} + +// StringType is the base framework type for a string. StringValue is the +// associated value type. +type StringType struct{} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// type. +func (t StringType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +func (t StringType) Equal(o attr.Type) bool { + _, ok := o.(StringType) + + return ok +} + +// String returns a human readable string of the type name. +func (t StringType) String() string { + return "basetypes.StringType" +} + +// TerraformType returns the tftypes.Type that should be used to represent this +// framework type. +func (t StringType) TerraformType(_ context.Context) tftypes.Type { + return tftypes.String +} + +// ValueFromString returns a StringValuable type given a StringValue. +func (t StringType) ValueFromString(_ context.Context, v StringValue) (StringValuable, diag.Diagnostics) { + return v, nil +} + +// ValueFromTerraform returns a Value given a tftypes.Value. This is meant to +// convert the tftypes.Value into a more convenient Go type for the provider to +// consume the data with. +func (t StringType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if !in.IsKnown() { + return NewStringUnknown(), nil + } + + if in.IsNull() { + return NewStringNull(), nil + } + + var s string + + err := in.As(&s) + + if err != nil { + return nil, err + } + + return NewStringValue(s), nil +} + +// ValueType returns the Value type. +func (t StringType) ValueType(_ context.Context) attr.Value { + // This Value does not need to be valid. + return StringValue{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/string_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/string_value.go new file mode 100644 index 00000000..46ac2248 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/string_value.go @@ -0,0 +1,187 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +var ( + _ StringValuable = StringValue{} +) + +// StringValuable extends attr.Value for string value types. +// Implement this interface to create a custom String value type. +type StringValuable interface { + attr.Value + + // ToStringValue should convert the value type to a String. + ToStringValue(ctx context.Context) (StringValue, diag.Diagnostics) +} + +// StringValuableWithSemanticEquals extends StringValuable with semantic +// equality logic. +type StringValuableWithSemanticEquals interface { + StringValuable + + // StringSemanticEquals should return true if the given value is + // semantically equal to the current value. This logic is used to prevent + // Terraform data consistency errors and resource drift where a value change + // may have inconsequential differences, such as spacing character removal + // in JSON formatted strings. + // + // Only known values are compared with this method as changing a value's + // state implicitly represents a different value. + StringSemanticEquals(context.Context, StringValuable) (bool, diag.Diagnostics) +} + +// NewStringNull creates a String with a null value. Determine whether the value is +// null via the String type IsNull method. +// +// Setting the deprecated String type Null, Unknown, or Value fields after +// creating a String with this function has no effect. +func NewStringNull() StringValue { + return StringValue{ + state: attr.ValueStateNull, + } +} + +// NewStringUnknown creates a String with an unknown value. Determine whether the +// value is unknown via the String type IsUnknown method. +// +// Setting the deprecated String type Null, Unknown, or Value fields after +// creating a String with this function has no effect. +func NewStringUnknown() StringValue { + return StringValue{ + state: attr.ValueStateUnknown, + } +} + +// NewStringValue creates a String with a known value. Access the value via the String +// type ValueString method. +// +// Setting the deprecated String type Null, Unknown, or Value fields after +// creating a String with this function has no effect. +func NewStringValue(value string) StringValue { + return StringValue{ + state: attr.ValueStateKnown, + value: value, + } +} + +// NewStringPointerValue creates a String with a null value if nil or a known +// value. Access the value via the String type ValueStringPointer method. +func NewStringPointerValue(value *string) StringValue { + if value == nil { + return NewStringNull() + } + + return NewStringValue(*value) +} + +// StringValue represents a UTF-8 string value. +type StringValue struct { + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState + + // value contains the known value, if not null or unknown. + value string +} + +// Type returns a StringType. +func (s StringValue) Type(_ context.Context) attr.Type { + return StringType{} +} + +// ToTerraformValue returns the data contained in the *String as a tftypes.Value. +func (s StringValue) ToTerraformValue(_ context.Context) (tftypes.Value, error) { + switch s.state { + case attr.ValueStateKnown: + if err := tftypes.ValidateValue(tftypes.String, s.value); err != nil { + return tftypes.NewValue(tftypes.String, tftypes.UnknownValue), err + } + + return tftypes.NewValue(tftypes.String, s.value), nil + case attr.ValueStateNull: + return tftypes.NewValue(tftypes.String, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(tftypes.String, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled String state in ToTerraformValue: %s", s.state)) + } +} + +// Equal returns true if `other` is a String and has the same value as `s`. +func (s StringValue) Equal(other attr.Value) bool { + o, ok := other.(StringValue) + + if !ok { + return false + } + + if s.state != o.state { + return false + } + + if s.state != attr.ValueStateKnown { + return true + } + + return s.value == o.value +} + +// IsNull returns true if the String represents a null value. +func (s StringValue) IsNull() bool { + return s.state == attr.ValueStateNull +} + +// IsUnknown returns true if the String represents a currently unknown value. +func (s StringValue) IsUnknown() bool { + return s.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the String value. Use +// the ValueString method for Terraform data handling instead. +// +// The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (s StringValue) String() string { + if s.IsUnknown() { + return attr.UnknownValueString + } + + if s.IsNull() { + return attr.NullValueString + } + + return fmt.Sprintf("%q", s.value) +} + +// ValueString returns the known string value. If String is null or unknown, returns +// "". +func (s StringValue) ValueString() string { + return s.value +} + +// ValueStringPointer returns a pointer to the known string value, nil for a +// null value, or a pointer to "" for an unknown value. +func (s StringValue) ValueStringPointer() *string { + if s.IsNull() { + return nil + } + + return &s.value +} + +// ToStringValue returns String. +func (s StringValue) ToStringValue(context.Context) (StringValue, diag.Diagnostics) { + return s, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/tuple_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/tuple_type.go new file mode 100644 index 00000000..89718268 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/tuple_type.go @@ -0,0 +1,138 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +var ( + _ attr.Type = TupleType{} + _ attr.TypeWithElementTypes = TupleType{} +) + +// TupleType implements a tuple type definition. This type intentionally includes less functionality +// than other types in the type system as it has limited real world application and therefore +// is not exposed to provider developers. +type TupleType struct { + // ElemTypes is an ordered list of element types for the tuple. + ElemTypes []attr.Type +} + +// ElementTypes returns the ordered attr.Type slice for the tuple. +func (t TupleType) ElementTypes() []attr.Type { + return t.ElemTypes +} + +// WithElementTypes returns a TupleType that is identical to `t`, but with the element types set to `types`. +func (t TupleType) WithElementTypes(types []attr.Type) attr.TypeWithElementTypes { + return TupleType{ElemTypes: types} +} + +// Equal returns true if `o` is also a TupleType and has the same ElemTypes in the same order. +func (t TupleType) Equal(o attr.Type) bool { + other, ok := o.(TupleType) + + if !ok { + return false + } + + if len(t.ElemTypes) != len(other.ElemTypes) { + return false + } + + for i, elemType := range t.ElemTypes { + if !elemType.Equal(other.ElemTypes[i]) { + return false + } + } + + return true +} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the tuple. +func (t TupleType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + indexStep, ok := step.(tftypes.ElementKeyInt) + if !ok { + return nil, fmt.Errorf("cannot apply step %T to TupleType", step) + } + + index := int(indexStep) + if index < 0 || index >= len(t.ElemTypes) { + return nil, fmt.Errorf("no element defined at index %d in TupleType", index) + } + + return t.ElemTypes[index], nil +} + +// String returns a human-friendly description of the TupleType. +func (t TupleType) String() string { + typeStrings := make([]string, len(t.ElemTypes)) + + for i, elemType := range t.ElemTypes { + typeStrings[i] = elemType.String() + } + + return "types.TupleType[" + strings.Join(typeStrings, ", ") + "]" +} + +// TerraformType returns the tftypes.Type that should be used to represent this type. +func (t TupleType) TerraformType(ctx context.Context) tftypes.Type { + tfTypes := make([]tftypes.Type, len(t.ElemTypes)) + + for i, elemType := range t.ElemTypes { + tfTypes[i] = elemType.TerraformType(ctx) + } + + return tftypes.Tuple{ + ElementTypes: tfTypes, + } +} + +// ValueFromTerraform returns an attr.Value given a tftypes.Value. This is meant to convert +// the tftypes.Value into a more convenient Go type for the provider to consume the data with. +func (t TupleType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewTupleNull(t.ElementTypes()), nil + } + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + if !in.IsKnown() { + return NewTupleUnknown(t.ElementTypes()), nil + } + if in.IsNull() { + return NewTupleNull(t.ElementTypes()), nil + } + val := []tftypes.Value{} + err := in.As(&val) + if err != nil { + return nil, err + } + elems := make([]attr.Value, 0, len(val)) + for i, elem := range val { + // Accessing this index is safe because of the type comparison above + av, err := t.ElemTypes[i].ValueFromTerraform(ctx, elem) + if err != nil { + return nil, err + } + elems = append(elems, av) + } + + // ValueFromTerraform above on each element should make this safe. + // Otherwise, this will need to do some Diagnostics to error conversion. + return NewTupleValueMust(t.ElementTypes(), elems), nil +} + +// ValueType returns the Value type. +func (t TupleType) ValueType(_ context.Context) attr.Value { + return TupleValue{ + elementTypes: t.ElementTypes(), + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/tuple_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/tuple_value.go new file mode 100644 index 00000000..5987d382 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/basetypes/tuple_value.go @@ -0,0 +1,254 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package basetypes + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +var _ attr.Value = TupleValue{} + +// NewTupleNull creates a Tuple with a null value. +func NewTupleNull(elementTypes []attr.Type) TupleValue { + return TupleValue{ + elementTypes: elementTypes, + state: attr.ValueStateNull, + } +} + +// NewTupleUnknown creates a Tuple with an unknown value. +func NewTupleUnknown(elementTypes []attr.Type) TupleValue { + return TupleValue{ + elementTypes: elementTypes, + state: attr.ValueStateUnknown, + } +} + +// NewTupleValue creates a Tuple with a known value. Access the value via the Tuple type Elements method. +func NewTupleValue(elementTypes []attr.Type, elements []attr.Value) (TupleValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + if len(elementTypes) != len(elements) { + givenTypes := make([]attr.Type, len(elements)) + for i, v := range elements { + givenTypes[i] = v.Type(ctx) + } + + diags.AddError( + "Invalid Tuple Elements", + "While creating a Tuple value, mismatched element types were detected. "+ + "A Tuple must be an ordered array of elements where the values exactly match the length and types of the defined element types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Tuple Expected Type: %v\n", elementTypes)+ + fmt.Sprintf("Tuple Given Type: %v", givenTypes), + ) + + return NewTupleUnknown(elementTypes), diags + } + + for i, element := range elements { + if !elementTypes[i].Equal(element.Type(ctx)) { + diags.AddError( + "Invalid Tuple Element", + "While creating a Tuple value, an invalid element was detected. "+ + "A Tuple must be an ordered array of elements where the values exactly match the length and types of the defined element types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Tuple Index (%d) Expected Type: %s\n", i, elementTypes[i])+ + fmt.Sprintf("Tuple Index (%d) Given Type: %s", i, element.Type(ctx)), + ) + } + } + + if diags.HasError() { + return NewTupleUnknown(elementTypes), diags + } + + return TupleValue{ + elementTypes: elementTypes, + elements: elements, + state: attr.ValueStateKnown, + }, nil +} + +// NewTupleValueMust creates a Tuple with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the Tuple type Elements method. +// +// This creation function is only recommended to create Tuple values which will +// not potentially affect practitioners, such as testing, or exhaustively +// tested provider logic. +func NewTupleValueMust(elementTypes []attr.Type, elements []attr.Value) TupleValue { + tuple, diags := NewTupleValue(elementTypes, elements) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewTupleValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return tuple +} + +// TupleValue represents an ordered list of attr.Value, with an attr.Type for each element. This type intentionally +// includes less functionality than other types in the type system as it has limited real world application and therefore +// is not exposed to provider developers. +type TupleValue struct { + // elements is the ordered list of known element values for the tuple. + elements []attr.Value + + // elementTypes is the ordered list of elements types for the tuple. + elementTypes []attr.Type + + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState +} + +// Elements returns a copy of the ordered list of known values for the Tuple. +func (v TupleValue) Elements() []attr.Value { + // Ensure callers cannot mutate the internal elements + result := make([]attr.Value, 0, len(v.elements)) + result = append(result, v.elements...) + + return result +} + +// ElementTypes returns the ordered list of element types for the Tuple. +func (v TupleValue) ElementTypes(ctx context.Context) []attr.Type { + return v.elementTypes +} + +// Equal returns true if the given attr.Value is also a Tuple, has the same value state, +// and contains exactly the same element types/values as defined by the Equal method of those +// underlying types/values. +func (v TupleValue) Equal(o attr.Value) bool { + other, ok := o.(TupleValue) + if !ok { + return false + } + + if len(v.elementTypes) != len(other.elementTypes) { + return false + } + + for i, elementType := range v.elementTypes { + if !elementType.Equal(other.elementTypes[i]) { + return false + } + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + // This statement should never be true, given that element type length must exactly match the number of elements, + // but checking to avoid an index out of range panic + if len(v.elements) != len(other.elements) { + return false + } + + for i, element := range v.elements { + if !element.Equal(other.elements[i]) { + return false + } + } + + return true +} + +// IsNull returns true if the Tuple represents a null value. +func (v TupleValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +// IsUnknown returns true if the Tuple represents an unknown value. +func (v TupleValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the Tuple. The string returned here is not protected by any +// compatibility guarantees, and is intended for logging and error reporting. +func (v TupleValue) String() string { + if v.IsUnknown() { + return attr.UnknownValueString + } + + if v.IsNull() { + return attr.NullValueString + } + + elements := v.Elements() + valueStrings := make([]string, len(elements)) + + for i, element := range elements { + valueStrings[i] = element.String() + } + + return "[" + strings.Join(valueStrings, ",") + "]" +} + +// Type returns a TupleType with the elements types for the Tuple. +func (v TupleValue) Type(ctx context.Context) attr.Type { + return TupleType{ + ElemTypes: v.ElementTypes(ctx), + } +} + +// ToTerraformValue returns the equivalent tftypes.Value for the Tuple. +func (v TupleValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + tfTypes := make([]tftypes.Type, len(v.elementTypes)) + for i, elementType := range v.elementTypes { + tfTypes[i] = elementType.TerraformType(ctx) + } + + tupleType := tftypes.Tuple{ElementTypes: tfTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make([]tftypes.Value, 0, len(v.elements)) + + for _, elem := range v.elements { + val, err := elem.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(tupleType, tftypes.UnknownValue), err + } + + vals = append(vals, val) + } + + if err := tftypes.ValidateValue(tupleType, vals); err != nil { + return tftypes.NewValue(tupleType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(tupleType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(tupleType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(tupleType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Tuple state in ToTerraformValue: %s", v.state)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/bool_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/bool_type.go new file mode 100644 index 00000000..7c8039b7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/bool_type.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +var BoolType = basetypes.BoolType{} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/bool_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/bool_value.go new file mode 100644 index 00000000..7aa982b6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/bool_value.go @@ -0,0 +1,31 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type Bool = basetypes.BoolValue + +// BoolNull creates a Bool with a null value. Determine whether the value is +// null via the Bool type IsNull method. +func BoolNull() basetypes.BoolValue { + return basetypes.NewBoolNull() +} + +// BoolUnknown creates a Bool with an unknown value. Determine whether the +// value is unknown via the Bool type IsUnknown method. +func BoolUnknown() basetypes.BoolValue { + return basetypes.NewBoolUnknown() +} + +// BoolValue creates a Bool with a known value. Access the value via the Bool +// type ValueBool method. +func BoolValue(value bool) basetypes.BoolValue { + return basetypes.NewBoolValue(value) +} + +// BoolPointerValue creates a Bool with a null value if nil or a known value. +func BoolPointerValue(value *bool) basetypes.BoolValue { + return basetypes.NewBoolPointerValue(value) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/doc.go new file mode 100644 index 00000000..c1323b49 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/doc.go @@ -0,0 +1,11 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package types contains the framework-defined data types and values, such as +// boolean, floating point, integer, list, map, object, set, and string. +// +// This package contains creation functions and type aliases for most provider +// use cases. The actual schema-ready type and value type implementations are +// under the basetypes package. Embed those basetypes implementations to create +// custom types. +package types diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/dynamic_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/dynamic_type.go new file mode 100644 index 00000000..f63d30cb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/dynamic_type.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +var DynamicType = basetypes.DynamicType{} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/dynamic_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/dynamic_value.go new file mode 100644 index 00000000..845cd377 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/dynamic_value.go @@ -0,0 +1,29 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type Dynamic = basetypes.DynamicValue + +// DynamicNull creates a Dynamic with a null value. Determine whether the value is +// null via the Dynamic type IsNull method. +func DynamicNull() basetypes.DynamicValue { + return basetypes.NewDynamicNull() +} + +// DynamicUnknown creates a Dynamic with an unknown value. Determine whether the +// value is unknown via the Dynamic type IsUnknown method. +func DynamicUnknown() basetypes.DynamicValue { + return basetypes.NewDynamicUnknown() +} + +// DynamicValue creates a Dynamic with a known value. Access the value via the Dynamic +// type UnderlyingValue method. +func DynamicValue(value attr.Value) basetypes.DynamicValue { + return basetypes.NewDynamicValue(value) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/float64_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/float64_type.go new file mode 100644 index 00000000..d9eafba9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/float64_type.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +var Float64Type = basetypes.Float64Type{} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/float64_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/float64_value.go new file mode 100644 index 00000000..b446a521 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/float64_value.go @@ -0,0 +1,31 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type Float64 = basetypes.Float64Value + +// Float64Null creates a Float64 with a null value. Determine whether the value is +// null via the Float64 type IsNull method. +func Float64Null() basetypes.Float64Value { + return basetypes.NewFloat64Null() +} + +// Float64Unknown creates a Float64 with an unknown value. Determine whether the +// value is unknown via the Float64 type IsUnknown method. +func Float64Unknown() basetypes.Float64Value { + return basetypes.NewFloat64Unknown() +} + +// Float64Value creates a Float64 with a known value. Access the value via the Float64 +// type ValueFloat64 method. +func Float64Value(value float64) basetypes.Float64Value { + return basetypes.NewFloat64Value(value) +} + +// Float64PointerValue creates a Float64 with a null value if nil or a known value. +func Float64PointerValue(value *float64) basetypes.Float64Value { + return basetypes.NewFloat64PointerValue(value) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/int64_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/int64_type.go new file mode 100644 index 00000000..5b53c550 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/int64_type.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +var Int64Type = basetypes.Int64Type{} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/int64_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/int64_value.go new file mode 100644 index 00000000..04e7da4f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/int64_value.go @@ -0,0 +1,31 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type Int64 = basetypes.Int64Value + +// Int64Null creates a Int64 with a null value. Determine whether the value is +// null via the Int64 type IsNull method. +func Int64Null() basetypes.Int64Value { + return basetypes.NewInt64Null() +} + +// Int64Unknown creates a Int64 with an unknown value. Determine whether the +// value is unknown via the Int64 type IsUnknown method. +func Int64Unknown() basetypes.Int64Value { + return basetypes.NewInt64Unknown() +} + +// Int64Value creates a Int64 with a known value. Access the value via the +// Int64 type ValueInt64 method. +func Int64Value(value int64) basetypes.Int64Value { + return basetypes.NewInt64Value(value) +} + +// Int64PointerValue creates a Int64 with a null value if nil or a known value. +func Int64PointerValue(value *int64) basetypes.Int64Value { + return basetypes.NewInt64PointerValue(value) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/list_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/list_type.go new file mode 100644 index 00000000..86e5c0ba --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/list_type.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type ListType = basetypes.ListType diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/list_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/list_value.go new file mode 100644 index 00000000..dfe2ed34 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/list_value.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type List = basetypes.ListValue + +// ListNull creates a List with a null value. Determine whether the value is +// null via the List type IsNull method. +func ListNull(elementType attr.Type) basetypes.ListValue { + return basetypes.NewListNull(elementType) +} + +// ListUnknown creates a List with an unknown value. Determine whether the +// value is unknown via the List type IsUnknown method. +func ListUnknown(elementType attr.Type) basetypes.ListValue { + return basetypes.NewListUnknown(elementType) +} + +// ListValue creates a List with a known value. Access the value via the List +// type Elements or ElementsAs methods. +func ListValue(elementType attr.Type, elements []attr.Value) (basetypes.ListValue, diag.Diagnostics) { + return basetypes.NewListValue(elementType, elements) +} + +// ListValueFrom creates a List with a known value, using reflection rules. +// The elements must be a slice which can convert into the given element type. +// Access the value via the List type Elements or ElementsAs methods. +func ListValueFrom(ctx context.Context, elementType attr.Type, elements any) (basetypes.ListValue, diag.Diagnostics) { + return basetypes.NewListValueFrom(ctx, elementType, elements) +} + +// ListValueMust creates a List with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the List +// type Elements or ElementsAs methods. +// +// This creation function is only recommended to create List values which will +// not potentially affect practitioners, such as testing, or exhaustively +// tested provider logic. +func ListValueMust(elementType attr.Type, elements []attr.Value) basetypes.ListValue { + return basetypes.NewListValueMust(elementType, elements) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/map_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/map_type.go new file mode 100644 index 00000000..08bd3f88 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/map_type.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type MapType = basetypes.MapType diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/map_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/map_value.go new file mode 100644 index 00000000..3c0b366a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/map_value.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type Map = basetypes.MapValue + +// MapNull creates a Map with a null value. Determine whether the value is +// null via the Map type IsNull method. +func MapNull(elementType attr.Type) basetypes.MapValue { + return basetypes.NewMapNull(elementType) +} + +// MapUnknown creates a Map with an unknown value. Determine whether the +// value is unknown via the Map type IsUnknown method. +func MapUnknown(elementType attr.Type) basetypes.MapValue { + return basetypes.NewMapUnknown(elementType) +} + +// MapValue creates a Map with a known value. Access the value via the Map +// type Elements or ElementsAs methods. +func MapValue(elementType attr.Type, elements map[string]attr.Value) (basetypes.MapValue, diag.Diagnostics) { + return basetypes.NewMapValue(elementType, elements) +} + +// MapValueFrom creates a Map with a known value, using reflection rules. +// The elements must be a map which can convert into the given element type. +// Access the value via the Map type Elements or ElementsAs methods. +func MapValueFrom(ctx context.Context, elementType attr.Type, elements any) (basetypes.MapValue, diag.Diagnostics) { + return basetypes.NewMapValueFrom(ctx, elementType, elements) +} + +// MapValueMust creates a Map with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the Map +// type Elements or ElementsAs methods. +// +// This creation function is only recommended to create Map values which will +// not potentially affect practitioners, such as testing, or exhaustively +// tested provider logic. +func MapValueMust(elementType attr.Type, elements map[string]attr.Value) basetypes.MapValue { + return basetypes.NewMapValueMust(elementType, elements) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/number_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/number_type.go new file mode 100644 index 00000000..ecfc8b1b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/number_type.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +var NumberType = basetypes.NumberType{} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/number_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/number_value.go new file mode 100644 index 00000000..dbed240a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/number_value.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import ( + "math/big" + + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type Number = basetypes.NumberValue + +// NumberNull creates a Number with a null value. Determine whether the value is +// null via the Number type IsNull method. +func NumberNull() basetypes.NumberValue { + return basetypes.NewNumberNull() +} + +// NumberUnknown creates a Number with an unknown value. Determine whether the +// value is unknown via the Number type IsUnknown method. +func NumberUnknown() basetypes.NumberValue { + return basetypes.NewNumberUnknown() +} + +// NumberValue creates a Number with a known value. Access the value via the Number +// type ValueBigFloat method. If the given value is nil, a null Number is created. +func NumberValue(value *big.Float) basetypes.NumberValue { + return basetypes.NewNumberValue(value) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/object_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/object_type.go new file mode 100644 index 00000000..3da2dede --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/object_type.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type ObjectType = basetypes.ObjectType diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/object_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/object_value.go new file mode 100644 index 00000000..a6257b77 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/object_value.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type Object = basetypes.ObjectValue + +// ObjectNull creates a Object with a null value. Determine whether the value is +// null via the Object type IsNull method. +func ObjectNull(attributeTypes map[string]attr.Type) basetypes.ObjectValue { + return basetypes.NewObjectNull(attributeTypes) +} + +// ObjectUnknown creates a Object with an unknown value. Determine whether the +// value is unknown via the Object type IsUnknown method. +func ObjectUnknown(attributeTypes map[string]attr.Type) basetypes.ObjectValue { + return basetypes.NewObjectUnknown(attributeTypes) +} + +// ObjectValue creates a Object with a known value. Access the value via the Object +// type Attributes or As methods. +func ObjectValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (basetypes.ObjectValue, diag.Diagnostics) { + return basetypes.NewObjectValue(attributeTypes, attributes) +} + +// ObjectValueFrom creates a Object with a known value, using reflection rules. +// The attributes must be a struct which can convert into the given attribute types. +// Access the value via the Object type Attributes or As methods. +func ObjectValueFrom(ctx context.Context, attributeTypes map[string]attr.Type, attributes any) (basetypes.ObjectValue, diag.Diagnostics) { + return basetypes.NewObjectValueFrom(ctx, attributeTypes, attributes) +} + +// ObjectValueMust creates a Object with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the Object +// type Attributes or As methods. +// +// This creation function is only recommended to create Object values which will +// not potentially affect practitioners, such as testing, or exhaustively +// tested provider logic. +func ObjectValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) basetypes.ObjectValue { + return basetypes.NewObjectValueMust(attributeTypes, attributes) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/set_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/set_type.go new file mode 100644 index 00000000..5e39f2e4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/set_type.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type SetType = basetypes.SetType diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/set_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/set_value.go new file mode 100644 index 00000000..934e58f9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/set_value.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type Set = basetypes.SetValue + +// SetNull creates a Set with a null value. Determine whether the value is +// null via the Set type IsNull method. +func SetNull(elementType attr.Type) basetypes.SetValue { + return basetypes.NewSetNull(elementType) +} + +// SetUnknown creates a Set with an unknown value. Determine whether the +// value is unknown via the Set type IsUnknown method. +func SetUnknown(elementType attr.Type) basetypes.SetValue { + return basetypes.NewSetUnknown(elementType) +} + +// SetValue creates a Set with a known value. Access the value via the Set +// type Elements or ElementsAs methods. +func SetValue(elementType attr.Type, elements []attr.Value) (basetypes.SetValue, diag.Diagnostics) { + return basetypes.NewSetValue(elementType, elements) +} + +// SetValueFrom creates a Set with a known value, using reflection rules. +// The elements must be a slice which can convert into the given element type. +// Access the value via the Set type Elements or ElementsAs methods. +func SetValueFrom(ctx context.Context, elementType attr.Type, elements any) (basetypes.SetValue, diag.Diagnostics) { + return basetypes.NewSetValueFrom(ctx, elementType, elements) +} + +// SetValueMust creates a Set with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the Set +// type Elements or ElementsAs methods. +// +// This creation function is only recommended to create Set values which will +// not potentially affect practitioners, such as testing, or exhaustively +// tested provider logic. +func SetValueMust(elementType attr.Type, elements []attr.Value) basetypes.SetValue { + return basetypes.NewSetValueMust(elementType, elements) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/string_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/string_type.go new file mode 100644 index 00000000..926905fd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/string_type.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +var StringType = basetypes.StringType{} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/string_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/string_value.go new file mode 100644 index 00000000..f3681297 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/string_value.go @@ -0,0 +1,31 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type String = basetypes.StringValue + +// StringNull creates a String with a null value. Determine whether the value is +// null via the String type IsNull method. +func StringNull() basetypes.StringValue { + return basetypes.NewStringNull() +} + +// StringUnknown creates a String with an unknown value. Determine whether the +// value is unknown via the String type IsUnknown method. +func StringUnknown() basetypes.StringValue { + return basetypes.NewStringUnknown() +} + +// StringValue creates a String with a known value. Access the value via the String +// type ValueString method. +func StringValue(value string) basetypes.StringValue { + return basetypes.NewStringValue(value) +} + +// StringPointerValue creates a String with a null value if nil or a known value. +func StringPointerValue(value *string) basetypes.StringValue { + return basetypes.NewStringPointerValue(value) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/tuple_type.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/tuple_type.go new file mode 100644 index 00000000..5c50b545 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/tuple_type.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type TupleType = basetypes.TupleType diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework/types/tuple_value.go b/vendor/github.com/hashicorp/terraform-plugin-framework/types/tuple_value.go new file mode 100644 index 00000000..412ccd1f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework/types/tuple_value.go @@ -0,0 +1,39 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type Tuple = basetypes.TupleValue + +// TupleNull creates a Tuple with a null value. Determine whether the value is +// null via the Tuple type IsNull method. +func TupleNull(elementTypes []attr.Type) basetypes.TupleValue { + return basetypes.NewTupleNull(elementTypes) +} + +// TupleUnknown creates a Tuple with an unknown value. Determine whether the +// value is unknown via the Tuple type IsUnknown method. +func TupleUnknown(elementTypes []attr.Type) basetypes.TupleValue { + return basetypes.NewTupleUnknown(elementTypes) +} + +// TupleValue creates a Tuple with a known value. Access the value via the Tuple type Elements method. +func TupleValue(elementTypes []attr.Type, elements []attr.Value) (basetypes.TupleValue, diag.Diagnostics) { + return basetypes.NewTupleValue(elementTypes, elements) +} + +// TupleValueMust creates a Tuple with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the Tuple type Elements method. +// +// This creation function is only recommended to create Tuple values which will +// not potentially affect practitioners, such as testing, or exhaustively +// tested provider logic. +func TupleValueMust(elementTypes []attr.Type, elements []attr.Value) basetypes.TupleValue { + return basetypes.NewTupleValueMust(elementTypes, elements) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/LICENSE b/vendor/github.com/hashicorp/terraform-plugin-testing/LICENSE new file mode 100644 index 00000000..07c59941 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/LICENSE @@ -0,0 +1,375 @@ +Copyright (c) 2014 HashiCorp, Inc. + +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/config/config.go b/vendor/github.com/hashicorp/terraform-plugin-testing/config/config.go new file mode 100644 index 00000000..4a663610 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/config/config.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package config + +// TestStepConfigFunc is the callback type used with acceptance tests to +// specify a string which either identifies a directory containing +// Terraform configuration files, or a file that contains Terraform +// configuration. +type TestStepConfigFunc func(TestStepConfigRequest) string + +// TestStepConfigRequest defines the request supplied to types +// implementing TestStepConfigFunc. StepNumber is one-based +// and is used in the predefined helper functions: +// +// - [config.TestStepDirectory] +// - [config.TestStepFile]. +// +// TestName is used in the predefined helper functions: +// +// - [config.TestNameDirectory] +// - [config.TestStepDirectory] +// - [config.TestNameFile] +// - [config.TestStepFile] +type TestStepConfigRequest struct { + StepNumber int + TestName string +} + +// Exec executes TestStepConfigFunc if it is not nil, otherwise an +// empty string is returned. +func (f TestStepConfigFunc) Exec(req TestStepConfigRequest) string { + if f != nil { + return f(req) + } + + return "" +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/config/constraints.go b/vendor/github.com/hashicorp/terraform-plugin-testing/config/constraints.go new file mode 100644 index 00000000..3842cc0c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/config/constraints.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package config + +// anyFloat is a constraint that permits any floating-point type. This type +// definition is copied rather than depending on x/exp/constraints since the +// dependency is otherwise unneeded, the definition is relatively trivial and +// static, and the Go language maintainers are not sure if/where these will live +// in the standard library. +// +// Reference: https://github.com/golang/go/issues/61914 +type anyFloat interface { + ~float32 | ~float64 +} + +// anyInteger is a constraint that permits any integer type. This type +// definition is copied rather than depending on x/exp/constraints since the +// dependency is otherwise unneeded, the definition is relatively trivial and +// static, and the Go language maintainers are not sure if/where these will live +// in the standard library. +// +// Reference: https://github.com/golang/go/issues/61914 +type anyInteger interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/config/directory.go b/vendor/github.com/hashicorp/terraform-plugin-testing/config/directory.go new file mode 100644 index 00000000..c3c9ab0c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/config/directory.go @@ -0,0 +1,63 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package config + +import ( + "path/filepath" + "strconv" +) + +// StaticDirectory returns the supplied directory. +func StaticDirectory(directory string) func(TestStepConfigRequest) string { + return func(_ TestStepConfigRequest) string { + return directory + } +} + +// TestNameDirectory returns the name of the test prefixed with +// "testdata". +// +// For example, given test code: +// +// func TestExampleCloudThing_basic(t *testing.T) { +// resource.Test(t, resource.TestCase{ +// Steps: []resource.TestStep{ +// { +// ConfigDirectory: config.TestNameDirectory(), +// }, +// }, +// }) +// } +// +// The testing configurations will be expected in the +// testdata/TestExampleCloudThing_basic/ directory. +func TestNameDirectory() func(TestStepConfigRequest) string { + return func(req TestStepConfigRequest) string { + return filepath.Join("testdata", req.TestName) + } +} + +// TestStepDirectory returns the name of the test suffixed with the +// test step number and prefixed with "testdata". +// +// For example, given test code: +// +// func TestExampleCloudThing_basic(t *testing.T) { +// resource.Test(t, resource.TestCase{ +// Steps: []resource.TestStep{ +// { +// ConfigDirectory: config.TestStepDirectory(), +// }, +// }, +// }) +// } +// +// The testing configurations will be expected in the +// testdata/TestExampleCloudThing_basic/1 directory as +// TestStepConfigRequest.StepNumber is one-based. +func TestStepDirectory() func(TestStepConfigRequest) string { + return func(req TestStepConfigRequest) string { + return filepath.Join("testdata", req.TestName, strconv.Itoa(req.StepNumber)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/config/doc.go b/vendor/github.com/hashicorp/terraform-plugin-testing/config/doc.go new file mode 100644 index 00000000..e85d5f81 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/config/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package config implements functionality for supporting native +// Terraform configuration and variables for testing purposes. +package config diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/config/file.go b/vendor/github.com/hashicorp/terraform-plugin-testing/config/file.go new file mode 100644 index 00000000..1974c406 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/config/file.go @@ -0,0 +1,63 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package config + +import ( + "path/filepath" + "strconv" +) + +// StaticFile returns the supplied file. +func StaticFile(file string) func(TestStepConfigRequest) string { + return func(_ TestStepConfigRequest) string { + return file + } +} + +// TestNameFile returns the name of the test suffixed with the supplied +// file and prefixed with "testdata". +// +// For example, given test code: +// +// func TestExampleCloudThing_basic(t *testing.T) { +// resource.Test(t, resource.TestCase{ +// Steps: []resource.TestStep{ +// { +// ConfigFile: config.TestNameFile("test.tf"), +// }, +// }, +// }) +// } +// +// The testing configuration will be expected in the +// testdata/TestExampleCloudThing_basic/test.tf file. +func TestNameFile(file string) func(TestStepConfigRequest) string { + return func(req TestStepConfigRequest) string { + return filepath.Join("testdata", req.TestName, file) + } +} + +// TestStepFile returns the name of the test suffixed with the test +// step number and the supplied file, and prefixed with "testdata". +// +// For example, given test code: +// +// func TestExampleCloudThing_basic(t *testing.T) { +// resource.Test(t, resource.TestCase{ +// Steps: []resource.TestStep{ +// { +// ConfigFile: config.TestStepFile("test.tf"), +// }, +// }, +// }) +// } +// +// The testing configuration will be expected in the +// testdata/TestExampleCloudThing_basic/1/test.tf file +// as TestStepConfigRequest.StepNumber is one-based. +func TestStepFile(file string) func(TestStepConfigRequest) string { + return func(req TestStepConfigRequest) string { + return filepath.Join("testdata", req.TestName, strconv.Itoa(req.StepNumber), file) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/config/variable.go b/vendor/github.com/hashicorp/terraform-plugin-testing/config/variable.go new file mode 100644 index 00000000..fa109a2a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/config/variable.go @@ -0,0 +1,324 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package config + +import ( + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + "reflect" +) + +const autoTFVarsJson = "terraform-plugin-testing.auto.tfvars.json" + +// Variable interface is an alias to json.Marshaler. +type Variable interface { + json.Marshaler +} + +// Variables is a type holding a key-value map of variable names +// to types implementing the Variable interface. +type Variables map[string]Variable + +// Write creates a file in the destination supplied +// containing JSON encoded Variables. +func (v Variables) Write(dest string) error { + if len(v) == 0 { + return nil + } + + b, err := json.Marshal(v) + + if err != nil { + return fmt.Errorf("cannot marshal variables: %s", err) + } + + outFilename := filepath.Join(dest, autoTFVarsJson) + + err = os.WriteFile(outFilename, b, 0600) + + if err != nil { + return fmt.Errorf("cannot write variables file: %s", err) + } + + return nil +} + +var _ Variable = boolVariable{} + +// boolVariable supports JSON encoding of a bool. +type boolVariable struct { + value bool +} + +// MarshalJSON returns the JSON encoding of boolVariable. +func (v boolVariable) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +// BoolVariable returns boolVariable which implements Variable. +func BoolVariable(value bool) boolVariable { + return boolVariable{ + value: value, + } +} + +var _ Variable = floatVariable{} + +// floatVariable supports JSON encoding of any floating-point type. +type floatVariable struct { + value any +} + +// MarshalJSON returns the JSON encoding of floatVariable. +func (v floatVariable) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +// FloatVariable returns floatVariable which implements Variable. +func FloatVariable[T anyFloat](value T) floatVariable { + return floatVariable{ + value: value, + } +} + +var _ Variable = integerVariable{} + +// integerVariable supports JSON encoding of any integer type. +type integerVariable struct { + value any +} + +// MarshalJSON returns the JSON encoding of integerVariable. +func (v integerVariable) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +// IntegerVariable returns integerVariable which implements Variable. +func IntegerVariable[T anyInteger](value T) integerVariable { + return integerVariable{ + value: value, + } +} + +var _ Variable = listVariable{} + +// listVariable supports JSON encoding of slice of Variable. +type listVariable struct { + value []Variable +} + +// MarshalJSON returns the JSON encoding of listVariable. +// Every Variable within a listVariable must be the same +// underlying type. +func (v listVariable) MarshalJSON() ([]byte, error) { + if !typesEq(v.value) { + return nil, errors.New("lists must contain the same type") + } + + return json.Marshal(v.value) +} + +// ListVariable returns listVariable which implements Variable. +func ListVariable(value ...Variable) listVariable { + return listVariable{ + value: value, + } +} + +var _ Variable = mapVariable{} + +// mapVariable supports JSON encoding of a key-value map of +// string to Variable. +type mapVariable struct { + value map[string]Variable +} + +// MarshalJSON returns the JSON encoding of mapVariable. +// Every Variable in a mapVariable must be the same +// underlying type. +func (v mapVariable) MarshalJSON() ([]byte, error) { + var variables []Variable + + for _, variable := range v.value { + variables = append(variables, variable) + } + + if !typesEq(variables) { + return nil, errors.New("maps must contain the same type") + } + + return json.Marshal(v.value) +} + +// MapVariable returns mapVariable which implements Variable. +func MapVariable(value map[string]Variable) mapVariable { + return mapVariable{ + value: value, + } +} + +var _ Variable = objectVariable{} + +// objectVariable supports JSON encoding of a key-value +// map of string to Variable in which each Variable +// can be a different underlying type. +type objectVariable struct { + value map[string]Variable +} + +// MarshalJSON returns the JSON encoding of objectVariable. +func (v objectVariable) MarshalJSON() ([]byte, error) { + b, err := json.Marshal(v.value) + + if err != nil { + innerErr := err + + // Unwrap is used here to expose the initial error, for example + // "maps must contain the same type" whilst removing any errors + // related to the implementation (i.e., the usage of + // encoding/json in this instance. + for errors.Unwrap(innerErr) != nil { + innerErr = errors.Unwrap(err) + } + + return nil, innerErr + } + + return b, nil +} + +// ObjectVariable returns objectVariable which implements Variable. +func ObjectVariable(value map[string]Variable) objectVariable { + return objectVariable{ + value: value, + } +} + +var _ Variable = setVariable{} + +// setVariable supports JSON encoding of a slice of Variable. +type setVariable struct { + value []Variable +} + +// MarshalJSON returns the JSON encoding of setVariable. +// Every Variable in a setVariable must be the same +// underlying type. +func (v setVariable) MarshalJSON() ([]byte, error) { + for kx, x := range v.value { + for ky := kx + 1; ky < len(v.value); ky++ { + y := v.value[ky] + + if _, ok := x.(setVariable); !ok { + continue + } + + if _, ok := y.(setVariable); !ok { + continue + } + + if reflect.DeepEqual(x, y) { + return nil, errors.New("sets must contain unique elements") + } + } + } + + if !typesEq(v.value) { + return nil, errors.New("sets must contain the same type") + } + + return json.Marshal(v.value) +} + +// SetVariable returns setVariable which implements Variable. +func SetVariable(value ...Variable) setVariable { + return setVariable{ + value: value, + } +} + +var _ Variable = stringVariable{} + +// stringVariable supports JSON encoding of a string. +type stringVariable struct { + value string +} + +// MarshalJSON returns the JSON encoding of stringVariable. +func (v stringVariable) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +// StringVariable returns stringVariable which implements Variable. +func StringVariable(value string) stringVariable { + return stringVariable{ + value: value, + } +} + +var _ Variable = tupleVariable{} + +// tupleVariable supports JSON encoding of a slice of Variable +// in which each element in the slice can be a different +// underlying type. +type tupleVariable struct { + value []Variable +} + +// MarshalJSON returns the JSON encoding of tupleVariable. +func (v tupleVariable) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +// TupleVariable returns tupleVariable which implements Variable. +func TupleVariable(value ...Variable) tupleVariable { + return tupleVariable{ + value: value, + } +} + +// typesEq verifies that every element in the supplied slice of Variable +// is the same underlying type. +func typesEq(variables []Variable) bool { + var t reflect.Type + + for _, variable := range variables { + switch x := variable.(type) { + case listVariable: + if !typesEq(x.value) { + return false + } + case mapVariable: + var vars []Variable + + for _, v := range x.value { + vars = append(vars, v) + } + + if !typesEq(vars) { + return false + } + case setVariable: + if !typesEq(x.value) { + return false + } + } + + typeOfVariable := reflect.TypeOf(variable) + + if t == nil { + t = typeOfVariable + continue + } + + if t != typeOfVariable { + return false + } + } + + return true +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/environment_variables.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/environment_variables.go new file mode 100644 index 00000000..98190879 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/environment_variables.go @@ -0,0 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +// Environment variables for acceptance testing. Additional environment +// variable constants can be found in the internal/plugintest package. +const ( + // Environment variable to enable acceptance tests using this package's + // ParallelTest and Test functions whose TestCase does not enable the + // IsUnitTest field. Defaults to disabled, in which each test will call + // (*testing.T).Skip(). Can be set to any value to enable acceptance tests, + // however "1" is conventional. + EnvTfAcc = "TF_ACC" + + // Environment variable with hostname for the provider under acceptance + // test. The hostname is the first portion of the full provider source + // address, such as "example.com" in example.com/myorg/myprovider. Defaults + // to "registry.terraform.io". + // + // Only required if any Terraform configuration set via the TestStep + // type Config field includes a provider source, such as the terraform + // configuration block required_providers attribute. + EnvTfAccProviderHost = "TF_ACC_PROVIDER_HOST" + + // Environment variable with namespace for the provider under acceptance + // test. The namespace is the second portion of the full provider source + // address, such as "myorg" in registry.terraform.io/myorg/myprovider. + // Defaults to "-" for Terraform 0.12-0.13 compatibility and "hashicorp". + // + // Only required if any Terraform configuration set via the TestStep + // type Config field includes a provider source, such as the terraform + // configuration block required_providers attribute. + EnvTfAccProviderNamespace = "TF_ACC_PROVIDER_NAMESPACE" +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/error.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/error.go new file mode 100644 index 00000000..3c990e35 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/error.go @@ -0,0 +1,132 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "fmt" + "strings" + "time" +) + +// NotFoundError represents when a StateRefreshFunc returns a nil result +// during a StateChangeConf waiter method and that StateChangeConf is +// configured for specific targets. +// +// Deprecated: Copy this type to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.NotFoundError. +type NotFoundError struct { + LastError error + LastRequest interface{} + LastResponse interface{} + Message string + Retries int +} + +// Error returns the Message string, if non-empty, or a string indicating +// the resource could not be found. +// +// Deprecated: Copy this method to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.NotFoundError. +func (e *NotFoundError) Error() string { + if e.Message != "" { + return e.Message + } + + if e.Retries > 0 { + return fmt.Sprintf("couldn't find resource (%d retries)", e.Retries) + } + + return "couldn't find resource" +} + +// Unwrap returns the LastError, compatible with errors.Unwrap. +// +// Deprecated: Copy this method to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.NotFoundError. +func (e *NotFoundError) Unwrap() error { + return e.LastError +} + +// UnexpectedStateError is returned when Refresh returns a state that's neither in Target nor Pending +// +// Deprecated: Copy this type to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.UnexpectedStateError. +type UnexpectedStateError struct { + LastError error + State string + ExpectedState []string +} + +// Error returns a string with the unexpected state value, the desired target, +// and any last error. +// +// Deprecated: Copy this method to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.UnexpectedStateError. +func (e *UnexpectedStateError) Error() string { + return fmt.Sprintf( + "unexpected state '%s', wanted target '%s'. last error: %s", + e.State, + strings.Join(e.ExpectedState, ", "), + e.LastError, + ) +} + +// Unwrap returns the LastError, compatible with errors.Unwrap. +// +// Deprecated: Copy this method to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.UnexpectedStateError. +func (e *UnexpectedStateError) Unwrap() error { + return e.LastError +} + +// TimeoutError is returned when WaitForState times out +// +// Deprecated: Copy this type to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.TimeoutError. +type TimeoutError struct { + LastError error + LastState string + Timeout time.Duration + ExpectedState []string +} + +// Error returns a string with any information available. +// +// Deprecated: Copy this method to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.TimeoutError. +func (e *TimeoutError) Error() string { + expectedState := "resource to be gone" + if len(e.ExpectedState) > 0 { + expectedState = fmt.Sprintf("state to become '%s'", strings.Join(e.ExpectedState, ", ")) + } + + extraInfo := make([]string, 0) + if e.LastState != "" { + extraInfo = append(extraInfo, fmt.Sprintf("last state: '%s'", e.LastState)) + } + if e.Timeout > 0 { + extraInfo = append(extraInfo, fmt.Sprintf("timeout: %s", e.Timeout.String())) + } + + suffix := "" + if len(extraInfo) > 0 { + suffix = fmt.Sprintf(" (%s)", strings.Join(extraInfo, ", ")) + } + + if e.LastError != nil { + return fmt.Sprintf("timeout while waiting for %s%s: %s", + expectedState, suffix, e.LastError) + } + + return fmt.Sprintf("timeout while waiting for %s%s", + expectedState, suffix) +} + +// Unwrap returns the LastError, compatible with errors.Unwrap. +// +// Deprecated: Copy this method to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.TimeoutError. +func (e *TimeoutError) Unwrap() error { + return e.LastError +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/id.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/id.go new file mode 100644 index 00000000..81c1f2e8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/id.go @@ -0,0 +1,62 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "fmt" + "strings" + "sync" + "time" +) + +// UniqueIdPrefix is a string prefix automatically added to return values of +// the UniqueId function. +// +// Deprecated: Copy this value to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/id.UniquePrefix. +const UniqueIdPrefix = `terraform-` + +// idCounter is a monotonic counter for generating ordered unique ids. +var idMutex sync.Mutex +var idCounter uint32 + +// Helper for a resource to generate a unique identifier w/ default prefix +// +// Deprecated: Copy this function to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/id.Unique. +func UniqueId() string { + return PrefixedUniqueId(UniqueIdPrefix) +} + +// UniqueIDSuffixLength is the string length of the suffix generated by +// PrefixedUniqueId. This can be used by length validation functions to +// ensure prefixes are the correct length for the target field. +// +// Deprecated: Copy this value to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/id.UniqueSuffixLength. +const UniqueIDSuffixLength = 26 + +// Helper for a resource to generate a unique identifier w/ given prefix +// +// After the prefix, the ID consists of an incrementing 26 digit value (to match +// previous timestamp output). After the prefix, the ID consists of a timestamp +// and an incrementing 8 hex digit value The timestamp means that multiple IDs +// created with the same prefix will sort in the order of their creation, even +// across multiple terraform executions, as long as the clock is not turned back +// between calls, and as long as any given terraform execution generates fewer +// than 4 billion IDs. +// +// Deprecated: Copy this function to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/id.PrefixedUnique. +func PrefixedUniqueId(prefix string) string { + // Be precise to 4 digits of fractional seconds, but remove the dot before the + // fractional seconds. + timestamp := strings.Replace( + time.Now().UTC().Format("20060102150405.0000"), ".", "", 1) + + idMutex.Lock() + defer idMutex.Unlock() + idCounter++ + return fmt.Sprintf("%s%s%08x", prefix, timestamp, idCounter) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/json.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/json.go new file mode 100644 index 00000000..9cd6a1b9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/json.go @@ -0,0 +1,15 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "bytes" + "encoding/json" +) + +func unmarshalJSON(data []byte, v interface{}) error { + dec := json.NewDecoder(bytes.NewReader(data)) + dec.UseNumber() + return dec.Decode(v) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/plan_checks.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/plan_checks.go new file mode 100644 index 00000000..c64c02ba --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/plan_checks.go @@ -0,0 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "errors" + + tfjson "github.com/hashicorp/terraform-json" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + "github.com/mitchellh/go-testing-interface" +) + +func runPlanChecks(ctx context.Context, t testing.T, plan *tfjson.Plan, planChecks []plancheck.PlanCheck) error { + t.Helper() + + var result []error + + for _, planCheck := range planChecks { + resp := plancheck.CheckPlanResponse{} + planCheck.CheckPlan(ctx, plancheck.CheckPlanRequest{Plan: plan}, &resp) + + result = append(result, resp.Error) + } + + return errors.Join(result...) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/plugin.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/plugin.go new file mode 100644 index 00000000..5c92f3ab --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/plugin.go @@ -0,0 +1,492 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "fmt" + "io" + "os" + "strings" + "sync" + + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/terraform-exec/tfexec" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" + "github.com/mitchellh/go-testing-interface" + + "github.com/hashicorp/terraform-plugin-testing/internal/logging" + "github.com/hashicorp/terraform-plugin-testing/internal/plugintest" +) + +// protov5ProviderFactory is a function which is called to start a protocol +// version 5 provider server. +type protov5ProviderFactory func() (tfprotov5.ProviderServer, error) + +// protov5ProviderFactories is a mapping of provider addresses to provider +// factory for protocol version 5 provider servers. +type protov5ProviderFactories map[string]func() (tfprotov5.ProviderServer, error) + +// merge combines provider factories. +// +// In case of an overlapping entry, the later entry will overwrite the previous +// value. +func (pf protov5ProviderFactories) merge(otherPfs ...protov5ProviderFactories) protov5ProviderFactories { + result := make(protov5ProviderFactories) + + for name, providerFactory := range pf { + result[name] = providerFactory + } + + for _, otherPf := range otherPfs { + for name, providerFactory := range otherPf { + result[name] = providerFactory + } + } + + return result +} + +// protov6ProviderFactory is a function which is called to start a protocol +// version 6 provider server. +type protov6ProviderFactory func() (tfprotov6.ProviderServer, error) + +// protov6ProviderFactories is a mapping of provider addresses to provider +// factory for protocol version 6 provider servers. +type protov6ProviderFactories map[string]func() (tfprotov6.ProviderServer, error) + +// merge combines provider factories. +// +// In case of an overlapping entry, the later entry will overwrite the previous +// value. +func (pf protov6ProviderFactories) merge(otherPfs ...protov6ProviderFactories) protov6ProviderFactories { + result := make(protov6ProviderFactories) + + for name, providerFactory := range pf { + result[name] = providerFactory + } + + for _, otherPf := range otherPfs { + for name, providerFactory := range otherPf { + result[name] = providerFactory + } + } + + return result +} + +// sdkProviderFactory is a function which is called to start a SDK provider +// server. +type sdkProviderFactory func() (*schema.Provider, error) + +// protov6ProviderFactories is a mapping of provider addresses to provider +// factory for protocol version 6 provider servers. +type sdkProviderFactories map[string]func() (*schema.Provider, error) + +// merge combines provider factories. +// +// In case of an overlapping entry, the later entry will overwrite the previous +// value. +func (pf sdkProviderFactories) merge(otherPfs ...sdkProviderFactories) sdkProviderFactories { + result := make(sdkProviderFactories) + + for name, providerFactory := range pf { + result[name] = providerFactory + } + + for _, otherPf := range otherPfs { + for name, providerFactory := range otherPf { + result[name] = providerFactory + } + } + + return result +} + +type providerFactories struct { + legacy sdkProviderFactories + protov5 protov5ProviderFactories + protov6 protov6ProviderFactories +} + +func runProviderCommand(ctx context.Context, t testing.T, f func() error, wd *plugintest.WorkingDir, factories *providerFactories) error { + // don't point to this as a test failure location + // point to whatever called it + t.Helper() + + // This should not happen, but prevent panics just in case. + if factories == nil { + err := fmt.Errorf("Provider factories are missing to run Terraform command. Please report this bug in the testing framework.") + logging.HelperResourceError(ctx, err.Error()) + return err + } + + // Run the providers in the same process as the test runner using the + // reattach behavior in Terraform. This ensures we get test coverage + // and enables the use of delve as a debugger. + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + // this is needed so Terraform doesn't default to expecting protocol 4; + // we're skipping the handshake because Terraform didn't launch the + // plugins. + os.Setenv("PLUGIN_PROTOCOL_VERSIONS", "5") + + // Acceptance testing does not need to call checkpoint as the output + // is not accessible, nor desirable if explicitly using + // TF_ACC_TERRAFORM_PATH or TF_ACC_TERRAFORM_VERSION environment variables. + // + // Avoid calling (tfexec.Terraform).SetEnv() as it will stop copying + // os.Environ() and prevents TF_VAR_ environment variable usage. + os.Setenv("CHECKPOINT_DISABLE", "1") + + // Terraform 0.12.X and 0.13.X+ treat namespaceless providers + // differently in terms of what namespace they default to. So we're + // going to set both variations, as we don't know which version of + // Terraform we're talking to. We're also going to allow overriding + // the host or namespace using environment variables. + var namespaces []string + host := "registry.terraform.io" + if v := os.Getenv(EnvTfAccProviderNamespace); v != "" { + namespaces = append(namespaces, v) + } else { + namespaces = append(namespaces, "-", "hashicorp") + } + if v := os.Getenv(EnvTfAccProviderHost); v != "" { + host = v + } + + // schema.Provider have a global stop context that is created outside + // the server context and have their own associated goroutine. Since + // Terraform does not call the StopProvider RPC to stop the server in + // reattach mode, ensure that we save these servers to later call that + // RPC and end those goroutines. + legacyProviderServers := make([]*schema.GRPCProviderServer, 0, len(factories.legacy)) + + // Spin up gRPC servers for every provider factory, start a + // WaitGroup to listen for all of the close channels. + var wg sync.WaitGroup + reattachInfo := map[string]tfexec.ReattachConfig{} + for providerName, factory := range factories.legacy { + // providerName may be returned as terraform-provider-foo, and + // we need just foo. So let's fix that. + providerName = strings.TrimPrefix(providerName, "terraform-provider-") + providerAddress := getProviderAddr(providerName) + + logging.HelperResourceDebug(ctx, "Creating sdkv2 provider instance", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + provider, err := factory() + if err != nil { + return fmt.Errorf("unable to create provider %q from factory: %w", providerName, err) + } + + logging.HelperResourceDebug(ctx, "Created sdkv2 provider instance", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + // keep track of the running factory, so we can make sure it's + // shut down. + wg.Add(1) + + grpcProviderServer := schema.NewGRPCProviderServer(provider) + legacyProviderServers = append(legacyProviderServers, grpcProviderServer) + + // Ensure StopProvider is always called when returning early. + defer grpcProviderServer.StopProvider(ctx, nil) //nolint:errcheck // does not return errors + + // configure the settings our plugin will be served with + // the GRPCProviderFunc wraps a non-gRPC provider server + // into a gRPC interface, and the logger just discards logs + // from go-plugin. + opts := &plugin.ServeOpts{ + GRPCProviderFunc: func() tfprotov5.ProviderServer { + return grpcProviderServer + }, + Logger: hclog.New(&hclog.LoggerOptions{ + Name: "plugintest", + Level: hclog.Trace, + Output: io.Discard, + }), + NoLogOutputOverride: true, + UseTFLogSink: t, + ProviderAddr: providerAddress, + } + + logging.HelperResourceDebug(ctx, "Starting sdkv2 provider instance server", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + config, closeCh, err := plugin.DebugServe(ctx, opts) + if err != nil { + return fmt.Errorf("unable to serve provider %q: %w", providerName, err) + } + + logging.HelperResourceDebug(ctx, "Started sdkv2 provider instance server", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + tfexecConfig := tfexec.ReattachConfig{ + Protocol: config.Protocol, + ProtocolVersion: config.ProtocolVersion, + Pid: config.Pid, + Test: config.Test, + Addr: tfexec.ReattachConfigAddr{ + Network: config.Addr.Network, + String: config.Addr.String, + }, + } + + // when the provider exits, remove one from the waitgroup + // so we can track when everything is done + go func(c <-chan struct{}) { + <-c + wg.Done() + }(closeCh) + + // set our provider's reattachinfo in our map, once + // for every namespace that different Terraform versions + // may expect. + for _, ns := range namespaces { + reattachInfo[strings.TrimSuffix(host, "/")+"/"+ + strings.TrimSuffix(ns, "/")+"/"+ + providerName] = tfexecConfig + } + } + + // Now spin up gRPC servers for every protov5 provider factory + // in the same way. + for providerName, factory := range factories.protov5 { + // providerName may be returned as terraform-provider-foo, and + // we need just foo. So let's fix that. + providerName = strings.TrimPrefix(providerName, "terraform-provider-") + providerAddress := getProviderAddr(providerName) + + // If the user has supplied the same provider in both + // ProviderFactories and ProtoV5ProviderFactories, they made a + // mistake and we should exit early. + for _, ns := range namespaces { + reattachString := strings.TrimSuffix(host, "/") + "/" + + strings.TrimSuffix(ns, "/") + "/" + + providerName + if _, ok := reattachInfo[reattachString]; ok { + return fmt.Errorf("Provider %s registered in both TestCase.ProviderFactories and TestCase.ProtoV5ProviderFactories: please use one or the other, or supply a muxed provider to TestCase.ProtoV5ProviderFactories.", providerName) + } + } + + logging.HelperResourceDebug(ctx, "Creating tfprotov5 provider instance", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + provider, err := factory() + if err != nil { + return fmt.Errorf("unable to create provider %q from factory: %w", providerName, err) + } + + logging.HelperResourceDebug(ctx, "Created tfprotov5 provider instance", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + // keep track of the running factory, so we can make sure it's + // shut down. + wg.Add(1) + + // configure the settings our plugin will be served with + // the GRPCProviderFunc wraps a non-gRPC provider server + // into a gRPC interface, and the logger just discards logs + // from go-plugin. + opts := &plugin.ServeOpts{ + GRPCProviderFunc: func() tfprotov5.ProviderServer { + return provider + }, + Logger: hclog.New(&hclog.LoggerOptions{ + Name: "plugintest", + Level: hclog.Trace, + Output: io.Discard, + }), + NoLogOutputOverride: true, + UseTFLogSink: t, + ProviderAddr: providerAddress, + } + + logging.HelperResourceDebug(ctx, "Starting tfprotov5 provider instance server", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + config, closeCh, err := plugin.DebugServe(ctx, opts) + if err != nil { + return fmt.Errorf("unable to serve provider %q: %w", providerName, err) + } + + logging.HelperResourceDebug(ctx, "Started tfprotov5 provider instance server", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + tfexecConfig := tfexec.ReattachConfig{ + Protocol: config.Protocol, + ProtocolVersion: config.ProtocolVersion, + Pid: config.Pid, + Test: config.Test, + Addr: tfexec.ReattachConfigAddr{ + Network: config.Addr.Network, + String: config.Addr.String, + }, + } + + // when the provider exits, remove one from the waitgroup + // so we can track when everything is done + go func(c <-chan struct{}) { + <-c + wg.Done() + }(closeCh) + + // set our provider's reattachinfo in our map, once + // for every namespace that different Terraform versions + // may expect. + for _, ns := range namespaces { + reattachString := strings.TrimSuffix(host, "/") + "/" + + strings.TrimSuffix(ns, "/") + "/" + + providerName + reattachInfo[reattachString] = tfexecConfig + } + } + + // Now spin up gRPC servers for every protov6 provider factory + // in the same way. + for providerName, factory := range factories.protov6 { + // providerName may be returned as terraform-provider-foo, and + // we need just foo. So let's fix that. + providerName = strings.TrimPrefix(providerName, "terraform-provider-") + providerAddress := getProviderAddr(providerName) + + // If the user has already registered this provider in + // ProviderFactories or ProtoV5ProviderFactories, they made a + // mistake and we should exit early. + for _, ns := range namespaces { + reattachString := strings.TrimSuffix(host, "/") + "/" + + strings.TrimSuffix(ns, "/") + "/" + + providerName + if _, ok := reattachInfo[reattachString]; ok { + return fmt.Errorf("Provider %s registered in both TestCase.ProtoV6ProviderFactories and either TestCase.ProviderFactories or TestCase.ProtoV5ProviderFactories: please use one of the three, or supply a muxed provider to TestCase.ProtoV5ProviderFactories.", providerName) + } + } + + logging.HelperResourceDebug(ctx, "Creating tfprotov6 provider instance", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + provider, err := factory() + if err != nil { + return fmt.Errorf("unable to create provider %q from factory: %w", providerName, err) + } + + logging.HelperResourceDebug(ctx, "Created tfprotov6 provider instance", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + // keep track of the running factory, so we can make sure it's + // shut down. + wg.Add(1) + + opts := &plugin.ServeOpts{ + GRPCProviderV6Func: func() tfprotov6.ProviderServer { + return provider + }, + Logger: hclog.New(&hclog.LoggerOptions{ + Name: "plugintest", + Level: hclog.Trace, + Output: io.Discard, + }), + NoLogOutputOverride: true, + UseTFLogSink: t, + ProviderAddr: providerAddress, + } + + logging.HelperResourceDebug(ctx, "Starting tfprotov6 provider instance server", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + config, closeCh, err := plugin.DebugServe(ctx, opts) + if err != nil { + return fmt.Errorf("unable to serve provider %q: %w", providerName, err) + } + + logging.HelperResourceDebug(ctx, "Started tfprotov6 provider instance server", map[string]interface{}{logging.KeyProviderAddress: providerAddress}) + + tfexecConfig := tfexec.ReattachConfig{ + Protocol: config.Protocol, + ProtocolVersion: config.ProtocolVersion, + Pid: config.Pid, + Test: config.Test, + Addr: tfexec.ReattachConfigAddr{ + Network: config.Addr.Network, + String: config.Addr.String, + }, + } + + // when the provider exits, remove one from the waitgroup + // so we can track when everything is done + go func(c <-chan struct{}) { + <-c + wg.Done() + }(closeCh) + + // set our provider's reattachinfo in our map, once + // for every namespace that different Terraform versions + // may expect. + for _, ns := range namespaces { + reattachString := strings.TrimSuffix(host, "/") + "/" + + strings.TrimSuffix(ns, "/") + "/" + + providerName + reattachInfo[reattachString] = tfexecConfig + } + } + + // set the working directory reattach info that will tell Terraform how to + // connect to our various running servers. + wd.SetReattachInfo(ctx, reattachInfo) + + logging.HelperResourceTrace(ctx, "Calling wrapped Terraform CLI command") + + // ok, let's call whatever Terraform command the test was trying to + // call, now that we know it'll attach back to those servers we just + // started. + err := f() + if err != nil { + logging.HelperResourceWarn(ctx, "Error running Terraform CLI command", map[string]interface{}{logging.KeyError: err}) + } + + logging.HelperResourceTrace(ctx, "Called wrapped Terraform CLI command") + logging.HelperResourceDebug(ctx, "Stopping providers") + + // cancel the servers so they'll return. Otherwise, this closeCh won't + // get closed, and we'll hang here. + cancel() + + // For legacy providers, call the StopProvider RPC so the StopContext + // goroutine is cleaned up properly. + for _, legacyProviderServer := range legacyProviderServers { + legacyProviderServer.StopProvider(ctx, nil) //nolint:errcheck // does not return errors + } + + logging.HelperResourceTrace(ctx, "Waiting for providers to stop") + + // wait for the servers to actually shut down; it may take a moment for + // them to clean up, or whatever. + // TODO: add a timeout here? + // PC: do we need one? The test will time out automatically... + wg.Wait() + + logging.HelperResourceTrace(ctx, "Providers have successfully stopped") + + // once we've run the Terraform command, let's remove the reattach + // information from the WorkingDir's environment. The WorkingDir will + // persist until the next call, but the server in the reattach info + // doesn't exist anymore at this point, so the reattach info is no + // longer valid. In theory it should be overwritten in the next call, + // but just to avoid any confusing bug reports, let's just unset the + // environment variable altogether. + wd.UnsetReattachInfo() + + // return any error returned from the orchestration code running + // Terraform commands + return err +} + +func getProviderAddr(name string) string { + host := "registry.terraform.io" + namespace := "hashicorp" + if v := os.Getenv(EnvTfAccProviderNamespace); v != "" { + namespace = v + } + if v := os.Getenv(EnvTfAccProviderHost); v != "" { + host = v + } + return strings.TrimSuffix(host, "/") + "/" + + strings.TrimSuffix(namespace, "/") + "/" + + name +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state.go new file mode 100644 index 00000000..9ed11327 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state.go @@ -0,0 +1,292 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "log" + "time" +) + +var refreshGracePeriod = 30 * time.Second + +// StateRefreshFunc is a function type used for StateChangeConf that is +// responsible for refreshing the item being watched for a state change. +// +// It returns three results. `result` is any object that will be returned +// as the final object after waiting for state change. This allows you to +// return the final updated object, for example an EC2 instance after refreshing +// it. A nil result represents not found. +// +// `state` is the latest state of that object. And `err` is any error that +// may have happened while refreshing the state. +// +// Deprecated: Copy this type to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.StateRefreshFunc. +type StateRefreshFunc func() (result interface{}, state string, err error) + +// StateChangeConf is the configuration struct used for `WaitForState`. +// +// Deprecated: Copy this type to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.StateChangeConf. +type StateChangeConf struct { + Delay time.Duration // Wait this time before starting checks + Pending []string // States that are "allowed" and will continue trying + Refresh StateRefreshFunc // Refreshes the current state + Target []string // Target state + Timeout time.Duration // The amount of time to wait before timeout + MinTimeout time.Duration // Smallest time to wait before refreshes + PollInterval time.Duration // Override MinTimeout/backoff and only poll this often + NotFoundChecks int // Number of times to allow not found (nil result from Refresh) + + // This is to work around inconsistent APIs + ContinuousTargetOccurence int // Number of times the Target state has to occur continuously +} + +// WaitForStateContext watches an object and waits for it to achieve the state +// specified in the configuration using the specified Refresh() func, +// waiting the number of seconds specified in the timeout configuration. +// +// If the Refresh function returns an error, exit immediately with that error. +// +// If the Refresh function returns a state other than the Target state or one +// listed in Pending, return immediately with an error. +// +// If the Timeout is exceeded before reaching the Target state, return an +// error. +// +// Otherwise, the result is the result of the first call to the Refresh function to +// reach the target state. +// +// # Cancellation from the passed in context will cancel the refresh loop +// +// Deprecated: Copy this method to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.StateChangeConf. +func (conf *StateChangeConf) WaitForStateContext(ctx context.Context) (interface{}, error) { + log.Printf("[DEBUG] Waiting for state to become: %s", conf.Target) + + notfoundTick := 0 + targetOccurence := 0 + + // Set a default for times to check for not found + if conf.NotFoundChecks == 0 { + conf.NotFoundChecks = 20 + } + + if conf.ContinuousTargetOccurence == 0 { + conf.ContinuousTargetOccurence = 1 + } + + type Result struct { + Result interface{} + State string + Error error + Done bool + } + + // Read every result from the refresh loop, waiting for a positive result.Done. + resCh := make(chan Result, 1) + // cancellation channel for the refresh loop + cancelCh := make(chan struct{}) + + result := Result{} + + go func() { + defer close(resCh) + + select { + case <-time.After(conf.Delay): + case <-cancelCh: + return + } + + // start with 0 delay for the first loop + var wait time.Duration + + for { + // store the last result + resCh <- result + + // wait and watch for cancellation + select { + case <-cancelCh: + return + case <-time.After(wait): + // first round had no wait + if wait == 0 { + wait = 100 * time.Millisecond + } + } + + res, currentState, err := conf.Refresh() + result = Result{ + Result: res, + State: currentState, + Error: err, + } + + if err != nil { + resCh <- result + return + } + + // If we're waiting for the absence of a thing, then return + if res == nil && len(conf.Target) == 0 { + targetOccurence++ + if conf.ContinuousTargetOccurence == targetOccurence { + result.Done = true + resCh <- result + return + } + continue + } + + if res == nil { + // If we didn't find the resource, check if we have been + // not finding it for awhile, and if so, report an error. + notfoundTick++ + if notfoundTick > conf.NotFoundChecks { + result.Error = &NotFoundError{ + LastError: err, + Retries: notfoundTick, + } + resCh <- result + return + } + } else { + // Reset the counter for when a resource isn't found + notfoundTick = 0 + found := false + + for _, allowed := range conf.Target { + if currentState == allowed { + found = true + targetOccurence++ + if conf.ContinuousTargetOccurence == targetOccurence { + result.Done = true + resCh <- result + return + } + continue + } + } + + for _, allowed := range conf.Pending { + if currentState == allowed { + found = true + targetOccurence = 0 + break + } + } + + if !found && len(conf.Pending) > 0 { + result.Error = &UnexpectedStateError{ + LastError: err, + State: result.State, + ExpectedState: conf.Target, + } + resCh <- result + return + } + } + + // Wait between refreshes using exponential backoff, except when + // waiting for the target state to reoccur. + if targetOccurence == 0 { + wait *= 2 + } + + // If a poll interval has been specified, choose that interval. + // Otherwise bound the default value. + if conf.PollInterval > 0 && conf.PollInterval < 180*time.Second { + wait = conf.PollInterval + } else { + if wait < conf.MinTimeout { + wait = conf.MinTimeout + } else if wait > 10*time.Second { + wait = 10 * time.Second + } + } + + log.Printf("[TRACE] Waiting %s before next try", wait) + } + }() + + // store the last value result from the refresh loop + lastResult := Result{} + + timeout := time.After(conf.Timeout) + for { + select { + case r, ok := <-resCh: + // channel closed, so return the last result + if !ok { + return lastResult.Result, lastResult.Error + } + + // we reached the intended state + if r.Done { + return r.Result, r.Error + } + + // still waiting, store the last result + lastResult = r + case <-ctx.Done(): + close(cancelCh) + return nil, ctx.Err() + case <-timeout: + log.Printf("[WARN] WaitForState timeout after %s", conf.Timeout) + log.Printf("[WARN] WaitForState starting %s refresh grace period", refreshGracePeriod) + + // cancel the goroutine and start our grace period timer + close(cancelCh) + timeout := time.After(refreshGracePeriod) + + // we need a for loop and a label to break on, because we may have + // an extra response value to read, but still want to wait for the + // channel to close. + forSelect: + for { + select { + case r, ok := <-resCh: + if r.Done { + // the last refresh loop reached the desired state + return r.Result, r.Error + } + + if !ok { + // the goroutine returned + break forSelect + } + + // target state not reached, save the result for the + // TimeoutError and wait for the channel to close + lastResult = r + case <-ctx.Done(): + log.Println("[ERROR] Context cancelation detected, abandoning grace period") + break forSelect + case <-timeout: + log.Println("[ERROR] WaitForState exceeded refresh grace period") + break forSelect + } + } + + return nil, &TimeoutError{ + LastError: lastResult.Error, + LastState: lastResult.State, + Timeout: conf.Timeout, + ExpectedState: conf.Target, + } + } + } +} + +// WaitForState watches an object and waits for it to achieve the state +// specified in the configuration using the specified Refresh() func, +// waiting the number of seconds specified in the timeout configuration. +// +// Deprecated: Please use WaitForStateContext to ensure proper plugin shutdown +func (conf *StateChangeConf) WaitForState() (interface{}, error) { + return conf.WaitForStateContext(context.Background()) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state_checks.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state_checks.go new file mode 100644 index 00000000..66c850ea --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state_checks.go @@ -0,0 +1,29 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "errors" + + tfjson "github.com/hashicorp/terraform-json" + "github.com/mitchellh/go-testing-interface" + + "github.com/hashicorp/terraform-plugin-testing/statecheck" +) + +func runStateChecks(ctx context.Context, t testing.T, state *tfjson.State, stateChecks []statecheck.StateCheck) error { + t.Helper() + + var result []error + + for _, stateCheck := range stateChecks { + resp := statecheck.CheckStateResponse{} + stateCheck.CheckState(ctx, statecheck.CheckStateRequest{State: state}, &resp) + + result = append(result, resp.Error) + } + + return errors.Join(result...) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state_shim.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state_shim.go new file mode 100644 index 00000000..c9659dc9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/state_shim.go @@ -0,0 +1,326 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "encoding/json" + "fmt" + "strconv" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/terraform" + + "github.com/hashicorp/terraform-plugin-testing/internal/addrs" + "github.com/hashicorp/terraform-plugin-testing/internal/tfdiags" +) + +type shimmedState struct { + state *terraform.State +} + +func shimStateFromJson(jsonState *tfjson.State) (*terraform.State, error) { + state := terraform.NewState() //nolint:staticcheck // legacy usage + state.TFVersion = jsonState.TerraformVersion + + if jsonState.Values == nil { + // the state is empty + return state, nil + } + + for key, output := range jsonState.Values.Outputs { + os, err := shimOutputState(output) + if err != nil { + return nil, err + } + state.RootModule().Outputs[key] = os + } + + ss := &shimmedState{state} + err := ss.shimStateModule(jsonState.Values.RootModule) + if err != nil { + return nil, err + } + + return state, nil +} + +func shimOutputState(so *tfjson.StateOutput) (*terraform.OutputState, error) { + os := &terraform.OutputState{ + Sensitive: so.Sensitive, + } + + switch v := so.Value.(type) { + case string: + os.Type = "string" + os.Value = v + return os, nil + case []interface{}: + os.Type = "list" + if len(v) == 0 { + os.Value = v + return os, nil + } + switch firstElem := v[0].(type) { + case string: + elements := make([]interface{}, len(v)) + for i, el := range v { + //nolint:forcetypeassert // Guaranteed by type switch + elements[i] = el.(string) + } + os.Value = elements + case bool: + elements := make([]interface{}, len(v)) + for i, el := range v { + //nolint:forcetypeassert // Guaranteed by type switch + elements[i] = el.(bool) + } + os.Value = elements + // unmarshalled number from JSON will always be json.Number + case json.Number: + elements := make([]interface{}, len(v)) + for i, el := range v { + //nolint:forcetypeassert // Guaranteed by type switch + elements[i] = el.(json.Number) + } + os.Value = elements + case []interface{}: + os.Value = v + case map[string]interface{}: + os.Value = v + default: + return nil, fmt.Errorf("unexpected output list element type: %T", firstElem) + } + return os, nil + case map[string]interface{}: + os.Type = "map" + os.Value = v + return os, nil + case bool: + os.Type = "string" + os.Value = strconv.FormatBool(v) + return os, nil + // unmarshalled number from JSON will always be json.Number + case json.Number: + os.Type = "string" + os.Value = v.String() + return os, nil + } + + return nil, fmt.Errorf("unexpected output type: %T", so.Value) +} + +func (ss *shimmedState) shimStateModule(sm *tfjson.StateModule) error { + var path addrs.ModuleInstance + + if sm.Address == "" { + path = addrs.RootModuleInstance + } else { + var diags tfdiags.Diagnostics + path, diags = addrs.ParseModuleInstanceStr(sm.Address) + if diags.HasErrors() { + return diags.Err() + } + } + + mod := ss.state.AddModule(path) //nolint:staticcheck // legacy usage + for _, res := range sm.Resources { + resourceState, err := shimResourceState(res) + if err != nil { + return err + } + + key, err := shimResourceStateKey(res) + if err != nil { + return err + } + + mod.Resources[key] = resourceState + } + + if len(sm.ChildModules) > 0 { + return fmt.Errorf("Modules are not supported. Found %d modules.", + len(sm.ChildModules)) + } + return nil +} + +func shimResourceStateKey(res *tfjson.StateResource) (string, error) { + if res.Index == nil { + return res.Address, nil + } + + var mode terraform.ResourceMode + switch res.Mode { + case tfjson.DataResourceMode: + mode = terraform.DataResourceMode + case tfjson.ManagedResourceMode: + mode = terraform.ManagedResourceMode + default: + return "", fmt.Errorf("unexpected resource mode for %q", res.Address) + } + + var index int + switch idx := res.Index.(type) { + case json.Number: + i, err := idx.Int64() + if err != nil { + return "", fmt.Errorf("unexpected index value (%q) for %q, ", + idx, res.Address) + } + index = int(i) + default: + return "", fmt.Errorf("unexpected index type (%T) for %q, "+ + "for_each is not supported", res.Index, res.Address) + } + + rsk := &terraform.ResourceStateKey{ + Mode: mode, + Type: res.Type, + Name: res.Name, + Index: index, + } + + return rsk.String(), nil +} + +func shimResourceState(res *tfjson.StateResource) (*terraform.ResourceState, error) { + sf := &shimmedFlatmap{} + err := sf.FromMap(res.AttributeValues) + if err != nil { + return nil, err + } + attributes := sf.Flatmap() + + // The instance state identifier was a Terraform versions 0.11 and earlier + // concept which helped core and the then SDK determine if the resource + // should be removed and as an identifier value in the human readable + // output. This concept unfortunately carried over to the testing logic when + // the testing logic was mostly changed to use the public, machine-readable + // JSON interface with Terraform, rather than reusing prior internal logic + // from Terraform. Using the "id" attribute value for this identifier was + // the default implementation and therefore those older versions of + // Terraform required the attribute. This is no longer necessary after + // Terraform versions 0.12 and later. + // + // If the "id" attribute is not found, set the instance state identifier to + // a synthetic value that can hopefully lead someone encountering the value + // to these comments. The prior logic used to raise an error if the + // attribute was not present, but this value should now only be present in + // legacy logic of this Go module, such as unintentionally exported logic in + // the terraform package, and not encountered during normal testing usage. + // + // Reference: https://github.com/hashicorp/terraform-plugin-testing/issues/84 + instanceStateID, ok := attributes["id"] + + if !ok { + instanceStateID = "id-attribute-not-set" + } + + return &terraform.ResourceState{ + Provider: res.ProviderName, + Type: res.Type, + Primary: &terraform.InstanceState{ + ID: instanceStateID, + Attributes: attributes, + Meta: map[string]interface{}{ + "schema_version": int(res.SchemaVersion), + }, + Tainted: res.Tainted, + }, + Dependencies: res.DependsOn, + }, nil +} + +type shimmedFlatmap struct { + m map[string]string +} + +func (sf *shimmedFlatmap) FromMap(attributes map[string]interface{}) error { + if sf.m == nil { + sf.m = make(map[string]string, len(attributes)) + } + + return sf.AddMap("", attributes) +} + +func (sf *shimmedFlatmap) AddMap(prefix string, m map[string]interface{}) error { + for key, value := range m { + k := key + if prefix != "" { + k = fmt.Sprintf("%s.%s", prefix, key) + } + + err := sf.AddEntry(k, value) + if err != nil { + return fmt.Errorf("unable to add map key %q entry: %w", k, err) + } + } + + mapLength := "%" + if prefix != "" { + mapLength = fmt.Sprintf("%s.%s", prefix, "%") + } + + if err := sf.AddEntry(mapLength, strconv.Itoa(len(m))); err != nil { + return fmt.Errorf("unable to add map length %q entry: %w", mapLength, err) + } + + return nil +} + +func (sf *shimmedFlatmap) AddSlice(name string, elements []interface{}) error { + for i, elem := range elements { + key := fmt.Sprintf("%s.%d", name, i) + err := sf.AddEntry(key, elem) + if err != nil { + return fmt.Errorf("unable to add slice key %q entry: %w", key, err) + } + } + + sliceLength := fmt.Sprintf("%s.#", name) + if err := sf.AddEntry(sliceLength, strconv.Itoa(len(elements))); err != nil { + return fmt.Errorf("unable to add slice length %q entry: %w", sliceLength, err) + } + + return nil +} + +func (sf *shimmedFlatmap) AddEntry(key string, value interface{}) error { + switch el := value.(type) { + case nil: + // omit the entry + return nil + case bool: + sf.m[key] = strconv.FormatBool(el) + case json.Number: + sf.m[key] = el.String() + case string: + sf.m[key] = el + case map[string]interface{}: + err := sf.AddMap(key, el) + if err != nil { + return err + } + case []interface{}: + err := sf.AddSlice(key, el) + if err != nil { + return err + } + default: + // This should never happen unless terraform-json + // changes how attributes (types) are represented. + // + // We handle all types which the JSON unmarshaler + // can possibly produce + // https://golang.org/pkg/encoding/json/#Unmarshal + + return fmt.Errorf("%q: unexpected type (%T)", key, el) + } + return nil +} + +func (sf *shimmedFlatmap) Flatmap() map[string]string { + return sf.m +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testcase_providers.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testcase_providers.go new file mode 100644 index 00000000..9639cb04 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testcase_providers.go @@ -0,0 +1,61 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "fmt" + "strings" +) + +// providerConfig takes the list of providers in a TestCase and returns a +// config with only empty provider blocks. This is useful for Import, where no +// config is provided, but the providers must be defined. +func (c TestCase) providerConfig(_ context.Context, skipProviderBlock bool) string { + var providerBlocks, requiredProviderBlocks strings.Builder + + // [BF] The Providers field handling predates the logic being moved to this + // method. It's not entirely clear to me at this time why this field + // is being used and not the others, but leaving it here just in case + // it does have a special purpose that wasn't being unit tested prior. + for name := range c.Providers { + providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name)) + } + + for name, externalProvider := range c.ExternalProviders { + if !skipProviderBlock { + providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name)) + } + + if externalProvider.Source == "" && externalProvider.VersionConstraint == "" { + continue + } + + requiredProviderBlocks.WriteString(fmt.Sprintf(" %s = {\n", name)) + + if externalProvider.Source != "" { + requiredProviderBlocks.WriteString(fmt.Sprintf(" source = %q\n", externalProvider.Source)) + } + + if externalProvider.VersionConstraint != "" { + requiredProviderBlocks.WriteString(fmt.Sprintf(" version = %q\n", externalProvider.VersionConstraint)) + } + + requiredProviderBlocks.WriteString(" }\n") + } + + if requiredProviderBlocks.Len() > 0 { + return fmt.Sprintf(` +terraform { + required_providers { +%[1]s + } +} + +%[2]s +`, strings.TrimSuffix(requiredProviderBlocks.String(), "\n"), providerBlocks.String()) + } + + return providerBlocks.String() +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testcase_validate.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testcase_validate.go new file mode 100644 index 00000000..6640f8c8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testcase_validate.go @@ -0,0 +1,113 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "fmt" + + "github.com/mitchellh/go-testing-interface" + + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/internal/logging" + "github.com/hashicorp/terraform-plugin-testing/internal/teststep" +) + +// hasProviders returns true if the TestCase has ExternalProviders set. +func (c TestCase) hasExternalProviders(_ context.Context) bool { + return len(c.ExternalProviders) > 0 +} + +// hasProviders returns true if the TestCase has set any of the +// ExternalProviders, ProtoV5ProviderFactories, ProtoV6ProviderFactories, +// ProviderFactories, or Providers fields. +func (c TestCase) hasProviders(_ context.Context) bool { + if len(c.ExternalProviders) > 0 { + return true + } + + if len(c.ProtoV5ProviderFactories) > 0 { + return true + } + + if len(c.ProtoV6ProviderFactories) > 0 { + return true + } + + if len(c.ProviderFactories) > 0 { + return true + } + + if len(c.Providers) > 0 { + return true + } + + return false +} + +// validate ensures the TestCase is valid based on the following criteria: +// +// - No overlapping ExternalProviders and Providers entries +// - No overlapping ExternalProviders and ProviderFactories entries +// - TestStep validations performed by the (TestStep).validate() method. +func (c TestCase) validate(ctx context.Context, t testing.T) error { + logging.HelperResourceTrace(ctx, "Validating TestCase") + + if len(c.Steps) == 0 { + err := fmt.Errorf("TestCase missing Steps") + logging.HelperResourceError(ctx, "TestCase validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + for name := range c.ExternalProviders { + if _, ok := c.Providers[name]; ok { + err := fmt.Errorf("TestCase provider %q set in both ExternalProviders and Providers", name) + logging.HelperResourceError(ctx, "TestCase validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + if _, ok := c.ProviderFactories[name]; ok { + err := fmt.Errorf("TestCase provider %q set in both ExternalProviders and ProviderFactories", name) + logging.HelperResourceError(ctx, "TestCase validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + } + + testCaseHasExternalProviders := c.hasExternalProviders(ctx) + testCaseHasProviders := c.hasProviders(ctx) + + for stepIndex, step := range c.Steps { + stepNumber := stepIndex + 1 // Use 1-based index for humans + + configRequest := teststep.PrepareConfigurationRequest{ + Directory: step.ConfigDirectory, + File: step.ConfigFile, + Raw: step.Config, + TestStepConfigRequest: config.TestStepConfigRequest{ + StepNumber: stepNumber, + TestName: t.Name(), + }, + }.Exec() + + stepConfiguration := teststep.Configuration(configRequest) + + stepValidateReq := testStepValidateRequest{ + StepConfiguration: stepConfiguration, + StepNumber: stepNumber, + TestCaseHasExternalProviders: testCaseHasExternalProviders, + TestCaseHasProviders: testCaseHasProviders, + TestName: t.Name(), + } + + err := step.validate(ctx, stepValidateReq) + + if err != nil { + err := fmt.Errorf("TestStep %d/%d validation error: %w", stepNumber, len(c.Steps), err) + logging.HelperResourceError(ctx, "TestCase validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing.go new file mode 100644 index 00000000..f98abda3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing.go @@ -0,0 +1,2097 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "errors" + "flag" + "fmt" + "log" + "os" + "regexp" + "strconv" + "strings" + "time" + + "github.com/mitchellh/go-testing-interface" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-plugin-testing/tfversion" + + "github.com/hashicorp/terraform-plugin-testing/internal/addrs" + "github.com/hashicorp/terraform-plugin-testing/internal/logging" + "github.com/hashicorp/terraform-plugin-testing/internal/plugintest" +) + +// flagSweep is a flag available when running tests on the command line. It +// contains a comma separated list of regions to for the sweeper functions to +// run in. This flag bypasses the normal Test path and instead runs functions designed to +// clean up any leaked resources a testing environment could have created. It is +// a best effort attempt, and relies on Provider authors to implement "Sweeper" +// methods for resources. + +// Adding Sweeper methods with AddTestSweepers will +// construct a list of sweeper funcs to be called here. We iterate through +// regions provided by the sweep flag, and for each region we iterate through the +// tests, and exit on any errors. At time of writing, sweepers are ran +// sequentially, however they can list dependencies to be ran first. We track +// the sweepers that have been ran, so as to not run a sweeper twice for a given +// region. +// +// WARNING: +// Sweepers are designed to be destructive. You should not use the -sweep flag +// in any environment that is not strictly a test environment. Resources will be +// destroyed. + +var flagSweep = flag.String("sweep", "", "List of Regions to run available Sweepers") +var flagSweepAllowFailures = flag.Bool("sweep-allow-failures", false, "Enable to allow Sweeper Tests to continue after failures") +var flagSweepRun = flag.String("sweep-run", "", "Comma separated list of Sweeper Tests to run") +var sweeperFuncs map[string]*Sweeper + +// SweeperFunc is a signature for a function that acts as a sweeper. It +// accepts a string for the region that the sweeper is to be ran in. This +// function must be able to construct a valid client for that region. +type SweeperFunc func(r string) error + +type Sweeper struct { + // Name for sweeper. Must be unique to be ran by the Sweeper Runner + Name string + + // Dependencies list the const names of other Sweeper functions that must be ran + // prior to running this Sweeper. This is an ordered list that will be invoked + // recursively at the helper/resource level + Dependencies []string + + // Sweeper function that when invoked sweeps the Provider of specific + // resources + F SweeperFunc +} + +func init() { + sweeperFuncs = make(map[string]*Sweeper) +} + +// AddTestSweepers function adds a given name and Sweeper configuration +// pair to the internal sweeperFuncs map. Invoke this function to register a +// resource sweeper to be available for running when the -sweep flag is used +// with `go test`. Sweeper names must be unique to help ensure a given sweeper +// is only ran once per run. +func AddTestSweepers(name string, s *Sweeper) { + if _, ok := sweeperFuncs[name]; ok { + log.Fatalf("[ERR] Error adding (%s) to sweeperFuncs: function already exists in map", name) + } + + sweeperFuncs[name] = s +} + +// TestMain adds sweeper functionality to the "go test" command, otherwise +// tests are executed as normal. Most provider acceptance tests are written +// using the Test() function of this package, which imposes its own +// requirements and Terraform CLI behavior. Refer to that function's +// documentation for additional details. +// +// Sweepers enable infrastructure cleanup functions to be included with +// resource definitions, typically so developers can remove all resources of +// that resource type from testing infrastructure in case of failures that +// prevented the normal resource destruction behavior of acceptance tests. +// Use the AddTestSweepers() function to configure available sweepers. +// +// Sweeper flags added to the "go test" command: +// +// -sweep: Comma-separated list of locations/regions to run available sweepers. +// -sweep-allow-failures: Enable to allow other sweepers to run after failures. +// -sweep-run: Comma-separated list of resource type sweepers to run. Defaults +// to all sweepers. +// +// Refer to the Env prefixed constants for environment variables that further +// control testing functionality. +func TestMain(m interface { + Run() int +}) { + flag.Parse() + if *flagSweep != "" { + // parse flagSweep contents for regions to run + regions := strings.Split(*flagSweep, ",") + + // get filtered list of sweepers to run based on sweep-run flag + sweepers := filterSweepers(*flagSweepRun, sweeperFuncs) + + if _, err := runSweepers(regions, sweepers, *flagSweepAllowFailures); err != nil { + os.Exit(1) + } + } else { + exitCode := m.Run() + os.Exit(exitCode) + } +} + +func runSweepers(regions []string, sweepers map[string]*Sweeper, allowFailures bool) (map[string]map[string]error, error) { + var sweeperErrorFound bool + sweeperRunList := make(map[string]map[string]error) + + for _, region := range regions { + region = strings.TrimSpace(region) + + var regionSweeperErrorFound bool + regionSweeperRunList := make(map[string]error) + + start := time.Now() + log.Printf("[DEBUG] Running Sweepers for region (%s):\n", region) + for _, sweeper := range sweepers { + if err := runSweeperWithRegion(region, sweeper, sweepers, regionSweeperRunList, allowFailures); err != nil { + if allowFailures { + continue + } + + sweeperRunList[region] = regionSweeperRunList + return sweeperRunList, fmt.Errorf("sweeper (%s) for region (%s) failed: %s", sweeper.Name, region, err) + } + } + elapsed := time.Since(start) + log.Printf("Completed Sweepers for region (%s) in %s", region, elapsed) + + log.Printf("Sweeper Tests for region (%s) ran successfully:\n", region) + for sweeper, sweeperErr := range regionSweeperRunList { + if sweeperErr == nil { + log.Printf("\t- %s\n", sweeper) + } else { + regionSweeperErrorFound = true + } + } + + if regionSweeperErrorFound { + sweeperErrorFound = true + log.Printf("Sweeper Tests for region (%s) ran unsuccessfully:\n", region) + for sweeper, sweeperErr := range regionSweeperRunList { + if sweeperErr != nil { + log.Printf("\t- %s: %s\n", sweeper, sweeperErr) + } + } + } + + sweeperRunList[region] = regionSweeperRunList + } + + if sweeperErrorFound { + return sweeperRunList, errors.New("at least one sweeper failed") + } + + return sweeperRunList, nil +} + +// filterSweepers takes a comma separated string listing the names of sweepers +// to be ran, and returns a filtered set from the list of all of sweepers to +// run based on the names given. +func filterSweepers(f string, source map[string]*Sweeper) map[string]*Sweeper { + filterSlice := strings.Split(strings.ToLower(f), ",") + if len(filterSlice) == 1 && filterSlice[0] == "" { + // if the filter slice is a single element of "" then no sweeper list was + // given, so just return the full list + return source + } + + sweepers := make(map[string]*Sweeper) + for name := range source { + for _, s := range filterSlice { + if strings.Contains(strings.ToLower(name), s) { + for foundName, foundSweeper := range filterSweeperWithDependencies(name, source) { + sweepers[foundName] = foundSweeper + } + } + } + } + return sweepers +} + +// filterSweeperWithDependencies recursively returns sweeper and all dependencies. +// Since filterSweepers performs fuzzy matching, this function is used +// to perform exact sweeper and dependency lookup. +func filterSweeperWithDependencies(name string, source map[string]*Sweeper) map[string]*Sweeper { + result := make(map[string]*Sweeper) + + currentSweeper, ok := source[name] + if !ok { + log.Printf("[WARN] Sweeper has dependency (%s), but that sweeper was not found", name) + return result + } + + result[name] = currentSweeper + + for _, dependency := range currentSweeper.Dependencies { + for foundName, foundSweeper := range filterSweeperWithDependencies(dependency, source) { + result[foundName] = foundSweeper + } + } + + return result +} + +// runSweeperWithRegion receives a sweeper and a region, and recursively calls +// itself with that region for every dependency found for that sweeper. If there +// are no dependencies, invoke the contained sweeper fun with the region, and +// add the success/fail status to the sweeperRunList. +func runSweeperWithRegion(region string, s *Sweeper, sweepers map[string]*Sweeper, sweeperRunList map[string]error, allowFailures bool) error { + for _, dep := range s.Dependencies { + depSweeper, ok := sweepers[dep] + + if !ok { + log.Printf("[ERROR] Sweeper (%s) has dependency (%s), but that sweeper was not found", s.Name, dep) + return fmt.Errorf("sweeper (%s) has dependency (%s), but that sweeper was not found", s.Name, dep) + } + + log.Printf("[DEBUG] Sweeper (%s) has dependency (%s), running..", s.Name, dep) + err := runSweeperWithRegion(region, depSweeper, sweepers, sweeperRunList, allowFailures) + + if err != nil { + if allowFailures { + log.Printf("[ERROR] Error running Sweeper (%s) in region (%s): %s", depSweeper.Name, region, err) + continue + } + + return err + } + } + + if _, ok := sweeperRunList[s.Name]; ok { + log.Printf("[DEBUG] Sweeper (%s) already ran in region (%s)", s.Name, region) + return nil + } + + log.Printf("[DEBUG] Running Sweeper (%s) in region (%s)", s.Name, region) + + start := time.Now() + runE := s.F(region) + elapsed := time.Since(start) + + log.Printf("[DEBUG] Completed Sweeper (%s) in region (%s) in %s", s.Name, region, elapsed) + + sweeperRunList[s.Name] = runE + + if runE != nil { + log.Printf("[ERROR] Error running Sweeper (%s) in region (%s): %s", s.Name, region, runE) + } + + return runE +} + +// Deprecated: Use EnvTfAcc instead. +const TestEnvVar = EnvTfAcc + +// TestCheckFunc is the callback type used with acceptance tests to check +// the state of a resource. The state passed in is the latest state known, +// or in the case of being after a destroy, it is the last known state when +// it was created. +type TestCheckFunc func(*terraform.State) error + +// ImportStateCheckFunc is the check function for ImportState tests +type ImportStateCheckFunc func([]*terraform.InstanceState) error + +// ImportStateIdFunc is an ID generation function to help with complex ID +// generation for ImportState tests. +type ImportStateIdFunc func(*terraform.State) (string, error) + +// ErrorCheckFunc is a function providers can use to handle errors. +type ErrorCheckFunc func(error) error + +// TestCase is a single acceptance test case used to test the apply/destroy +// lifecycle of a resource in a specific configuration. +// +// When the destroy plan is executed, the config from the last TestStep +// is used to plan it. +// +// Refer to the Env prefixed constants for environment variables that further +// control testing functionality. +type TestCase struct { + // IsUnitTest allows a test to run regardless of the TF_ACC + // environment variable. This should be used with care - only for + // fast tests on local resources (e.g. remote state with a local + // backend) but can be used to increase confidence in correct + // operation of Terraform without waiting for a full acctest run. + IsUnitTest bool + + // PreCheck, if non-nil, will be called before any test steps are + // executed. It will only be executed in the case that the steps + // would run, so it can be used for some validation before running + // acceptance tests, such as verifying that keys are setup. + PreCheck func() + + // TerraformVersionChecks is a list of checks to run against + // the Terraform CLI version which is running the testing. + // Each check is executed in order, respecting the first skip + // or fail response, unless the Any() meta check is also used. + TerraformVersionChecks []tfversion.TerraformVersionCheck + + // ProviderFactories can be specified for the providers that are valid. + // + // This can also be specified at the TestStep level to enable per-step + // differences in providers, however all provider specifications must + // be done either at the TestCase level or TestStep level, otherwise the + // testing framework will raise an error and fail the test. + // + // These are the providers that can be referenced within the test. Each key + // is an individually addressable provider. Typically you will only pass a + // single value here for the provider you are testing. Aliases are not + // supported by the test framework, so to use multiple provider instances, + // you should add additional copies to this map with unique names. To set + // their configuration, you would reference them similar to the following: + // + // provider "my_factory_key" { + // # ... + // } + // + // resource "my_resource" "mr" { + // provider = my_factory_key + // + // # ... + // } + ProviderFactories map[string]func() (*schema.Provider, error) + + // ProtoV5ProviderFactories serves the same purpose as ProviderFactories, + // but for protocol v5 providers defined using the terraform-plugin-go + // ProviderServer interface. + // + // This can also be specified at the TestStep level to enable per-step + // differences in providers, however all provider specifications must + // be done either at the TestCase level or TestStep level, otherwise the + // testing framework will raise an error and fail the test. + ProtoV5ProviderFactories map[string]func() (tfprotov5.ProviderServer, error) + + // ProtoV6ProviderFactories serves the same purpose as ProviderFactories, + // but for protocol v6 providers defined using the terraform-plugin-go + // ProviderServer interface. + // The version of Terraform used in acceptance testing must be greater + // than or equal to v0.15.4 to use ProtoV6ProviderFactories. + // + // This can also be specified at the TestStep level to enable per-step + // differences in providers, however all provider specifications must + // be done either at the TestCase level or TestStep level, otherwise the + // testing framework will raise an error and fail the test. + ProtoV6ProviderFactories map[string]func() (tfprotov6.ProviderServer, error) + + // Providers is the ResourceProvider that will be under test. + // + // Deprecated: Providers is deprecated, please use ProviderFactories + Providers map[string]*schema.Provider + + // ExternalProviders are providers the TestCase relies on that should + // be downloaded from the registry during init. + // + // This can also be specified at the TestStep level to enable per-step + // differences in providers, however all provider specifications must + // be done either at the TestCase level or TestStep level, otherwise the + // testing framework will raise an error and fail the test. + // + // This is generally unnecessary to set at the TestCase level, however + // it has existing in the testing framework prior to the introduction of + // TestStep level specification and was only necessary for performing + // import testing where the configuration contained a provider outside the + // one under test. + ExternalProviders map[string]ExternalProvider + + // PreventPostDestroyRefresh can be set to true for cases where data sources + // are tested alongside real resources + PreventPostDestroyRefresh bool + + // CheckDestroy is called after the resource is finally destroyed + // to allow the tester to test that the resource is truly gone. + CheckDestroy TestCheckFunc + + // ErrorCheck allows providers the option to handle errors such as skipping + // tests based on certain errors. + // + // This functionality is only intended for provider-controlled error + // messaging. While in certain scenarios this can also catch testing logic + // error messages, those messages are not protected by compatibility + // promises. + ErrorCheck ErrorCheckFunc + + // Steps are the apply sequences done within the context of the + // same state. Each step can have its own check to verify correctness. + Steps []TestStep + + // IDRefreshName is the name of the resource to check during ID-only + // refresh testing, which ensures that a resource can be refreshed solely + // by its identifier. This will default to the first non-nil primary + // resource in the state. It runs every TestStep. + // + // While not deprecated, most resource tests should instead prefer using + // TestStep.ImportState based testing as it works with multiple attribute + // identifiers and also verifies resource import functionality. + IDRefreshName string + + // IDRefreshIgnore is a list of configuration keys that will be ignored + // during ID-only refresh testing. + IDRefreshIgnore []string + + // WorkingDir sets the base directory where testing files used by the testing + // module are generated. If WorkingDir is unset, a randomized, temporary + // directory is used. + // + // Use the TF_ACC_PERSIST_WORKING_DIR environment variable, conventionally + // set to "1", to persist any working directory files. Otherwise, this directory is + // automatically cleaned up at the end of the TestCase. + WorkingDir string +} + +// ExternalProvider holds information about third-party providers that should +// be downloaded by Terraform as part of running the test step. +type ExternalProvider struct { + VersionConstraint string // the version constraint for the provider + Source string // the provider source +} + +// TestStep is a single apply sequence of a test, done within the +// context of a state. +// +// Multiple TestSteps can be sequenced in a Test to allow testing +// potentially complex update logic. In general, simply create/destroy +// tests will only need one step. +// +// Refer to the Env prefixed constants for environment variables that further +// control testing functionality. +type TestStep struct { + // ResourceName should be set to the name of the resource + // that is being tested. Example: "aws_instance.foo". Various test + // modes use this to auto-detect state information. + // + // This is only required if the test mode settings below say it is + // for the mode you're using. + ResourceName string + + // PreConfig is called before the Config is applied to perform any per-step + // setup that needs to happen. This is called regardless of "test mode" + // below. + PreConfig func() + + // Taint is a list of resource addresses to taint prior to the execution of + // the step. Be sure to only include this at a step where the referenced + // address will be present in state, as it will fail the test if the resource + // is missing. + // + // This option is ignored on ImportState tests, and currently only works for + // resources in the root module path. + Taint []string + + //--------------------------------------------------------------- + // Test modes. One of the following groups of settings must be + // set to determine what the test step will do. Ideally we would've + // used Go interfaces here but there are now hundreds of tests we don't + // want to re-type so instead we just determine which step logic + // to run based on what settings below are set. + //--------------------------------------------------------------- + + //--------------------------------------------------------------- + // Plan, Apply testing + //--------------------------------------------------------------- + + // Config a string of the configuration to give to Terraform. If this + // is set, then the TestCase will execute this step with the same logic + // as a `terraform apply`. If both Config and ConfigDirectory are set + // an error will be returned. + // + // JSON Configuration Syntax can be used and is assumed whenever Config + // contains valid JSON. + // + // Only one of Config, ConfigDirectory or ConfigFile can be set + // otherwise an error will be returned. + Config string + + // ConfigDirectory is a function which returns a function that + // accepts config.TestStepProviderConfig and returns a string + // representing a directory that contains Terraform + // configuration files. + // + // There are helper functions in the [config] package that can be used, + // such as: + // + // - [config.StaticDirectory] + // - [config.TestNameDirectory] + // - [config.TestStepDirectory] + // + // When running Terraform operations for the test, Terraform will + // be executed with copies of the files of this directory as its + // working directory. Only one of Config, ConfigDirectory or + // ConfigFile can be set otherwise an error will be returned. + ConfigDirectory config.TestStepConfigFunc + + // ConfigFile is a function which returns a function that + // accepts config.TestStepProviderConfig and returns a string + // representing a file that contains Terraform configuration. + // + // There are helper functions in the [config] package that can be used, + // such as: + // + // - [config.StaticFile] + // - [config.TestNameFile] + // - [config.TestStepFile] + // + // When running Terraform operations for the test, Terraform will + // be executed with a copy of the file as its working directory. + // Only one of Config, ConfigDirectory or ConfigFile can be set + // otherwise an error will be returned. + ConfigFile config.TestStepConfigFunc + + // ConfigVariables is a map defining variables for use in conjunction + // with Terraform configuration. If this map is populated then it + // will be used to assemble an *.auto.tfvars.json which will be + // written into the working directory. Any variables that are + // defined within the Terraform configuration that have a matching + // variable definition in *.auto.tfvars.json will have their value + // substituted when the acceptance test is executed. + ConfigVariables config.Variables + + // Check is called after the Config is applied. Use this step to + // make your own API calls to check the status of things, and to + // inspect the format of the ResourceState itself. + // + // If an error is returned, the test will fail. In this case, a + // destroy plan will still be attempted. + // + // If this is nil, no check is done on this step. + Check TestCheckFunc + + // Destroy will create a destroy plan if set to true. + Destroy bool + + // ExpectNonEmptyPlan can be set to true for specific types of tests that are + // looking to verify that a diff occurs + ExpectNonEmptyPlan bool + + // ExpectError allows the construction of test cases that we expect to fail + // with an error. The specified regexp must match against the error for the + // test to pass. + // + // This functionality is only intended for provider-controlled error + // messaging. While in certain scenarios this can also catch testing logic + // error messages, those messages are not protected by compatibility + // promises. + ExpectError *regexp.Regexp + + // ConfigPlanChecks allows assertions to be made against the plan file at different points of a Config (apply) test using a plan check. + // Custom plan checks can be created by implementing the [PlanCheck] interface, or by using a PlanCheck implementation from the provided [plancheck] package + // + // [PlanCheck]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck#PlanCheck + // [plancheck]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck + ConfigPlanChecks ConfigPlanChecks + + // RefreshPlanChecks allows assertions to be made against the plan file at different points of a Refresh test using a plan check. + // Custom plan checks can be created by implementing the [PlanCheck] interface, or by using a PlanCheck implementation from the provided [plancheck] package + // + // [PlanCheck]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck#PlanCheck + // [plancheck]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck + RefreshPlanChecks RefreshPlanChecks + + // ConfigStateChecks allow assertions to be made against the state file during a Config (apply) test using a state check. + // Custom state checks can be created by implementing the [statecheck.StateCheck] interface, or by using a StateCheck implementation from the provided [statecheck] package. + ConfigStateChecks []statecheck.StateCheck + + // PlanOnly can be set to only run `plan` with this configuration, and not + // actually apply it. This is useful for ensuring config changes result in + // no-op plans + PlanOnly bool + + // PreventDiskCleanup can be set to true for testing terraform modules which + // require access to disk at runtime. Note that this will leave files in the + // temp folder + PreventDiskCleanup bool + + // PreventPostDestroyRefresh can be set to true for cases where data sources + // are tested alongside real resources + PreventPostDestroyRefresh bool + + // SkipFunc enables skipping the TestStep, based on environment criteria. + // For example, this can prevent running certain steps that may be runtime + // platform or API configuration dependent. + // + // Return true with no error to skip the test step. The error return + // should be used to signify issues that prevented the function from + // completing as expected. + // + // SkipFunc is called after PreConfig but before applying the Config. + SkipFunc func() (bool, error) + + //--------------------------------------------------------------- + // ImportState testing + //--------------------------------------------------------------- + + // ImportState, if true, will test the functionality of ImportState + // by importing the resource with ResourceName (must be set) and the + // ID of that resource. + ImportState bool + + // ImportStateId is the ID to perform an ImportState operation with. + // This is optional. If it isn't set, then the resource ID is automatically + // determined by inspecting the state for ResourceName's ID. + ImportStateId string + + // ImportStateIdPrefix is the prefix added in front of ImportStateId. + // This can be useful in complex import cases, where more than one + // attribute needs to be passed on as the Import ID. Mainly in cases + // where the ID is not known, and a known prefix needs to be added to + // the unset ImportStateId field. + ImportStateIdPrefix string + + // ImportStateIdFunc is a function that can be used to dynamically generate + // the ID for the ImportState tests. It is sent the state, which can be + // checked to derive the attributes necessary and generate the string in the + // desired format. + ImportStateIdFunc ImportStateIdFunc + + // ImportStateCheck checks the results of ImportState. It should be + // used to verify that the resulting value of ImportState has the + // proper resources, IDs, and attributes. + // + // Prefer ImportStateVerify over ImportStateCheck, unless the resource + // import explicitly is expected to create multiple resources (not a + // recommended resource implementation) or if attributes are imported with + // syntactically different but semantically/functionally equivalent values + // where special logic is needed. + // + // Terraform versions 1.3 and later can include data source states during + // import, which the testing framework will skip to prevent the need for + // Terraform version specific logic in provider testing. + ImportStateCheck ImportStateCheckFunc + + // ImportStateVerify, if true, will also check that the state values + // that are finally put into the state after import match for all the + // IDs returned by the Import. Note that this checks for strict equality + // and does not respect DiffSuppressFunc or CustomizeDiff. + // + // By default, the prior resource state and import resource state are + // matched by the "id" attribute. If the "id" attribute is not implemented + // or another attribute more uniquely identifies the resource, set the + // ImportStateVerifyIdentifierAttribute field to adjust the attribute for + // matching. + // + // If certain attributes cannot be correctly imported, set the + // ImportStateVerifyIgnore field. + ImportStateVerify bool + + // ImportStateVerifyIdentifierAttribute is the resource attribute for + // matching the prior resource state and import resource state during import + // verification. By default, the "id" attribute is used. + ImportStateVerifyIdentifierAttribute string + + // ImportStateVerifyIgnore is a list of prefixes of fields that should + // not be verified to be equal. These can be set to ephemeral fields or + // fields that can't be refreshed and don't matter. + ImportStateVerifyIgnore []string + + // ImportStatePersist, if true, will update the persisted state with the + // state generated by the import operation (i.e., terraform import). When + // false (default) the state generated by the import operation is discarded + // at the end of the test step that is verifying import behavior. + ImportStatePersist bool + + //--------------------------------------------------------------- + // RefreshState testing + //--------------------------------------------------------------- + + // RefreshState, if true, will test the functionality of `terraform + // refresh` by refreshing the state, running any checks against the + // refreshed state, and running a plan to verify against unexpected plan + // differences. + // + // If the refresh is expected to result in a non-empty plan + // ExpectNonEmptyPlan should be set to true in the same TestStep. + // + // RefreshState cannot be the first TestStep and, it is mutually exclusive + // with ImportState. + RefreshState bool + + // ProviderFactories can be specified for the providers that are valid for + // this TestStep. When providers are specified at the TestStep level, all + // TestStep within a TestCase must declare providers. + // + // This can also be specified at the TestCase level for all TestStep, + // however all provider specifications must be done either at the TestCase + // level or TestStep level, otherwise the testing framework will raise an + // error and fail the test. + // + // These are the providers that can be referenced within the test. Each key + // is an individually addressable provider. Typically you will only pass a + // single value here for the provider you are testing. Aliases are not + // supported by the test framework, so to use multiple provider instances, + // you should add additional copies to this map with unique names. To set + // their configuration, you would reference them similar to the following: + // + // provider "my_factory_key" { + // # ... + // } + // + // resource "my_resource" "mr" { + // provider = my_factory_key + // + // # ... + // } + ProviderFactories map[string]func() (*schema.Provider, error) + + // ProtoV5ProviderFactories serves the same purpose as ProviderFactories, + // but for protocol v5 providers defined using the terraform-plugin-go + // ProviderServer interface. When providers are specified at the TestStep + // level, all TestStep within a TestCase must declare providers. + // + // This can also be specified at the TestCase level for all TestStep, + // however all provider specifications must be done either at the TestCase + // level or TestStep level, otherwise the testing framework will raise an + // error and fail the test. + ProtoV5ProviderFactories map[string]func() (tfprotov5.ProviderServer, error) + + // ProtoV6ProviderFactories serves the same purpose as ProviderFactories, + // but for protocol v6 providers defined using the terraform-plugin-go + // ProviderServer interface. + // The version of Terraform used in acceptance testing must be greater + // than or equal to v0.15.4 to use ProtoV6ProviderFactories. When providers + // are specified at the TestStep level, all TestStep within a TestCase must + // declare providers. + // + // This can also be specified at the TestCase level for all TestStep, + // however all provider specifications must be done either at the TestCase + // level or TestStep level, otherwise the testing framework will raise an + // error and fail the test. + ProtoV6ProviderFactories map[string]func() (tfprotov6.ProviderServer, error) + + // ExternalProviders are providers the TestStep relies on that should + // be downloaded from the registry during init. When providers are + // specified at the TestStep level, all TestStep within a TestCase must + // declare providers. + // + // This can also be specified at the TestCase level for all TestStep, + // however all provider specifications must be done either at the TestCase + // level or TestStep level, otherwise the testing framework will raise an + // error and fail the test. + // + // Outside specifying an earlier version of the provider under test, + // typically for state upgrader testing, this is generally only necessary + // for performing import testing where the prior TestStep configuration + // contained a provider outside the one under test. + ExternalProviders map[string]ExternalProvider +} + +// ConfigPlanChecks defines the different points in a Config TestStep when plan checks can be run. +type ConfigPlanChecks struct { + // PreApply runs all plan checks in the slice. This occurs before the apply of a Config test is run. This slice cannot be populated + // with TestStep.PlanOnly, as there is no PreApply plan run with that flag set. All errors by plan checks in this slice are aggregated, reported, and will result in a test failure. + PreApply []plancheck.PlanCheck + + // PostApplyPreRefresh runs all plan checks in the slice. This occurs after the apply and before the refresh of a Config test is run. + // All errors by plan checks in this slice are aggregated, reported, and will result in a test failure. + PostApplyPreRefresh []plancheck.PlanCheck + + // PostApplyPostRefresh runs all plan checks in the slice. This occurs after the apply and refresh of a Config test are run. + // All errors by plan checks in this slice are aggregated, reported, and will result in a test failure. + PostApplyPostRefresh []plancheck.PlanCheck +} + +// RefreshPlanChecks defines the different points in a Refresh TestStep when plan checks can be run. +type RefreshPlanChecks struct { + // PostRefresh runs all plan checks in the slice. This occurs after the refresh of the Refresh test is run. + // All errors by plan checks in this slice are aggregated, reported, and will result in a test failure. + PostRefresh []plancheck.PlanCheck +} + +// ParallelTest performs an acceptance test on a resource, allowing concurrency +// with other ParallelTest. The number of concurrent tests is controlled by the +// "go test" command -parallel flag. +// +// Tests will fail if they do not properly handle conditions to allow multiple +// tests to occur against the same resource or service (e.g. random naming). +// +// Test() function requirements and documentation also apply to this function. +func ParallelTest(t testing.T, c TestCase) { + t.Helper() + t.Parallel() + Test(t, c) +} + +// Test performs an acceptance test on a resource. +// +// Tests are not run unless an environmental variable "TF_ACC" is +// set to some non-empty value. This is to avoid test cases surprising +// a user by creating real resources. +// +// Tests will fail unless the verbose flag (`go test -v`, or explicitly +// the "-test.v" flag) is set. Because some acceptance tests take quite +// long, we require the verbose flag so users are able to see progress +// output. +// +// Use the ParallelTest() function to automatically set (*testing.T).Parallel() +// to enable testing concurrency. Use the UnitTest() function to automatically +// set the TestCase type IsUnitTest field. +// +// This function will automatically find or install Terraform CLI into a +// temporary directory, based on the following behavior: +// +// - If the TF_ACC_TERRAFORM_PATH environment variable is set, that +// Terraform CLI binary is used if found and executable. If not found or +// executable, an error will be returned unless the +// TF_ACC_TERRAFORM_VERSION environment variable is also set. +// - If the TF_ACC_TERRAFORM_VERSION environment variable is set, install +// and use that Terraform CLI version. +// - If both the TF_ACC_TERRAFORM_PATH and TF_ACC_TERRAFORM_VERSION +// environment variables are unset, perform a lookup for the Terraform +// CLI binary based on the operating system PATH. If not found, the +// latest available Terraform CLI binary is installed. +// +// Refer to the Env prefixed constants for additional details about these +// environment variables, and others, that control testing functionality. +func Test(t testing.T, c TestCase) { + t.Helper() + + ctx := context.Background() + ctx = logging.InitTestContext(ctx, t) + + err := c.validate(ctx, t) + + if err != nil { + logging.HelperResourceError(ctx, + "Test validation error", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Test validation error: %s", err) + } + + // We only run acceptance tests if an env var is set because they're + // slow and generally require some outside configuration. You can opt out + // of this with OverrideEnvVar on individual TestCases. + if os.Getenv(EnvTfAcc) == "" && !c.IsUnitTest { + t.Skip(fmt.Sprintf( + "Acceptance tests skipped unless env '%s' set", + EnvTfAcc)) + return + } + + // Copy any explicitly passed providers to factories, this is for backwards compatibility. + if len(c.Providers) > 0 { + c.ProviderFactories = map[string]func() (*schema.Provider, error){} + + for name, p := range c.Providers { + prov := p + c.ProviderFactories[name] = func() (*schema.Provider, error) { //nolint:unparam // required signature + return prov, nil + } + } + } + + logging.HelperResourceDebug(ctx, "Starting TestCase") + + // Run the PreCheck if we have it. + // This is done after the auto-configure to allow providers + // to override the default auto-configure parameters. + if c.PreCheck != nil { + logging.HelperResourceDebug(ctx, "Calling TestCase PreCheck") + + c.PreCheck() + + logging.HelperResourceDebug(ctx, "Called TestCase PreCheck") + } + + sourceDir, err := os.Getwd() + if err != nil { + t.Fatalf("Error getting working dir: %s", err) + } + helper := plugintest.AutoInitProviderHelper(ctx, sourceDir) + defer func(helper *plugintest.Helper) { + err := helper.Close() + if err != nil { + logging.HelperResourceError(ctx, "Unable to clean up temporary test files", map[string]interface{}{logging.KeyError: err}) + } + }(helper) + + // Run the TerraformVersionChecks if we have it. + // This is done after creating the helper because a working directory is required + // to retrieve the Terraform version. + if c.TerraformVersionChecks != nil { + logging.HelperResourceDebug(ctx, "Calling TestCase Terraform version checks") + + runTFVersionChecks(ctx, t, helper.TerraformVersion(), c.TerraformVersionChecks) + + logging.HelperResourceDebug(ctx, "Called TestCase Terraform version checks") + } + + runNewTest(ctx, t, c, helper) + + logging.HelperResourceDebug(ctx, "Finished TestCase") +} + +// UnitTest is a helper to force the acceptance testing harness to run in the +// normal unit test suite. This should only be used for resource that don't +// have any external dependencies. +// +// Test() function requirements and documentation also apply to this function. +func UnitTest(t testing.T, c TestCase) { + t.Helper() + + c.IsUnitTest = true + Test(t, c) +} + +func testResource(c TestStep, state *terraform.State) (*terraform.ResourceState, error) { + for _, m := range state.Modules { + if len(m.Resources) > 0 { + if v, ok := m.Resources[c.ResourceName]; ok { + return v, nil + } + } + } + + return nil, fmt.Errorf( + "Resource specified by ResourceName couldn't be found: %s", c.ResourceName) +} + +// ComposeTestCheckFunc lets you compose multiple TestCheckFuncs into +// a single TestCheckFunc. +// +// As a user testing their provider, this lets you decompose your checks +// into smaller pieces more easily. +// +// ComposeTestCheckFunc returns immediately on the first TestCheckFunc error. +// To aggregrate all errors, use ComposeAggregateTestCheckFunc instead. +func ComposeTestCheckFunc(fs ...TestCheckFunc) TestCheckFunc { + return func(s *terraform.State) error { + for i, f := range fs { + if err := f(s); err != nil { + return fmt.Errorf("Check %d/%d error: %w", i+1, len(fs), err) + } + } + + return nil + } +} + +// ComposeAggregateTestCheckFunc lets you compose multiple TestCheckFuncs into +// a single TestCheckFunc. +// +// As a user testing their provider, this lets you decompose your checks +// into smaller pieces more easily. +// +// Unlike ComposeTestCheckFunc, ComposeAggergateTestCheckFunc runs _all_ of the +// TestCheckFuncs and aggregates failures. +func ComposeAggregateTestCheckFunc(fs ...TestCheckFunc) TestCheckFunc { + return func(s *terraform.State) error { + var result []error + + for i, f := range fs { + if err := f(s); err != nil { + result = append(result, fmt.Errorf("Check %d/%d error: %w", i+1, len(fs), err)) + } + } + + return errors.Join(result...) + } +} + +// TestCheckResourceAttrSet ensures any value exists in the state for the +// given name and key combination. The opposite of this TestCheckFunc is +// TestCheckNoResourceAttr. State value checking is only recommended for +// testing Computed attributes and attribute defaults. +// +// Use this as a last resort when a more specific TestCheckFunc cannot be +// implemented, such as: +// +// - TestCheckResourceAttr: Equality checking of non-TypeSet state value. +// - TestCheckResourceAttrPair: Equality checking of non-TypeSet state +// value, based on another state value. +// - TestCheckTypeSet*: Equality checking of TypeSet state values. +// - TestMatchResourceAttr: Regular expression checking of non-TypeSet +// state value. +// - TestMatchTypeSet*: Regular expression checking on TypeSet state values. +// +// For managed resources, the name parameter is combination of the resource +// type, a period (.), and the name label. The name for the below example +// configuration would be "myprovider_thing.example". +// +// resource "myprovider_thing" "example" { ... } +// +// For data sources, the name parameter is a combination of the keyword "data", +// a period (.), the data source type, a period (.), and the name label. The +// name for the below example configuration would be +// "data.myprovider_thing.example". +// +// data "myprovider_thing" "example" { ... } +// +// The key parameter is an attribute path in Terraform CLI 0.11 and earlier +// "flatmap" syntax. Keys start with the attribute name of a top-level +// attribute. Use the following special key syntax to inspect underlying +// values of a list or map attribute: +// +// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element +// - .{KEY}: Map value at key, e.g. .example to inspect the example key +// value +// +// While it is possible to check nested attributes under list and map +// attributes using the special key syntax, checking a list, map, or set +// attribute directly is not supported. Use TestCheckResourceAttr with +// the special .# or .% key syntax for those situations instead. +// +// An experimental interface exists to potentially replace the +// TestCheckResourceAttrSet functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestCheckResourceAttrSet with that experimental interface, by +// using [ExpectKnownValue] with [knownvalue.NotNull]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/knownvalue" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +// ) +// +// func TestExpectKnownValue_CheckState_AttributeFound(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example resource containing a computed attribute named "computed_attribute" +// Config: `resource "test_resource" "one" {}`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownValue( +// "test_resource.one", +// tfjsonpath.New("computed_attribute"), +// knownvalue.NotNull(), +// ), +// }, +// }, +// }, +// }) +// } +func TestCheckResourceAttrSet(name, key string) TestCheckFunc { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { + is, err := primaryInstanceState(s, name) + if err != nil { + return err + } + + return testCheckResourceAttrSet(is, name, key) + }) +} + +// TestCheckModuleResourceAttrSet - as per TestCheckResourceAttrSet but with +// support for non-root modules +// +// Deprecated: This functionality is deprecated without replacement. The +// terraform-plugin-testing Go module is intended for provider testing, which +// should always be possible within the root module of a configuration. This +// functionality is a carryover of when this code was used within Terraform +// core to test both providers and modules. Modern testing implementations to +// verify interactions between modules should be tested in Terraform core or +// using tooling outside this Go module. +func TestCheckModuleResourceAttrSet(mp []string, name string, key string) TestCheckFunc { + mpt := addrs.Module(mp).UnkeyedInstanceShim() + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { + is, err := modulePathPrimaryInstanceState(s, mpt, name) + if err != nil { + return err + } + + return testCheckResourceAttrSet(is, name, key) + }) +} + +func testCheckResourceAttrSet(is *terraform.InstanceState, name string, key string) error { + val, ok := is.Attributes[key] + + if ok && val != "" { + return nil + } + + if _, ok := is.Attributes[key+".#"]; ok { + return fmt.Errorf( + "%s: list or set attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s). Set element value checks should use TestCheckTypeSet functions instead.", + name, + key, + key+".#", + key+".0", + ) + } + + if _, ok := is.Attributes[key+".%"]; ok { + return fmt.Errorf( + "%s: map attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s).", + name, + key, + key+".%", + key+".examplekey", + ) + } + + return fmt.Errorf("%s: Attribute '%s' expected to be set", name, key) +} + +// TestCheckResourceAttr ensures a specific value is stored in state for the +// given name and key combination. State value checking is only recommended for +// testing Computed attributes and attribute defaults. +// +// For managed resources, the name parameter is combination of the resource +// type, a period (.), and the name label. The name for the below example +// configuration would be "myprovider_thing.example". +// +// resource "myprovider_thing" "example" { ... } +// +// For data sources, the name parameter is a combination of the keyword "data", +// a period (.), the data source type, a period (.), and the name label. The +// name for the below example configuration would be +// "data.myprovider_thing.example". +// +// data "myprovider_thing" "example" { ... } +// +// The key parameter is an attribute path in Terraform CLI 0.11 and earlier +// "flatmap" syntax. Keys start with the attribute name of a top-level +// attribute. Use the following special key syntax to inspect list, map, and +// set attributes: +// +// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element. +// Use the TestCheckTypeSet* and TestMatchTypeSet* functions instead +// for sets. +// - .{KEY}: Map value at key, e.g. .example to inspect the example key +// value. +// - .#: Number of elements in list or set. +// - .%: Number of elements in map. +// +// The value parameter is the stringified data to check at the given key. Use +// the following attribute type rules to set the value: +// +// - Boolean: "false" or "true". +// - Float/Integer: Stringified number, such as "1.2" or "123". +// - String: No conversion necessary. +// +// An experimental interface exists to potentially replace the +// TestCheckResourceAttr functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestCheckResourceAttr with that experimental interface, by +// using [statecheck.ExpectKnownValue]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/knownvalue" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +// ) +// +// func TestExpectKnownValue_CheckState_Bool(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example resource containing a computed boolean attribute named "computed_attribute" +// Config: `resource "test_resource" "one" {}`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownValue( +// "test_resource.one", +// tfjsonpath.New("computed_attribute"), +// knownvalue.Bool(true), +// ), +// }, +// }, +// }, +// }) +// } +func TestCheckResourceAttr(name, key, value string) TestCheckFunc { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { + is, err := primaryInstanceState(s, name) + if err != nil { + return err + } + + return testCheckResourceAttr(is, name, key, value) + }) +} + +// TestCheckModuleResourceAttr - as per TestCheckResourceAttr but with +// support for non-root modules +// +// Deprecated: This functionality is deprecated without replacement. The +// terraform-plugin-testing Go module is intended for provider testing, which +// should always be possible within the root module of a configuration. This +// functionality is a carryover of when this code was used within Terraform +// core to test both providers and modules. Modern testing implementations to +// verify interactions between modules should be tested in Terraform core or +// using tooling outside this Go module. +func TestCheckModuleResourceAttr(mp []string, name string, key string, value string) TestCheckFunc { + mpt := addrs.Module(mp).UnkeyedInstanceShim() + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { + is, err := modulePathPrimaryInstanceState(s, mpt, name) + if err != nil { + return err + } + + return testCheckResourceAttr(is, name, key, value) + }) +} + +func testCheckResourceAttr(is *terraform.InstanceState, name string, key string, value string) error { + v, ok := is.Attributes[key] + + if !ok { + // Empty containers may be elided from the state. + // If the intent here is to check for an empty container, allow the key to + // also be non-existent. + if value == "0" && (strings.HasSuffix(key, ".#") || strings.HasSuffix(key, ".%")) { + return nil + } + + if _, ok := is.Attributes[key+".#"]; ok { + return fmt.Errorf( + "%s: list or set attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s). Set element value checks should use TestCheckTypeSet functions instead.", + name, + key, + key+".#", + key+".0", + ) + } + + if _, ok := is.Attributes[key+".%"]; ok { + return fmt.Errorf( + "%s: map attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s).", + name, + key, + key+".%", + key+".examplekey", + ) + } + + return fmt.Errorf("%s: Attribute '%s' not found", name, key) + } + + if v != value { + return fmt.Errorf( + "%s: Attribute '%s' expected %#v, got %#v", + name, + key, + value, + v) + } + + return nil +} + +// CheckResourceAttrWithFunc is the callback type used to apply a custom checking logic +// when using TestCheckResourceAttrWith and a value is found for the given name and key. +// +// When this function returns an error, TestCheckResourceAttrWith will fail the check. +// +// An experimental interface exists to potentially replace the +// CheckResourceAttrWithFunc functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestCheckResourceAttrWith with that experimental interface, by +// using [statecheck.ExpectKnownValue] in combination with +// [knownvalue.StringRegexp]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +// ) +// +// func TestExpectKnownValue_CheckState_String_Custom(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example resource containing a computed string attribute named "computed_attribute" +// Config: `resource "test_resource" "one" {}`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownValue( +// "test_resource.one", +// tfjsonpath.New("computed_attribute"), +// knownvalue.StringRegexp(regexp.MustCompile("str")), +// }, +// }, +// }, +// }) +// } +type CheckResourceAttrWithFunc func(value string) error + +// TestCheckResourceAttrWith ensures a value stored in state for the +// given name and key combination, is checked against a custom logic. +// State value checking is only recommended for testing Computed attributes +// and attribute defaults. +// +// For managed resources, the name parameter is combination of the resource +// type, a period (.), and the name label. The name for the below example +// configuration would be "myprovider_thing.example". +// +// resource "myprovider_thing" "example" { ... } +// +// For data sources, the name parameter is a combination of the keyword "data", +// a period (.), the data source type, a period (.), and the name label. The +// name for the below example configuration would be +// "data.myprovider_thing.example". +// +// data "myprovider_thing" "example" { ... } +// +// The key parameter is an attribute path in Terraform CLI 0.11 and earlier +// "flatmap" syntax. Keys start with the attribute name of a top-level +// attribute. Use the following special key syntax to inspect list, map, and +// set attributes: +// +// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element. +// Use the TestCheckTypeSet* and TestMatchTypeSet* functions instead +// for sets. +// - .{KEY}: Map value at key, e.g. .example to inspect the example key +// value. +// - .#: Number of elements in list or set. +// - .%: Number of elements in map. +// +// The checkValueFunc parameter is a CheckResourceAttrWithFunc, +// and it's provided with the attribute value to apply a custom checking logic, +// if it was found in the state. The function must return an error for the +// check to fail, or `nil` to succeed. +// +// An experimental interface exists to potentially replace the +// TestCheckResourceAttrWith functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestCheckResourceAttrWith with that experimental interface, by +// using [statecheck.ExpectKnownValue] in combination with +// [knownvalue.StringRegexp]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +// ) +// +// func TestExpectKnownValue_CheckState_String_Custom(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example resource containing a computed string attribute named "computed_attribute" +// Config: `resource "test_resource" "one" {}`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownValue( +// "test_resource.one", +// tfjsonpath.New("computed_attribute"), +// knownvalue.StringRegexp(regexp.MustCompile("str")), +// }, +// }, +// }, +// }) +// } +func TestCheckResourceAttrWith(name, key string, checkValueFunc CheckResourceAttrWithFunc) TestCheckFunc { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { + is, err := primaryInstanceState(s, name) + if err != nil { + return err + } + + err = testCheckResourceAttrSet(is, name, key) + if err != nil { + return err + } + + err = checkValueFunc(is.Attributes[key]) + if err != nil { + return fmt.Errorf("%s: Attribute %q value: %w", name, key, err) + } + + return nil + }) +} + +// TestCheckNoResourceAttr ensures no value exists in the state for the +// given name and key combination. The opposite of this TestCheckFunc is +// TestCheckResourceAttrSet. State value checking is only recommended for +// testing Computed attributes and attribute defaults. +// +// For managed resources, the name parameter is combination of the resource +// type, a period (.), and the name label. The name for the below example +// configuration would be "myprovider_thing.example". +// +// resource "myprovider_thing" "example" { ... } +// +// For data sources, the name parameter is a combination of the keyword "data", +// a period (.), the data source type, a period (.), and the name label. The +// name for the below example configuration would be +// "data.myprovider_thing.example". +// +// data "myprovider_thing" "example" { ... } +// +// The key parameter is an attribute path in Terraform CLI 0.11 and earlier +// "flatmap" syntax. Keys start with the attribute name of a top-level +// attribute. Use the following special key syntax to inspect underlying +// values of a list or map attribute: +// +// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element. +// - .{KEY}: Map value at key, e.g. .example to inspect the example key +// value. +// +// While it is possible to check nested attributes under list and map +// attributes using the special key syntax, checking a list, map, or set +// attribute directly is not supported. Use TestCheckResourceAttr with +// the special .# or .% key syntax for those situations instead. +// +// An experimental interface exists to potentially replace the +// TestCheckNoResourceAttr functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestCheckNoResourceAttr with that experimental interface, by +// using [statecheck.ExpectKnownValue] with [knownvalue.Null]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +// ) +// +// func TestExpectKnownValue_CheckState_AttributeNull(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example resource containing a computed attribute named "computed_attribute" that has a null value +// Config: `resource "test_resource" "one" {}`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownValue( +// "test_resource.one", +// tfjsonpath.New("computed_attribute"), +// knownvalue.Null(), +// ), +// }, +// }, +// }, +// }) +// } +func TestCheckNoResourceAttr(name, key string) TestCheckFunc { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { + is, err := primaryInstanceState(s, name) + if err != nil { + return err + } + + return testCheckNoResourceAttr(is, name, key) + }) +} + +// TestCheckModuleNoResourceAttr - as per TestCheckNoResourceAttr but with +// support for non-root modules +// +// Deprecated: This functionality is deprecated without replacement. The +// terraform-plugin-testing Go module is intended for provider testing, which +// should always be possible within the root module of a configuration. This +// functionality is a carryover of when this code was used within Terraform +// core to test both providers and modules. Modern testing implementations to +// verify interactions between modules should be tested in Terraform core or +// using tooling outside this Go module. +func TestCheckModuleNoResourceAttr(mp []string, name string, key string) TestCheckFunc { + mpt := addrs.Module(mp).UnkeyedInstanceShim() + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { + is, err := modulePathPrimaryInstanceState(s, mpt, name) + if err != nil { + return err + } + + return testCheckNoResourceAttr(is, name, key) + }) +} + +func testCheckNoResourceAttr(is *terraform.InstanceState, name string, key string) error { + v, ok := is.Attributes[key] + + // Empty containers may sometimes be included in the state. + // If the intent here is to check for an empty container, allow the value to + // also be "0". + if v == "0" && (strings.HasSuffix(key, ".#") || strings.HasSuffix(key, ".%")) { + return nil + } + + if ok { + return fmt.Errorf("%s: Attribute '%s' found when not expected", name, key) + } + + if _, ok := is.Attributes[key+".#"]; ok { + return fmt.Errorf( + "%s: list or set attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s). Set element value checks should use TestCheckTypeSet functions instead.", + name, + key, + key+".#", + key+".0", + ) + } + + if _, ok := is.Attributes[key+".%"]; ok { + return fmt.Errorf( + "%s: map attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s).", + name, + key, + key+".%", + key+".examplekey", + ) + } + + return nil +} + +// TestMatchResourceAttr ensures a value matching a regular expression is +// stored in state for the given name and key combination. State value checking +// is only recommended for testing Computed attributes and attribute defaults. +// +// For managed resources, the name parameter is combination of the resource +// type, a period (.), and the name label. The name for the below example +// configuration would be "myprovider_thing.example". +// +// resource "myprovider_thing" "example" { ... } +// +// For data sources, the name parameter is a combination of the keyword "data", +// a period (.), the data source type, a period (.), and the name label. The +// name for the below example configuration would be +// "data.myprovider_thing.example". +// +// data "myprovider_thing" "example" { ... } +// +// The key parameter is an attribute path in Terraform CLI 0.11 and earlier +// "flatmap" syntax. Keys start with the attribute name of a top-level +// attribute. Use the following special key syntax to inspect list, map, and +// set attributes: +// +// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element. +// Use the TestCheckTypeSet* and TestMatchTypeSet* functions instead +// for sets. +// - .{KEY}: Map value at key, e.g. .example to inspect the example key +// value. +// - .#: Number of elements in list or set. +// - .%: Number of elements in map. +// +// The value parameter is a compiled regular expression. A typical pattern is +// using the regexp.MustCompile() function, which will automatically ensure the +// regular expression is supported by the Go regular expression handlers during +// compilation. +// +// An experimental interface exists to potentially replace the +// TestMatchResourceAttr functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestMatchResourceAttr with that experimental interface, by +// using [statecheck.ExpectKnownValue] in combination with +// [knownvalue.StringRegexp]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +// ) +// +// func TestExpectKnownValue_CheckState_String_Custom(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example resource containing a computed string attribute named "computed_attribute" +// Config: `resource "test_resource" "one" {}`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownValue( +// "test_resource.one", +// tfjsonpath.New("computed_attribute"), +// knownvalue.StringRegexp(regexp.MustCompile("str")), +// }, +// }, +// }, +// }) +// } +func TestMatchResourceAttr(name, key string, r *regexp.Regexp) TestCheckFunc { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { + is, err := primaryInstanceState(s, name) + if err != nil { + return err + } + + return testMatchResourceAttr(is, name, key, r) + }) +} + +// TestModuleMatchResourceAttr - as per TestMatchResourceAttr but with +// support for non-root modules +// +// Deprecated: This functionality is deprecated without replacement. The +// terraform-plugin-testing Go module is intended for provider testing, which +// should always be possible within the root module of a configuration. This +// functionality is a carryover of when this code was used within Terraform +// core to test both providers and modules. Modern testing implementations to +// verify interactions between modules should be tested in Terraform core or +// using tooling outside this Go module. +func TestModuleMatchResourceAttr(mp []string, name string, key string, r *regexp.Regexp) TestCheckFunc { + mpt := addrs.Module(mp).UnkeyedInstanceShim() + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { + is, err := modulePathPrimaryInstanceState(s, mpt, name) + if err != nil { + return err + } + + return testMatchResourceAttr(is, name, key, r) + }) +} + +func testMatchResourceAttr(is *terraform.InstanceState, name string, key string, r *regexp.Regexp) error { + if !r.MatchString(is.Attributes[key]) { + return fmt.Errorf( + "%s: Attribute '%s' didn't match %q, got %#v", + name, + key, + r.String(), + is.Attributes[key]) + } + + return nil +} + +// TestCheckResourceAttrPtr is like TestCheckResourceAttr except the +// value is a pointer so that it can be updated while the test is running. +// It will only be dereferenced at the point this step is run. +// +// Refer to the TestCheckResourceAttr documentation for more information about +// setting the name, key, and value parameters. +func TestCheckResourceAttrPtr(name string, key string, value *string) TestCheckFunc { + return func(s *terraform.State) error { + return TestCheckResourceAttr(name, key, *value)(s) + } +} + +// TestCheckModuleResourceAttrPtr - as per TestCheckResourceAttrPtr but with +// support for non-root modules +// +// Deprecated: This functionality is deprecated without replacement. The +// terraform-plugin-testing Go module is intended for provider testing, which +// should always be possible within the root module of a configuration. This +// functionality is a carryover of when this code was used within Terraform +// core to test both providers and modules. Modern testing implementations to +// verify interactions between modules should be tested in Terraform core or +// using tooling outside this Go module. +func TestCheckModuleResourceAttrPtr(mp []string, name string, key string, value *string) TestCheckFunc { + return func(s *terraform.State) error { + return TestCheckModuleResourceAttr(mp, name, key, *value)(s) + } +} + +// TestCheckResourceAttrPair ensures value equality in state between the first +// given name and key combination and the second name and key combination. +// State value checking is only recommended for testing Computed attributes +// and attribute defaults. +// +// For managed resources, the name parameter is combination of the resource +// type, a period (.), and the name label. The name for the below example +// configuration would be "myprovider_thing.example". +// +// resource "myprovider_thing" "example" { ... } +// +// For data sources, the name parameter is a combination of the keyword "data", +// a period (.), the data source type, a period (.), and the name label. The +// name for the below example configuration would be +// "data.myprovider_thing.example". +// +// data "myprovider_thing" "example" { ... } +// +// The first and second names may use any combination of managed resources +// and/or data sources. +// +// The key parameter is an attribute path in Terraform CLI 0.11 and earlier +// "flatmap" syntax. Keys start with the attribute name of a top-level +// attribute. Use the following special key syntax to inspect list, map, and +// set attributes: +// +// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element. +// Use the TestCheckTypeSet* and TestMatchTypeSet* functions instead +// for sets. +// - .{KEY}: Map value at key, e.g. .example to inspect the example key +// value. +// - .#: Number of elements in list or set. +// - .%: Number of elements in map. +func TestCheckResourceAttrPair(nameFirst, keyFirst, nameSecond, keySecond string) TestCheckFunc { + return checkIfIndexesIntoTypeSetPair(keyFirst, keySecond, func(s *terraform.State) error { + isFirst, err := primaryInstanceState(s, nameFirst) + if err != nil { + return err + } + + isSecond, err := primaryInstanceState(s, nameSecond) + if err != nil { + return err + } + + return testCheckResourceAttrPair(isFirst, nameFirst, keyFirst, isSecond, nameSecond, keySecond) + }) +} + +// TestCheckModuleResourceAttrPair - as per TestCheckResourceAttrPair but with +// support for non-root modules +// +// Deprecated: This functionality is deprecated without replacement. The +// terraform-plugin-testing Go module is intended for provider testing, which +// should always be possible within the root module of a configuration. This +// functionality is a carryover of when this code was used within Terraform +// core to test both providers and modules. Modern testing implementations to +// verify interactions between modules should be tested in Terraform core or +// using tooling outside this Go module. +func TestCheckModuleResourceAttrPair(mpFirst []string, nameFirst string, keyFirst string, mpSecond []string, nameSecond string, keySecond string) TestCheckFunc { + mptFirst := addrs.Module(mpFirst).UnkeyedInstanceShim() + mptSecond := addrs.Module(mpSecond).UnkeyedInstanceShim() + return checkIfIndexesIntoTypeSetPair(keyFirst, keySecond, func(s *terraform.State) error { + isFirst, err := modulePathPrimaryInstanceState(s, mptFirst, nameFirst) + if err != nil { + return err + } + + isSecond, err := modulePathPrimaryInstanceState(s, mptSecond, nameSecond) + if err != nil { + return err + } + + return testCheckResourceAttrPair(isFirst, nameFirst, keyFirst, isSecond, nameSecond, keySecond) + }) +} + +func testCheckResourceAttrPair(isFirst *terraform.InstanceState, nameFirst string, keyFirst string, isSecond *terraform.InstanceState, nameSecond string, keySecond string) error { + if nameFirst == nameSecond && keyFirst == keySecond { + return fmt.Errorf( + "comparing self: resource %s attribute %s", + nameFirst, + keyFirst, + ) + } + + vFirst, okFirst := isFirst.Attributes[keyFirst] + vSecond, okSecond := isSecond.Attributes[keySecond] + + // Container count values of 0 should not be relied upon, and not reliably + // maintained by helper/schema. For the purpose of tests, consider unset and + // 0 to be equal. + if len(keyFirst) > 2 && len(keySecond) > 2 && keyFirst[len(keyFirst)-2:] == keySecond[len(keySecond)-2:] && + (strings.HasSuffix(keyFirst, ".#") || strings.HasSuffix(keyFirst, ".%")) { + // they have the same suffix, and it is a collection count key. + if vFirst == "0" || vFirst == "" { + okFirst = false + } + if vSecond == "0" || vSecond == "" { + okSecond = false + } + } + + if okFirst != okSecond { + if !okFirst { + return fmt.Errorf("%s: Attribute %q not set, but %q is set in %s as %q", nameFirst, keyFirst, keySecond, nameSecond, vSecond) + } + return fmt.Errorf("%s: Attribute %q is %q, but %q is not set in %s", nameFirst, keyFirst, vFirst, keySecond, nameSecond) + } + if !(okFirst || okSecond) { + // If they both don't exist then they are equally unset, so that's okay. + return nil + } + + if vFirst != vSecond { + return fmt.Errorf( + "%s: Attribute '%s' expected %#v, got %#v", + nameFirst, + keyFirst, + vSecond, + vFirst) + } + + return nil +} + +// TestCheckOutput checks an output in the Terraform configuration +// +// An experimental interface exists to potentially replace the +// TestCheckOutput functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestCheckOutput with that experimental interface, by +// using [statecheck.ExpectKnownOutputValue]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/knownvalue" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfversion" +// ) +// +// func TestExpectKnownOutputValue_CheckState_Bool(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// TerraformVersionChecks: []tfversion.TerraformVersionCheck{ +// tfversion.SkipBelow(tfversion.Version1_8_0), +// }, +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example provider containing a provider-defined function named "bool" +// Config: `output "test" { +// value = provider::example::bool(true) +// }`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownOutputValue("test", knownvalue.Bool(true)), +// }, +// }, +// }, +// }) +// } +// +// An experimental interface exists to potentially replace the +// TestCheckOutput functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestCheckOutput with that experimental interface, by using +// [statecheck.ExpectKnownOutputValueAtPath]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/knownvalue" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +// ) +// +// func TestExpectKnownOutputValueAtPath_CheckState_Bool(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example resource containing a computed boolean attribute named "computed_attribute" +// Config: `resource "test_resource" "one" {} +// +// // Generally, it is not necessary to use an output to test a resource attribute, +// // the resource attribute should be tested directly instead, by inspecting the +// // value of the resource attribute. For instance: +// // +// // ConfigStateChecks: []statecheck.StateCheck{ +// // statecheck.ExpectKnownValue( +// // "test_resource.one", +// // tfjsonpath.New("computed_attribute"), +// // knownvalue.Bool(true), +// // ), +// // }, +// // +// // This is only shown as an example. +// output test_resource_one_output { +// value = test_resource.one +// }`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownOutputValueAtPath( +// "test_resource_one_output", +// tfjsonpath.New("computed_attribute"), +// knownvalue.Bool(true), +// ), +// }, +// }, +// }, +// }) +// } +func TestCheckOutput(name, value string) TestCheckFunc { + return func(s *terraform.State) error { + ms := s.RootModule() + rs, ok := ms.Outputs[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + if rs.Value != value { + return fmt.Errorf( + "Output '%s': expected %#v, got %#v", + name, + value, + rs) + } + + return nil + } +} + +// TestMatchOutput ensures a value matching a regular expression is +// stored in state for the given name. State value checking is only +// recommended for testing Computed attributes and attribute defaults. +// +// An experimental interface exists to potentially replace the +// TestMatchOutput functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestMatchOutput with that experimental interface, by using +// [statecheck.ExpectKnownOutputValueAtPath] in combination with +// [knownvalue.StringRegexp]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +// ) +// +// func TestExpectKnownOutputValueAtPath_CheckState_String_Custom(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example resource containing a computed string attribute named "computed_attribute" +// Config: `resource "test_resource" "one" {} +// +// // Generally, it is not necessary to use an output to test a resource attribute, +// // the resource attribute should be tested directly instead, by inspecting the +// // value of the resource attribute. For instance: +// // +// // ConfigStateChecks: []statecheck.StateCheck{ +// // statecheck.ExpectKnownValue( +// // "test_resource.one", +// // tfjsonpath.New("computed_attribute"), +// // knownvalue.StringRegexp(regexp.MustCompile("str")), +// // ), +// // }, +// // +// // This is only shown as an example. +// output test_resource_one_output { +// value = test_resource.one +// }`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownOutputValueAtPath( +// "test_resource_one_output", +// tfjsonpath.New("computed_attribute"), +// knownvalue.StringRegexp(regexp.MustCompile("str"), +// ), +// }, +// }, +// }, +// }) +// } +func TestMatchOutput(name string, r *regexp.Regexp) TestCheckFunc { + return func(s *terraform.State) error { + ms := s.RootModule() + rs, ok := ms.Outputs[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + valStr, ok := rs.Value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for resource value", rs.Value) + } + + if !r.MatchString(valStr) { + return fmt.Errorf( + "Output '%s': %#v didn't match %q", + name, + rs, + r.String()) + } + + return nil + } +} + +// modulePrimaryInstanceState returns the instance state for the given resource +// name in a ModuleState +func modulePrimaryInstanceState(ms *terraform.ModuleState, name string) (*terraform.InstanceState, error) { + rs, ok := ms.Resources[name] + if !ok { + return nil, fmt.Errorf("Not found: %s in %s", name, ms.Path) + } + + is := rs.Primary + if is == nil { + return nil, fmt.Errorf("No primary instance: %s in %s", name, ms.Path) + } + + return is, nil +} + +// modulePathPrimaryInstanceState returns the primary instance state for the +// given resource name in a given module path. +func modulePathPrimaryInstanceState(s *terraform.State, mp addrs.ModuleInstance, name string) (*terraform.InstanceState, error) { + ms := s.ModuleByPath(mp) //nolint:staticcheck // legacy usage + if ms == nil { + return nil, fmt.Errorf("No module found at: %s", mp) + } + + return modulePrimaryInstanceState(ms, name) +} + +// primaryInstanceState returns the primary instance state for the given +// resource name in the root module. +func primaryInstanceState(s *terraform.State, name string) (*terraform.InstanceState, error) { + ms := s.RootModule() //nolint:staticcheck // legacy usage + return modulePrimaryInstanceState(ms, name) +} + +// indexesIntoTypeSet is a heuristic to try and identify if a flatmap style +// string address uses a precalculated TypeSet hash, which are integers and +// typically are large and obviously not a list index +func indexesIntoTypeSet(key string) bool { + for _, part := range strings.Split(key, ".") { + if i, err := strconv.Atoi(part); err == nil && i > 100 { + return true + } + } + return false +} + +func checkIfIndexesIntoTypeSet(key string, f TestCheckFunc) TestCheckFunc { + return func(s *terraform.State) error { + err := f(s) + if err != nil && indexesIntoTypeSet(key) { + return fmt.Errorf("Error in test check: %s\nTest check address %q likely indexes into TypeSet\nThis is currently not possible in the SDK", err, key) + } + return err + } +} + +func checkIfIndexesIntoTypeSetPair(keyFirst, keySecond string, f TestCheckFunc) TestCheckFunc { + return func(s *terraform.State) error { + err := f(s) + if err != nil && (indexesIntoTypeSet(keyFirst) || indexesIntoTypeSet(keySecond)) { + return fmt.Errorf("Error in test check: %s\nTest check address %q or %q likely indexes into TypeSet\nThis is currently not possible in the SDK", err, keyFirst, keySecond) + } + return err + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_config.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_config.go new file mode 100644 index 00000000..57bc0d8c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_config.go @@ -0,0 +1,29 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-testing/internal/logging" + + "github.com/hashicorp/terraform-plugin-testing/internal/plugintest" +) + +func testStepTaint(ctx context.Context, step TestStep, wd *plugintest.WorkingDir) error { + if len(step.Taint) == 0 { + return nil + } + + logging.HelperResourceTrace(ctx, fmt.Sprintf("Using TestStep Taint: %v", step.Taint)) + + for _, p := range step.Taint { + err := wd.Taint(ctx, p) + if err != nil { + return fmt.Errorf("error tainting resource: %s", err) + } + } + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new.go new file mode 100644 index 00000000..0a7c7e7f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new.go @@ -0,0 +1,668 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "fmt" + "os" + "path/filepath" + "reflect" + "strconv" + "strings" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/go-version" + tfjson "github.com/hashicorp/terraform-json" + "github.com/mitchellh/go-testing-interface" + + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/internal/logging" + "github.com/hashicorp/terraform-plugin-testing/internal/plugintest" + "github.com/hashicorp/terraform-plugin-testing/internal/teststep" + "github.com/hashicorp/terraform-plugin-testing/terraform" +) + +func runPostTestDestroy(ctx context.Context, t testing.T, c TestCase, wd *plugintest.WorkingDir, providers *providerFactories, statePreDestroy *terraform.State) error { + t.Helper() + + err := runProviderCommand(ctx, t, func() error { + return wd.Destroy(ctx) + }, wd, providers) + if err != nil { + return err + } + + if c.CheckDestroy != nil { + logging.HelperResourceTrace(ctx, "Using TestCase CheckDestroy") + logging.HelperResourceDebug(ctx, "Calling TestCase CheckDestroy") + + if err := c.CheckDestroy(statePreDestroy); err != nil { + return err + } + + logging.HelperResourceDebug(ctx, "Called TestCase CheckDestroy") + } + + return nil +} + +func runNewTest(ctx context.Context, t testing.T, c TestCase, helper *plugintest.Helper) { + t.Helper() + + wd := helper.RequireNewWorkingDir(ctx, t, c.WorkingDir) + + ctx = logging.TestTerraformPathContext(ctx, wd.GetHelper().TerraformExecPath()) + ctx = logging.TestWorkingDirectoryContext(ctx, wd.GetHelper().WorkingDirectory()) + + providers := &providerFactories{ + legacy: c.ProviderFactories, + protov5: c.ProtoV5ProviderFactories, + protov6: c.ProtoV6ProviderFactories, + } + + defer func() { + t.Helper() + + var statePreDestroy *terraform.State + var err error + err = runProviderCommand(ctx, t, func() error { + statePreDestroy, err = getState(ctx, t, wd) + if err != nil { + return err + } + return nil + }, wd, providers) + if err != nil { + logging.HelperResourceError(ctx, + "Error retrieving state, there may be dangling resources", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Error retrieving state, there may be dangling resources: %s", err.Error()) + return + } + + if !stateIsEmpty(statePreDestroy) { + err := runPostTestDestroy(ctx, t, c, wd, providers, statePreDestroy) + if err != nil { + logging.HelperResourceError(ctx, + "Error running post-test destroy, there may be dangling resources", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Error running post-test destroy, there may be dangling resources: %s", err.Error()) + } + } + + wd.Close() + }() + + // Return value from c.ProviderConfig() is assigned to Raw as this was previously being + // passed to wd.SetConfig() when the second argument accept a configuration string. + if c.hasProviders(ctx) { + config := teststep.Configuration( + teststep.ConfigurationRequest{ + Raw: teststep.Pointer(c.providerConfig(ctx, false)), + }, + ) + + err := wd.SetConfig(ctx, config, nil) + + if err != nil { + logging.HelperResourceError(ctx, + "TestCase error setting provider configuration", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("TestCase error setting provider configuration: %s", err) + } + + err = runProviderCommand(ctx, t, func() error { + return wd.Init(ctx) + }, wd, providers) + + if err != nil { + logging.HelperResourceError(ctx, + "TestCase error running init", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("TestCase error running init: %s", err.Error()) + } + } + + logging.HelperResourceDebug(ctx, "Starting TestSteps") + + // use this to track last step successfully applied + // acts as default for import tests + var appliedCfg teststep.Config + var stepNumber int + + for stepIndex, step := range c.Steps { + if stepNumber > 0 { + copyWorkingDir(ctx, t, stepNumber, wd) + } + + stepNumber = stepIndex + 1 // 1-based indexing for humans + + configRequest := teststep.PrepareConfigurationRequest{ + Directory: step.ConfigDirectory, + File: step.ConfigFile, + Raw: step.Config, + TestStepConfigRequest: config.TestStepConfigRequest{ + StepNumber: stepNumber, + TestName: t.Name(), + }, + }.Exec() + + cfg := teststep.Configuration(configRequest) + + ctx = logging.TestStepNumberContext(ctx, stepNumber) + + logging.HelperResourceDebug(ctx, "Starting TestStep") + + if step.PreConfig != nil { + logging.HelperResourceDebug(ctx, "Calling TestStep PreConfig") + step.PreConfig() + logging.HelperResourceDebug(ctx, "Called TestStep PreConfig") + } + + if step.SkipFunc != nil { + logging.HelperResourceDebug(ctx, "Calling TestStep SkipFunc") + + skip, err := step.SkipFunc() + if err != nil { + logging.HelperResourceError(ctx, + "Error calling TestStep SkipFunc", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Error calling TestStep SkipFunc: %s", err.Error()) + } + + logging.HelperResourceDebug(ctx, "Called TestStep SkipFunc") + + if skip { + t.Logf("Skipping step %d/%d due to SkipFunc", stepNumber, len(c.Steps)) + logging.HelperResourceWarn(ctx, "Skipping TestStep due to SkipFunc") + continue + } + } + + if cfg != nil && !step.Destroy && len(step.Taint) > 0 { + err := testStepTaint(ctx, step, wd) + + if err != nil { + logging.HelperResourceError(ctx, + "TestStep error tainting resources", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("TestStep %d/%d error tainting resources: %s", stepNumber, len(c.Steps), err) + } + } + + hasProviders, err := step.hasProviders(ctx, stepIndex, t.Name()) + + if err != nil { + logging.HelperResourceError(ctx, + "TestStep error checking for providers", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("TestStep %d/%d error checking for providers: %s", stepNumber, len(c.Steps), err) + } + + if hasProviders { + providers = &providerFactories{ + legacy: sdkProviderFactories(c.ProviderFactories).merge(step.ProviderFactories), + protov5: protov5ProviderFactories(c.ProtoV5ProviderFactories).merge(step.ProtoV5ProviderFactories), + protov6: protov6ProviderFactories(c.ProtoV6ProviderFactories).merge(step.ProtoV6ProviderFactories), + } + + var hasProviderBlock bool + + if cfg != nil { + hasProviderBlock, err = cfg.HasProviderBlock(ctx) + + if err != nil { + logging.HelperResourceError(ctx, + "TestStep error determining whether configuration contains provider block", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("TestStep %d/%d error determining whether configuration contains provider block: %s", stepNumber, len(c.Steps), err) + } + } + + var testStepConfig teststep.Config + + rawCfg, err := step.providerConfig(ctx, hasProviderBlock, helper.TerraformVersion()) + + if err != nil { + logging.HelperResourceError(ctx, + "TestStep error generating provider configuration", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("TestStep %d/%d error generating provider configuration: %s", stepNumber, len(c.Steps), err) + } + + // Return value from step.providerConfig() is assigned to Raw as this was previously being + // passed to wd.SetConfig() directly when the second argument to wd.SetConfig() accepted a + // configuration string. + confRequest := teststep.PrepareConfigurationRequest{ + Directory: step.ConfigDirectory, + File: step.ConfigFile, + Raw: rawCfg, + TestStepConfigRequest: config.TestStepConfigRequest{ + StepNumber: stepIndex + 1, + TestName: t.Name(), + }, + }.Exec() + + testStepConfig = teststep.Configuration(confRequest) + + err = wd.SetConfig(ctx, testStepConfig, step.ConfigVariables) + + if err != nil { + logging.HelperResourceError(ctx, + "TestStep error setting provider configuration", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("TestStep %d/%d error setting test provider configuration: %s", stepNumber, len(c.Steps), err) + } + + err = runProviderCommand( + ctx, + t, + func() error { + return wd.Init(ctx) + }, + wd, + providers, + ) + + if err != nil { + logging.HelperResourceError(ctx, + "TestStep error running init", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("TestStep %d/%d running init: %s", stepNumber, len(c.Steps), err.Error()) + return + } + } + + if step.ImportState { + logging.HelperResourceTrace(ctx, "TestStep is ImportState mode") + + err := testStepNewImportState(ctx, t, helper, wd, step, appliedCfg, providers, stepIndex) + if step.ExpectError != nil { + logging.HelperResourceDebug(ctx, "Checking TestStep ExpectError") + if err == nil { + logging.HelperResourceError(ctx, + "Error running import: expected an error but got none", + ) + t.Fatalf("Step %d/%d error running import: expected an error but got none", stepNumber, len(c.Steps)) + } + if !step.ExpectError.MatchString(err.Error()) { + logging.HelperResourceError(ctx, + fmt.Sprintf("Error running import: expected an error with pattern (%s)", step.ExpectError.String()), + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Step %d/%d error running import, expected an error with pattern (%s), no match on: %s", stepNumber, len(c.Steps), step.ExpectError.String(), err) + } + } else { + if err != nil && c.ErrorCheck != nil { + logging.HelperResourceDebug(ctx, "Calling TestCase ErrorCheck") + err = c.ErrorCheck(err) + logging.HelperResourceDebug(ctx, "Called TestCase ErrorCheck") + } + if err != nil { + logging.HelperResourceError(ctx, + "Error running import", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Step %d/%d error running import: %s", stepNumber, len(c.Steps), err) + } + } + + logging.HelperResourceDebug(ctx, "Finished TestStep") + + continue + } + + if step.RefreshState { + logging.HelperResourceTrace(ctx, "TestStep is RefreshState mode") + + err := testStepNewRefreshState(ctx, t, wd, step, providers) + if step.ExpectError != nil { + logging.HelperResourceDebug(ctx, "Checking TestStep ExpectError") + if err == nil { + logging.HelperResourceError(ctx, + "Error running refresh: expected an error but got none", + ) + t.Fatalf("Step %d/%d error running refresh: expected an error but got none", stepNumber, len(c.Steps)) + } + if !step.ExpectError.MatchString(err.Error()) { + logging.HelperResourceError(ctx, + fmt.Sprintf("Error running refresh: expected an error with pattern (%s)", step.ExpectError.String()), + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Step %d/%d error running refresh, expected an error with pattern (%s), no match on: %s", stepNumber, len(c.Steps), step.ExpectError.String(), err) + } + } else { + if err != nil && c.ErrorCheck != nil { + logging.HelperResourceDebug(ctx, "Calling TestCase ErrorCheck") + err = c.ErrorCheck(err) + logging.HelperResourceDebug(ctx, "Called TestCase ErrorCheck") + } + if err != nil { + logging.HelperResourceError(ctx, + "Error running refresh", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Step %d/%d error running refresh: %s", stepNumber, len(c.Steps), err) + } + } + + logging.HelperResourceDebug(ctx, "Finished TestStep") + + continue + } + + if cfg != nil { + logging.HelperResourceTrace(ctx, "TestStep is Config mode") + + err := testStepNewConfig(ctx, t, c, wd, step, providers, stepIndex, helper) + if step.ExpectError != nil { + logging.HelperResourceDebug(ctx, "Checking TestStep ExpectError") + + if err == nil { + logging.HelperResourceError(ctx, + "Expected an error but got none", + ) + t.Fatalf("Step %d/%d, expected an error but got none", stepNumber, len(c.Steps)) + } + if !step.ExpectError.MatchString(err.Error()) { + logging.HelperResourceError(ctx, + fmt.Sprintf("Expected an error with pattern (%s)", step.ExpectError.String()), + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Step %d/%d, expected an error with pattern, no match on: %s", stepNumber, len(c.Steps), err) + } + } else { + if err != nil && c.ErrorCheck != nil { + logging.HelperResourceDebug(ctx, "Calling TestCase ErrorCheck") + + err = c.ErrorCheck(err) + + logging.HelperResourceDebug(ctx, "Called TestCase ErrorCheck") + } + if err != nil { + logging.HelperResourceError(ctx, + "Unexpected error", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Step %d/%d error: %s", stepNumber, len(c.Steps), err) + } + } + + var hasTerraformBlock bool + var hasProviderBlock bool + + if cfg != nil { + hasTerraformBlock, err = cfg.HasTerraformBlock(ctx) + + if err != nil { + logging.HelperResourceError(ctx, + "Error determining whether configuration contains terraform block", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Error determining whether configuration contains terraform block: %s", err) + } + + hasProviderBlock, err = cfg.HasProviderBlock(ctx) + + if err != nil { + logging.HelperResourceError(ctx, + "Error determining whether configuration contains provider block", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Error determining whether configuration contains provider block: %s", err) + } + } + + mergedConfig, err := step.mergedConfig(ctx, c, hasTerraformBlock, hasProviderBlock, helper.TerraformVersion()) + + if err != nil { + logging.HelperResourceError(ctx, + "Error generating merged configuration", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Error generating merged configuration: %s", err) + } + + confRequest := teststep.PrepareConfigurationRequest{ + Directory: step.ConfigDirectory, + File: step.ConfigFile, + Raw: mergedConfig, + TestStepConfigRequest: config.TestStepConfigRequest{ + StepNumber: stepIndex + 1, + TestName: t.Name(), + }, + }.Exec() + + appliedCfg = teststep.Configuration(confRequest) + + logging.HelperResourceDebug(ctx, "Finished TestStep") + + continue + } + + t.Fatalf("Step %d/%d, unsupported test mode", stepNumber, len(c.Steps)) + } + + if stepNumber > 0 { + copyWorkingDir(ctx, t, stepNumber, wd) + } +} + +func getState(ctx context.Context, t testing.T, wd *plugintest.WorkingDir) (*terraform.State, error) { + t.Helper() + + jsonState, err := wd.State(ctx) + if err != nil { + return nil, err + } + state, err := shimStateFromJson(jsonState) + if err != nil { + t.Fatal(err) + } + return state, nil +} + +func stateIsEmpty(state *terraform.State) bool { + return state.Empty() || !state.HasResources() //nolint:staticcheck // legacy usage +} + +func planIsEmpty(plan *tfjson.Plan, tfVersion *version.Version) bool { + for _, rc := range plan.ResourceChanges { + for _, a := range rc.Change.Actions { + if a != tfjson.ActionNoop { + return false + } + } + } + + if tfVersion.LessThan(expectNonEmptyPlanOutputChangesMinTFVersion) { + return true + } + + for _, change := range plan.OutputChanges { + if !change.Actions.NoOp() { + return false + } + } + + return true +} + +func testIDRefresh(ctx context.Context, t testing.T, c TestCase, wd *plugintest.WorkingDir, step TestStep, r *terraform.ResourceState, providers *providerFactories, stepIndex int, helper *plugintest.Helper) error { + t.Helper() + + // Build the state. The state is just the resource with an ID. There + // are no attributes. We only set what is needed to perform a refresh. + state := terraform.NewState() //nolint:staticcheck // legacy usage + state.RootModule().Resources = make(map[string]*terraform.ResourceState) + state.RootModule().Resources[c.IDRefreshName] = &terraform.ResourceState{} + + configRequest := teststep.PrepareConfigurationRequest{ + Directory: step.ConfigDirectory, + File: step.ConfigFile, + Raw: step.Config, + TestStepConfigRequest: config.TestStepConfigRequest{ + StepNumber: stepIndex + 1, + TestName: t.Name(), + }, + }.Exec() + + cfg := teststep.Configuration(configRequest) + + var hasProviderBlock bool + + if cfg != nil { + var err error + + hasProviderBlock, err = cfg.HasProviderBlock(ctx) + + if err != nil { + logging.HelperResourceError(ctx, + "Error determining whether configuration contains provider block for import test config", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Error determining whether configuration contains provider block for import test config: %s", err) + } + } + + // Return value from c.ProviderConfig() is assigned to Raw as this was previously being + // passed to wd.SetConfig() when the second argument accept a configuration string. + testStepConfig := teststep.Configuration( + teststep.ConfigurationRequest{ + Raw: teststep.Pointer(c.providerConfig(ctx, hasProviderBlock)), + }, + ) + + // Temporarily set the config to a minimal provider config for the refresh + // test. After the refresh we can reset it. + err := wd.SetConfig(ctx, testStepConfig, step.ConfigVariables) + if err != nil { + t.Fatalf("Error setting import test config: %s", err) + } + + rawCfg, err := step.providerConfig(ctx, hasProviderBlock, helper.TerraformVersion()) + + if err != nil { + t.Fatalf("Error generating import provider config: %s", err) + } + + defer func() { + t.Helper() + + confRequest := teststep.PrepareConfigurationRequest{ + Directory: step.ConfigDirectory, + File: step.ConfigFile, + Raw: rawCfg, + TestStepConfigRequest: config.TestStepConfigRequest{ + StepNumber: stepIndex + 1, + TestName: t.Name(), + }, + }.Exec() + + testStepConfigDefer := teststep.Configuration(confRequest) + + err = wd.SetConfig(ctx, testStepConfigDefer, step.ConfigVariables) + + if err != nil { + t.Fatalf("Error resetting test config: %s", err) + } + }() + + // Refresh! + err = runProviderCommand(ctx, t, func() error { + err = wd.Refresh(ctx) + if err != nil { + t.Fatalf("Error running terraform refresh: %s", err) + } + state, err = getState(ctx, t, wd) + if err != nil { + return err + } + return nil + }, wd, providers) + if err != nil { + return err + } + + // Verify attribute equivalence. + actualR := state.RootModule().Resources[c.IDRefreshName] + if actualR == nil { + return fmt.Errorf("Resource gone!") + } + if actualR.Primary == nil { + return fmt.Errorf("Resource has no primary instance") + } + actual := actualR.Primary.Attributes + expected := r.Primary.Attributes + + if len(c.IDRefreshIgnore) > 0 { + logging.HelperResourceTrace(ctx, fmt.Sprintf("Using TestCase IDRefreshIgnore: %v", c.IDRefreshIgnore)) + } + + // Remove fields we're ignoring + for _, v := range c.IDRefreshIgnore { + for k := range actual { + if strings.HasPrefix(k, v) { + delete(actual, k) + } + } + for k := range expected { + if strings.HasPrefix(k, v) { + delete(expected, k) + } + } + } + + if !reflect.DeepEqual(actual, expected) { + // Determine only the different attributes + for k, v := range expected { + if av, ok := actual[k]; ok && v == av { + delete(expected, k) + delete(actual, k) + } + } + + if diff := cmp.Diff(expected, actual); diff != "" { + return fmt.Errorf("IDRefreshName attributes not equivalent. Difference is shown below. The - symbol indicates attributes missing after refresh.\n\n%s", diff) + } + } + + return nil +} + +func copyWorkingDir(ctx context.Context, t testing.T, stepNumber int, wd *plugintest.WorkingDir) { + if os.Getenv(plugintest.EnvTfAccPersistWorkingDir) == "" { + return + } + + workingDir := wd.GetHelper().WorkingDirectory() + + dest := filepath.Join(workingDir, fmt.Sprintf("%s%s", "step_", strconv.Itoa(stepNumber))) + + baseDir := wd.BaseDir() + rootBaseDir := strings.TrimLeft(baseDir, workingDir) + + err := plugintest.CopyDir(workingDir, dest, rootBaseDir) + if err != nil { + logging.HelperResourceError(ctx, + "Unexpected error copying working directory files", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("TestStep %d/%d error copying working directory files: %s", stepNumber, err) + } + + t.Logf("Working directory and files have been copied to: %s", dest) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_config.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_config.go new file mode 100644 index 00000000..9747eaf6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_config.go @@ -0,0 +1,410 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "errors" + "fmt" + + "github.com/hashicorp/terraform-exec/tfexec" + tfjson "github.com/hashicorp/terraform-json" + "github.com/mitchellh/go-testing-interface" + + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/internal/teststep" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-plugin-testing/tfversion" + + "github.com/hashicorp/terraform-plugin-testing/internal/logging" + "github.com/hashicorp/terraform-plugin-testing/internal/plugintest" +) + +// expectNonEmptyPlanOutputChangesMinTFVersion is used to keep compatibility for +// Terraform 0.12 and 0.13 after enabling ExpectNonEmptyPlan to check output +// changes. Those older versions will always show outputs being created. +var expectNonEmptyPlanOutputChangesMinTFVersion = tfversion.Version0_14_0 + +func testStepNewConfig(ctx context.Context, t testing.T, c TestCase, wd *plugintest.WorkingDir, step TestStep, providers *providerFactories, stepIndex int, helper *plugintest.Helper) error { + t.Helper() + + configRequest := teststep.PrepareConfigurationRequest{ + Directory: step.ConfigDirectory, + File: step.ConfigFile, + Raw: step.Config, + TestStepConfigRequest: config.TestStepConfigRequest{ + StepNumber: stepIndex + 1, + TestName: t.Name(), + }, + }.Exec() + + cfg := teststep.Configuration(configRequest) + + var hasTerraformBlock bool + var hasProviderBlock bool + + if cfg != nil { + var err error + + hasTerraformBlock, err = cfg.HasTerraformBlock(ctx) + + if err != nil { + logging.HelperResourceError(ctx, + "Error determining whether configuration contains terraform block", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Error determining whether configuration contains terraform block: %s", err) + } + + hasProviderBlock, err = cfg.HasProviderBlock(ctx) + + if err != nil { + logging.HelperResourceError(ctx, + "Error determining whether configuration contains provider block", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Error determining whether configuration contains provider block: %s", err) + } + } + + mergedConfig, err := step.mergedConfig(ctx, c, hasTerraformBlock, hasProviderBlock, helper.TerraformVersion()) + + if err != nil { + logging.HelperResourceError(ctx, + "Error generating merged configuration", + map[string]interface{}{logging.KeyError: err}, + ) + t.Fatalf("Error generating merged configuration: %s", err) + } + + confRequest := teststep.PrepareConfigurationRequest{ + Directory: step.ConfigDirectory, + File: step.ConfigFile, + Raw: mergedConfig, + TestStepConfigRequest: config.TestStepConfigRequest{ + StepNumber: stepIndex + 1, + TestName: t.Name(), + }, + }.Exec() + + testStepConfig := teststep.Configuration(confRequest) + + err = wd.SetConfig(ctx, testStepConfig, step.ConfigVariables) + if err != nil { + return fmt.Errorf("Error setting config: %w", err) + } + + // If this step is a PlanOnly step, skip over this first Plan and + // subsequent Apply, and use the follow-up Plan that checks for + // permadiffs + if !step.PlanOnly { + logging.HelperResourceDebug(ctx, "Running Terraform CLI plan and apply") + + // Plan! + err := runProviderCommand(ctx, t, func() error { + var opts []tfexec.PlanOption + if step.Destroy { + opts = append(opts, tfexec.Destroy(true)) + } + return wd.CreatePlan(ctx, opts...) + }, wd, providers) + if err != nil { + return fmt.Errorf("Error running pre-apply plan: %w", err) + } + + // Run pre-apply plan checks + if len(step.ConfigPlanChecks.PreApply) > 0 { + var plan *tfjson.Plan + err = runProviderCommand(ctx, t, func() error { + var err error + plan, err = wd.SavedPlan(ctx) + return err + }, wd, providers) + if err != nil { + return fmt.Errorf("Error retrieving pre-apply plan: %w", err) + } + + err = runPlanChecks(ctx, t, plan, step.ConfigPlanChecks.PreApply) + if err != nil { + return fmt.Errorf("Pre-apply plan check(s) failed:\n%w", err) + } + } + + // We need to keep a copy of the state prior to destroying such + // that the destroy steps can verify their behavior in the + // check function + var stateBeforeApplication *terraform.State + + if step.Check != nil && step.Destroy { + // Refresh the state before shimming it for destroy checks later. + // This re-implements previously existing test step logic for the + // specific situation that a provider developer has applied a + // resource with a previous schema version and is destroying it with + // a provider that has a newer schema version. Without this refresh + // the shim logic will return an error such as: + // + // Failed to marshal state to json: schema version 0 for null_resource.test in state does not match version 1 from the provider + err := runProviderCommand(ctx, t, func() error { + return wd.Refresh(ctx) + }, wd, providers) + + if err != nil { + return fmt.Errorf("Error running pre-apply refresh: %w", err) + } + + err = runProviderCommand(ctx, t, func() error { + stateBeforeApplication, err = getState(ctx, t, wd) + if err != nil { + return err + } + return nil + }, wd, providers) + + if err != nil { + return fmt.Errorf("Error retrieving pre-apply state: %w", err) + } + } + + // Apply the diff, creating real resources + err = runProviderCommand(ctx, t, func() error { + return wd.Apply(ctx) + }, wd, providers) + if err != nil { + if step.Destroy { + return fmt.Errorf("Error running destroy: %w", err) + } + return fmt.Errorf("Error running apply: %w", err) + } + + // Run any configured checks + if step.Check != nil { + logging.HelperResourceTrace(ctx, "Using TestStep Check") + + if step.Destroy { + if err := step.Check(stateBeforeApplication); err != nil { + return fmt.Errorf("Check failed: %w", err) + } + } else { + var state *terraform.State + + err := runProviderCommand(ctx, t, func() error { + state, err = getState(ctx, t, wd) + if err != nil { + return err + } + return nil + }, wd, providers) + + if err != nil { + return fmt.Errorf("Error retrieving state after apply: %w", err) + } + + if err := step.Check(state); err != nil { + return fmt.Errorf("Check failed: %w", err) + } + } + } + + // Run state checks + if len(step.ConfigStateChecks) > 0 { + var state *tfjson.State + + err = runProviderCommand(ctx, t, func() error { + var err error + state, err = wd.State(ctx) + return err + }, wd, providers) + + if err != nil { + return fmt.Errorf("Error retrieving post-apply, post-refresh state: %w", err) + } + + err = runStateChecks(ctx, t, state, step.ConfigStateChecks) + if err != nil { + return fmt.Errorf("Post-apply refresh state check(s) failed:\n%w", err) + } + } + } + + // Test for perpetual diffs by performing a plan, a refresh, and another plan + logging.HelperResourceDebug(ctx, "Running Terraform CLI plan to check for perpetual differences") + + // do a plan + err = runProviderCommand(ctx, t, func() error { + opts := []tfexec.PlanOption{ + tfexec.Refresh(false), + } + if step.Destroy { + opts = append(opts, tfexec.Destroy(true)) + } + return wd.CreatePlan(ctx, opts...) + }, wd, providers) + if err != nil { + if step.PlanOnly { + return fmt.Errorf("Error running non-refresh plan: %w", err) + } + + return fmt.Errorf("Error running post-apply non-refresh plan: %w", err) + } + + var plan *tfjson.Plan + err = runProviderCommand(ctx, t, func() error { + var err error + plan, err = wd.SavedPlan(ctx) + return err + }, wd, providers) + if err != nil { + if step.PlanOnly { + return fmt.Errorf("Error reading saved non-refresh plan: %w", err) + } + + return fmt.Errorf("Error reading saved post-apply non-refresh plan: %w", err) + } + + // Run post-apply, pre-refresh plan checks + if len(step.ConfigPlanChecks.PostApplyPreRefresh) > 0 { + err = runPlanChecks(ctx, t, plan, step.ConfigPlanChecks.PostApplyPreRefresh) + if err != nil { + if step.PlanOnly { + return fmt.Errorf("Non-refresh plan checks(s) failed:\n%w", err) + } + + return fmt.Errorf("Post-apply, pre-refresh plan check(s) failed:\n%w", err) + } + } + + if !planIsEmpty(plan, helper.TerraformVersion()) && !step.ExpectNonEmptyPlan { + var stdout string + err = runProviderCommand(ctx, t, func() error { + var err error + stdout, err = wd.SavedPlanRawStdout(ctx) + return err + }, wd, providers) + if err != nil { + return fmt.Errorf("Error reading saved human-readable non-refresh plan output: %w", err) + } + + if step.PlanOnly { + return fmt.Errorf("The non-refresh plan was not empty.\nstdout:\n\n%s", stdout) + } + + return fmt.Errorf("After applying this test step, the non-refresh plan was not empty.\nstdout:\n\n%s", stdout) + } + + // do another plan + err = runProviderCommand(ctx, t, func() error { + var opts []tfexec.PlanOption + if step.Destroy { + opts = append(opts, tfexec.Destroy(true)) + + if step.PreventPostDestroyRefresh { + opts = append(opts, tfexec.Refresh(false)) + } + } + return wd.CreatePlan(ctx, opts...) + }, wd, providers) + if err != nil { + if step.PlanOnly { + return fmt.Errorf("Error running refresh plan: %w", err) + } + + return fmt.Errorf("Error running post-apply refresh plan: %w", err) + } + + err = runProviderCommand(ctx, t, func() error { + var err error + plan, err = wd.SavedPlan(ctx) + return err + }, wd, providers) + if err != nil { + if step.PlanOnly { + return fmt.Errorf("Error reading refresh plan: %w", err) + } + + return fmt.Errorf("Error reading post-apply refresh plan: %w", err) + } + + // Run post-apply, post-refresh plan checks + if len(step.ConfigPlanChecks.PostApplyPostRefresh) > 0 { + err = runPlanChecks(ctx, t, plan, step.ConfigPlanChecks.PostApplyPostRefresh) + if err != nil { + return fmt.Errorf("Post-apply refresh plan check(s) failed:\n%w", err) + } + } + + // check if plan is empty + if !planIsEmpty(plan, helper.TerraformVersion()) && !step.ExpectNonEmptyPlan { + var stdout string + err = runProviderCommand(ctx, t, func() error { + var err error + stdout, err = wd.SavedPlanRawStdout(ctx) + return err + }, wd, providers) + if err != nil { + return fmt.Errorf("Error reading human-readable refresh plan output: %w", err) + } + + if step.PlanOnly { + return fmt.Errorf("The refresh plan was not empty.\nstdout\n\n%s", stdout) + } + + return fmt.Errorf("After applying this test step, the refresh plan was not empty.\nstdout\n\n%s", stdout) + } else if step.ExpectNonEmptyPlan && planIsEmpty(plan, helper.TerraformVersion()) { + return errors.New("Expected a non-empty plan, but got an empty refresh plan") + } + + // ID-ONLY REFRESH + // If we've never checked an id-only refresh and our state isn't + // empty, find the first resource and test it. + if c.IDRefreshName != "" { + logging.HelperResourceTrace(ctx, "Using TestCase IDRefreshName") + + var state *terraform.State + + err = runProviderCommand(ctx, t, func() error { + state, err = getState(ctx, t, wd) + if err != nil { + return err + } + return nil + }, wd, providers) + + if err != nil { + return err + } + + //nolint:staticcheck // legacy usage + if state.Empty() { + return nil + } + + var idRefreshCheck *terraform.ResourceState + + // Find the first non-nil resource in the state + for _, m := range state.Modules { + if len(m.Resources) > 0 { + if v, ok := m.Resources[c.IDRefreshName]; ok { + idRefreshCheck = v + } + + break + } + } + + // If we have an instance to check for refreshes, do it + // immediately. We do it in the middle of another test + // because it shouldn't affect the overall state (refresh + // is read-only semantically) and we want to fail early if + // this fails. If refresh isn't read-only, then this will have + // caught a different bug. + if idRefreshCheck != nil { + if err := testIDRefresh(ctx, t, c, wd, step, idRefreshCheck, providers, stepIndex, helper); err != nil { + return fmt.Errorf( + "[ERROR] Test: ID-only test failed: %s", err) + } + } + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_import_state.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_import_state.go new file mode 100644 index 00000000..7dbc0b80 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_import_state.go @@ -0,0 +1,318 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "fmt" + "reflect" + "strings" + + "github.com/google/go-cmp/cmp" + "github.com/mitchellh/go-testing-interface" + + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/internal/teststep" + "github.com/hashicorp/terraform-plugin-testing/terraform" + + "github.com/hashicorp/terraform-plugin-testing/internal/logging" + "github.com/hashicorp/terraform-plugin-testing/internal/plugintest" +) + +func testStepNewImportState(ctx context.Context, t testing.T, helper *plugintest.Helper, wd *plugintest.WorkingDir, step TestStep, cfg teststep.Config, providers *providerFactories, stepIndex int) error { + t.Helper() + + configRequest := teststep.PrepareConfigurationRequest{ + Directory: step.ConfigDirectory, + File: step.ConfigFile, + Raw: step.Config, + TestStepConfigRequest: config.TestStepConfigRequest{ + StepNumber: stepIndex + 1, + TestName: t.Name(), + }, + }.Exec() + + testStepConfig := teststep.Configuration(configRequest) + + if step.ResourceName == "" { + t.Fatal("ResourceName is required for an import state test") + } + + // get state from check sequence + var state *terraform.State + var err error + + err = runProviderCommand(ctx, t, func() error { + state, err = getState(ctx, t, wd) + if err != nil { + return err + } + return nil + }, wd, providers) + if err != nil { + t.Fatalf("Error getting state: %s", err) + } + + // Determine the ID to import + var importId string + switch { + case step.ImportStateIdFunc != nil: + logging.HelperResourceTrace(ctx, "Using TestStep ImportStateIdFunc for import identifier") + + var err error + + logging.HelperResourceDebug(ctx, "Calling TestStep ImportStateIdFunc") + + importId, err = step.ImportStateIdFunc(state) + + if err != nil { + t.Fatal(err) + } + + logging.HelperResourceDebug(ctx, "Called TestStep ImportStateIdFunc") + case step.ImportStateId != "": + logging.HelperResourceTrace(ctx, "Using TestStep ImportStateId for import identifier") + + importId = step.ImportStateId + default: + logging.HelperResourceTrace(ctx, "Using resource identifier for import identifier") + + resource, err := testResource(step, state) + if err != nil { + t.Fatal(err) + } + importId = resource.Primary.ID + } + + if step.ImportStateIdPrefix != "" { + logging.HelperResourceTrace(ctx, "Prepending TestStep ImportStateIdPrefix for import identifier") + + importId = step.ImportStateIdPrefix + importId + } + + logging.HelperResourceTrace(ctx, fmt.Sprintf("Using import identifier: %s", importId)) + + // Create working directory for import tests + if testStepConfig == nil { + logging.HelperResourceTrace(ctx, "Using prior TestStep Config for import") + + testStepConfig = cfg + if testStepConfig == nil { + t.Fatal("Cannot import state with no specified config") + } + } + + var importWd *plugintest.WorkingDir + + // Use the same working directory to persist the state from import + if step.ImportStatePersist { + importWd = wd + } else { + importWd = helper.RequireNewWorkingDir(ctx, t, "") + defer importWd.Close() + } + + err = importWd.SetConfig(ctx, testStepConfig, step.ConfigVariables) + if err != nil { + t.Fatalf("Error setting test config: %s", err) + } + + logging.HelperResourceDebug(ctx, "Running Terraform CLI init and import") + + if !step.ImportStatePersist { + err = runProviderCommand(ctx, t, func() error { + return importWd.Init(ctx) + }, importWd, providers) + if err != nil { + t.Fatalf("Error running init: %s", err) + } + } + + err = runProviderCommand(ctx, t, func() error { + return importWd.Import(ctx, step.ResourceName, importId) + }, importWd, providers) + if err != nil { + return err + } + + var importState *terraform.State + err = runProviderCommand(ctx, t, func() error { + importState, err = getState(ctx, t, importWd) + if err != nil { + return err + } + return nil + }, importWd, providers) + if err != nil { + t.Fatalf("Error getting state: %s", err) + } + + // Go through the imported state and verify + if step.ImportStateCheck != nil { + logging.HelperResourceTrace(ctx, "Using TestStep ImportStateCheck") + + var states []*terraform.InstanceState + for address, r := range importState.RootModule().Resources { + if strings.HasPrefix(address, "data.") { + continue + } + + if r.Primary == nil { + continue + } + + is := r.Primary.DeepCopy() //nolint:staticcheck // legacy usage + is.Ephemeral.Type = r.Type // otherwise the check function cannot see the type + states = append(states, is) + } + + logging.HelperResourceDebug(ctx, "Calling TestStep ImportStateCheck") + + if err := step.ImportStateCheck(states); err != nil { + t.Fatal(err) + } + + logging.HelperResourceDebug(ctx, "Called TestStep ImportStateCheck") + } + + // Verify that all the states match + if step.ImportStateVerify { + logging.HelperResourceTrace(ctx, "Using TestStep ImportStateVerify") + + // Ensure that we do not match against data sources as they + // cannot be imported and are not what we want to verify. + // Mode is not present in ResourceState so we use the + // stringified ResourceStateKey for comparison. + newResources := make(map[string]*terraform.ResourceState) + for k, v := range importState.RootModule().Resources { + if !strings.HasPrefix(k, "data.") { + newResources[k] = v + } + } + oldResources := make(map[string]*terraform.ResourceState) + for k, v := range state.RootModule().Resources { + if !strings.HasPrefix(k, "data.") { + oldResources[k] = v + } + } + + identifierAttribute := step.ImportStateVerifyIdentifierAttribute + + if identifierAttribute == "" { + identifierAttribute = "id" + } + + for _, r := range newResources { + rIdentifier, ok := r.Primary.Attributes[identifierAttribute] + + if !ok { + t.Fatalf("ImportStateVerify: New resource missing identifier attribute %q, ensure attribute value is properly set or use ImportStateVerifyIdentifierAttribute to choose different attribute", identifierAttribute) + } + + // Find the existing resource + var oldR *terraform.ResourceState + for _, r2 := range oldResources { + if r2.Primary == nil || r2.Type != r.Type || r2.Provider != r.Provider { + continue + } + + r2Identifier, ok := r2.Primary.Attributes[identifierAttribute] + + if !ok { + t.Fatalf("ImportStateVerify: Old resource missing identifier attribute %q, ensure attribute value is properly set or use ImportStateVerifyIdentifierAttribute to choose different attribute", identifierAttribute) + } + + if r2Identifier == rIdentifier { + oldR = r2 + break + } + } + if oldR == nil || oldR.Primary == nil { + t.Fatalf( + "Failed state verification, resource with ID %s not found", + rIdentifier) + } + + // don't add empty flatmapped containers, so we can more easily + // compare the attributes + skipEmpty := func(k, v string) bool { + if strings.HasSuffix(k, ".#") || strings.HasSuffix(k, ".%") { + if v == "0" { + return true + } + } + return false + } + + // Compare their attributes + actual := make(map[string]string) + for k, v := range r.Primary.Attributes { + if skipEmpty(k, v) { + continue + } + actual[k] = v + } + + expected := make(map[string]string) + for k, v := range oldR.Primary.Attributes { + if skipEmpty(k, v) { + continue + } + expected[k] = v + } + + // Remove fields we're ignoring + for _, v := range step.ImportStateVerifyIgnore { + for k := range actual { + if strings.HasPrefix(k, v) { + delete(actual, k) + } + } + for k := range expected { + if strings.HasPrefix(k, v) { + delete(expected, k) + } + } + } + + // timeouts are only _sometimes_ added to state. To + // account for this, just don't compare timeouts at + // all. + for k := range actual { + if strings.HasPrefix(k, "timeouts.") { + delete(actual, k) + } + if k == "timeouts" { + delete(actual, k) + } + } + for k := range expected { + if strings.HasPrefix(k, "timeouts.") { + delete(expected, k) + } + if k == "timeouts" { + delete(expected, k) + } + } + + if !reflect.DeepEqual(actual, expected) { + // Determine only the different attributes + // go-cmp tries to show surrounding identical map key/value for + // context of differences, which may be confusing. + for k, v := range expected { + if av, ok := actual[k]; ok && v == av { + delete(expected, k) + delete(actual, k) + } + } + + if diff := cmp.Diff(expected, actual); diff != "" { + return fmt.Errorf("ImportStateVerify attributes not equivalent. Difference is shown below. The - symbol indicates attributes missing after import.\n\n%s", diff) + } + } + } + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_refresh_state.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_refresh_state.go new file mode 100644 index 00000000..5c0e3875 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_new_refresh_state.go @@ -0,0 +1,105 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + "github.com/mitchellh/go-testing-interface" + + "github.com/hashicorp/terraform-plugin-testing/terraform" + + "github.com/hashicorp/terraform-plugin-testing/internal/logging" + "github.com/hashicorp/terraform-plugin-testing/internal/plugintest" +) + +func testStepNewRefreshState(ctx context.Context, t testing.T, wd *plugintest.WorkingDir, step TestStep, providers *providerFactories) error { + t.Helper() + + var err error + // Explicitly ensure prior state exists before refresh. + err = runProviderCommand(ctx, t, func() error { + _, err = getState(ctx, t, wd) + if err != nil { + return err + } + return nil + }, wd, providers) + if err != nil { + t.Fatalf("Error getting state: %s", err) + } + + err = runProviderCommand(ctx, t, func() error { + return wd.Refresh(ctx) + }, wd, providers) + if err != nil { + return err + } + + var refreshState *terraform.State + err = runProviderCommand(ctx, t, func() error { + refreshState, err = getState(ctx, t, wd) + if err != nil { + return err + } + return nil + }, wd, providers) + if err != nil { + t.Fatalf("Error getting state: %s", err) + } + + // Go through the refreshed state and verify + if step.Check != nil { + logging.HelperResourceDebug(ctx, "Calling TestStep Check for RefreshState") + + if err := step.Check(refreshState); err != nil { + t.Fatal(err) + } + + logging.HelperResourceDebug(ctx, "Called TestStep Check for RefreshState") + } + + // do a plan + err = runProviderCommand(ctx, t, func() error { + return wd.CreatePlan(ctx) + }, wd, providers) + if err != nil { + return fmt.Errorf("Error running post-refresh plan: %w", err) + } + + var plan *tfjson.Plan + err = runProviderCommand(ctx, t, func() error { + var err error + plan, err = wd.SavedPlan(ctx) + return err + }, wd, providers) + if err != nil { + return fmt.Errorf("Error retrieving post-refresh plan: %w", err) + } + + // Run post-refresh plan checks + if len(step.RefreshPlanChecks.PostRefresh) > 0 { + err = runPlanChecks(ctx, t, plan, step.RefreshPlanChecks.PostRefresh) + if err != nil { + return fmt.Errorf("Post-refresh plan check(s) failed:\n%w", err) + } + } + + if !planIsEmpty(plan, wd.GetHelper().TerraformVersion()) && !step.ExpectNonEmptyPlan { + var stdout string + err = runProviderCommand(ctx, t, func() error { + var err error + stdout, err = wd.SavedPlanRawStdout(ctx) + return err + }, wd, providers) + if err != nil { + return fmt.Errorf("Error retrieving formatted plan output: %w", err) + } + return fmt.Errorf("After refreshing state during this test step, a followup plan was not empty.\nstdout:\n\n%s", stdout) + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_sets.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_sets.go new file mode 100644 index 00000000..85112220 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/testing_sets.go @@ -0,0 +1,492 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// These test helpers were developed by the AWS provider team at HashiCorp. + +package resource + +import ( + "fmt" + "regexp" + "strings" + + "github.com/hashicorp/terraform-plugin-testing/terraform" +) + +const ( + sentinelIndex = "*" +) + +// TestCheckTypeSetElemNestedAttrs ensures a subset map of values is stored in +// state for the given name and key combination of attributes nested under a +// list or set block. Use this TestCheckFunc in preference over non-set +// variants to simplify testing code and ensure compatibility with indicies, +// which can easily change with schema changes. State value checking is only +// recommended for testing Computed attributes and attribute defaults. +// +// For managed resources, the name parameter is a combination of the resource +// type, a period (.), and the name label. The name for the below example +// configuration would be "myprovider_thing.example". +// +// resource "myprovider_thing" "example" { ... } +// +// For data sources, the name parameter is a combination of the keyword "data", +// a period (.), the data source type, a period (.), and the name label. The +// name for the below example configuration would be +// "data.myprovider_thing.example". +// +// data "myprovider_thing" "example" { ... } +// +// The key parameter is an attribute path in Terraform CLI 0.11 and earlier +// "flatmap" syntax. Keys start with the attribute name of a top-level +// attribute. Use the sentinel value '*' to replace the element indexing into +// a list or set. The sentinel value can be used for each list or set index, if +// there are multiple lists or sets in the attribute path. +// +// The values parameter is the map of attribute names to attribute values +// expected to be nested under the list or set. +// +// You may check for unset nested attributes, however this will also match keys +// set to an empty string. Use a map with at least 1 non-empty value. +// +// map[string]string{ +// "key1": "value", +// "key2": "", +// } +// +// If the values map is not granular enough, it is possible to match an element +// you were not intending to in the set. Provide the most complete mapping of +// attributes possible to be sure the unique element exists. +// +// An experimental interface exists to potentially replace the +// TestCheckTypeSetElemNestedAttrs functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestCheckTypeSetElemNestedAttrs with that experimental interface, by using +// [statecheck.ExpectKnownValue] in combination with [knownvalue.SetPartial]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/knownvalue" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +// ) +// +// func TestExpectKnownValue_CheckState_SetPartial(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example resource containing a computed set attribute named "computed_attribute" +// Config: `resource "test_resource" "one" {}`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownValue( +// "test_resource.one", +// tfjsonpath.New("computed_attribute"), +// knownvalue.SetPartial([]knownvalue.Check{ +// knownvalue.StringExact("value2"), +// }), +// ), +// }, +// }, +// }, +// }) +// } +func TestCheckTypeSetElemNestedAttrs(name, attr string, values map[string]string) TestCheckFunc { + return func(s *terraform.State) error { + is, err := primaryInstanceState(s, name) + if err != nil { + return err + } + + attrParts := strings.Split(attr, ".") + if attrParts[len(attrParts)-1] != sentinelIndex { + return fmt.Errorf("%q does not end with the special value %q", attr, sentinelIndex) + } + // account for cases where the user is trying to see if the value is unset/empty + // there may be ambiguous scenarios where a field was deliberately unset vs set + // to the empty string, this will match both, which may be a false positive. + var matchCount int + for _, v := range values { + if v != "" { + matchCount++ + } + } + if matchCount == 0 { + return fmt.Errorf("%#v has no non-empty values", values) + } + + if testCheckTypeSetElemNestedAttrsInState(is, attrParts, matchCount, values) { + return nil + } + return fmt.Errorf("%q no TypeSet element %q, with nested attrs %#v in state: %#v", name, attr, values, is.Attributes) + } +} + +// TestMatchTypeSetElemNestedAttrs ensures a subset map of values, compared by +// regular expressions, is stored in state for the given name and key +// combination of attributes nested under a list or set block. Use this +// TestCheckFunc in preference over non-set variants to simplify testing code +// and ensure compatibility with indicies, which can easily change with schema +// changes. State value checking is only recommended for testing Computed +// attributes and attribute defaults. +// +// For managed resources, the name parameter is a combination of the resource +// type, a period (.), and the name label. The name for the below example +// configuration would be "myprovider_thing.example". +// +// resource "myprovider_thing" "example" { ... } +// +// For data sources, the name parameter is a combination of the keyword "data", +// a period (.), the data source type, a period (.), and the name label. The +// name for the below example configuration would be +// "data.myprovider_thing.example". +// +// data "myprovider_thing" "example" { ... } +// +// The key parameter is an attribute path in Terraform CLI 0.11 and earlier +// "flatmap" syntax. Keys start with the attribute name of a top-level +// attribute. Use the sentinel value '*' to replace the element indexing into +// a list or set. The sentinel value can be used for each list or set index, if +// there are multiple lists or sets in the attribute path. +// +// The values parameter is the map of attribute names to regular expressions +// for matching attribute values expected to be nested under the list or set. +// +// You may check for unset nested attributes, however this will also match keys +// set to an empty string. Use a map with at least 1 non-empty value. +// +// map[string]*regexp.Regexp{ +// "key1": regexp.MustCompile(`^value`), +// "key2": regexp.MustCompile(`^$`), +// } +// +// If the values map is not granular enough, it is possible to match an element +// you were not intending to in the set. Provide the most complete mapping of +// attributes possible to be sure the unique element exists. +// +// If the values map is not granular enough, it is possible to match an element +// you were not intending to in the set. Provide the most complete mapping of +// attributes possible to be sure the unique element exists. +// +// An experimental interface exists to potentially replace the +// TestMatchTypeSetElemNestedAttrs functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestMatchTypeSetElemNestedAttrs with that experimental interface, by using +// [statecheck.ExpectKnownValue] in combination with [knownvalue.SetExact], +// with a nested [knownvalue.StringRegexp]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/knownvalue" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +// ) +// +// func TestExpectKnownValue_CheckState_SetNestedBlock_Custom(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example resource containing a set nested block name "block" which contains a computed string attribute named "computed_attribute" +// Config: `resource "test_resource" "one" {}`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownValue( +// "test_resource.one", +// tfjsonpath.New("block"), +// knownvalue.SetExact([]knownvalue.Check{ +// knownvalue.MapExact(map[string]knownvalue.Check{ +// "computed_attribute": knownvalue.StringRegexp(regexp.MustCompile("str")), +// }), +// knownvalue.MapExact(map[string]knownvalue.Check{ +// "computed_attribute": knownvalue.StringRegexp(regexp.MustCompile("rts")), +// }), +// }), +// ), +// }, +// }, +// }, +// }) +// } +func TestMatchTypeSetElemNestedAttrs(name, attr string, values map[string]*regexp.Regexp) TestCheckFunc { + return func(s *terraform.State) error { + is, err := primaryInstanceState(s, name) + if err != nil { + return err + } + + attrParts := strings.Split(attr, ".") + if attrParts[len(attrParts)-1] != sentinelIndex { + return fmt.Errorf("%q does not end with the special value %q", attr, sentinelIndex) + } + // account for cases where the user is trying to see if the value is unset/empty + // there may be ambiguous scenarios where a field was deliberately unset vs set + // to the empty string, this will match both, which may be a false positive. + var matchCount int + for _, v := range values { + if v != nil { + matchCount++ + } + } + if matchCount == 0 { + return fmt.Errorf("%#v has no non-empty values", values) + } + + if testCheckTypeSetElemNestedAttrsInState(is, attrParts, matchCount, values) { + return nil + } + return fmt.Errorf("%q no TypeSet element %q, with the regex provided, match in state: %#v", name, attr, is.Attributes) + } +} + +// TestCheckTypeSetElemAttr is a TestCheckFunc that accepts a resource +// name, an attribute path, which should use the sentinel value '*' for indexing +// into a TypeSet. The function verifies that an element matches the provided +// value. +// +// Use this function over SDK provided TestCheckFunctions when validating a +// TypeSet where its elements are a simple value + +// TestCheckTypeSetElemAttr ensures a specific value is stored in state for the +// given name and key combination under a list or set. Use this TestCheckFunc +// in preference over non-set variants to simplify testing code and ensure +// compatibility with indicies, which can easily change with schema changes. +// State value checking is only recommended for testing Computed attributes and +// attribute defaults. +// +// For managed resources, the name parameter is a combination of the resource +// type, a period (.), and the name label. The name for the below example +// configuration would be "myprovider_thing.example". +// +// resource "myprovider_thing" "example" { ... } +// +// For data sources, the name parameter is a combination of the keyword "data", +// a period (.), the data source type, a period (.), and the name label. The +// name for the below example configuration would be +// "data.myprovider_thing.example". +// +// data "myprovider_thing" "example" { ... } +// +// The key parameter is an attribute path in Terraform CLI 0.11 and earlier +// "flatmap" syntax. Keys start with the attribute name of a top-level +// attribute. Use the sentinel value '*' to replace the element indexing into +// a list or set. The sentinel value can be used for each list or set index, if +// there are multiple lists or sets in the attribute path. +// +// The value parameter is the stringified data to check at the given key. Use +// the following attribute type rules to set the value: +// +// - Boolean: "false" or "true". +// - Float/Integer: Stringified number, such as "1.2" or "123". +// - String: No conversion necessary. +// +// An experimental interface exists to potentially replace the +// TestCheckTypeSetElemAttr functionality in the future and feedback +// would be appreciated. This example performs the same check as +// TestCheckTypeSetElemAttr with that experimental interface, by using +// [statecheck.ExpectKnownValue] in combination with [knownvalue.SetExact]: +// +// package example_test +// +// import ( +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/knownvalue" +// "github.com/hashicorp/terraform-plugin-testing/statecheck" +// "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +// ) +// +// func TestExpectKnownValue_CheckState_Set(t *testing.T) { +// t.Parallel() +// +// resource.Test(t, resource.TestCase{ +// // Provider definition omitted. +// Steps: []resource.TestStep{ +// { +// // Example resource containing a computed set attribute named "computed_attribute" +// Config: `resource "test_resource" "one" {}`, +// ConfigStateChecks: []statecheck.StateCheck{ +// statecheck.ExpectKnownValue( +// "test_resource.one", +// tfjsonpath.New("computed_attribute"), +// knownvalue.SetExact([]knownvalue.Check{ +// knownvalue.StringExact("value2"), +// knownvalue.StringExact("value1"), +// }), +// ), +// }, +// }, +// }, +// }) +// } +func TestCheckTypeSetElemAttr(name, attr, value string) TestCheckFunc { + return func(s *terraform.State) error { + is, err := primaryInstanceState(s, name) + if err != nil { + return err + } + + err = testCheckTypeSetElem(is, attr, value) + if err != nil { + return fmt.Errorf("%q error: %s", name, err) + } + + return nil + } +} + +// TestCheckTypeSetElemAttrPair ensures value equality in state between the +// first given name and key combination and the second name and key +// combination. State value checking is only recommended for testing Computed +// attributes and attribute defaults. +// +// For managed resources, the name parameter is a combination of the resource +// type, a period (.), and the name label. The name for the below example +// configuration would be "myprovider_thing.example". +// +// resource "myprovider_thing" "example" { ... } +// +// For data sources, the name parameter is a combination of the keyword "data", +// a period (.), the data source type, a period (.), and the name label. The +// name for the below example configuration would be +// "data.myprovider_thing.example". +// +// data "myprovider_thing" "example" { ... } +// +// The first and second names may use any combination of managed resources +// and/or data sources. +// +// The key parameter is an attribute path in Terraform CLI 0.11 and earlier +// "flatmap" syntax. Keys start with the attribute name of a top-level +// attribute. Use the sentinel value '*' to replace the element indexing into +// a list or set. The sentinel value can be used for each list or set index, if +// there are multiple lists or sets in the attribute path. +func TestCheckTypeSetElemAttrPair(nameFirst, keyFirst, nameSecond, keySecond string) TestCheckFunc { + return func(s *terraform.State) error { + isFirst, err := primaryInstanceState(s, nameFirst) + if err != nil { + return err + } + + isSecond, err := primaryInstanceState(s, nameSecond) + if err != nil { + return err + } + + vSecond, okSecond := isSecond.Attributes[keySecond] + if !okSecond { + return fmt.Errorf("%s: Attribute %q not set, cannot be checked against TypeSet", nameSecond, keySecond) + } + + return testCheckTypeSetElemPair(isFirst, keyFirst, vSecond) + } +} + +func testCheckTypeSetElem(is *terraform.InstanceState, attr, value string) error { + attrParts := strings.Split(attr, ".") + if attrParts[len(attrParts)-1] != sentinelIndex { + return fmt.Errorf("%q does not end with the special value %q", attr, sentinelIndex) + } + for stateKey, stateValue := range is.Attributes { + if stateValue == value { + stateKeyParts := strings.Split(stateKey, ".") + if len(stateKeyParts) == len(attrParts) { + for i := range attrParts { + if attrParts[i] != stateKeyParts[i] && attrParts[i] != sentinelIndex { + break + } + if i == len(attrParts)-1 { + return nil + } + } + } + } + } + + return fmt.Errorf("no TypeSet element %q, with value %q in state: %#v", attr, value, is.Attributes) +} + +func testCheckTypeSetElemPair(is *terraform.InstanceState, attr, value string) error { + attrParts := strings.Split(attr, ".") + for stateKey, stateValue := range is.Attributes { + if stateValue == value { + stateKeyParts := strings.Split(stateKey, ".") + if len(stateKeyParts) == len(attrParts) { + for i := range attrParts { + if attrParts[i] != stateKeyParts[i] && attrParts[i] != sentinelIndex { + break + } + if i == len(attrParts)-1 { + return nil + } + } + } + } + } + + return fmt.Errorf("no TypeSet element %q, with value %q in state: %#v", attr, value, is.Attributes) +} + +// testCheckTypeSetElemNestedAttrsInState is a helper function +// to determine if nested attributes and their values are equal to those +// in the instance state. Currently, the function accepts a "values" param of type +// map[string]string or map[string]*regexp.Regexp. +// Returns true if all attributes match, else false. +func testCheckTypeSetElemNestedAttrsInState(is *terraform.InstanceState, attrParts []string, matchCount int, values interface{}) bool { + matches := make(map[string]int) + + for stateKey, stateValue := range is.Attributes { + stateKeyParts := strings.Split(stateKey, ".") + // a Set/List item with nested attrs would have a flatmap address of + // at least length 3 + // foo.0.name = "bar" + if len(stateKeyParts) < 3 || len(attrParts) > len(stateKeyParts) { + continue + } + var pathMatch bool + for i := range attrParts { + if attrParts[i] != stateKeyParts[i] && attrParts[i] != sentinelIndex { + break + } + if i == len(attrParts)-1 { + pathMatch = true + } + } + if !pathMatch { + continue + } + id := stateKeyParts[len(attrParts)-1] + nestedAttr := strings.Join(stateKeyParts[len(attrParts):], ".") + + var match bool + switch t := values.(type) { + case map[string]string: + if v, keyExists := t[nestedAttr]; keyExists && v == stateValue { + match = true + } + case map[string]*regexp.Regexp: + if v, keyExists := t[nestedAttr]; keyExists && v != nil && v.MatchString(stateValue) { + match = true + } + } + if match { + matches[id] = matches[id] + 1 + if matches[id] == matchCount { + return true + } + } + } + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/teststep_providers.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/teststep_providers.go new file mode 100644 index 00000000..bd9f43b8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/teststep_providers.go @@ -0,0 +1,258 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/hashicorp/go-version" +) + +// tfBlockMinReqTFVersion is used to prevent errors arising from +// adding required providers to the terraform block when Terraform +// is any version prior to v1.0.0 +const tfBlockMinReqTFVersion = "1.0.0" + +// mergedConfig prepends any necessary terraform configuration blocks to the +// TestStep Config. +// +// If there are ExternalProviders configurations in either the TestCase or +// TestStep, the terraform configuration block should be included with the +// step configuration to prevent errors with providers outside the +// registry.terraform.io hostname or outside the hashicorp namespace. +// This is only necessary when using TestStep.Config. +// +// When TestStep.ConfigDirectory is used, the expectation is that the +// Terraform configuration files will specify a terraform configuration +// block and/or provider blocks as necessary. +func (s TestStep) mergedConfig(ctx context.Context, testCase TestCase, configHasTerraformBlock, configHasProviderBlock bool, tfVersion *version.Version) (string, error) { + var config strings.Builder + + // Prevent issues with existing configurations containing the terraform + // configuration block. + if configHasTerraformBlock { + config.WriteString(s.Config) + + return config.String(), nil + } + + if testCase.hasProviders(ctx) { + cfg, err := s.providerConfigTestCase(ctx, configHasProviderBlock, testCase, tfVersion) + + if err != nil { + return "", err + } + + config.WriteString(cfg) + } else { + cfg, err := s.providerConfig(ctx, configHasProviderBlock, tfVersion) + + if err != nil { + return "", err + } + + config.WriteString(cfg) + } + + config.WriteString(s.Config) + + return config.String(), nil +} + +// providerConfig takes the list of providers in a TestStep and returns a +// config with only empty provider blocks. This is useful for Import, where no +// config is provided, but the providers must be defined. +func (s TestStep) providerConfig(_ context.Context, skipProviderBlock bool, tfVersion *version.Version) (string, error) { + var providerBlocks, requiredProviderBlocks strings.Builder + + for name, externalProvider := range s.ExternalProviders { + if !skipProviderBlock { + providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name)) + } + + if externalProvider.Source == "" && externalProvider.VersionConstraint == "" { + continue + } + + requiredProviderBlocks.WriteString(fmt.Sprintf(" %s = {\n", name)) + + if externalProvider.Source != "" { + requiredProviderBlocks.WriteString(fmt.Sprintf(" source = %q\n", externalProvider.Source)) + } + + if externalProvider.VersionConstraint != "" { + requiredProviderBlocks.WriteString(fmt.Sprintf(" version = %q\n", externalProvider.VersionConstraint)) + } + + requiredProviderBlocks.WriteString(" }\n") + } + + minReqVersion, err := version.NewVersion(tfBlockMinReqTFVersion) + + if err != nil { + return "", err + } + + for name := range s.ProviderFactories { + if tfVersion.LessThan(minReqVersion) { + break + } + + requiredProviderBlocks.WriteString(addTerraformBlockSource(name, s.Config)) + } + + for name := range s.ProtoV5ProviderFactories { + if tfVersion.LessThan(minReqVersion) { + break + } + + requiredProviderBlocks.WriteString(addTerraformBlockSource(name, s.Config)) + } + + for name := range s.ProtoV6ProviderFactories { + if tfVersion.LessThan(minReqVersion) { + break + } + + requiredProviderBlocks.WriteString(addTerraformBlockSource(name, s.Config)) + } + + if requiredProviderBlocks.Len() > 0 { + return fmt.Sprintf(` +terraform { + required_providers { +%[1]s + } +} + +%[2]s +`, strings.TrimSuffix(requiredProviderBlocks.String(), "\n"), providerBlocks.String()), nil + } + + return providerBlocks.String(), nil +} + +func (s TestStep) providerConfigTestCase(_ context.Context, skipProviderBlock bool, testCase TestCase, tfVersion *version.Version) (string, error) { + var providerBlocks, requiredProviderBlocks strings.Builder + + providerNames := make(map[string]struct{}, len(testCase.Providers)) + + for name := range testCase.Providers { + providerNames[name] = struct{}{} + } + + for name := range testCase.ProviderFactories { + delete(providerNames, name) + } + + // [BF] The Providers field handling predates the logic being moved to this + // method. It's not entirely clear to me at this time why this field + // is being used and not the others, but leaving it here just in case + // it does have a special purpose that wasn't being unit tested prior. + for name := range providerNames { + providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name)) + + requiredProviderBlocks.WriteString(fmt.Sprintf(" %s = {\n", name)) + + requiredProviderBlocks.WriteString(" }\n") + } + + for name, externalProvider := range testCase.ExternalProviders { + if !skipProviderBlock { + providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name)) + } + + if externalProvider.Source == "" && externalProvider.VersionConstraint == "" { + continue + } + + requiredProviderBlocks.WriteString(fmt.Sprintf(" %s = {\n", name)) + + if externalProvider.Source != "" { + requiredProviderBlocks.WriteString(fmt.Sprintf(" source = %q\n", externalProvider.Source)) + } + + if externalProvider.VersionConstraint != "" { + requiredProviderBlocks.WriteString(fmt.Sprintf(" version = %q\n", externalProvider.VersionConstraint)) + } + + requiredProviderBlocks.WriteString(" }\n") + } + + minReqVersion, err := version.NewVersion(tfBlockMinReqTFVersion) + + if err != nil { + return "", err + } + + for name := range testCase.ProviderFactories { + if tfVersion.LessThan(minReqVersion) { + break + } + + providerFactoryBlocks := addTerraformBlockSource(name, s.Config) + + if len(providerFactoryBlocks) > 0 { + requiredProviderBlocks.WriteString(providerFactoryBlocks) + } + } + + for name := range testCase.ProtoV5ProviderFactories { + if tfVersion.LessThan(minReqVersion) { + break + } + + protov5ProviderFactoryBlocks := addTerraformBlockSource(name, s.Config) + + if len(protov5ProviderFactoryBlocks) > 0 { + requiredProviderBlocks.WriteString(protov5ProviderFactoryBlocks) + } + } + + for name := range testCase.ProtoV6ProviderFactories { + if tfVersion.LessThan(minReqVersion) { + break + } + + protov6ProviderFactoryBlocks := addTerraformBlockSource(name, s.Config) + + if len(protov6ProviderFactoryBlocks) > 0 { + requiredProviderBlocks.WriteString(addTerraformBlockSource(name, s.Config)) + } + } + + if requiredProviderBlocks.Len() > 0 { + return fmt.Sprintf(` +terraform { + required_providers { +%[1]s + } +} + +%[2]s +`, strings.TrimSuffix(requiredProviderBlocks.String(), "\n"), providerBlocks.String()), nil + } + + return providerBlocks.String(), nil +} + +func addTerraformBlockSource(name, config string) string { + var js json.RawMessage + + // Do not process JSON. + if err := json.Unmarshal([]byte(config), &js); err == nil { + return "" + } + + var providerBlocks strings.Builder + + providerBlocks.WriteString(fmt.Sprintf(" %s = {\n", name)) + providerBlocks.WriteString(fmt.Sprintf(" source = %q\n", getProviderAddr(name))) + providerBlocks.WriteString(" }\n") + + return providerBlocks.String() +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/teststep_validate.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/teststep_validate.go new file mode 100644 index 00000000..8590ca46 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/teststep_validate.go @@ -0,0 +1,245 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/internal/logging" + "github.com/hashicorp/terraform-plugin-testing/internal/teststep" +) + +// testStepValidateRequest contains data for the (TestStep).validate() method. +type testStepValidateRequest struct { + // StepConfiguration contains the TestStep configuration derived from + // TestStep.Config, TestStep.ConfigDirectory, or TestStep.ConfigFile. + StepConfiguration teststep.Config + + // StepNumber is the index of the TestStep in the TestCase.Steps. + StepNumber int + + // TestCaseHasExternalProviders is enabled if the TestCase has + // ExternalProviders. + TestCaseHasExternalProviders bool + + // TestCaseHasProviders is enabled if the TestCase has set any of + // ExternalProviders, ProtoV5ProviderFactories, ProtoV6ProviderFactories, + // or ProviderFactories. + TestCaseHasProviders bool + + // TestName is the name of the test. + TestName string +} + +// hasExternalProviders returns true if the TestStep has +// ExternalProviders set. +func (s TestStep) hasExternalProviders() bool { + return len(s.ExternalProviders) > 0 +} + +// hasProviders returns true if the TestStep has set any of the +// ExternalProviders, ProtoV5ProviderFactories, ProtoV6ProviderFactories, or +// ProviderFactories fields. It will also return true if ConfigDirectory or +// Config contain terraform configuration which specify a provider block. +func (s TestStep) hasProviders(ctx context.Context, stepIndex int, testName string) (bool, error) { + if len(s.ExternalProviders) > 0 { + return true, nil + } + + if len(s.ProtoV5ProviderFactories) > 0 { + return true, nil + } + + if len(s.ProtoV6ProviderFactories) > 0 { + return true, nil + } + + if len(s.ProviderFactories) > 0 { + return true, nil + } + + configRequest := teststep.PrepareConfigurationRequest{ + Directory: s.ConfigDirectory, + File: s.ConfigFile, + TestStepConfigRequest: config.TestStepConfigRequest{ + StepNumber: stepIndex + 1, + TestName: testName, + }, + }.Exec() + + cfg := teststep.Configuration(configRequest) + + var cfgHasProviders bool + + if cfg != nil { + var err error + + cfgHasProviders, err = cfg.HasProviderBlock(ctx) + + if err != nil { + return false, err + } + } + + if cfgHasProviders { + return true, nil + } + + return false, nil +} + +// validate ensures the TestStep is valid based on the following criteria: +// +// - Config or ImportState or RefreshState is set. +// - Config and RefreshState are not both set. +// - RefreshState and Destroy are not both set. +// - RefreshState is not the first TestStep. +// - Providers are not specified (ExternalProviders, +// ProtoV5ProviderFactories, ProtoV6ProviderFactories, ProviderFactories) +// if specified at the TestCase level. +// - Providers are specified (ExternalProviders, ProtoV5ProviderFactories, +// ProtoV6ProviderFactories, ProviderFactories) if not specified at the +// TestCase level. +// - No overlapping ExternalProviders and ProviderFactories entries +// - ResourceName is not empty when ImportState is true, ImportStateIdFunc +// is not set, and ImportStateId is not set. +// - ConfigPlanChecks (PreApply, PostApplyPreRefresh, PostApplyPostRefresh) are only set when Config is set. +// - ConfigPlanChecks.PreApply are only set when PlanOnly is false. +// - RefreshPlanChecks (PostRefresh) are only set when RefreshState is set. +func (s TestStep) validate(ctx context.Context, req testStepValidateRequest) error { + ctx = logging.TestStepNumberContext(ctx, req.StepNumber) + + logging.HelperResourceTrace(ctx, "Validating TestStep") + + if req.StepConfiguration == nil && !s.ImportState && !s.RefreshState { + err := fmt.Errorf("TestStep missing Config or ConfigDirectory or ConfigFile or ImportState or RefreshState") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + if req.StepConfiguration != nil && s.RefreshState { + err := fmt.Errorf("TestStep cannot have Config or ConfigDirectory or ConfigFile and RefreshState") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + if s.RefreshState && s.Destroy { + err := fmt.Errorf("TestStep cannot have RefreshState and Destroy") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + if s.RefreshState && req.StepNumber == 1 { + err := fmt.Errorf("TestStep cannot have RefreshState as first step") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + if s.ImportState && s.RefreshState { + err := fmt.Errorf("TestStep cannot have ImportState and RefreshState in same step") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + for name := range s.ExternalProviders { + if _, ok := s.ProviderFactories[name]; ok { + err := fmt.Errorf("TestStep provider %q set in both ExternalProviders and ProviderFactories", name) + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + } + + if req.TestCaseHasExternalProviders && req.StepConfiguration != nil && req.StepConfiguration.HasConfigurationFiles() { + err := fmt.Errorf("Providers must only be specified within the terraform configuration files when using TestStep.Config") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + if s.hasExternalProviders() && req.StepConfiguration != nil && req.StepConfiguration.HasConfigurationFiles() { + err := fmt.Errorf("Providers must only be specified within the terraform configuration files when using TestStep.Config") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + // We need a 0-based step index for consistency + hasProviders, err := s.hasProviders(ctx, req.StepNumber-1, req.TestName) + + if err != nil { + logging.HelperResourceError(ctx, "TestStep error checking for providers", map[string]interface{}{logging.KeyError: err}) + return err + } + + if req.TestCaseHasProviders && hasProviders { + err := fmt.Errorf("Providers must only be specified either at the TestCase or TestStep level") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + var cfgHasProviderBlock bool + + if req.StepConfiguration != nil { + cfgHasProviderBlock, err = req.StepConfiguration.HasProviderBlock(ctx) + + if err != nil { + logging.HelperResourceError(ctx, "TestStep error checking for if configuration has provider block", map[string]interface{}{logging.KeyError: err}) + return err + } + } + + if !req.TestCaseHasProviders && !hasProviders && !cfgHasProviderBlock { + err := fmt.Errorf("Providers must be specified at the TestCase level, or in all TestStep, or in TestStep.ConfigDirectory or TestStep.ConfigFile") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + if s.ImportState { + if s.ImportStateId == "" && s.ImportStateIdFunc == nil && s.ResourceName == "" { + err := fmt.Errorf("TestStep ImportState must be specified with ImportStateId, ImportStateIdFunc, or ResourceName") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + } + + if len(s.ConfigPlanChecks.PreApply) > 0 { + if req.StepConfiguration == nil { + err := fmt.Errorf("TestStep ConfigPlanChecks.PreApply must only be specified with Config, ConfigDirectory or ConfigFile") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + if s.PlanOnly { + err := fmt.Errorf("TestStep ConfigPlanChecks.PreApply cannot be run with PlanOnly") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + } + + if len(s.ConfigPlanChecks.PostApplyPreRefresh) > 0 && req.StepConfiguration == nil { + err := fmt.Errorf("TestStep ConfigPlanChecks.PostApplyPreRefresh must only be specified with Config, ConfigDirectory or ConfigFile") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + if len(s.ConfigPlanChecks.PostApplyPostRefresh) > 0 && req.StepConfiguration == nil { + err := fmt.Errorf("TestStep ConfigPlanChecks.PostApplyPostRefresh must only be specified with Config, ConfigDirectory or ConfigFile") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + if len(s.RefreshPlanChecks.PostRefresh) > 0 && !s.RefreshState { + err := fmt.Errorf("TestStep RefreshPlanChecks.PostRefresh must only be specified with RefreshState") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + if len(s.ConfigStateChecks) > 0 && req.StepConfiguration == nil { + err := fmt.Errorf("TestStep ConfigStateChecks must only be specified with Config, ConfigDirectory or ConfigFile") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/tfversion_checks.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/tfversion_checks.go new file mode 100644 index 00000000..1bec0abd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/tfversion_checks.go @@ -0,0 +1,31 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + + "github.com/hashicorp/go-version" + "github.com/mitchellh/go-testing-interface" + + "github.com/hashicorp/terraform-plugin-testing/tfversion" +) + +func runTFVersionChecks(ctx context.Context, t testing.T, terraformVersion *version.Version, terraformVersionChecks []tfversion.TerraformVersionCheck) { + t.Helper() + + for _, tfVersionCheck := range terraformVersionChecks { + resp := tfversion.CheckTerraformVersionResponse{} + tfVersionCheck.CheckTerraformVersion(ctx, tfversion.CheckTerraformVersionRequest{TerraformVersion: terraformVersion}, &resp) + + if resp.Error != nil { + t.Fatalf(resp.Error.Error()) + } + + if resp.Skip != "" { + t.Skip(resp.Skip) + } + } + +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/wait.go b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/wait.go new file mode 100644 index 00000000..332791bc --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/helper/resource/wait.go @@ -0,0 +1,135 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "errors" + "sync" + "time" +) + +// RetryContext is a basic wrapper around StateChangeConf that will just retry +// a function until it no longer returns an error. +// +// Cancellation from the passed in context will propagate through to the +// underlying StateChangeConf +// +// Deprecated: Copy this function to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.RetryContext. +func RetryContext(ctx context.Context, timeout time.Duration, f RetryFunc) error { + // These are used to pull the error out of the function; need a mutex to + // avoid a data race. + var resultErr error + var resultErrMu sync.Mutex + + c := &StateChangeConf{ + Pending: []string{"retryableerror"}, + Target: []string{"success"}, + Timeout: timeout, + MinTimeout: 500 * time.Millisecond, + Refresh: func() (interface{}, string, error) { + rerr := f() + + resultErrMu.Lock() + defer resultErrMu.Unlock() + + if rerr == nil { + resultErr = nil + return 42, "success", nil + } + + resultErr = rerr.Err + + if rerr.Retryable { + return 42, "retryableerror", nil + } + return nil, "quit", rerr.Err + }, + } + + _, waitErr := c.WaitForStateContext(ctx) + + // Need to acquire the lock here to be able to avoid race using resultErr as + // the return value + resultErrMu.Lock() + defer resultErrMu.Unlock() + + // resultErr may be nil because the wait timed out and resultErr was never + // set; this is still an error + if resultErr == nil { + return waitErr + } + // resultErr takes precedence over waitErr if both are set because it is + // more likely to be useful + return resultErr +} + +// Retry is a basic wrapper around StateChangeConf that will just retry +// a function until it no longer returns an error. +// +// Deprecated: Please use RetryContext to ensure proper plugin shutdown +func Retry(timeout time.Duration, f RetryFunc) error { + return RetryContext(context.Background(), timeout, f) +} + +// RetryFunc is the function retried until it succeeds. +// +// Deprecated: Copy this type to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.RetryFunc. +type RetryFunc func() *RetryError + +// RetryError is the required return type of RetryFunc. It forces client code +// to choose whether or not a given error is retryable. +// +// Deprecated: Copy this type to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.RetryError. +type RetryError struct { + Err error + Retryable bool +} + +// Unwrap returns the Err, compatible with errors.Unwrap. +// +// Deprecated: Copy this method to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.RetryError. +func (e *RetryError) Unwrap() error { + return e.Err +} + +// RetryableError is a helper to create a RetryError that's retryable from a +// given error. To prevent logic errors, will return an error when passed a +// nil error. +// +// Deprecated: Copy this function to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.RetryableError. +func RetryableError(err error) *RetryError { + if err == nil { + return &RetryError{ + Err: errors.New("empty retryable error received. " + + "This is a bug with the Terraform provider and should be " + + "reported as a GitHub issue in the provider repository."), + Retryable: false, + } + } + return &RetryError{Err: err, Retryable: true} +} + +// NonRetryableError is a helper to create a RetryError that's _not_ retryable +// from a given error. To prevent logic errors, will return an error when +// passed a nil error. +// +// Deprecated: Copy this function to the provider codebase or use +// github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry.NonRetryableError. +func NonRetryableError(err error) *RetryError { + if err == nil { + return &RetryError{ + Err: errors.New("empty non-retryable error received. " + + "This is a bug with the Terraform provider and should be " + + "reported as a GitHub issue in the provider repository."), + Retryable: false, + } + } + return &RetryError{Err: err, Retryable: false} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/doc.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/doc.go new file mode 100644 index 00000000..0d29d9f4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/doc.go @@ -0,0 +1,20 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package addrs contains types that represent "addresses", which are +// references to specific objects within a Terraform configuration or +// state. +// +// All addresses have string representations based on HCL traversal syntax +// which should be used in the user-interface, and also in-memory +// representations that can be used internally. +// +// For object types that exist within Terraform modules a pair of types is +// used. The "local" part of the address is represented by a type, and then +// an absolute path to that object in the context of its module is represented +// by a type of the same name with an "Abs" prefix added, for "absolute". +// +// All types within this package should be treated as immutable, even if this +// is not enforced by the Go compiler. It is always an implementation error +// to modify an address object in-place after it is initially constructed. +package addrs diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/instance_key.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/instance_key.go new file mode 100644 index 00000000..56700fc0 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/instance_key.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package addrs + +import ( + "fmt" +) + +// instanceKey represents the key of an instance within an object that +// contains multiple instances due to using "count" or "for_each" arguments +// in configuration. +// +// intKey and stringKey are the two implementations of this type. No other +// implementations are allowed. The single instance of an object that _isn't_ +// using "count" or "for_each" is represented by NoKey, which is a nil +// InstanceKey. +type instanceKey interface { + instanceKeySigil() + String() string +} + +// NoKey represents the absence of an instanceKey, for the single instance +// of a configuration object that does not use "count" or "for_each" at all. +var NoKey instanceKey + +// intKey is the InstanceKey representation representing integer indices, as +// used when the "count" argument is specified or if for_each is used with +// a sequence type. +type intKey int + +func (k intKey) instanceKeySigil() { +} + +func (k intKey) String() string { + return fmt.Sprintf("[%d]", int(k)) +} + +// stringKey is the InstanceKey representation representing string indices, as +// used when the "for_each" argument is specified with a map or object type. +type stringKey string + +func (k stringKey) instanceKeySigil() { +} + +func (k stringKey) String() string { + // FIXME: This isn't _quite_ right because Go's quoted string syntax is + // slightly different than HCL's, but we'll accept it for now. + return fmt.Sprintf("[%q]", string(k)) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/module.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/module.go new file mode 100644 index 00000000..8dbbb469 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/module.go @@ -0,0 +1,16 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package addrs + +// Module is an address for a module call within configuration. This is +// the static counterpart of ModuleInstance, representing a traversal through +// the static module call tree in configuration and does not take into account +// the potentially-multiple instances of a module that might be created by +// "count" and "for_each" arguments within those calls. +// +// This type should be used only in very specialized cases when working with +// the static module call tree. Type ModuleInstance is appropriate in more cases. +// +// Although Module is a slice, it should be treated as immutable after creation. +type Module []string diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/module_instance.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/module_instance.go new file mode 100644 index 00000000..e43fd3e3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/addrs/module_instance.go @@ -0,0 +1,242 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package addrs + +import ( + "bytes" + "fmt" + + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcl/v2/hclsyntax" + "github.com/zclconf/go-cty/cty" + "github.com/zclconf/go-cty/cty/gocty" + + "github.com/hashicorp/terraform-plugin-testing/internal/tfdiags" +) + +// ModuleInstance is an address for a particular module instance within the +// dynamic module tree. This is an extension of the static traversals +// represented by type Module that deals with the possibility of a single +// module call producing multiple instances via the "count" and "for_each" +// arguments. +// +// Although ModuleInstance is a slice, it should be treated as immutable after +// creation. +type ModuleInstance []ModuleInstanceStep + +func parseModuleInstance(traversal hcl.Traversal) (ModuleInstance, tfdiags.Diagnostics) { + mi, remain, diags := parseModuleInstancePrefix(traversal) + if len(remain) != 0 { + if len(remain) == len(traversal) { + diags = append(diags, tfdiags.Diag( + tfdiags.Error, + "Invalid module instance address", + "A module instance address must begin with \"module.\".", + )) + } else { + diags = append(diags, tfdiags.Diag( + tfdiags.Error, + "Invalid module instance address", + "The module instance address is followed by additional invalid content.", + )) + } + } + return mi, diags +} + +// ParseModuleInstanceStr is a helper wrapper around ParseModuleInstance +// that takes a string and parses it with the HCL native syntax traversal parser +// before interpreting it. +// +// This should be used only in specialized situations since it will cause the +// created references to not have any meaningful source location information. +// If a reference string is coming from a source that should be identified in +// error messages then the caller should instead parse it directly using a +// suitable function from the HCL API and pass the traversal itself to +// ParseProviderConfigCompact. +// +// Error diagnostics are returned if either the parsing fails or the analysis +// of the traversal fails. There is no way for the caller to distinguish the +// two kinds of diagnostics programmatically. If error diagnostics are returned +// then the returned address is invalid. +func ParseModuleInstanceStr(str string) (ModuleInstance, tfdiags.Diagnostics) { + var diags tfdiags.Diagnostics + + traversal, parseDiags := hclsyntax.ParseTraversalAbs([]byte(str), "", hcl.Pos{Line: 1, Column: 1}) + for _, err := range parseDiags.Errs() { + // ignore warnings, they don't matter in this case + diags = append(diags, tfdiags.FromError(err)) + } + if parseDiags.HasErrors() { + return nil, diags + } + + addr, addrDiags := parseModuleInstance(traversal) + diags = append(diags, addrDiags...) + return addr, diags +} + +func parseModuleInstancePrefix(traversal hcl.Traversal) (ModuleInstance, hcl.Traversal, tfdiags.Diagnostics) { + remain := traversal + var mi ModuleInstance + var diags tfdiags.Diagnostics + + for len(remain) > 0 { + var next string + switch tt := remain[0].(type) { + case hcl.TraverseRoot: + next = tt.Name + case hcl.TraverseAttr: + next = tt.Name + default: + diags = append(diags, tfdiags.Diag( + tfdiags.Error, + "Invalid address operator", + "Module address prefix must be followed by dot and then a name.", + )) + } + + if next != "module" { + break + } + + remain = remain[1:] + // If we have the prefix "module" then we should be followed by an + // module call name, as an attribute, and then optionally an index step + // giving the instance key. + if len(remain) == 0 { + diags = append(diags, tfdiags.Diag( + tfdiags.Error, + "Invalid address operator", + "Prefix \"module.\" must be followed by a module name.", + )) + break + } + + var moduleName string + switch tt := remain[0].(type) { + case hcl.TraverseAttr: + moduleName = tt.Name + default: + diags = append(diags, tfdiags.Diag( + tfdiags.Error, + "Invalid address operator", + "Prefix \"module.\" must be followed by a module name.", + )) + } + remain = remain[1:] + step := ModuleInstanceStep{ + Name: moduleName, + } + + if len(remain) > 0 { + if idx, ok := remain[0].(hcl.TraverseIndex); ok { + remain = remain[1:] + + switch idx.Key.Type() { + case cty.String: + step.InstanceKey = stringKey(idx.Key.AsString()) + case cty.Number: + var idxInt int + err := gocty.FromCtyValue(idx.Key, &idxInt) + if err == nil { + step.InstanceKey = intKey(idxInt) + } else { + diags = append(diags, tfdiags.Diag( + tfdiags.Error, + "Invalid address operator", + fmt.Sprintf("Invalid module index: %s.", err), + )) + } + default: + // Should never happen, because no other types are allowed in traversal indices. + diags = append(diags, tfdiags.Diag( + tfdiags.Error, + "Invalid address operator", + "Invalid module key: must be either a string or an integer.", + )) + } + } + } + + mi = append(mi, step) + } + + var retRemain hcl.Traversal + if len(remain) > 0 { + retRemain = make(hcl.Traversal, len(remain)) + copy(retRemain, remain) + // The first element here might be either a TraverseRoot or a + // TraverseAttr, depending on whether we had a module address on the + // front. To make life easier for callers, we'll normalize to always + // start with a TraverseRoot. + if tt, ok := retRemain[0].(hcl.TraverseAttr); ok { + retRemain[0] = hcl.TraverseRoot{ + Name: tt.Name, + SrcRange: tt.SrcRange, + } + } + } + + return mi, retRemain, diags +} + +// UnkeyedInstanceShim is a shim method for converting a Module address to the +// equivalent ModuleInstance address that assumes that no modules have +// keyed instances. +// +// This is a temporary allowance for the fact that Terraform does not presently +// support "count" and "for_each" on modules, and thus graph building code that +// derives graph nodes from configuration must just assume unkeyed modules +// in order to construct the graph. At a later time when "count" and "for_each" +// support is added for modules, all callers of this method will need to be +// reworked to allow for keyed module instances. +func (m Module) UnkeyedInstanceShim() ModuleInstance { + path := make(ModuleInstance, len(m)) + for i, name := range m { + path[i] = ModuleInstanceStep{Name: name} + } + return path +} + +// ModuleInstanceStep is a single traversal step through the dynamic module +// tree. It is used only as part of ModuleInstance. +type ModuleInstanceStep struct { + Name string + InstanceKey instanceKey +} + +// RootModuleInstance is the module instance address representing the root +// module, which is also the zero value of ModuleInstance. +var RootModuleInstance ModuleInstance + +// Child returns the address of a child module instance of the receiver, +// identified by the given name and key. +func (m ModuleInstance) Child(name string, key instanceKey) ModuleInstance { + ret := make(ModuleInstance, 0, len(m)+1) + ret = append(ret, m...) + return append(ret, ModuleInstanceStep{ + Name: name, + InstanceKey: key, + }) +} + +// String returns a string representation of the receiver, in the format used +// within e.g. user-provided resource addresses. +// +// The address of the root module has the empty string as its representation. +func (m ModuleInstance) String() string { + var buf bytes.Buffer + sep := "" + for _, step := range m { + buf.WriteString(sep) + buf.WriteString("module.") + buf.WriteString(step.Name) + if step.InstanceKey != NoKey { + buf.WriteString(step.InstanceKey.String()) + } + sep = "." + } + return buf.String() +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/coerce_value.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/coerce_value.go new file mode 100644 index 00000000..d12ff8cc --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/coerce_value.go @@ -0,0 +1,253 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package configschema + +import ( + "fmt" + + "github.com/hashicorp/go-cty/cty" + "github.com/hashicorp/go-cty/cty/convert" +) + +// CoerceValue attempts to force the given value to conform to the type +// implied by the receiever. +// +// This is useful in situations where a configuration must be derived from +// an already-decoded value. It is always better to decode directly from +// configuration where possible since then source location information is +// still available to produce diagnostics, but in special situations this +// function allows a compatible result to be obtained even if the +// configuration objects are not available. +// +// If the given value cannot be converted to conform to the receiving schema +// then an error is returned describing one of possibly many problems. This +// error may be a cty.PathError indicating a position within the nested +// data structure where the problem applies. +func (b *Block) CoerceValue(in cty.Value) (cty.Value, error) { + var path cty.Path + return b.coerceValue(in, path) +} + +func (b *Block) coerceValue(in cty.Value, path cty.Path) (cty.Value, error) { + switch { + case in.IsNull(): + return cty.NullVal(b.ImpliedType()), nil + case !in.IsKnown(): + return cty.UnknownVal(b.ImpliedType()), nil + } + + ty := in.Type() + if !ty.IsObjectType() { + return cty.UnknownVal(b.ImpliedType()), path.NewErrorf("an object is required") + } + + for name := range ty.AttributeTypes() { + if _, defined := b.Attributes[name]; defined { + continue + } + if _, defined := b.BlockTypes[name]; defined { + continue + } + return cty.UnknownVal(b.ImpliedType()), path.NewErrorf("unexpected attribute %q", name) + } + + attrs := make(map[string]cty.Value) + + for name, attrS := range b.Attributes { + var val cty.Value + switch { + case ty.HasAttribute(name): + val = in.GetAttr(name) + case attrS.Computed || attrS.Optional: + val = cty.NullVal(attrS.Type) + default: + return cty.UnknownVal(b.ImpliedType()), path.NewErrorf("attribute %q is required", name) + } + + val, err := attrS.coerceValue(val, append(path, cty.GetAttrStep{Name: name})) + if err != nil { + return cty.UnknownVal(b.ImpliedType()), err + } + + attrs[name] = val + } + for typeName, blockS := range b.BlockTypes { + switch blockS.Nesting { + + case NestingSingle, NestingGroup: + switch { + case ty.HasAttribute(typeName): + var err error + val := in.GetAttr(typeName) + attrs[typeName], err = blockS.coerceValue(val, append(path, cty.GetAttrStep{Name: typeName})) + if err != nil { + return cty.UnknownVal(b.ImpliedType()), err + } + default: + attrs[typeName] = blockS.EmptyValue() + } + + case NestingList: + switch { + case ty.HasAttribute(typeName): + coll := in.GetAttr(typeName) + + switch { + case coll.IsNull(): + attrs[typeName] = cty.NullVal(cty.List(blockS.ImpliedType())) + continue + case !coll.IsKnown(): + attrs[typeName] = cty.UnknownVal(cty.List(blockS.ImpliedType())) + continue + } + + if !coll.CanIterateElements() { + return cty.UnknownVal(b.ImpliedType()), path.NewErrorf("must be a list") + } + l := coll.LengthInt() + + if l == 0 { + attrs[typeName] = cty.ListValEmpty(blockS.ImpliedType()) + continue + } + elems := make([]cty.Value, 0, l) + { + path = append(path, cty.GetAttrStep{Name: typeName}) + for it := coll.ElementIterator(); it.Next(); { + var err error + idx, val := it.Element() + val, err = blockS.coerceValue(val, append(path, cty.IndexStep{Key: idx})) + if err != nil { + return cty.UnknownVal(b.ImpliedType()), err + } + elems = append(elems, val) + } + } + attrs[typeName] = cty.ListVal(elems) + default: + attrs[typeName] = cty.ListValEmpty(blockS.ImpliedType()) + } + + case NestingSet: + switch { + case ty.HasAttribute(typeName): + coll := in.GetAttr(typeName) + + switch { + case coll.IsNull(): + attrs[typeName] = cty.NullVal(cty.Set(blockS.ImpliedType())) + continue + case !coll.IsKnown(): + attrs[typeName] = cty.UnknownVal(cty.Set(blockS.ImpliedType())) + continue + } + + if !coll.CanIterateElements() { + return cty.UnknownVal(b.ImpliedType()), path.NewErrorf("must be a set") + } + l := coll.LengthInt() + + if l == 0 { + attrs[typeName] = cty.SetValEmpty(blockS.ImpliedType()) + continue + } + elems := make([]cty.Value, 0, l) + { + path = append(path, cty.GetAttrStep{Name: typeName}) + for it := coll.ElementIterator(); it.Next(); { + var err error + idx, val := it.Element() + val, err = blockS.coerceValue(val, append(path, cty.IndexStep{Key: idx})) + if err != nil { + return cty.UnknownVal(b.ImpliedType()), err + } + elems = append(elems, val) + } + } + attrs[typeName] = cty.SetVal(elems) + default: + attrs[typeName] = cty.SetValEmpty(blockS.ImpliedType()) + } + + case NestingMap: + switch { + case ty.HasAttribute(typeName): + coll := in.GetAttr(typeName) + + switch { + case coll.IsNull(): + attrs[typeName] = cty.NullVal(cty.Map(blockS.ImpliedType())) + continue + case !coll.IsKnown(): + attrs[typeName] = cty.UnknownVal(cty.Map(blockS.ImpliedType())) + continue + } + + if !coll.CanIterateElements() { + return cty.UnknownVal(b.ImpliedType()), path.NewErrorf("must be a map") + } + l := coll.LengthInt() + if l == 0 { + attrs[typeName] = cty.MapValEmpty(blockS.ImpliedType()) + continue + } + elems := make(map[string]cty.Value) + { + path = append(path, cty.GetAttrStep{Name: typeName}) + for it := coll.ElementIterator(); it.Next(); { + var err error + key, val := it.Element() + if key.Type() != cty.String || key.IsNull() || !key.IsKnown() { + return cty.UnknownVal(b.ImpliedType()), path.NewErrorf("must be a map") + } + val, err = blockS.coerceValue(val, append(path, cty.IndexStep{Key: key})) + if err != nil { + return cty.UnknownVal(b.ImpliedType()), err + } + elems[key.AsString()] = val + } + } + + // If the attribute values here contain any DynamicPseudoTypes, + // the concrete type must be an object. + useObject := false + switch { + case coll.Type().IsObjectType(): + useObject = true + default: + // It's possible that we were given a map, and need to coerce it to an object + ety := coll.Type().ElementType() + for _, v := range elems { + if !v.Type().Equals(ety) { + useObject = true + break + } + } + } + + if useObject { + attrs[typeName] = cty.ObjectVal(elems) + } else { + attrs[typeName] = cty.MapVal(elems) + } + default: + attrs[typeName] = cty.MapValEmpty(blockS.ImpliedType()) + } + + default: + // should never happen because above is exhaustive + panic(fmt.Errorf("unsupported nesting mode %#v", blockS.Nesting)) + } + } + + return cty.ObjectVal(attrs), nil +} + +func (a *Attribute) coerceValue(in cty.Value, path cty.Path) (cty.Value, error) { + val, err := convert.Convert(in, a.Type) + if err != nil { + return cty.UnknownVal(a.Type), path.NewError(err) + } + return val, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/doc.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/doc.go new file mode 100644 index 00000000..d96be9c7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/doc.go @@ -0,0 +1,17 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package configschema contains types for describing the expected structure +// of a configuration block whose shape is not known until runtime. +// +// For example, this is used to describe the expected contents of a resource +// configuration block, which is defined by the corresponding provider plugin +// and thus not compiled into Terraform core. +// +// A configschema primarily describes the shape of configuration, but it is +// also suitable for use with other structures derived from the configuration, +// such as the cached state of a resource or a resource diff. +// +// This package should not be confused with the package helper/schema, which +// is the higher-level helper library used to implement providers themselves. +package configschema diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/empty_value.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/empty_value.go new file mode 100644 index 00000000..cc1107fa --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/empty_value.go @@ -0,0 +1,62 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package configschema + +import ( + "github.com/hashicorp/go-cty/cty" +) + +// EmptyValue returns the "empty value" for the receiving block, which for +// a block type is a non-null object where all of the attribute values are +// the empty values of the block's attributes and nested block types. +// +// In other words, it returns the value that would be returned if an empty +// block were decoded against the receiving schema, assuming that no required +// attribute or block constraints were honored. +func (b *Block) EmptyValue() cty.Value { + vals := make(map[string]cty.Value) + for name, attrS := range b.Attributes { + vals[name] = attrS.EmptyValue() + } + for name, blockS := range b.BlockTypes { + vals[name] = blockS.EmptyValue() + } + return cty.ObjectVal(vals) +} + +// EmptyValue returns the "empty value" for the receiving attribute, which is +// the value that would be returned if there were no definition of the attribute +// at all, ignoring any required constraint. +func (a *Attribute) EmptyValue() cty.Value { + return cty.NullVal(a.Type) +} + +// EmptyValue returns the "empty value" for when there are zero nested blocks +// present of the receiving type. +func (b *NestedBlock) EmptyValue() cty.Value { + switch b.Nesting { + case NestingSingle: + return cty.NullVal(b.Block.ImpliedType()) + case NestingGroup: + return b.Block.EmptyValue() + case NestingList: + if ty := b.Block.ImpliedType(); ty.HasDynamicTypes() { + return cty.EmptyTupleVal + } else { + return cty.ListValEmpty(ty) + } + case NestingMap: + if ty := b.Block.ImpliedType(); ty.HasDynamicTypes() { + return cty.EmptyObjectVal + } else { + return cty.MapValEmpty(ty) + } + case NestingSet: + return cty.SetValEmpty(b.Block.ImpliedType()) + default: + // Should never get here because the above is intended to be exhaustive, + // but we'll be robust and return a result nonetheless. + return cty.NullVal(cty.DynamicPseudoType) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/implied_type.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/implied_type.go new file mode 100644 index 00000000..4de41351 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/implied_type.go @@ -0,0 +1,71 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package configschema + +import ( + "github.com/hashicorp/go-cty/cty" +) + +// ImpliedType returns the cty.Type that would result from decoding a +// configuration block using the receiving block schema. +// +// ImpliedType always returns a result, even if the given schema is +// inconsistent. +func (b *Block) ImpliedType() cty.Type { + if b == nil { + return cty.EmptyObject + } + + atys := make(map[string]cty.Type) + + for name, attrS := range b.Attributes { + atys[name] = attrS.Type + } + + for name, blockS := range b.BlockTypes { + if _, exists := atys[name]; exists { + panic("invalid schema, blocks and attributes cannot have the same name") + } + + childType := blockS.Block.ImpliedType() + + switch blockS.Nesting { + case NestingSingle, NestingGroup: + atys[name] = childType + case NestingList: + // We prefer to use a list where possible, since it makes our + // implied type more complete, but if there are any + // dynamically-typed attributes inside we must use a tuple + // instead, which means our type _constraint_ must be + // cty.DynamicPseudoType to allow the tuple type to be decided + // separately for each value. + if childType.HasDynamicTypes() { + atys[name] = cty.DynamicPseudoType + } else { + atys[name] = cty.List(childType) + } + case NestingSet: + if childType.HasDynamicTypes() { + panic("can't use cty.DynamicPseudoType inside a block type with NestingSet") + } + atys[name] = cty.Set(childType) + case NestingMap: + // We prefer to use a map where possible, since it makes our + // implied type more complete, but if there are any + // dynamically-typed attributes inside we must use an object + // instead, which means our type _constraint_ must be + // cty.DynamicPseudoType to allow the tuple type to be decided + // separately for each value. + if childType.HasDynamicTypes() { + atys[name] = cty.DynamicPseudoType + } else { + atys[name] = cty.Map(childType) + } + default: + panic("invalid nesting type") + } + } + + return cty.Object(atys) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/nestingmode_string.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/nestingmode_string.go new file mode 100644 index 00000000..febe743e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/nestingmode_string.go @@ -0,0 +1,28 @@ +// Code generated by "stringer -type=NestingMode"; DO NOT EDIT. + +package configschema + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[nestingModeInvalid-0] + _ = x[NestingSingle-1] + _ = x[NestingGroup-2] + _ = x[NestingList-3] + _ = x[NestingSet-4] + _ = x[NestingMap-5] +} + +const _NestingMode_name = "nestingModeInvalidNestingSingleNestingGroupNestingListNestingSetNestingMap" + +var _NestingMode_index = [...]uint8{0, 18, 31, 43, 54, 64, 74} + +func (i NestingMode) String() string { + if i < 0 || i >= NestingMode(len(_NestingMode_index)-1) { + return "NestingMode(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _NestingMode_name[_NestingMode_index[i]:_NestingMode_index[i+1]] +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/schema.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/schema.go new file mode 100644 index 00000000..fafe3fa9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema/schema.go @@ -0,0 +1,161 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package configschema + +import ( + "github.com/hashicorp/go-cty/cty" +) + +// StringKind represents the format a string is in. +type StringKind int + +const ( + // StringPlain indicates a string is plain-text and requires no processing for display. + StringPlain StringKind = iota + // StringMarkdown indicates a string is in markdown format and may + // require additional processing to display. + StringMarkdown +) + +// Block represents a configuration block. +// +// "Block" here is a logical grouping construct, though it happens to map +// directly onto the physical block syntax of Terraform's native configuration +// syntax. It may be a more a matter of convention in other syntaxes, such as +// JSON. +// +// When converted to a value, a Block always becomes an instance of an object +// type derived from its defined attributes and nested blocks +type Block struct { + // Attributes describes any attributes that may appear directly inside + // the block. + Attributes map[string]*Attribute + + // BlockTypes describes any nested block types that may appear directly + // inside the block. + BlockTypes map[string]*NestedBlock + + // Description and DescriptionKind contain a user facing description of the block + // and the format of that string. + Description string + DescriptionKind StringKind + + // Deprecated indicates whether the block has been marked as deprecated in the + // provider and usage should be discouraged. + Deprecated bool +} + +// Attribute represents a configuration attribute, within a block. +type Attribute struct { + // Type is a type specification that the attribute's value must conform to. + Type cty.Type + + // Description is an English-language description of the purpose and + // usage of the attribute. A description should be concise and use only + // one or two sentences, leaving full definition to longer-form + // documentation defined elsewhere. + Description string + DescriptionKind StringKind + + // Required, if set to true, specifies that an omitted or null value is + // not permitted. + Required bool + + // Optional, if set to true, specifies that an omitted or null value is + // permitted. This field conflicts with Required. + Optional bool + + // Computed, if set to true, specifies that the value comes from the + // provider rather than from configuration. If combined with Optional, + // then the config may optionally provide an overridden value. + Computed bool + + // Sensitive, if set to true, indicates that an attribute may contain + // sensitive information. + // + // At present nothing is done with this information, but callers are + // encouraged to set it where appropriate so that it may be used in the + // future to help Terraform mask sensitive information. (Terraform + // currently achieves this in a limited sense via other mechanisms.) + Sensitive bool + + // Deprecated indicates whether the attribute has been marked as deprecated in the + // provider and usage should be discouraged. + Deprecated bool +} + +// NestedBlock represents the embedding of one block within another. +type NestedBlock struct { + // Block is the description of the block that's nested. + Block + + // Nesting provides the nesting mode for the child block, which determines + // how many instances of the block are allowed, how many labels it expects, + // and how the resulting data will be converted into a data structure. + Nesting NestingMode + + // MinItems and MaxItems set, for the NestingList and NestingSet nesting + // modes, lower and upper limits on the number of child blocks allowed + // of the given type. If both are left at zero, no limit is applied. + // + // As a special case, both values can be set to 1 for NestingSingle in + // order to indicate that a particular single block is required. + // + // These fields are ignored for other nesting modes and must both be left + // at zero. + MinItems, MaxItems int +} + +// NestingMode is an enumeration of modes for nesting blocks inside other +// blocks. +type NestingMode int + +// This code was previously generated with a go:generate directive calling: +// go run golang.org/x/tools/cmd/stringer -type=NestingMode +// However, it is now considered frozen and the tooling dependency has been +// removed. The String method can be manually updated if necessary. + +const ( + nestingModeInvalid NestingMode = iota + + // NestingSingle indicates that only a single instance of a given + // block type is permitted, with no labels, and its content should be + // provided directly as an object value. + NestingSingle + + // NestingGroup is similar to NestingSingle in that it calls for only a + // single instance of a given block type with no labels, but it additionally + // guarantees that its result will never be null, even if the block is + // absent, and instead the nested attributes and blocks will be treated + // as absent in that case. (Any required attributes or blocks within the + // nested block are not enforced unless the block is explicitly present + // in the configuration, so they are all effectively optional when the + // block is not present.) + // + // This is useful for the situation where a remote API has a feature that + // is always enabled but has a group of settings related to that feature + // that themselves have default values. By using NestingGroup instead of + // NestingSingle in that case, generated plans will show the block as + // present even when not present in configuration, thus allowing any + // default values within to be displayed to the user. + NestingGroup + + // NestingList indicates that multiple blocks of the given type are + // permitted, with no labels, and that their corresponding objects should + // be provided in a list. + NestingList + + // NestingSet indicates that multiple blocks of the given type are + // permitted, with no labels, and that their corresponding objects should + // be provided in a set. + NestingSet + + // NestingMap indicates that multiple blocks of the given type are + // permitted, each with a single label, and that their corresponding + // objects should be provided in a map whose keys are the labels. + // + // It's an error, therefore, to use the same label value on multiple + // blocks. + NestingMap +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/flatmap.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/flatmap.go new file mode 100644 index 00000000..2bad034d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/flatmap.go @@ -0,0 +1,426 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package hcl2shim + +import ( + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/go-cty/cty" + "github.com/hashicorp/go-cty/cty/convert" +) + +// FlatmapValueFromHCL2 converts a value from HCL2 (really, from the cty dynamic +// types library that HCL2 uses) to a map compatible with what would be +// produced by the "flatmap" package. +// +// The type of the given value informs the structure of the resulting map. +// The value must be of an object type or this function will panic. +// +// Flatmap values can only represent maps when they are of primitive types, +// so the given value must not have any maps of complex types or the result +// is undefined. +func FlatmapValueFromHCL2(v cty.Value) map[string]string { + if v.IsNull() { + return nil + } + + if !v.Type().IsObjectType() { + panic(fmt.Sprintf("HCL2ValueFromFlatmap called on %#v", v.Type())) + } + + m := make(map[string]string) + flatmapValueFromHCL2Map(m, "", v) + return m +} + +func flatmapValueFromHCL2Value(m map[string]string, key string, val cty.Value) { + ty := val.Type() + switch { + case ty.IsPrimitiveType() || ty == cty.DynamicPseudoType: + flatmapValueFromHCL2Primitive(m, key, val) + case ty.IsObjectType() || ty.IsMapType(): + flatmapValueFromHCL2Map(m, key+".", val) + case ty.IsTupleType() || ty.IsListType() || ty.IsSetType(): + flatmapValueFromHCL2Seq(m, key+".", val) + default: + panic(fmt.Sprintf("cannot encode %s to flatmap", ty.FriendlyName())) + } +} + +func flatmapValueFromHCL2Primitive(m map[string]string, key string, val cty.Value) { + if !val.IsKnown() { + m[key] = UnknownVariableValue + return + } + if val.IsNull() { + // Omit entirely + return + } + + var err error + val, err = convert.Convert(val, cty.String) + if err != nil { + // Should not be possible, since all primitive types can convert to string. + panic(fmt.Sprintf("invalid primitive encoding to flatmap: %s", err)) + } + m[key] = val.AsString() +} + +func flatmapValueFromHCL2Map(m map[string]string, prefix string, val cty.Value) { + if val.IsNull() { + // Omit entirely + return + } + if !val.IsKnown() { + switch { + case val.Type().IsObjectType(): + // Whole objects can't be unknown in flatmap, so instead we'll + // just write all of the attribute values out as unknown. + for name, aty := range val.Type().AttributeTypes() { + flatmapValueFromHCL2Value(m, prefix+name, cty.UnknownVal(aty)) + } + default: + m[prefix+"%"] = UnknownVariableValue + } + return + } + + valLen := 0 + for it := val.ElementIterator(); it.Next(); { + ak, av := it.Element() + name := ak.AsString() + flatmapValueFromHCL2Value(m, prefix+name, av) + valLen++ + } + if !val.Type().IsObjectType() { // objects don't have an explicit count included, since their attribute count is fixed + m[prefix+"%"] = strconv.Itoa(valLen) + } +} + +func flatmapValueFromHCL2Seq(m map[string]string, prefix string, val cty.Value) { + if val.IsNull() { + // Omit entirely + return + } + if !val.IsKnown() { + m[prefix+"#"] = UnknownVariableValue + return + } + + // For sets this won't actually generate exactly what helper/schema would've + // generated, because we don't have access to the set key function it + // would've used. However, in practice it doesn't actually matter what the + // keys are as long as they are unique, so we'll just generate sequential + // indexes for them as if it were a list. + // + // An important implication of this, however, is that the set ordering will + // not be consistent across mutations and so different keys may be assigned + // to the same value when round-tripping. Since this shim is intended to + // be short-lived and not used for round-tripping, we accept this. + i := 0 + for it := val.ElementIterator(); it.Next(); { + _, av := it.Element() + key := prefix + strconv.Itoa(i) + flatmapValueFromHCL2Value(m, key, av) + i++ + } + m[prefix+"#"] = strconv.Itoa(i) +} + +// HCL2ValueFromFlatmap converts a map compatible with what would be produced +// by the "flatmap" package to a HCL2 (really, the cty dynamic types library +// that HCL2 uses) object type. +// +// The intended result type must be provided in order to guide how the +// map contents are decoded. This must be an object type or this function +// will panic. +// +// Flatmap values can only represent maps when they are of primitive types, +// so the given type must not have any maps of complex types or the result +// is undefined. +// +// The result may contain null values if the given map does not contain keys +// for all of the different key paths implied by the given type. +func HCL2ValueFromFlatmap(m map[string]string, ty cty.Type) (cty.Value, error) { + if m == nil { + return cty.NullVal(ty), nil + } + if !ty.IsObjectType() { + panic(fmt.Sprintf("HCL2ValueFromFlatmap called on %#v", ty)) + } + + return hcl2ValueFromFlatmapObject(m, "", ty.AttributeTypes()) +} + +func hcl2ValueFromFlatmapValue(m map[string]string, key string, ty cty.Type) (cty.Value, error) { + var val cty.Value + var err error + switch { + case ty.IsPrimitiveType(): + val, err = hcl2ValueFromFlatmapPrimitive(m, key, ty) + case ty.IsObjectType(): + val, err = hcl2ValueFromFlatmapObject(m, key+".", ty.AttributeTypes()) + case ty.IsTupleType(): + val, err = hcl2ValueFromFlatmapTuple(m, key+".", ty.TupleElementTypes()) + case ty.IsMapType(): + val, err = hcl2ValueFromFlatmapMap(m, key+".", ty) + case ty.IsListType(): + val, err = hcl2ValueFromFlatmapList(m, key+".", ty) + case ty.IsSetType(): + val, err = hcl2ValueFromFlatmapSet(m, key+".", ty) + default: + err = fmt.Errorf("cannot decode %s from flatmap", ty.FriendlyName()) + } + + if err != nil { + return cty.DynamicVal, err + } + return val, nil +} + +func hcl2ValueFromFlatmapPrimitive(m map[string]string, key string, ty cty.Type) (cty.Value, error) { + rawVal, exists := m[key] + if !exists { + return cty.NullVal(ty), nil + } + if rawVal == UnknownVariableValue { + return cty.UnknownVal(ty), nil + } + + var err error + val := cty.StringVal(rawVal) + val, err = convert.Convert(val, ty) + if err != nil { + // This should never happen for _valid_ input, but flatmap data might + // be tampered with by the user and become invalid. + return cty.DynamicVal, fmt.Errorf("invalid value for %q in state: %s", key, err) + } + + return val, nil +} + +func hcl2ValueFromFlatmapObject(m map[string]string, prefix string, atys map[string]cty.Type) (cty.Value, error) { + vals := make(map[string]cty.Value) + for name, aty := range atys { + val, err := hcl2ValueFromFlatmapValue(m, prefix+name, aty) + if err != nil { + return cty.DynamicVal, err + } + vals[name] = val + } + return cty.ObjectVal(vals), nil +} + +func hcl2ValueFromFlatmapTuple(m map[string]string, prefix string, etys []cty.Type) (cty.Value, error) { + var vals []cty.Value + + // if the container is unknown, there is no count string + listName := strings.TrimRight(prefix, ".") + if m[listName] == UnknownVariableValue { + return cty.UnknownVal(cty.Tuple(etys)), nil + } + + countStr, exists := m[prefix+"#"] + if !exists { + return cty.NullVal(cty.Tuple(etys)), nil + } + if countStr == UnknownVariableValue { + return cty.UnknownVal(cty.Tuple(etys)), nil + } + + count, err := strconv.Atoi(countStr) + if err != nil { + return cty.DynamicVal, fmt.Errorf("invalid count value for %q in state: %s", prefix, err) + } + if count != len(etys) { + return cty.DynamicVal, fmt.Errorf("wrong number of values for %q in state: got %d, but need %d", prefix, count, len(etys)) + } + + vals = make([]cty.Value, len(etys)) + for i, ety := range etys { + key := prefix + strconv.Itoa(i) + val, err := hcl2ValueFromFlatmapValue(m, key, ety) + if err != nil { + return cty.DynamicVal, err + } + vals[i] = val + } + return cty.TupleVal(vals), nil +} + +func hcl2ValueFromFlatmapMap(m map[string]string, prefix string, ty cty.Type) (cty.Value, error) { + vals := make(map[string]cty.Value) + ety := ty.ElementType() + + // if the container is unknown, there is no count string + listName := strings.TrimRight(prefix, ".") + if m[listName] == UnknownVariableValue { + return cty.UnknownVal(ty), nil + } + + // We actually don't really care about the "count" of a map for our + // purposes here, but we do need to check if it _exists_ in order to + // recognize the difference between null (not set at all) and empty. + if strCount, exists := m[prefix+"%"]; !exists { + return cty.NullVal(ty), nil + } else if strCount == UnknownVariableValue { + return cty.UnknownVal(ty), nil + } + + for fullKey := range m { + if !strings.HasPrefix(fullKey, prefix) { + continue + } + + // The flatmap format doesn't allow us to distinguish between keys + // that contain periods and nested objects, so by convention a + // map is only ever of primitive type in flatmap, and we just assume + // that the remainder of the raw key (dots and all) is the key we + // want in the result value. + key := fullKey[len(prefix):] + if key == "%" { + // Ignore the "count" key + continue + } + + val, err := hcl2ValueFromFlatmapValue(m, fullKey, ety) + if err != nil { + return cty.DynamicVal, err + } + vals[key] = val + } + + if len(vals) == 0 { + return cty.MapValEmpty(ety), nil + } + return cty.MapVal(vals), nil +} + +func hcl2ValueFromFlatmapList(m map[string]string, prefix string, ty cty.Type) (cty.Value, error) { + var vals []cty.Value + + // if the container is unknown, there is no count string + listName := strings.TrimRight(prefix, ".") + if m[listName] == UnknownVariableValue { + return cty.UnknownVal(ty), nil + } + + countStr, exists := m[prefix+"#"] + if !exists { + return cty.NullVal(ty), nil + } + if countStr == UnknownVariableValue { + return cty.UnknownVal(ty), nil + } + + count, err := strconv.Atoi(countStr) + if err != nil { + return cty.DynamicVal, fmt.Errorf("invalid count value for %q in state: %s", prefix, err) + } + + ety := ty.ElementType() + if count == 0 { + return cty.ListValEmpty(ety), nil + } + + vals = make([]cty.Value, count) + for i := 0; i < count; i++ { + key := prefix + strconv.Itoa(i) + val, err := hcl2ValueFromFlatmapValue(m, key, ety) + if err != nil { + return cty.DynamicVal, err + } + vals[i] = val + } + + return cty.ListVal(vals), nil +} + +func hcl2ValueFromFlatmapSet(m map[string]string, prefix string, ty cty.Type) (cty.Value, error) { + var vals []cty.Value + ety := ty.ElementType() + + // if the container is unknown, there is no count string + listName := strings.TrimRight(prefix, ".") + if m[listName] == UnknownVariableValue { + return cty.UnknownVal(ty), nil + } + + strCount, exists := m[prefix+"#"] + if !exists { + return cty.NullVal(ty), nil + } else if strCount == UnknownVariableValue { + return cty.UnknownVal(ty), nil + } + + // Keep track of keys we've seen, se we don't add the same set value + // multiple times. The cty.Set will normally de-duplicate values, but we may + // have unknown values that would not show as equivalent. + seen := map[string]bool{} + + for fullKey := range m { + if !strings.HasPrefix(fullKey, prefix) { + continue + } + subKey := fullKey[len(prefix):] + if subKey == "#" { + // Ignore the "count" key + continue + } + key := fullKey + if dot := strings.IndexByte(subKey, '.'); dot != -1 { + key = fullKey[:dot+len(prefix)] + } + + if seen[key] { + continue + } + + seen[key] = true + + // The flatmap format doesn't allow us to distinguish between keys + // that contain periods and nested objects, so by convention a + // map is only ever of primitive type in flatmap, and we just assume + // that the remainder of the raw key (dots and all) is the key we + // want in the result value. + + val, err := hcl2ValueFromFlatmapValue(m, key, ety) + if err != nil { + return cty.DynamicVal, err + } + vals = append(vals, val) + } + + if len(vals) == 0 && strCount == "1" { + // An empty set wouldn't be represented in the flatmap, so this must be + // a single empty object since the count is actually 1. + // Add an appropriately typed null value to the set. + var val cty.Value + switch { + case ety.IsMapType(): + val = cty.MapValEmpty(ety) + case ety.IsListType(): + val = cty.ListValEmpty(ety) + case ety.IsSetType(): + val = cty.SetValEmpty(ety) + case ety.IsObjectType(): + // TODO: cty.ObjectValEmpty + objectMap := map[string]cty.Value{} + for attr, ty := range ety.AttributeTypes() { + objectMap[attr] = cty.NullVal(ty) + } + val = cty.ObjectVal(objectMap) + default: + val = cty.NullVal(ety) + } + vals = append(vals, val) + + } else if len(vals) == 0 { + return cty.SetValEmpty(ety), nil + } + + return cty.SetVal(vals), nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/paths.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/paths.go new file mode 100644 index 00000000..628a8bf6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/paths.go @@ -0,0 +1,279 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package hcl2shim + +import ( + "fmt" + "reflect" + "strconv" + "strings" + + "github.com/hashicorp/go-cty/cty" +) + +// RequiresReplace takes a list of flatmapped paths from a +// InstanceDiff.Attributes along with the corresponding cty.Type, and returns +// the list of the cty.Paths that are flagged as causing the resource +// replacement (RequiresNew). +// This will filter out redundant paths, paths that refer to flatmapped indexes +// (e.g. "#", "%"), and will return any changes within a set as the path to the +// set itself. +func RequiresReplace(attrs []string, ty cty.Type) ([]cty.Path, error) { + var paths []cty.Path + + for _, attr := range attrs { + p, err := requiresReplacePath(attr, ty) + if err != nil { + return nil, err + } + + paths = append(paths, p) + } + + // now trim off any trailing paths that aren't GetAttrSteps, since only an + // attribute itself can require replacement + paths = trimPaths(paths) + + // There may be redundant paths due to set elements or index attributes + // Do some ugly n^2 filtering, but these are always fairly small sets. + for i := 0; i < len(paths)-1; i++ { + for j := i + 1; j < len(paths); j++ { + if reflect.DeepEqual(paths[i], paths[j]) { + // swap the tail and slice it off + paths[j], paths[len(paths)-1] = paths[len(paths)-1], paths[j] + paths = paths[:len(paths)-1] + j-- + } + } + } + + return paths, nil +} + +// trimPaths removes any trailing steps that aren't of type GetAttrSet, since +// only an attribute itself can require replacement +func trimPaths(paths []cty.Path) []cty.Path { + var trimmed []cty.Path + for _, path := range paths { + path = trimPath(path) + if len(path) > 0 { + trimmed = append(trimmed, path) + } + } + return trimmed +} + +func trimPath(path cty.Path) cty.Path { + for len(path) > 0 { + _, isGetAttr := path[len(path)-1].(cty.GetAttrStep) + if isGetAttr { + break + } + path = path[:len(path)-1] + } + return path +} + +// requiresReplacePath takes a key from a flatmap along with the cty.Type +// describing the structure, and returns the cty.Path that would be used to +// reference the nested value in the data structure. +// This is used specifically to record the RequiresReplace attributes from a +// ResourceInstanceDiff. +func requiresReplacePath(k string, ty cty.Type) (cty.Path, error) { + if k == "" { + return nil, nil + } + if !ty.IsObjectType() { + panic(fmt.Sprintf("requires replace path on non-object type: %#v", ty)) + } + + path, err := pathFromFlatmapKeyObject(k, ty.AttributeTypes()) + if err != nil { + return path, fmt.Errorf("[%s] %s", k, err) + } + return path, nil +} + +func pathSplit(p string) (string, string) { + parts := strings.SplitN(p, ".", 2) + head := parts[0] + rest := "" + if len(parts) > 1 { + rest = parts[1] + } + return head, rest +} + +func pathFromFlatmapKeyObject(key string, atys map[string]cty.Type) (cty.Path, error) { + k, rest := pathSplit(key) + + path := cty.Path{cty.GetAttrStep{Name: k}} + + ty, ok := atys[k] + if !ok { + return path, fmt.Errorf("attribute %q not found", k) + } + + if rest == "" { + return path, nil + } + + p, err := pathFromFlatmapKeyValue(rest, ty) + if err != nil { + return path, err + } + + return append(path, p...), nil +} + +func pathFromFlatmapKeyValue(key string, ty cty.Type) (cty.Path, error) { + var path cty.Path + var err error + + switch { + case ty.IsPrimitiveType(): + err = fmt.Errorf("invalid step %q with type %#v", key, ty) + case ty.IsObjectType(): + path, err = pathFromFlatmapKeyObject(key, ty.AttributeTypes()) + case ty.IsTupleType(): + path, err = pathFromFlatmapKeyTuple(key, ty.TupleElementTypes()) + case ty.IsMapType(): + path, err = pathFromFlatmapKeyMap(key, ty) + case ty.IsListType(): + path, err = pathFromFlatmapKeyList(key, ty) + case ty.IsSetType(): + path, err = pathFromFlatmapKeySet(key, ty) + default: + err = fmt.Errorf("unrecognized type: %s", ty.FriendlyName()) + } + + if err != nil { + return path, err + } + + return path, nil +} + +func pathFromFlatmapKeyTuple(key string, etys []cty.Type) (cty.Path, error) { + var path cty.Path + var err error + + k, rest := pathSplit(key) + + // we don't need to convert the index keys to paths + if k == "#" { + return path, nil + } + + idx, err := strconv.Atoi(k) + if err != nil { + return path, err + } + + path = cty.Path{cty.IndexStep{Key: cty.NumberIntVal(int64(idx))}} + + if idx >= len(etys) { + return path, fmt.Errorf("index %s out of range in %#v", key, etys) + } + + if rest == "" { + return path, nil + } + + ty := etys[idx] + + p, err := pathFromFlatmapKeyValue(rest, ty.ElementType()) + if err != nil { + return path, err + } + + return append(path, p...), nil +} + +func pathFromFlatmapKeyMap(key string, ty cty.Type) (cty.Path, error) { + var path cty.Path + var err error + + k, rest := key, "" + if !ty.ElementType().IsPrimitiveType() { + k, rest = pathSplit(key) + } + + // we don't need to convert the index keys to paths + if k == "%" { + return path, nil + } + + path = cty.Path{cty.IndexStep{Key: cty.StringVal(k)}} + + if rest == "" { + return path, nil + } + + p, err := pathFromFlatmapKeyValue(rest, ty.ElementType()) + if err != nil { + return path, err + } + + return append(path, p...), nil +} + +func pathFromFlatmapKeyList(key string, ty cty.Type) (cty.Path, error) { + var path cty.Path + var err error + + k, rest := pathSplit(key) + + // we don't need to convert the index keys to paths + if key == "#" { + return path, nil + } + + idx, err := strconv.Atoi(k) + if err != nil { + return path, err + } + + path = cty.Path{cty.IndexStep{Key: cty.NumberIntVal(int64(idx))}} + + if rest == "" { + return path, nil + } + + p, err := pathFromFlatmapKeyValue(rest, ty.ElementType()) + if err != nil { + return path, err + } + + return append(path, p...), nil +} + +func pathFromFlatmapKeySet(key string, ty cty.Type) (cty.Path, error) { + // once we hit a set, we can't return consistent paths, so just mark the + // set as a whole changed. + return nil, nil +} + +// FlatmapKeyFromPath returns the flatmap equivalent of the given cty.Path for +// use in generating legacy style diffs. +func FlatmapKeyFromPath(path cty.Path) string { + var parts []string + + for _, step := range path { + switch step := step.(type) { + case cty.GetAttrStep: + parts = append(parts, step.Name) + case cty.IndexStep: + switch ty := step.Key.Type(); { + case ty == cty.String: + parts = append(parts, step.Key.AsString()) + case ty == cty.Number: + i, _ := step.Key.AsBigFloat().Int64() + parts = append(parts, strconv.Itoa(int(i))) + } + } + } + + return strings.Join(parts, ".") +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/values.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/values.go new file mode 100644 index 00000000..191f1bc7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/values.go @@ -0,0 +1,233 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package hcl2shim + +import ( + "fmt" + "math/big" + + "github.com/hashicorp/go-cty/cty" + + "github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema" +) + +// UnknownVariableValue is a sentinel value that can be used +// to denote that the value of a variable is unknown at this time. +// RawConfig uses this information to build up data about +// unknown keys. +const UnknownVariableValue = "74D93920-ED26-11E3-AC10-0800200C9A66" + +// ConfigValueFromHCL2Block is like ConfigValueFromHCL2 but it works only for +// known object values and uses the provided block schema to perform some +// additional normalization to better mimic the shape of value that the old +// HCL1/HIL-based codepaths would've produced. +// +// In particular, it discards the collections that we use to represent nested +// blocks (other than NestingSingle) if they are empty, which better mimics +// the HCL1 behavior because HCL1 had no knowledge of the schema and so didn't +// know that an unspecified block _could_ exist. +// +// The given object value must conform to the schema's implied type or this +// function will panic or produce incorrect results. +// +// This is primarily useful for the final transition from new-style values to +// terraform.ResourceConfig before calling to a legacy provider, since +// helper/schema (the old provider SDK) is particularly sensitive to these +// subtle differences within its validation code. +func ConfigValueFromHCL2Block(v cty.Value, schema *configschema.Block) map[string]interface{} { + if v.IsNull() { + return nil + } + if !v.IsKnown() { + panic("ConfigValueFromHCL2Block used with unknown value") + } + if !v.Type().IsObjectType() { + panic(fmt.Sprintf("ConfigValueFromHCL2Block used with non-object value %#v", v)) + } + + atys := v.Type().AttributeTypes() + ret := make(map[string]interface{}) + + for name := range schema.Attributes { + if _, exists := atys[name]; !exists { + continue + } + + av := v.GetAttr(name) + if av.IsNull() { + // Skip nulls altogether, to better mimic how HCL1 would behave + continue + } + ret[name] = ConfigValueFromHCL2(av) + } + + for name, blockS := range schema.BlockTypes { + if _, exists := atys[name]; !exists { + continue + } + bv := v.GetAttr(name) + if !bv.IsKnown() { + ret[name] = UnknownVariableValue + continue + } + if bv.IsNull() { + continue + } + + switch blockS.Nesting { + + case configschema.NestingSingle, configschema.NestingGroup: + ret[name] = ConfigValueFromHCL2Block(bv, &blockS.Block) + + case configschema.NestingList, configschema.NestingSet: + l := bv.LengthInt() + if l == 0 { + // skip empty collections to better mimic how HCL1 would behave + continue + } + + elems := make([]interface{}, 0, l) + for it := bv.ElementIterator(); it.Next(); { + _, ev := it.Element() + if !ev.IsKnown() { + elems = append(elems, UnknownVariableValue) + continue + } + elems = append(elems, ConfigValueFromHCL2Block(ev, &blockS.Block)) + } + ret[name] = elems + + case configschema.NestingMap: + if bv.LengthInt() == 0 { + // skip empty collections to better mimic how HCL1 would behave + continue + } + + elems := make(map[string]interface{}) + for it := bv.ElementIterator(); it.Next(); { + ek, ev := it.Element() + if !ev.IsKnown() { + elems[ek.AsString()] = UnknownVariableValue + continue + } + elems[ek.AsString()] = ConfigValueFromHCL2Block(ev, &blockS.Block) + } + ret[name] = elems + } + } + + return ret +} + +// ConfigValueFromHCL2 converts a value from HCL2 (really, from the cty dynamic +// types library that HCL2 uses) to a value type that matches what would've +// been produced from the HCL-based interpolator for an equivalent structure. +// +// This function will transform a cty null value into a Go nil value, which +// isn't a possible outcome of the HCL/HIL-based decoder and so callers may +// need to detect and reject any null values. +func ConfigValueFromHCL2(v cty.Value) interface{} { + if !v.IsKnown() { + return UnknownVariableValue + } + if v.IsNull() { + return nil + } + + switch v.Type() { + case cty.Bool: + return v.True() // like HCL.BOOL + case cty.String: + return v.AsString() // like HCL token.STRING or token.HEREDOC + case cty.Number: + // We can't match HCL _exactly_ here because it distinguishes between + // int and float values, but we'll get as close as we can by using + // an int if the number is exactly representable, and a float if not. + // The conversion to float will force precision to that of a float64, + // which is potentially losing information from the specific number + // given, but no worse than what HCL would've done in its own conversion + // to float. + + f := v.AsBigFloat() + if i, acc := f.Int64(); acc == big.Exact { + // if we're on a 32-bit system and the number is too big for 32-bit + // int then we'll fall through here and use a float64. + const MaxInt = int(^uint(0) >> 1) + const MinInt = -MaxInt - 1 + if i <= int64(MaxInt) && i >= int64(MinInt) { + return int(i) // Like HCL token.NUMBER + } + } + + f64, _ := f.Float64() + return f64 // like HCL token.FLOAT + } + + if v.Type().IsListType() || v.Type().IsSetType() || v.Type().IsTupleType() { + l := make([]interface{}, 0, v.LengthInt()) + it := v.ElementIterator() + for it.Next() { + _, ev := it.Element() + l = append(l, ConfigValueFromHCL2(ev)) + } + return l + } + + if v.Type().IsMapType() || v.Type().IsObjectType() { + l := make(map[string]interface{}) + it := v.ElementIterator() + for it.Next() { + ek, ev := it.Element() + cv := ConfigValueFromHCL2(ev) + if cv != nil { + l[ek.AsString()] = cv + } + } + return l + } + + // If we fall out here then we have some weird type that we haven't + // accounted for. This should never happen unless the caller is using + // capsule types, and we don't currently have any such types defined. + panic(fmt.Errorf("can't convert %#v to config value", v)) +} + +// HCL2ValueFromConfigValue is the opposite of configValueFromHCL2: it takes +// a value as would be returned from the old interpolator and turns it into +// a cty.Value so it can be used within, for example, an HCL2 EvalContext. +func HCL2ValueFromConfigValue(v interface{}) cty.Value { + if v == nil { + return cty.NullVal(cty.DynamicPseudoType) + } + if v == UnknownVariableValue { + return cty.DynamicVal + } + + switch tv := v.(type) { + case bool: + return cty.BoolVal(tv) + case string: + return cty.StringVal(tv) + case int: + return cty.NumberIntVal(int64(tv)) + case float64: + return cty.NumberFloatVal(tv) + case []interface{}: + vals := make([]cty.Value, len(tv)) + for i, ev := range tv { + vals[i] = HCL2ValueFromConfigValue(ev) + } + return cty.TupleVal(vals) + case map[string]interface{}: + vals := map[string]cty.Value{} + for k, ev := range tv { + vals[k] = HCL2ValueFromConfigValue(ev) + } + return cty.ObjectVal(vals) + default: + // HCL/HIL should never generate anything that isn't caught by + // the above, so if we get here something has gone very wrong. + panic(fmt.Errorf("can't convert %#v to cty.Value", v)) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/values_equiv.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/values_equiv.go new file mode 100644 index 00000000..6b2be223 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim/values_equiv.go @@ -0,0 +1,217 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package hcl2shim + +import ( + "github.com/hashicorp/go-cty/cty" +) + +// ValuesSDKEquivalent returns true if both of the given values seem equivalent +// as far as the legacy SDK diffing code would be concerned. +// +// Since SDK diffing is a fuzzy, inexact operation, this function is also +// fuzzy and inexact. It will err on the side of returning false if it +// encounters an ambiguous situation. Ambiguity is most common in the presence +// of sets because in practice it is impossible to exactly correlate +// nonequal-but-equivalent set elements because they have no identity separate +// from their value. +// +// This must be used _only_ for comparing values for equivalence within the +// SDK planning code. It is only meaningful to compare the "prior state" +// provided by Terraform Core with the "planned new state" produced by the +// legacy SDK code via shims. In particular it is not valid to use this +// function with their the config value or the "proposed new state" value +// because they contain only the subset of data that Terraform Core itself is +// able to determine. +func ValuesSDKEquivalent(a, b cty.Value) bool { + if a == cty.NilVal || b == cty.NilVal { + // We don't generally expect nils to appear, but we'll allow them + // for robustness since the data structures produced by legacy SDK code + // can sometimes be non-ideal. + return a == b // equivalent if they are _both_ nil + } + if a.RawEquals(b) { + // Easy case. We use RawEquals because we want two unknowns to be + // considered equal here, whereas "Equals" would return unknown. + return true + } + if !a.IsKnown() || !b.IsKnown() { + // Two unknown values are equivalent regardless of type. A known is + // never equivalent to an unknown. + return a.IsKnown() == b.IsKnown() + } + if aZero, bZero := valuesSDKEquivalentIsNullOrZero(a), valuesSDKEquivalentIsNullOrZero(b); aZero || bZero { + // Two null/zero values are equivalent regardless of type. A non-zero is + // never equivalent to a zero. + return aZero == bZero + } + + // If we get down here then we are guaranteed that both a and b are known, + // non-null values. + + aTy := a.Type() + bTy := b.Type() + switch { + case aTy.IsSetType() && bTy.IsSetType(): + return valuesSDKEquivalentSets(a, b) + case aTy.IsListType() && bTy.IsListType(): + return valuesSDKEquivalentSequences(a, b) + case aTy.IsTupleType() && bTy.IsTupleType(): + return valuesSDKEquivalentSequences(a, b) + case aTy.IsMapType() && bTy.IsMapType(): + return valuesSDKEquivalentMappings(a, b) + case aTy.IsObjectType() && bTy.IsObjectType(): + return valuesSDKEquivalentMappings(a, b) + case aTy == cty.Number && bTy == cty.Number: + return valuesSDKEquivalentNumbers(a, b) + default: + // We've now covered all the interesting cases, so anything that falls + // down here cannot be equivalent. + return false + } +} + +// valuesSDKEquivalentIsNullOrZero returns true if the given value is either +// null or is the "zero value" (in the SDK/Go sense) for its type. +func valuesSDKEquivalentIsNullOrZero(v cty.Value) bool { + if v == cty.NilVal { + return true + } + + ty := v.Type() + switch { + case !v.IsKnown(): + return false + case v.IsNull(): + return true + + // After this point, v is always known and non-null + case ty.IsListType() || ty.IsSetType() || ty.IsMapType() || ty.IsObjectType() || ty.IsTupleType(): + return v.LengthInt() == 0 + case ty == cty.String: + return v.RawEquals(cty.StringVal("")) + case ty == cty.Number: + return v.RawEquals(cty.Zero) + case ty == cty.Bool: + return v.RawEquals(cty.False) + default: + // The above is exhaustive, but for robustness we'll consider anything + // else to _not_ be zero unless it is null. + return false + } +} + +// valuesSDKEquivalentSets returns true only if each of the elements in a can +// be correlated with at least one equivalent element in b and vice-versa. +// This is a fuzzy operation that prefers to signal non-equivalence if it cannot +// be certain that all elements are accounted for. +func valuesSDKEquivalentSets(a, b cty.Value) bool { + if aLen, bLen := a.LengthInt(), b.LengthInt(); aLen != bLen { + return false + } + + // Our methodology here is a little tricky, to deal with the fact that + // it's impossible to directly correlate two non-equal set elements because + // they don't have identities separate from their values. + // The approach is to count the number of equivalent elements each element + // of a has in b and vice-versa, and then return true only if each element + // in both sets has at least one equivalent. + as := a.AsValueSlice() + bs := b.AsValueSlice() + aeqs := make([]bool, len(as)) + beqs := make([]bool, len(bs)) + for ai, av := range as { + for bi, bv := range bs { + if ValuesSDKEquivalent(av, bv) { + aeqs[ai] = true + beqs[bi] = true + } + } + } + + for _, eq := range aeqs { + if !eq { + return false + } + } + for _, eq := range beqs { + if !eq { + return false + } + } + return true +} + +// valuesSDKEquivalentSequences decides equivalence for two sequence values +// (lists or tuples). +func valuesSDKEquivalentSequences(a, b cty.Value) bool { + as := a.AsValueSlice() + bs := b.AsValueSlice() + if len(as) != len(bs) { + return false + } + + for i := range as { + if !ValuesSDKEquivalent(as[i], bs[i]) { + return false + } + } + return true +} + +// valuesSDKEquivalentMappings decides equivalence for two mapping values +// (maps or objects). +func valuesSDKEquivalentMappings(a, b cty.Value) bool { + as := a.AsValueMap() + bs := b.AsValueMap() + if len(as) != len(bs) { + return false + } + + for k, av := range as { + bv, ok := bs[k] + if !ok { + return false + } + if !ValuesSDKEquivalent(av, bv) { + return false + } + } + return true +} + +// valuesSDKEquivalentNumbers decides equivalence for two number values based +// on the fact that the SDK uses int and float64 representations while +// cty (and thus Terraform Core) uses big.Float, and so we expect to lose +// precision in the round-trip. +// +// This does _not_ attempt to allow for an epsilon difference that may be +// caused by accumulated innacuracy in a float calculation, under the +// expectation that providers generally do not actually do compuations on +// floats and instead just pass string representations of them on verbatim +// to remote APIs. A remote API _itself_ may introduce inaccuracy, but that's +// a problem for the provider itself to deal with, based on its knowledge of +// the remote system, e.g. using DiffSuppressFunc. +func valuesSDKEquivalentNumbers(a, b cty.Value) bool { + if a.RawEquals(b) { + return true // easy + } + + af := a.AsBigFloat() + bf := b.AsBigFloat() + + if af.IsInt() != bf.IsInt() { + return false + } + if af.IsInt() && bf.IsInt() { + return false // a.RawEquals(b) test above is good enough for integers + } + + // The SDK supports only int and float64, so if it's not an integer + // we know that only a float64-level of precision can possibly be + // significant. + af64, _ := af.Float64() + bf64, _ := bf.Float64() + return af64 == bf64 +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/context.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/context.go new file mode 100644 index 00000000..0fe8002a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/context.go @@ -0,0 +1,78 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package logging + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-log/tfsdklog" + helperlogging "github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging" + testing "github.com/mitchellh/go-testing-interface" +) + +// InitContext creates SDK logger contexts when the provider is running in +// "production" (not under acceptance testing). The incoming context will +// already have the root SDK logger and root provider logger setup from +// terraform-plugin-go tf5server RPC handlers. +func InitContext(ctx context.Context) context.Context { + ctx = tfsdklog.NewSubsystem(ctx, SubsystemHelperSchema, + // All calls are through the HelperSchema* helper functions + tfsdklog.WithAdditionalLocationOffset(1), + tfsdklog.WithLevelFromEnv(EnvTfLogSdkHelperSchema), + // Propagate tf_req_id, tf_rpc, etc. fields + tfsdklog.WithRootFields(), + ) + + return ctx +} + +// InitTestContext registers the terraform-plugin-log/tfsdklog test sink, +// configures the standard library log package, and creates SDK logger +// contexts. The incoming context is expected to be devoid of logging setup. +// +// The standard library log package handling is important as provider code +// under test may be using that package or another logging library outside of +// terraform-plugin-log. +func InitTestContext(ctx context.Context, t testing.T) context.Context { + helperlogging.SetOutput(t) + + ctx = tfsdklog.RegisterTestSink(ctx, t) + ctx = tfsdklog.NewRootSDKLogger(ctx, tfsdklog.WithLevelFromEnv(EnvTfLogSdk)) + ctx = tfsdklog.NewSubsystem(ctx, SubsystemHelperResource, + // All calls are through the HelperResource* helper functions + tfsdklog.WithAdditionalLocationOffset(1), + tfsdklog.WithLevelFromEnv(EnvTfLogSdkHelperResource), + ) + ctx = TestNameContext(ctx, t.Name()) + + return ctx +} + +// TestNameContext adds the current test name to loggers. +func TestNameContext(ctx context.Context, testName string) context.Context { + ctx = tfsdklog.SubsystemSetField(ctx, SubsystemHelperResource, KeyTestName, testName) + + return ctx +} + +// TestStepNumberContext adds the current test step number to loggers. +func TestStepNumberContext(ctx context.Context, stepNumber int) context.Context { + ctx = tfsdklog.SubsystemSetField(ctx, SubsystemHelperResource, KeyTestStepNumber, stepNumber) + + return ctx +} + +// TestTerraformPathContext adds the current test Terraform CLI path to loggers. +func TestTerraformPathContext(ctx context.Context, terraformPath string) context.Context { + ctx = tfsdklog.SubsystemSetField(ctx, SubsystemHelperResource, KeyTestTerraformPath, terraformPath) + + return ctx +} + +// TestWorkingDirectoryContext adds the current test working directory to loggers. +func TestWorkingDirectoryContext(ctx context.Context, workingDirectory string) context.Context { + ctx = tfsdklog.SubsystemSetField(ctx, SubsystemHelperResource, KeyTestWorkingDirectory, workingDirectory) + + return ctx +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/environment_variables.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/environment_variables.go new file mode 100644 index 00000000..2ffc73ee --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/environment_variables.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package logging + +// Environment variables. +const ( + // EnvTfLogSdk is an environment variable that sets the logging level of + // the root SDK logger, while the provider is under test. In "production" + // usage, this environment variable is handled by terraform-plugin-go. + // + // Terraform CLI's logging must be explicitly turned on before this + // environment varable can be used to reduce the SDK logging levels. It + // cannot be used to show only SDK logging unless all other logging levels + // are turned off. + EnvTfLogSdk = "TF_LOG_SDK" + + // EnvTfLogSdkHelperResource is an environment variable that sets the logging + // level of SDK helper/resource loggers. Infers root SDK logging level, if + // unset. + EnvTfLogSdkHelperResource = "TF_LOG_SDK_HELPER_RESOURCE" + + // EnvTfLogSdkHelperSchema is an environment variable that sets the logging + // level of SDK helper/schema loggers. Infers root SDK logging level, if + // unset. + EnvTfLogSdkHelperSchema = "TF_LOG_SDK_HELPER_SCHEMA" +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/helper_resource.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/helper_resource.go new file mode 100644 index 00000000..1b1459f2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/helper_resource.go @@ -0,0 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package logging + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-log/tfsdklog" +) + +const ( + // SubsystemHelperResource is the tfsdklog subsystem name for helper/resource. + SubsystemHelperResource = "helper_resource" +) + +// HelperResourceTrace emits a helper/resource subsystem log at TRACE level. +func HelperResourceTrace(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemTrace(ctx, SubsystemHelperResource, msg, additionalFields...) +} + +// HelperResourceDebug emits a helper/resource subsystem log at DEBUG level. +func HelperResourceDebug(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemDebug(ctx, SubsystemHelperResource, msg, additionalFields...) +} + +// HelperResourceWarn emits a helper/resource subsystem log at WARN level. +func HelperResourceWarn(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemWarn(ctx, SubsystemHelperResource, msg, additionalFields...) +} + +// HelperResourceError emits a helper/resource subsystem log at ERROR level. +func HelperResourceError(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemError(ctx, SubsystemHelperResource, msg, additionalFields...) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/helper_schema.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/helper_schema.go new file mode 100644 index 00000000..0ecf6bf2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/helper_schema.go @@ -0,0 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package logging + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-log/tfsdklog" +) + +const ( + // SubsystemHelperSchema is the tfsdklog subsystem name for helper/schema. + SubsystemHelperSchema = "helper_schema" +) + +// HelperSchemaDebug emits a helper/schema subsystem log at DEBUG level. +func HelperSchemaDebug(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemDebug(ctx, SubsystemHelperSchema, msg, additionalFields...) +} + +// HelperSchemaError emits a helper/schema subsystem log at ERROR level. +func HelperSchemaError(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemError(ctx, SubsystemHelperSchema, msg, additionalFields...) +} + +// HelperSchemaTrace emits a helper/schema subsystem log at TRACE level. +func HelperSchemaTrace(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemTrace(ctx, SubsystemHelperSchema, msg, additionalFields...) +} + +// HelperSchemaWarn emits a helper/schema subsystem log at WARN level. +func HelperSchemaWarn(ctx context.Context, msg string, additionalFields ...map[string]interface{}) { + tfsdklog.SubsystemWarn(ctx, SubsystemHelperSchema, msg, additionalFields...) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/keys.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/keys.go new file mode 100644 index 00000000..983fde43 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/logging/keys.go @@ -0,0 +1,63 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package logging + +// Structured logging keys. +// +// Practitioners or tooling reading logs may be depending on these keys, so be +// conscious of that when changing them. +// +// Refer to the terraform-plugin-go logging keys as well, which should be +// equivalent to these when possible. +const ( + // Attribute path representation, which is typically in flatmap form such + // as parent.0.child in this project. + KeyAttributePath = "tf_attribute_path" + + // The type of data source being operated on, such as "archive_file" + KeyDataSourceType = "tf_data_source_type" + + // Underlying Go error string when logging an error. + KeyError = "error" + + // The full address of the provider, such as + // registry.terraform.io/hashicorp/random + KeyProviderAddress = "tf_provider_addr" + + // The type of resource being operated on, such as "random_pet" + KeyResourceType = "tf_resource_type" + + // The name of the test being executed. + KeyTestName = "test_name" + + // The TestStep number of the test being executed. Starts at 1. + KeyTestStepNumber = "test_step_number" + + // Terraform configuration used during acceptance testing Terraform operations. + KeyTestTerraformConfiguration = "test_terraform_configuration" + + // The Terraform CLI logging level (TF_LOG) used for an acceptance test. + KeyTestTerraformLogLevel = "test_terraform_log_level" + + // The Terraform CLI logging level (TF_LOG_CORE) used for an acceptance test. + KeyTestTerraformLogCoreLevel = "test_terraform_log_core_level" + + // The Terraform CLI logging level (TF_LOG_PROVIDER) used for an acceptance test. + KeyTestTerraformLogProviderLevel = "test_terraform_log_provider_level" + + // The path to the Terraform CLI logging file used for an acceptance test. + // + // This should match where the rest of the acceptance test logs are going + // already, but is provided for troubleshooting in case it does not. + KeyTestTerraformLogPath = "test_terraform_log_path" + + // The path to the Terraform CLI used for an acceptance test. + KeyTestTerraformPath = "test_terraform_path" + + // Terraform plan output generated during a TestStep. + KeyTestTerraformPlan = "test_terraform_plan" + + // The working directory of the acceptance test. + KeyTestWorkingDirectory = "test_working_directory" +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/config.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/config.go new file mode 100644 index 00000000..b63a55e4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/config.go @@ -0,0 +1,96 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugintest + +import ( + "context" + "fmt" + "os" + "strings" + + "github.com/hashicorp/go-version" + install "github.com/hashicorp/hc-install" + "github.com/hashicorp/hc-install/checkpoint" + "github.com/hashicorp/hc-install/fs" + "github.com/hashicorp/hc-install/product" + "github.com/hashicorp/hc-install/releases" + "github.com/hashicorp/hc-install/src" + + "github.com/hashicorp/terraform-plugin-testing/internal/logging" +) + +// Config is used to configure the test helper. In most normal test programs +// the configuration is discovered automatically by an Init* function using +// DiscoverConfig, but this is exposed so that more complex scenarios can be +// implemented by direct configuration. +type Config struct { + SourceDir string + TerraformExec string + execTempDir string + PreviousPluginExec string +} + +// DiscoverConfig uses environment variables and other means to automatically +// discover a reasonable test helper configuration. +func DiscoverConfig(ctx context.Context, sourceDir string) (*Config, error) { + tfVersion := strings.TrimPrefix(os.Getenv(EnvTfAccTerraformVersion), "v") + tfPath := os.Getenv(EnvTfAccTerraformPath) + + tempDir := os.Getenv(EnvTfAccTempDir) + tfDir, err := os.MkdirTemp(tempDir, "plugintest-terraform") + if err != nil { + return nil, fmt.Errorf("failed to create temp dir: %w", err) + } + + var sources []src.Source + switch { + case tfPath != "": + logging.HelperResourceTrace(ctx, fmt.Sprintf("Adding potential Terraform CLI source of exact path: %s", tfPath)) + + sources = append(sources, &fs.AnyVersion{ + ExactBinPath: tfPath, + }) + case tfVersion != "": + tfVersion, err := version.NewVersion(tfVersion) + + if err != nil { + return nil, fmt.Errorf("invalid Terraform version: %w", err) + } + + logging.HelperResourceTrace(ctx, fmt.Sprintf("Adding potential Terraform CLI source of releases.hashicorp.com exact version %q for installation in: %s", tfVersion, tfDir)) + + sources = append(sources, &releases.ExactVersion{ + InstallDir: tfDir, + Product: product.Terraform, + Version: tfVersion, + }) + default: + logging.HelperResourceTrace(ctx, "Adding potential Terraform CLI source of local filesystem PATH lookup") + logging.HelperResourceTrace(ctx, fmt.Sprintf("Adding potential Terraform CLI source of checkpoint.hashicorp.com latest version for installation in: %s", tfDir)) + + sources = append(sources, &fs.AnyVersion{ + Product: &product.Terraform, + }) + sources = append(sources, &checkpoint.LatestVersion{ + InstallDir: tfDir, + Product: product.Terraform, + }) + } + + installer := install.NewInstaller() + tfExec, err := installer.Ensure(context.Background(), sources) + if err != nil { + return nil, fmt.Errorf("failed to find or install Terraform CLI from %+v: %w", sources, err) + } + + ctx = logging.TestTerraformPathContext(ctx, tfExec) + + logging.HelperResourceDebug(ctx, "Found Terraform CLI") + + return &Config{ + SourceDir: sourceDir, + TerraformExec: tfExec, + execTempDir: tfDir, + }, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/doc.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/doc.go new file mode 100644 index 00000000..1b34a0b2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/doc.go @@ -0,0 +1,10 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package plugintest contains utilities to help with writing tests for +// Terraform plugins. +// +// This is not a package for testing configurations or modules written in the +// Terraform language. It is for testing the plugins that allow Terraform to +// manage various cloud services and other APIs. +package plugintest diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/environment_variables.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/environment_variables.go new file mode 100644 index 00000000..361de8f1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/environment_variables.go @@ -0,0 +1,119 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugintest + +// Environment variables +const ( + // Environment variable with acceptance testing temporary directory for + // testing files and Terraform CLI installation, if installation is + // required. By default, the operating system temporary directory is used. + // + // Setting TF_ACC_TERRAFORM_PATH does not override this value for Terraform + // CLI installation, if installation is required. + EnvTfAccTempDir = "TF_ACC_TEMP_DIR" + + // Environment variable with level to filter Terraform logs during + // acceptance testing. This value sets TF_LOG in a safe manner when + // executing Terraform CLI commands, which would otherwise interfere + // with the testing framework using TF_LOG to set the Go standard library + // log package level. + // + // This value takes precedence over TF_LOG_CORE, due to precedence rules + // in the Terraform core code, so it is not possible to set this to a level + // and also TF_LOG_CORE=OFF. Use TF_LOG_CORE and TF_LOG_PROVIDER in that + // case instead. + // + // If not set, but TF_ACC_LOG_PATH or TF_LOG_PATH_MASK is set, it defaults + // to TRACE. If Terraform CLI is version 0.14 or earlier, it will have no + // separate affect from the TF_ACC_LOG_PATH or TF_LOG_PATH_MASK behavior, + // as those earlier versions of Terraform are unreliable with the logging + // level being outside TRACE. + EnvTfAccLog = "TF_ACC_LOG" + + // Environment variable with path to save Terraform logs during acceptance + // testing. This value sets TF_LOG_PATH in a safe manner when executing + // Terraform CLI commands, which would otherwise be ignored since it could + // interfere with how the underlying execution is performed. + // + // If TF_LOG_PATH_MASK is set, it takes precedence over this value. + EnvTfAccLogPath = "TF_ACC_LOG_PATH" + + // Environment variable with level to filter Terraform core logs during + // acceptance testing. This value sets TF_LOG_CORE separate from + // TF_LOG_PROVIDER when calling Terraform. + // + // This value has no affect when TF_ACC_LOG is set (which sets Terraform's + // TF_LOG), due to precedence rules in the Terraform core code. Use + // TF_LOG_CORE and TF_LOG_PROVIDER in that case instead. + // + // If not set, defaults to TF_ACC_LOG behaviors. + EnvTfLogCore = "TF_LOG_CORE" + + // Environment variable with path containing the string %s, which is + // replaced with the test name, to save separate Terraform logs during + // acceptance testing. This value sets TF_LOG_PATH in a safe manner when + // executing Terraform CLI commands, which would otherwise be ignored since + // it could interfere with how the underlying execution is performed. + // + // Takes precedence over TF_ACC_LOG_PATH. + EnvTfLogPathMask = "TF_LOG_PATH_MASK" + + // Environment variable with level to filter Terraform provider logs during + // acceptance testing. This value sets TF_LOG_PROVIDER separate from + // TF_LOG_CORE. + // + // During testing, this only affects external providers whose logging goes + // through Terraform. The logging for the provider under test is controlled + // by the testing framework as it is running the provider code. Provider + // code using the Go standard library log package is controlled by TF_LOG + // for historical compatibility. + // + // This value takes precedence over TF_ACC_LOG for external provider logs, + // due to rules in the Terraform core code. + // + // If not set, defaults to TF_ACC_LOG behaviors. + EnvTfLogProvider = "TF_LOG_PROVIDER" + + // Environment variable with acceptance testing Terraform CLI version to + // download from releases.hashicorp.com, checksum verify, and install. The + // value can be any valid Terraform CLI version, such as 1.1.6, with or + // without a prepended v character. + // + // Setting this value takes precedence over using an available Terraform + // binary in the operation system PATH, or if not found, installing the + // latest version according to checkpoint.hashicorp.com. + // + // By default, the binary is installed in the operating system temporary + // directory, however that directory can be overridden with the + // TF_ACC_TEMP_DIR environment variable. + // + // If TF_ACC_TERRAFORM_PATH is also set, this installation method is + // only invoked when a binary does not exist at that path. No version + // checks are performed against an existing TF_ACC_TERRAFORM_PATH. + EnvTfAccTerraformVersion = "TF_ACC_TERRAFORM_VERSION" + + // Acceptance testing path to Terraform CLI binary. + // + // Setting this value takes precedence over using an available Terraform + // binary in the operation system PATH, or if not found, installing the + // latest version according to checkpoint.hashicorp.com. This value does + // not override TF_ACC_TEMP_DIR for Terraform CLI installation, if + // installation is required. + // + // If TF_ACC_TERRAFORM_VERSION is not set, the binary must exist and be + // executable, or an error will be returned. + // + // If TF_ACC_TERRAFORM_VERSION is also set, that Terraform CLI version + // will be installed if a binary is not found at the given path. No version + // checks are performed against an existing binary. + EnvTfAccTerraformPath = "TF_ACC_TERRAFORM_PATH" + + // EnvTfAccPersistWorkingDir environment variable enables persisting + // the working directory and the files generated during execution of + // TestStep(s). Default is disabled, in which case the working directory + // and the files it contains are deleted at the end of each acceptance + // test. Can be set to any value to persist the working directory and + // its contents, however "1" is conventional. + EnvTfAccPersistWorkingDir = "TF_ACC_PERSIST_WORKING_DIR" +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/guard.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/guard.go new file mode 100644 index 00000000..77f87398 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/guard.go @@ -0,0 +1,52 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugintest + +import ( + "fmt" +) + +// TestControl is an interface requiring a subset of *testing.T which is used +// by the test guards and helpers in this package. Most callers can simply +// pass their *testing.T value here, but the interface allows other +// implementations to potentially be provided instead, for example to allow +// meta-testing (testing of the test utilities themselves). +// +// This interface also describes the subset of normal test functionality the +// guards and helpers can perform: they can only create log lines, fail tests, +// and skip tests. All other test control is the responsibility of the main +// test code. +type TestControl interface { + Helper() + Log(args ...interface{}) + FailNow() + SkipNow() + Name() string +} + +// testingT wraps a TestControl to recover some of the convenience behaviors +// that would normally come from a real *testing.T, so we can keep TestControl +// small while still having these conveniences. This is an abstraction +// inversion, but accepted because it makes the public API more convenient +// without any considerable disadvantage. +type testingT struct { + TestControl +} + +func (t testingT) Logf(f string, args ...interface{}) { + t.Helper() + t.Log(fmt.Sprintf(f, args...)) +} + +func (t testingT) Fatalf(f string, args ...interface{}) { + t.Helper() + t.Log(fmt.Sprintf(f, args...)) + t.FailNow() +} + +func (t testingT) Skipf(f string, args ...interface{}) { + t.Helper() + t.Log(fmt.Sprintf(f, args...)) + t.SkipNow() +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/helper.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/helper.go new file mode 100644 index 00000000..3c9772cf --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/helper.go @@ -0,0 +1,322 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugintest + +import ( + "context" + "errors" + "fmt" + "os" + "strings" + + "github.com/hashicorp/go-version" + "github.com/hashicorp/terraform-exec/tfexec" + + "github.com/hashicorp/terraform-plugin-testing/internal/logging" +) + +// AutoInitProviderHelper is the main entrypoint for testing provider plugins +// using this package. It is intended to be called during TestMain to prepare +// for provider testing. +// +// AutoInitProviderHelper will discover the location of a current Terraform CLI +// executable to test against, detect whether a prior version of the plugin is +// available for upgrade tests, and then will return an object containing the +// results of that initialization which can then be stored in a global variable +// for use in other tests. +func AutoInitProviderHelper(ctx context.Context, sourceDir string) *Helper { + helper, err := AutoInitHelper(ctx, sourceDir) + if err != nil { + fmt.Fprintf(os.Stderr, "cannot run Terraform provider tests: %s\n", err) + os.Exit(1) + } + return helper +} + +// Helper is intended as a per-package singleton created in TestMain which +// other tests in a package can use to create Terraform execution contexts +type Helper struct { + baseDir string + + // sourceDir is the dir containing the provider source code, needed + // for tests that use fixture files. + sourceDir string + terraformExec string + terraformVer *version.Version + + // execTempDir is created during DiscoverConfig to store any downloaded + // binaries + execTempDir string +} + +// AutoInitHelper uses the auto-discovery behavior of DiscoverConfig to prepare +// a configuration and then calls InitHelper with it. This is a convenient +// way to get the standard init behavior based on environment variables, and +// callers should use this unless they have an unusual requirement that calls +// for constructing a config in a different way. +func AutoInitHelper(ctx context.Context, sourceDir string) (*Helper, error) { + config, err := DiscoverConfig(ctx, sourceDir) + if err != nil { + return nil, err + } + + return InitHelper(ctx, config) +} + +// InitHelper prepares a testing helper with the given configuration. +// +// For most callers it is sufficient to call AutoInitHelper instead, which +// will construct a configuration automatically based on certain environment +// variables. +// +// If this function returns an error then it may have left some temporary files +// behind in the system's temporary directory. There is currently no way to +// automatically clean those up. +func InitHelper(ctx context.Context, config *Config) (*Helper, error) { + tempDir := os.Getenv(EnvTfAccTempDir) + baseDir, err := os.MkdirTemp(tempDir, "plugintest") + if err != nil { + return nil, fmt.Errorf("failed to create temporary directory for test helper: %s", err) + } + + tf, err := tfexec.NewTerraform(baseDir, config.TerraformExec) + if err != nil { + return nil, fmt.Errorf("unable to create terraform-exec instance: %w", err) + } + + tfVersion, _, err := tf.Version(ctx, false) + + if err != nil { + return nil, fmt.Errorf("error calling terraform version command: %w", err) + } + + return &Helper{ + baseDir: baseDir, + sourceDir: config.SourceDir, + terraformExec: config.TerraformExec, + execTempDir: config.execTempDir, + terraformVer: tfVersion, + }, nil +} + +// Close cleans up temporary files and directories created to support this +// helper, returning an error if any of the cleanup fails. +// +// Call this before returning from TestMain to minimize the amount of detritus +// left behind in the filesystem after the tests complete. +func (h *Helper) Close() error { + if os.Getenv(EnvTfAccPersistWorkingDir) != "" { + return nil + } + + if h.execTempDir != "" { + err := os.RemoveAll(h.execTempDir) + if err != nil { + return err + } + } + + return os.RemoveAll(h.baseDir) +} + +// NewWorkingDir creates a new working directory for use in the implementation +// of a single test, returning a WorkingDir object representing that directory. +// +// If the working directory object is not itself closed by the time the test +// program exits, the Close method on the helper itself will attempt to +// delete it. +func (h *Helper) NewWorkingDir(ctx context.Context, t TestControl, wd string) (*WorkingDir, error) { + workingDir := h.baseDir + + if wd != "" { + workingDir = wd + h.baseDir = wd + } + + dir, err := os.MkdirTemp(workingDir, "work") + if err != nil { + return nil, err + } + + ctx = logging.TestWorkingDirectoryContext(ctx, dir) + + // symlink the provider source files into the config directory + // e.g. testdata + logging.HelperResourceTrace(ctx, "Symlinking source directories to work directory") + err = symlinkDirectoriesOnly(h.sourceDir, dir) + if err != nil { + return nil, err + } + + tf, err := tfexec.NewTerraform(dir, h.terraformExec) + + if err != nil { + return nil, fmt.Errorf("unable to create terraform-exec instance: %w", err) + } + + err = tf.SetDisablePluginTLS(true) + + if err != nil { + return nil, fmt.Errorf("unable to disable terraform-exec plugin TLS: %w", err) + } + + err = tf.SetSkipProviderVerify(true) // Only required for Terraform CLI 0.12.x + + var mismatch *tfexec.ErrVersionMismatch + if err != nil && !errors.As(err, &mismatch) { + return nil, fmt.Errorf("unable to disable terraform-exec provider verification: %w", err) + } + + tfAccLog := os.Getenv(EnvTfAccLog) + tfAccLogPath := os.Getenv(EnvTfAccLogPath) + tfLogCore := os.Getenv(EnvTfLogCore) + tfLogPathMask := os.Getenv(EnvTfLogPathMask) + tfLogProvider := os.Getenv(EnvTfLogProvider) + + if tfAccLog != "" && tfLogCore != "" { + err = fmt.Errorf( + "Invalid environment variable configuration. Cannot set both TF_ACC_LOG and TF_LOG_CORE. " + + "Use TF_LOG_CORE and TF_LOG_PROVIDER to separately control the Terraform CLI logging subsystems. " + + "To control the Go standard library log package for the provider under test, use TF_LOG.", + ) + logging.HelperResourceError(ctx, err.Error()) + return nil, err + } + + if tfAccLog != "" { + logging.HelperResourceTrace( + ctx, + fmt.Sprintf("Setting terraform-exec log level via %s environment variable, if Terraform CLI is version 0.15 or later", EnvTfAccLog), + map[string]interface{}{logging.KeyTestTerraformLogLevel: tfAccLog}, + ) + + err := tf.SetLog(tfAccLog) + + if err != nil { + if !errors.As(err, new(*tfexec.ErrVersionMismatch)) { + logging.HelperResourceError( + ctx, + "Unable to set terraform-exec log level", + map[string]interface{}{logging.KeyError: err.Error()}, + ) + return nil, fmt.Errorf("unable to set terraform-exec log level (%s): %w", tfAccLog, err) + } + + logging.HelperResourceWarn( + ctx, + fmt.Sprintf("Unable to set terraform-exec log level via %s environment variable, as Terraform CLI is version 0.14 or earlier. It will default to TRACE.", EnvTfAccLog), + map[string]interface{}{logging.KeyTestTerraformLogLevel: "TRACE"}, + ) + } + } + + if tfLogCore != "" { + logging.HelperResourceTrace( + ctx, + fmt.Sprintf("Setting terraform-exec core log level via %s environment variable, if Terraform CLI is version 0.15 or later", EnvTfLogCore), + map[string]interface{}{ + logging.KeyTestTerraformLogCoreLevel: tfLogCore, + }, + ) + + err := tf.SetLogCore(tfLogCore) + + if err != nil { + logging.HelperResourceError( + ctx, + "Unable to set terraform-exec core log level", + map[string]interface{}{logging.KeyError: err.Error()}, + ) + return nil, fmt.Errorf("unable to set terraform-exec core log level (%s): %w", tfLogCore, err) + } + } + + if tfLogProvider != "" { + logging.HelperResourceTrace( + ctx, + fmt.Sprintf("Setting terraform-exec provider log level via %s environment variable, if Terraform CLI is version 0.15 or later", EnvTfLogProvider), + map[string]interface{}{ + logging.KeyTestTerraformLogCoreLevel: tfLogProvider, + }, + ) + + err := tf.SetLogProvider(tfLogProvider) + + if err != nil { + logging.HelperResourceError( + ctx, + "Unable to set terraform-exec provider log level", + map[string]interface{}{logging.KeyError: err.Error()}, + ) + return nil, fmt.Errorf("unable to set terraform-exec provider log level (%s): %w", tfLogProvider, err) + } + } + + var logPath, logPathEnvVar string + + if tfAccLogPath != "" { + logPath = tfAccLogPath + logPathEnvVar = EnvTfAccLogPath + } + + // Similar to helper/logging.LogOutput() and + // terraform-plugin-log/tfsdklog.RegisterTestSink(), the TF_LOG_PATH_MASK + // environment variable should take precedence over TF_ACC_LOG_PATH. + if tfLogPathMask != "" { + // Escape special characters which may appear if we have subtests + testName := strings.Replace(t.Name(), "/", "__", -1) + logPath = fmt.Sprintf(tfLogPathMask, testName) + logPathEnvVar = EnvTfLogPathMask + } + + if logPath != "" { + logging.HelperResourceTrace( + ctx, + fmt.Sprintf("Setting terraform-exec log path via %s environment variable", logPathEnvVar), + map[string]interface{}{logging.KeyTestTerraformLogPath: logPath}, + ) + + if err := tf.SetLogPath(logPath); err != nil { + return nil, fmt.Errorf("unable to set terraform-exec log path (%s): %w", logPath, err) + } + } + + return &WorkingDir{ + h: h, + tf: tf, + baseDir: dir, + terraformExec: h.terraformExec, + }, nil +} + +// RequireNewWorkingDir is a variant of NewWorkingDir that takes a TestControl +// object and will immediately fail the running test if the creation of the +// working directory fails. +func (h *Helper) RequireNewWorkingDir(ctx context.Context, t TestControl, workingDir string) *WorkingDir { + t.Helper() + + wd, err := h.NewWorkingDir(ctx, t, workingDir) + if err != nil { + t := testingT{t} + t.Fatalf("failed to create new working directory: %s", err) + return nil + } + return wd +} + +// WorkingDirectory returns the working directory being used when running tests. +func (h *Helper) WorkingDirectory() string { + return h.baseDir +} + +// TerraformExecPath returns the location of the Terraform CLI executable that +// should be used when running tests. +func (h *Helper) TerraformExecPath() string { + return h.terraformExec +} + +// TerraformVersion returns the Terraform CLI version being used when running tests. +func (h *Helper) TerraformVersion() *version.Version { + return h.terraformVer +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/util.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/util.go new file mode 100644 index 00000000..be187a01 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/util.go @@ -0,0 +1,186 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugintest + +import ( + "fmt" + "io" + "io/fs" + "os" + "path" + "path/filepath" + "strings" + "testing" +) + +func symlinkFile(src string, dest string) error { + err := os.Symlink(src, dest) + + if err != nil { + return fmt.Errorf("unable to symlink %q to %q: %w", src, dest, err) + } + + srcInfo, err := os.Stat(src) + + if err != nil { + return fmt.Errorf("unable to stat %q: %w", src, err) + } + + err = os.Chmod(dest, srcInfo.Mode()) + + if err != nil { + return fmt.Errorf("unable to set %q permissions: %w", dest, err) + } + + return nil +} + +// symlinkDirectoriesOnly finds only the first-level child directories in srcDir +// and symlinks them into destDir. +// Unlike symlinkDir, this is done non-recursively in order to limit the number +// of file descriptors used. +func symlinkDirectoriesOnly(srcDir string, destDir string) error { + srcInfo, err := os.Stat(srcDir) + if err != nil { + return fmt.Errorf("unable to stat source directory %q: %w", srcDir, err) + } + + err = os.MkdirAll(destDir, srcInfo.Mode()) + if err != nil { + return fmt.Errorf("unable to make destination directory %q: %w", destDir, err) + } + + dirEntries, err := os.ReadDir(srcDir) + + if err != nil { + return fmt.Errorf("unable to read source directory %q: %w", srcDir, err) + } + + for _, dirEntry := range dirEntries { + if !dirEntry.IsDir() { + continue + } + + srcPath := filepath.Join(srcDir, dirEntry.Name()) + destPath := filepath.Join(destDir, dirEntry.Name()) + err := symlinkFile(srcPath, destPath) + + if err != nil { + return fmt.Errorf("unable to symlink directory %q to %q: %w", srcPath, destPath, err) + } + } + + return nil +} + +// CopyFile copies a single file from src to dest. +func CopyFile(src, dest string) error { + var srcFileInfo os.FileInfo + + srcFile, err := os.Open(src) + if err != nil { + return fmt.Errorf("unable to open file: %w", err) + } + defer srcFile.Close() + + destFile, err := os.Create(dest) + if err != nil { + return fmt.Errorf("unable to create file: %w", err) + } + defer destFile.Close() + + if _, err = io.Copy(destFile, srcFile); err != nil { + return fmt.Errorf("unable to copy: %w", err) + } + + if srcFileInfo, err = os.Stat(src); err != nil { + return fmt.Errorf("unable to stat: %w", err) + } + + return os.Chmod(dest, srcFileInfo.Mode()) +} + +// CopyDir recursively copies directories and files +// from src to dest. +func CopyDir(src, dest, baseDirName string) error { + srcInfo, err := os.Stat(src) + if err != nil { + return fmt.Errorf("unable to stat: %w", err) + } + + if err = os.MkdirAll(dest, srcInfo.Mode()); err != nil { + return fmt.Errorf("unable to create dir: %w", err) + } + + dirEntries, err := os.ReadDir(src) + if err != nil { + return fmt.Errorf("unable to read dir: %w", err) + } + + for _, dirEntry := range dirEntries { + srcFilepath := path.Join(src, dirEntry.Name()) + destFilepath := path.Join(dest, dirEntry.Name()) + + if !strings.Contains(srcFilepath, baseDirName) { + continue + } + + fi, err := dirEntry.Info() + + if err != nil { + return fmt.Errorf("unable to get dir entry info: %w", err) + } + + if dirEntry.IsDir() || fi.Mode()&fs.ModeSymlink == fs.ModeSymlink { + if err = CopyDir(srcFilepath, destFilepath, baseDirName); err != nil { + return fmt.Errorf("unable to copy directory: %w", err) + } + } else { + if err = CopyFile(srcFilepath, destFilepath); err != nil { + return fmt.Errorf("unable to copy file: %w", err) + } + } + } + + return nil +} + +// TestExpectTFatal provides a wrapper for logic which should call +// (*testing.T).Fatal() or (*testing.T).Fatalf(). +// +// Since we do not want the wrapping test to fail when an expected test error +// occurs, it is required that the testLogic passed in uses +// github.com/mitchellh/go-testing-interface.RuntimeT instead of the real +// *testing.T. +// +// If Fatal() or Fatalf() is not called in the logic, the real (*testing.T).Fatal() will +// be called to fail the test. +func TestExpectTFatal(t *testing.T, testLogic func()) { + t.Helper() + + var recoverIface interface{} + + func() { + defer func() { + recoverIface = recover() + }() + + testLogic() + }() + + if recoverIface == nil { + t.Fatalf("expected t.Fatal(), got none") + } + + recoverStr, ok := recoverIface.(string) + + if !ok { + t.Fatalf("expected string from recover(), got: %v (%T)", recoverIface, recoverIface) + } + + // this string is hardcoded in github.com/mitchellh/go-testing-interface + if !strings.HasPrefix(recoverStr, "testing.T failed, see logs for output") { + t.Fatalf("expected t.Fatal(), got: %s", recoverStr) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/working_dir.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/working_dir.go new file mode 100644 index 00000000..2c8888d7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/plugintest/working_dir.go @@ -0,0 +1,395 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugintest + +import ( + "context" + "fmt" + "os" + "path/filepath" + + "github.com/hashicorp/terraform-exec/tfexec" + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/internal/logging" + "github.com/hashicorp/terraform-plugin-testing/internal/teststep" +) + +const ( + ConfigFileName = "terraform_plugin_test.tf" + PlanFileName = "tfplan" +) + +// WorkingDir represents a distinct working directory that can be used for +// running tests. Each test should construct its own WorkingDir by calling +// NewWorkingDir or RequireNewWorkingDir on its package's singleton +// plugintest.Helper. +type WorkingDir struct { + h *Helper + + // baseDir is the root of the working directory tree + baseDir string + + // configFilename is the full filename where the latest configuration + // was stored; empty until SetConfig is called. + configFilename string + + // tf is the instance of tfexec.Terraform used for running Terraform commands + tf *tfexec.Terraform + + // terraformExec is a path to a terraform binary, inherited from Helper + terraformExec string + + // reattachInfo stores the gRPC socket info required for Terraform's + // plugin reattach functionality + reattachInfo tfexec.ReattachInfo +} + +// BaseDir returns the path to the root of the working directory tree. +func (wd *WorkingDir) BaseDir() string { + return wd.baseDir +} + +// Close deletes the directories and files created to represent the receiving +// working directory. After this method is called, the working directory object +// is invalid and may no longer be used. +func (wd *WorkingDir) Close() error { + if os.Getenv(EnvTfAccPersistWorkingDir) != "" { + return nil + } + + return os.RemoveAll(wd.baseDir) +} + +func (wd *WorkingDir) SetReattachInfo(ctx context.Context, reattachInfo tfexec.ReattachInfo) { + logging.HelperResourceTrace(ctx, "Setting Terraform CLI reattach configuration", map[string]interface{}{"tf_reattach_config": reattachInfo}) + wd.reattachInfo = reattachInfo +} + +func (wd *WorkingDir) UnsetReattachInfo() { + wd.reattachInfo = nil +} + +// GetHelper returns the Helper set on the WorkingDir. +func (wd *WorkingDir) GetHelper() *Helper { + return wd.h +} + +// SetConfig sets a new configuration for the working directory. +// +// This must be called at least once before any call to Init, Plan, Apply, or +// Destroy to establish the configuration. Any previously-set configuration is +// discarded and any saved plan is cleared. +func (wd *WorkingDir) SetConfig(ctx context.Context, cfg teststep.Config, vars config.Variables) error { + // Remove old config and variables files first + d, err := os.Open(wd.baseDir) + + if err != nil { + return err + } + + defer d.Close() + + fi, err := d.Readdir(-1) + + if err != nil { + return err + } + + for _, file := range fi { + if file.Mode().IsRegular() { + if filepath.Ext(file.Name()) == ".tf" || filepath.Ext(file.Name()) == ".json" { + err = os.Remove(filepath.Join(d.Name(), file.Name())) + + if err != nil && !os.IsNotExist(err) { + return err + } + } + } + } + + logging.HelperResourceTrace(ctx, "Setting Terraform configuration", map[string]any{logging.KeyTestTerraformConfiguration: cfg}) + + outFilename := filepath.Join(wd.baseDir, ConfigFileName) + + // This file has to be written otherwise wd.Init() will return an error. + err = os.WriteFile(outFilename, nil, 0700) + + if err != nil { + return err + } + + // wd.configFilename must be set otherwise wd.Init() will return an error. + wd.configFilename = outFilename + + // Write configuration + if cfg != nil { + err = cfg.Write(ctx, wd.baseDir) + + if err != nil { + return err + } + } + + //Write configuration variables + err = vars.Write(wd.baseDir) + + if err != nil { + return err + } + + // Changing configuration invalidates any saved plan. + err = wd.ClearPlan(ctx) + + if err != nil { + return err + } + + return nil +} + +// ClearState deletes any Terraform state present in the working directory. +// +// Any remote objects tracked by the state are not destroyed first, so this +// will leave them dangling in the remote system. +func (wd *WorkingDir) ClearState(ctx context.Context) error { + logging.HelperResourceTrace(ctx, "Clearing Terraform state") + + err := os.Remove(filepath.Join(wd.baseDir, "terraform.tfstate")) + + if os.IsNotExist(err) { + logging.HelperResourceTrace(ctx, "No Terraform state to clear") + return nil + } + + if err != nil { + return err + } + + logging.HelperResourceTrace(ctx, "Cleared Terraform state") + + return nil +} + +// ClearPlan deletes any saved plan present in the working directory. +func (wd *WorkingDir) ClearPlan(ctx context.Context) error { + logging.HelperResourceTrace(ctx, "Clearing Terraform plan") + + err := os.Remove(wd.planFilename()) + + if os.IsNotExist(err) { + logging.HelperResourceTrace(ctx, "No Terraform plan to clear") + return nil + } + + if err != nil { + return err + } + + logging.HelperResourceTrace(ctx, "Cleared Terraform plan") + + return nil +} + +var errWorkingDirSetConfigNotCalled = fmt.Errorf("must call SetConfig before Init") + +// Init runs "terraform init" for the given working directory, forcing Terraform +// to use the current version of the plugin under test. +func (wd *WorkingDir) Init(ctx context.Context) error { + if wd.configFilename == "" { + return errWorkingDirSetConfigNotCalled + } + if _, err := os.Stat(wd.configFilename); err != nil { + return errWorkingDirSetConfigNotCalled + } + + logging.HelperResourceTrace(ctx, "Calling Terraform CLI init command") + + // -upgrade=true is required for per-TestStep provider version changes + // e.g. TestTest_TestStep_ExternalProviders_DifferentVersions + err := wd.tf.Init(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.Upgrade(true)) + + logging.HelperResourceTrace(ctx, "Called Terraform CLI init command") + + return err +} + +func (wd *WorkingDir) planFilename() string { + return filepath.Join(wd.baseDir, PlanFileName) +} + +// CreatePlan runs "terraform plan" to create a saved plan file, which if successful +// will then be used for the next call to Apply. +func (wd *WorkingDir) CreatePlan(ctx context.Context, opts ...tfexec.PlanOption) error { + logging.HelperResourceTrace(ctx, "Calling Terraform CLI plan command") + + opts = append(opts, tfexec.Reattach(wd.reattachInfo)) + opts = append(opts, tfexec.Out(PlanFileName)) + + hasChanges, err := wd.tf.Plan(context.Background(), opts...) + + logging.HelperResourceTrace(ctx, "Called Terraform CLI plan command") + + if err != nil { + return err + } + + if !hasChanges { + logging.HelperResourceTrace(ctx, "Created plan with no changes") + + return nil + } + + stdout, err := wd.SavedPlanRawStdout(ctx) + + if err != nil { + return fmt.Errorf("error retrieving formatted plan output: %w", err) + } + + logging.HelperResourceTrace(ctx, "Created plan with changes", map[string]any{logging.KeyTestTerraformPlan: stdout}) + + return nil +} + +// Apply runs "terraform apply". If CreatePlan has previously completed +// successfully and the saved plan has not been cleared in the meantime then +// this will apply the saved plan. Otherwise, it will implicitly create a new +// plan and apply it. +func (wd *WorkingDir) Apply(ctx context.Context) error { + args := []tfexec.ApplyOption{tfexec.Reattach(wd.reattachInfo), tfexec.Refresh(false)} + if wd.HasSavedPlan() { + args = append(args, tfexec.DirOrPlan(PlanFileName)) + } + + logging.HelperResourceTrace(ctx, "Calling Terraform CLI apply command") + + err := wd.tf.Apply(context.Background(), args...) + + logging.HelperResourceTrace(ctx, "Called Terraform CLI apply command") + + return err +} + +// Destroy runs "terraform destroy". It does not consider or modify any saved +// plan, and is primarily for cleaning up at the end of a test run. +// +// If destroy fails then remote objects might still exist, and continue to +// exist after a particular test is concluded. +func (wd *WorkingDir) Destroy(ctx context.Context) error { + logging.HelperResourceTrace(ctx, "Calling Terraform CLI destroy command") + + err := wd.tf.Destroy(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.Refresh(false)) + + logging.HelperResourceTrace(ctx, "Called Terraform CLI destroy command") + + return err +} + +// HasSavedPlan returns true if there is a saved plan in the working directory. If +// so, a subsequent call to Apply will apply that saved plan. +func (wd *WorkingDir) HasSavedPlan() bool { + _, err := os.Stat(wd.planFilename()) + return err == nil +} + +// SavedPlan returns an object describing the current saved plan file, if any. +// +// If no plan is saved or if the plan file cannot be read, SavedPlan returns +// an error. +func (wd *WorkingDir) SavedPlan(ctx context.Context) (*tfjson.Plan, error) { + if !wd.HasSavedPlan() { + return nil, fmt.Errorf("there is no current saved plan") + } + + logging.HelperResourceTrace(ctx, "Calling Terraform CLI show command for JSON plan") + + plan, err := wd.tf.ShowPlanFile(context.Background(), wd.planFilename(), tfexec.Reattach(wd.reattachInfo), tfexec.JSONNumber(true)) + + logging.HelperResourceTrace(ctx, "Calling Terraform CLI show command for JSON plan") + + return plan, err +} + +// SavedPlanRawStdout returns a human readable stdout capture of the current saved plan file, if any. +// +// If no plan is saved or if the plan file cannot be read, SavedPlanRawStdout returns +// an error. +func (wd *WorkingDir) SavedPlanRawStdout(ctx context.Context) (string, error) { + if !wd.HasSavedPlan() { + return "", fmt.Errorf("there is no current saved plan") + } + + logging.HelperResourceTrace(ctx, "Calling Terraform CLI show command for stdout plan") + + stdout, err := wd.tf.ShowPlanFileRaw(context.Background(), wd.planFilename(), tfexec.Reattach(wd.reattachInfo)) + + logging.HelperResourceTrace(ctx, "Called Terraform CLI show command for stdout plan") + + if err != nil { + return "", err + } + + return stdout, nil +} + +// State returns an object describing the current state. +// + +// If the state cannot be read, State returns an error. +func (wd *WorkingDir) State(ctx context.Context) (*tfjson.State, error) { + logging.HelperResourceTrace(ctx, "Calling Terraform CLI show command for JSON state") + + state, err := wd.tf.Show(context.Background(), tfexec.Reattach(wd.reattachInfo)) + + logging.HelperResourceTrace(ctx, "Called Terraform CLI show command for JSON state") + + return state, err +} + +// Import runs terraform import +func (wd *WorkingDir) Import(ctx context.Context, resource, id string) error { + logging.HelperResourceTrace(ctx, "Calling Terraform CLI import command") + + err := wd.tf.Import(context.Background(), resource, id, tfexec.Config(wd.baseDir), tfexec.Reattach(wd.reattachInfo)) + + logging.HelperResourceTrace(ctx, "Called Terraform CLI import command") + + return err +} + +// Taint runs terraform taint +func (wd *WorkingDir) Taint(ctx context.Context, address string) error { + logging.HelperResourceTrace(ctx, "Calling Terraform CLI taint command") + + err := wd.tf.Taint(context.Background(), address) + + logging.HelperResourceTrace(ctx, "Called Terraform CLI taint command") + + return err +} + +// Refresh runs terraform refresh +func (wd *WorkingDir) Refresh(ctx context.Context) error { + logging.HelperResourceTrace(ctx, "Calling Terraform CLI refresh command") + + err := wd.tf.Refresh(context.Background(), tfexec.Reattach(wd.reattachInfo)) + + logging.HelperResourceTrace(ctx, "Called Terraform CLI refresh command") + + return err +} + +// Schemas returns an object describing the provider schemas. +// +// If the schemas cannot be read, Schemas returns an error. +func (wd *WorkingDir) Schemas(ctx context.Context) (*tfjson.ProviderSchemas, error) { + logging.HelperResourceTrace(ctx, "Calling Terraform CLI providers schema command") + + providerSchemas, err := wd.tf.ProvidersSchema(context.Background()) + + logging.HelperResourceTrace(ctx, "Called Terraform CLI providers schema command") + + return providerSchemas, err +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/config.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/config.go new file mode 100644 index 00000000..b81c264d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/config.go @@ -0,0 +1,250 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package teststep + +import ( + "context" + "fmt" + "io" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/hashicorp/terraform-plugin-testing/config" +) + +const ( + rawConfigFileName = "terraform_plugin_test.tf" + rawConfigFileNameJSON = rawConfigFileName + ".json" +) + +var ( + // Expected to match: + // provider "example" { + // provider "example"{ + // provider example { + // provider example{ + // provider"example"{ + providerConfigBlockRegex = regexp.MustCompile(`provider(\s*"[a-zA-Z0-9_-]+"\s*|\s+[a-zA-Z0-9_-]+\s*){`) + // Expected to match: + // terraform { + // terraform{ + terraformConfigBlockRegex = regexp.MustCompile(`terraform\s*{`) +) + +// Config defines an interface implemented by all types +// that represent Terraform configuration: +// +// - [config.configurationDirectory] +// - [config.configurationFile] +// - [config.configurationString] +type Config interface { + HasConfigurationFiles() bool + HasProviderBlock(context.Context) (bool, error) + HasTerraformBlock(context.Context) (bool, error) + Write(context.Context, string) error +} + +// PrepareConfigurationRequest is used to simplify the generation of +// a ConfigurationRequest which is required when calling the +// Configuration func. +type PrepareConfigurationRequest struct { + Directory config.TestStepConfigFunc + File config.TestStepConfigFunc + Raw string + TestStepConfigRequest config.TestStepConfigRequest +} + +// Exec returns a Configuration request which is required when +// calling the Configuration func. +func (p PrepareConfigurationRequest) Exec() ConfigurationRequest { + directory := Pointer(p.Directory.Exec(p.TestStepConfigRequest)) + file := Pointer(p.File.Exec(p.TestStepConfigRequest)) + raw := Pointer(p.Raw) + + return ConfigurationRequest{ + Directory: directory, + File: file, + Raw: raw, + } +} + +// ConfigurationRequest is used by the Configuration func to determine +// the underlying type to instantiate. +type ConfigurationRequest struct { + Directory *string + File *string + Raw *string +} + +// Validate ensures that only one of Directory, File or Raw are non-empty. +func (c ConfigurationRequest) Validate() error { + var configSet []string + + if c.Directory != nil && *c.Directory != "" { + configSet = append(configSet, "directory") + } + + if c.File != nil && *c.File != "" { + configSet = append(configSet, "file") + } + + if c.Raw != nil && *c.Raw != "" { + configSet = append(configSet, "raw") + } + + if len(configSet) > 1 { + configSetStr := strings.Join(configSet, `, `) + + i := strings.LastIndex(configSetStr, ", ") + + if i != -1 { + configSetStr = configSetStr[:i] + " and " + configSetStr[i+len(", "):] + } + + return fmt.Errorf(`%s are populated, only one of "directory", "file", or "raw" is allowed`, configSetStr) + } + + return nil +} + +// Configuration uses the supplied ConfigurationRequest to determine +// which of the types that implement Config to instantiate. If none +// of the fields in ConfigurationRequest are populated nil is returned. +func Configuration(req ConfigurationRequest) Config { + if req.Directory != nil && *req.Directory != "" { + return configurationDirectory{ + directory: *req.Directory, + } + } + + if req.File != nil && *req.File != "" { + return configurationFile{ + file: *req.File, + } + } + + if req.Raw != nil && *req.Raw != "" { + return configurationString{ + raw: *req.Raw, + } + } + + return nil +} + +// copyFiles accepts a path to a directory and a destination. Only +// files in the path directory are copied, any nested directories +// are ignored. +func copyFiles(path string, dstPath string) error { + infos, err := os.ReadDir(path) + + if err != nil { + return err + } + + for _, info := range infos { + srcPath := filepath.Join(path, info.Name()) + + if info.IsDir() { + continue + } else { + err = copyFile(srcPath, dstPath) + + if err != nil { + return err + } + } + + } + return nil +} + +// copyFile accepts a path to a file and a destination, +// copying the file from path to destination. +func copyFile(path string, dstPath string) error { + srcF, err := os.Open(path) + + if err != nil { + return err + } + + defer srcF.Close() + + di, err := os.Stat(dstPath) + + if err != nil { + return err + } + + if di.IsDir() { + _, file := filepath.Split(path) + dstPath = filepath.Join(dstPath, file) + } + + dstF, err := os.Create(dstPath) + + if err != nil { + return err + } + + defer dstF.Close() + + if _, err := io.Copy(dstF, srcF); err != nil { + return err + } + + return nil +} + +// filesContains accepts a string representing a directory and a +// regular expression. For each file that is found within the +// directory fileContains func is called. Any nested directories +// within the directory specified by dir are ignored. +func filesContains(dir string, find *regexp.Regexp) (bool, error) { + dirEntries, err := os.ReadDir(dir) + + if err != nil { + return false, err + } + + for _, dirEntry := range dirEntries { + if dirEntry.IsDir() { + continue + } + + path := filepath.Join(dir, dirEntry.Name()) + + contains, err := fileContains(path, find) + + if err != nil { + return false, err + } + + if contains { + return true, nil + } + } + + return false, nil +} + +// fileContains accepts a path and a regular expression. The +// file is read and the supplied regular expression is used +// to determine whether the file contains the specified string. +func fileContains(path string, find *regexp.Regexp) (bool, error) { + f, err := os.ReadFile(path) + + if err != nil { + return false, err + } + + return find.MatchString(string(f)), nil +} + +// Pointer returns a pointer to any type. +func Pointer[T any](in T) *T { + return &in +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/directory.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/directory.go new file mode 100644 index 00000000..0126e82a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/directory.go @@ -0,0 +1,94 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package teststep + +import ( + "context" + "os" + "path/filepath" +) + +var _ Config = configurationDirectory{} + +type configurationDirectory struct { + directory string +} + +// HasConfigurationFiles is used during validation to ensure that +// ExternalProviders are not declared at the TestCase or TestStep +// level when using TestStep.ConfigDirectory. +func (c configurationDirectory) HasConfigurationFiles() bool { + return true +} + +// HasProviderBlock returns true if the Config has declared a provider +// configuration block, e.g. provider "examplecloud" {...} +func (c configurationDirectory) HasProviderBlock(ctx context.Context) (bool, error) { + configDirectory := c.directory + + if !filepath.IsAbs(configDirectory) { + pwd, err := os.Getwd() + + if err != nil { + return false, err + } + + configDirectory = filepath.Join(pwd, configDirectory) + } + + contains, err := filesContains(configDirectory, providerConfigBlockRegex) + + if err != nil { + return false, err + } + + return contains, nil +} + +// HasTerraformBlock returns true if the Config has declared a terraform +// configuration block, e.g. terraform {...} +func (c configurationDirectory) HasTerraformBlock(ctx context.Context) (bool, error) { + configDirectory := c.directory + + if !filepath.IsAbs(configDirectory) { + pwd, err := os.Getwd() + + if err != nil { + return false, err + } + + configDirectory = filepath.Join(pwd, configDirectory) + } + + contains, err := filesContains(configDirectory, terraformConfigBlockRegex) + + if err != nil { + return false, err + } + + return contains, nil +} + +// Write copies all files from directory to destination. +func (c configurationDirectory) Write(ctx context.Context, dest string) error { + configDirectory := c.directory + + if !filepath.IsAbs(configDirectory) { + pwd, err := os.Getwd() + + if err != nil { + return err + } + + configDirectory = filepath.Join(pwd, configDirectory) + } + + err := copyFiles(configDirectory, dest) + + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/file.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/file.go new file mode 100644 index 00000000..6de3f075 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/file.go @@ -0,0 +1,94 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package teststep + +import ( + "context" + "os" + "path/filepath" +) + +var _ Config = configurationFile{} + +type configurationFile struct { + file string +} + +// HasConfigurationFiles is used during validation to ensure that +// ExternalProviders are not declared at the TestCase or TestStep +// level when using TestStep.ConfigFile. +func (c configurationFile) HasConfigurationFiles() bool { + return true +} + +// HasProviderBlock returns true if the Config has declared a provider +// configuration block, e.g. provider "examplecloud" {...} +func (c configurationFile) HasProviderBlock(ctx context.Context) (bool, error) { + configFile := c.file + + if !filepath.IsAbs(configFile) { + pwd, err := os.Getwd() + + if err != nil { + return false, err + } + + configFile = filepath.Join(pwd, configFile) + } + + contains, err := fileContains(configFile, providerConfigBlockRegex) + + if err != nil { + return false, err + } + + return contains, nil +} + +// HasTerraformBlock returns true if the Config has declared a terraform +// configuration block, e.g. terraform {...} +func (c configurationFile) HasTerraformBlock(ctx context.Context) (bool, error) { + configFile := c.file + + if !filepath.IsAbs(configFile) { + pwd, err := os.Getwd() + + if err != nil { + return false, err + } + + configFile = filepath.Join(pwd, configFile) + } + + contains, err := fileContains(configFile, terraformConfigBlockRegex) + + if err != nil { + return false, err + } + + return contains, nil +} + +// Write copies file from c.file to destination. +func (c configurationFile) Write(ctx context.Context, dest string) error { + configFile := c.file + + if !filepath.IsAbs(configFile) { + pwd, err := os.Getwd() + + if err != nil { + return err + } + + configFile = filepath.Join(pwd, configFile) + } + + err := copyFile(configFile, dest) + + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/string.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/string.go new file mode 100644 index 00000000..4143b484 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/teststep/string.go @@ -0,0 +1,61 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package teststep + +import ( + "context" + "encoding/json" + "fmt" + "os" + "path/filepath" +) + +var _ Config = configurationString{} + +type configurationString struct { + raw string +} + +// HasConfigurationFiles is used during validation to allow declaration +// of ExternalProviders at the TestCase or TestStep level when using +// TestStep.Config. +func (c configurationString) HasConfigurationFiles() bool { + return false +} + +// HasProviderBlock returns true if the Config has declared a provider +// configuration block, e.g. provider "examplecloud" {...} +func (c configurationString) HasProviderBlock(ctx context.Context) (bool, error) { + return providerConfigBlockRegex.MatchString(c.raw), nil +} + +// HasTerraformBlock returns true if the Config has declared a terraform +// configuration block, e.g. terraform {...} +func (c configurationString) HasTerraformBlock(ctx context.Context) (bool, error) { + return terraformConfigBlockRegex.MatchString(c.raw), nil +} + +// Write creates a file and writes c.raw into it. +func (c configurationString) Write(ctx context.Context, dest string) error { + outFilename := filepath.Join(dest, rawConfigFileName) + rmFilename := filepath.Join(dest, rawConfigFileNameJSON) + + bCfg := []byte(c.raw) + + if json.Valid(bCfg) { + outFilename, rmFilename = rmFilename, outFilename + } + + if err := os.Remove(rmFilename); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("unable to remove %q: %w", rmFilename, err) + } + + err := os.WriteFile(outFilename, bCfg, 0700) + + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/config_traversals.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/config_traversals.go new file mode 100644 index 00000000..6208117c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/config_traversals.go @@ -0,0 +1,59 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfdiags + +import ( + "bytes" + "fmt" + "strconv" + + "github.com/hashicorp/go-cty/cty" +) + +// FormatCtyPath is a helper function to produce a user-friendly string +// representation of a cty.Path. The result uses a syntax similar to the +// HCL expression language in the hope of it being familiar to users. +func FormatCtyPath(path cty.Path) string { + var buf bytes.Buffer + for _, step := range path { + switch ts := step.(type) { + case cty.GetAttrStep: + fmt.Fprintf(&buf, ".%s", ts.Name) + case cty.IndexStep: + buf.WriteByte('[') + key := ts.Key + keyTy := key.Type() + switch { + case key.IsNull(): + buf.WriteString("null") + case !key.IsKnown(): + buf.WriteString("(not yet known)") + case keyTy == cty.Number: + bf := key.AsBigFloat() + buf.WriteString(bf.Text('g', -1)) + case keyTy == cty.String: + buf.WriteString(strconv.Quote(key.AsString())) + default: + buf.WriteString("...") + } + buf.WriteByte(']') + } + } + return buf.String() +} + +// FormatError is a helper function to produce a user-friendly string +// representation of certain special error types that we might want to +// include in diagnostic messages. +// +// This currently has special behavior only for cty.PathError, where a +// non-empty path is rendered in a HCL-like syntax as context. +func FormatError(err error) string { + perr, ok := err.(cty.PathError) + if !ok || len(perr.Path) == 0 { + return err.Error() + } + + return fmt.Sprintf("%s: %s", FormatCtyPath(perr.Path), perr.Error()) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/contextual.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/contextual.go new file mode 100644 index 00000000..a9b5c7e8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/contextual.go @@ -0,0 +1,84 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfdiags + +import ( + "github.com/hashicorp/go-cty/cty" +) + +// AttributeValue returns a diagnostic about an attribute value in an implied current +// configuration context. This should be returned only from functions whose +// interface specifies a clear configuration context that this will be +// resolved in. +// +// The given path is relative to the implied configuration context. To describe +// a top-level attribute, it should be a single-element cty.Path with a +// cty.GetAttrStep. It's assumed that the path is returning into a structure +// that would be produced by our conventions in the configschema package; it +// may return unexpected results for structures that can't be represented by +// configschema. +// +// Since mapping attribute paths back onto configuration is an imprecise +// operation (e.g. dynamic block generation may cause the same block to be +// evaluated multiple times) the diagnostic detail should include the attribute +// name and other context required to help the user understand what is being +// referenced in case the identified source range is not unique. +// +// The returned attribute will not have source location information until +// context is applied to the containing diagnostics using diags.InConfigBody. +// After context is applied, the source location is the value assigned to the +// named attribute, or the containing body's "missing item range" if no +// value is present. +func AttributeValue(severity Severity, summary, detail string, attrPath cty.Path) Diagnostic { + return &attributeDiagnostic{ + diagnosticBase: diagnosticBase{ + severity: severity, + summary: summary, + detail: detail, + }, + attrPath: attrPath, + } +} + +// GetAttribute extracts an attribute cty.Path from a diagnostic if it contains +// one. Normally this is not accessed directly, and instead the config body is +// added to the Diagnostic to create a more complete message for the user. In +// some cases however, we may want to know just the name of the attribute that +// generated the Diagnostic message. +// This returns a nil cty.Path if it does not exist in the Diagnostic. +func GetAttribute(d Diagnostic) cty.Path { + if d, ok := d.(*attributeDiagnostic); ok { + return d.attrPath + } + return nil +} + +type attributeDiagnostic struct { + diagnosticBase + attrPath cty.Path +} + +// WholeContainingBody returns a diagnostic about the body that is an implied +// current configuration context. This should be returned only from +// functions whose interface specifies a clear configuration context that this +// will be resolved in. +// +// The returned attribute will not have source location information until +// context is applied to the containing diagnostics using diags.InConfigBody. +// After context is applied, the source location is currently the missing item +// range of the body. In future, this may change to some other suitable +// part of the containing body. +func WholeContainingBody(severity Severity, summary, detail string) Diagnostic { + return &wholeBodyDiagnostic{ + diagnosticBase: diagnosticBase{ + severity: severity, + summary: summary, + detail: detail, + }, + } +} + +type wholeBodyDiagnostic struct { + diagnosticBase +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostic.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostic.go new file mode 100644 index 00000000..54727134 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostic.go @@ -0,0 +1,26 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfdiags + +type Diagnostic interface { + Severity() Severity + Description() Description +} + +type Severity rune + +// This code was previously generated with a go:generate directive calling: +// go run golang.org/x/tools/cmd/stringer -type=Severity +// However, it is now considered frozen and the tooling dependency has been +// removed. The String method can be manually updated if necessary. + +const ( + Error Severity = 'E' + Warning Severity = 'W' +) + +type Description struct { + Summary string + Detail string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostic_base.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostic_base.go new file mode 100644 index 00000000..505692ce --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostic_base.go @@ -0,0 +1,34 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfdiags + +// diagnosticBase can be embedded in other diagnostic structs to get +// default implementations of Severity and Description. This type also +// has default implementations of Source that return no source +// location or expression-related information, so embedders should generally +// override those method to return more useful results where possible. +type diagnosticBase struct { + severity Severity + summary string + detail string +} + +func (d diagnosticBase) Severity() Severity { + return d.severity +} + +func (d diagnosticBase) Description() Description { + return Description{ + Summary: d.summary, + Detail: d.detail, + } +} + +func Diag(sev Severity, summary, detail string) Diagnostic { + return &diagnosticBase{ + severity: sev, + summary: summary, + detail: detail, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostics.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostics.go new file mode 100644 index 00000000..4fc99c1b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/diagnostics.go @@ -0,0 +1,196 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfdiags + +import ( + "bytes" + "fmt" + "sort" +) + +// Diagnostics is a list of diagnostics. Diagnostics is intended to be used +// where a Go "error" might normally be used, allowing richer information +// to be conveyed (more context, support for warnings). +// +// A nil Diagnostics is a valid, empty diagnostics list, thus allowing +// heap allocation to be avoided in the common case where there are no +// diagnostics to report at all. +type Diagnostics []Diagnostic + +// HasErrors returns true if any of the diagnostics in the list have +// a severity of Error. +func (diags Diagnostics) HasErrors() bool { + for _, diag := range diags { + if diag.Severity() == Error { + return true + } + } + return false +} + +// Err flattens a diagnostics list into a single Go error, or to nil +// if the diagnostics list does not include any error-level diagnostics. +// +// This can be used to smuggle diagnostics through an API that deals in +// native errors, but unfortunately it will lose naked warnings (warnings +// that aren't accompanied by at least one error) since such APIs have no +// mechanism through which to report these. +// +// return result, diags.Error() +func (diags Diagnostics) Err() error { + if !diags.HasErrors() { + return nil + } + return diagnosticsAsError{diags} +} + +// ErrWithWarnings is similar to Err except that it will also return a non-nil +// error if the receiver contains only warnings. +// +// In the warnings-only situation, the result is guaranteed to be of dynamic +// type NonFatalError, allowing diagnostics-aware callers to type-assert +// and unwrap it, treating it as non-fatal. +// +// This should be used only in contexts where the caller is able to recognize +// and handle NonFatalError. For normal callers that expect a lack of errors +// to be signaled by nil, use just Diagnostics.Err. +func (diags Diagnostics) ErrWithWarnings() error { + if len(diags) == 0 { + return nil + } + if diags.HasErrors() { + return diags.Err() + } + return NonFatalError{diags} +} + +// NonFatalErr is similar to Err except that it always returns either nil +// (if there are no diagnostics at all) or NonFatalError. +// +// This allows diagnostics to be returned over an error return channel while +// being explicit that the diagnostics should not halt processing. +// +// This should be used only in contexts where the caller is able to recognize +// and handle NonFatalError. For normal callers that expect a lack of errors +// to be signaled by nil, use just Diagnostics.Err. +func (diags Diagnostics) NonFatalErr() error { + if len(diags) == 0 { + return nil + } + return NonFatalError{diags} +} + +type diagnosticsAsError struct { + Diagnostics +} + +func (dae diagnosticsAsError) Error() string { + diags := dae.Diagnostics + switch { + case len(diags) == 0: + // should never happen, since we don't create this wrapper if + // there are no diagnostics in the list. + return "no errors" + case len(diags) == 1: + desc := diags[0].Description() + if desc.Detail == "" { + return desc.Summary + } + return fmt.Sprintf("%s: %s", desc.Summary, desc.Detail) + default: + var ret bytes.Buffer + fmt.Fprintf(&ret, "%d problems:\n", len(diags)) + for _, diag := range dae.Diagnostics { + desc := diag.Description() + if desc.Detail == "" { + fmt.Fprintf(&ret, "\n- %s", desc.Summary) + } else { + fmt.Fprintf(&ret, "\n- %s: %s", desc.Summary, desc.Detail) + } + } + return ret.String() + } +} + +// WrappedErrors is an implementation of errwrap.Wrapper so that an error-wrapped +// diagnostics object can be picked apart by errwrap-aware code. +func (dae diagnosticsAsError) WrappedErrors() []error { + var errs []error + for _, diag := range dae.Diagnostics { + if wrapper, isErr := diag.(nativeError); isErr { + errs = append(errs, wrapper.err) + } + } + return errs +} + +// NonFatalError is a special error type, returned by +// Diagnostics.ErrWithWarnings and Diagnostics.NonFatalErr, +// that indicates that the wrapped diagnostics should be treated as non-fatal. +// Callers can conditionally type-assert an error to this type in order to +// detect the non-fatal scenario and handle it in a different way. +type NonFatalError struct { + Diagnostics +} + +func (woe NonFatalError) Error() string { + diags := woe.Diagnostics + switch { + case len(diags) == 0: + // should never happen, since we don't create this wrapper if + // there are no diagnostics in the list. + return "no errors or warnings" + case len(diags) == 1: + desc := diags[0].Description() + if desc.Detail == "" { + return desc.Summary + } + return fmt.Sprintf("%s: %s", desc.Summary, desc.Detail) + default: + var ret bytes.Buffer + if diags.HasErrors() { + fmt.Fprintf(&ret, "%d problems:\n", len(diags)) + } else { + fmt.Fprintf(&ret, "%d warnings:\n", len(diags)) + } + for _, diag := range woe.Diagnostics { + desc := diag.Description() + if desc.Detail == "" { + fmt.Fprintf(&ret, "\n- %s", desc.Summary) + } else { + fmt.Fprintf(&ret, "\n- %s: %s", desc.Summary, desc.Detail) + } + } + return ret.String() + } +} + +// sortDiagnostics is an implementation of sort.Interface +type sortDiagnostics []Diagnostic + +var _ sort.Interface = sortDiagnostics(nil) + +func (sd sortDiagnostics) Len() int { + return len(sd) +} + +func (sd sortDiagnostics) Less(i, j int) bool { + iD, jD := sd[i], sd[j] + iSev, jSev := iD.Severity(), jD.Severity() + + switch { + case iSev != jSev: + return iSev == Warning + default: + // The remaining properties do not have a defined ordering, so + // we'll leave it unspecified. Since we use sort.Stable in + // the caller of this, the ordering of remaining items will + // be preserved. + return false + } +} + +func (sd sortDiagnostics) Swap(i, j int) { + sd[i], sd[j] = sd[j], sd[i] +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/doc.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/doc.go new file mode 100644 index 00000000..23be0a8b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/doc.go @@ -0,0 +1,19 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package tfdiags is a utility package for representing errors and +// warnings in a manner that allows us to produce good messages for the +// user. +// +// "diag" is short for "diagnostics", and is meant as a general word for +// feedback to a user about potential or actual problems. +// +// A design goal for this package is for it to be able to provide rich +// messaging where possible but to also be pragmatic about dealing with +// generic errors produced by system components that _can't_ provide +// such rich messaging. As a consequence, the main types in this package -- +// Diagnostics and Diagnostic -- are designed so that they can be "smuggled" +// over an error channel and then be unpacked at the other end, so that +// error diagnostics (at least) can transit through APIs that are not +// aware of this package. +package tfdiags diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/error.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/error.go new file mode 100644 index 00000000..f7c9c65d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/error.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfdiags + +// nativeError is a Diagnostic implementation that wraps a normal Go error +type nativeError struct { + err error +} + +var _ Diagnostic = nativeError{} + +func (e nativeError) Severity() Severity { + return Error +} + +func (e nativeError) Description() Description { + return Description{ + Summary: FormatError(e.err), + } +} + +func FromError(err error) Diagnostic { + return &nativeError{ + err: err, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/severity_string.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/severity_string.go new file mode 100644 index 00000000..78a72106 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/severity_string.go @@ -0,0 +1,29 @@ +// Code generated by "stringer -type=Severity"; DO NOT EDIT. + +package tfdiags + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[Error-69] + _ = x[Warning-87] +} + +const ( + _Severity_name_0 = "Error" + _Severity_name_1 = "Warning" +) + +func (i Severity) String() string { + switch { + case i == 69: + return _Severity_name_0 + case i == 87: + return _Severity_name_1 + default: + return "Severity(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/simple_warning.go b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/simple_warning.go new file mode 100644 index 00000000..0c90c478 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/internal/tfdiags/simple_warning.go @@ -0,0 +1,23 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfdiags + +type simpleWarning string + +var _ Diagnostic = simpleWarning("") + +// SimpleWarning constructs a simple (summary-only) warning diagnostic. +func SimpleWarning(msg string) Diagnostic { + return simpleWarning(msg) +} + +func (e simpleWarning) Severity() Severity { + return Warning +} + +func (e simpleWarning) Description() Description { + return Description{ + Summary: string(e), + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/bool.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/bool.go new file mode 100644 index 00000000..fba10ee8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/bool.go @@ -0,0 +1,44 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" + "strconv" +) + +var _ Check = boolValue{} + +type boolValue struct { + value bool +} + +// CheckValue determines whether the passed value is of type bool, and +// contains a matching bool value. +func (v boolValue) CheckValue(other any) error { + otherVal, ok := other.(bool) + + if !ok { + return fmt.Errorf("expected bool value for Bool check, got: %T", other) + } + + if otherVal != v.value { + return fmt.Errorf("expected value %t for Bool check, got: %t", v.value, otherVal) + } + + return nil +} + +// String returns the string representation of the bool value. +func (v boolValue) String() string { + return strconv.FormatBool(v.value) +} + +// Bool returns a Check for asserting equality between the +// supplied bool and the value passed to the CheckValue method. +func Bool(value bool) boolValue { + return boolValue{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/check.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/check.go new file mode 100644 index 00000000..cef532c9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/check.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +// Check defines an interface that is implemented to determine whether type and value match. Individual +// implementations determine how the match is performed (e.g., exact match, partial match). +type Check interface { + // CheckValue should assert the given known value against any expectations. Use the error + // return to signal unexpected values or implementation errors. + CheckValue(value any) error + // String should return a string representation of the type and value. + String() string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/doc.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/doc.go new file mode 100644 index 00000000..4041c3e9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/doc.go @@ -0,0 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package knownvalue contains the known value interface, and types implementing the known value interface. +package knownvalue diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/float64.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/float64.go new file mode 100644 index 00000000..bacdaa6f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/float64.go @@ -0,0 +1,51 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "encoding/json" + "fmt" + "strconv" +) + +var _ Check = float64Exact{} + +type float64Exact struct { + value float64 +} + +// CheckValue determines whether the passed value is of type float64, and +// contains a matching float64 value. +func (v float64Exact) CheckValue(other any) error { + jsonNum, ok := other.(json.Number) + + if !ok { + return fmt.Errorf("expected json.Number value for Float64Exact check, got: %T", other) + } + + otherVal, err := jsonNum.Float64() + + if err != nil { + return fmt.Errorf("expected json.Number to be parseable as float64 value for Float64Exact check: %s", err) + } + + if otherVal != v.value { + return fmt.Errorf("expected value %s for Float64Exact check, got: %s", v.String(), strconv.FormatFloat(otherVal, 'f', -1, 64)) + } + + return nil +} + +// String returns the string representation of the float64 value. +func (v float64Exact) String() string { + return strconv.FormatFloat(v.value, 'f', -1, 64) +} + +// Float64Exact returns a Check for asserting equality between the +// supplied float64 and the value passed to the CheckValue method. +func Float64Exact(value float64) float64Exact { + return float64Exact{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/int64.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/int64.go new file mode 100644 index 00000000..19f80362 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/int64.go @@ -0,0 +1,51 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "encoding/json" + "fmt" + "strconv" +) + +var _ Check = int64Exact{} + +type int64Exact struct { + value int64 +} + +// CheckValue determines whether the passed value is of type int64, and +// contains a matching int64 value. +func (v int64Exact) CheckValue(other any) error { + jsonNum, ok := other.(json.Number) + + if !ok { + return fmt.Errorf("expected json.Number value for Int64Exact check, got: %T", other) + } + + otherVal, err := jsonNum.Int64() + + if err != nil { + return fmt.Errorf("expected json.Number to be parseable as int64 value for Int64Exact check: %s", err) + } + + if otherVal != v.value { + return fmt.Errorf("expected value %d for Int64Exact check, got: %d", v.value, otherVal) + } + + return nil +} + +// String returns the string representation of the int64 value. +func (v int64Exact) String() string { + return strconv.FormatInt(v.value, 10) +} + +// Int64Exact returns a Check for asserting equality between the +// supplied int64 and the value passed to the CheckValue method. +func Int64Exact(value int64) int64Exact { + return int64Exact{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list.go new file mode 100644 index 00000000..50017524 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list.go @@ -0,0 +1,67 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" +) + +var _ Check = listExact{} + +type listExact struct { + value []Check +} + +// CheckValue determines whether the passed value is of type []any, and +// contains matching slice entries in the same sequence. +func (v listExact) CheckValue(other any) error { + otherVal, ok := other.([]any) + + if !ok { + return fmt.Errorf("expected []any value for ListExact check, got: %T", other) + } + + if len(otherVal) != len(v.value) { + expectedElements := "elements" + actualElements := "elements" + + if len(v.value) == 1 { + expectedElements = "element" + } + + if len(otherVal) == 1 { + actualElements = "element" + } + + return fmt.Errorf("expected %d %s for ListExact check, got %d %s", len(v.value), expectedElements, len(otherVal), actualElements) + } + + for i := 0; i < len(v.value); i++ { + if err := v.value[i].CheckValue(otherVal[i]); err != nil { + return fmt.Errorf("list element index %d: %s", i, err) + } + } + + return nil +} + +// String returns the string representation of the value. +func (v listExact) String() string { + var listVals []string + + for _, val := range v.value { + listVals = append(listVals, val.String()) + } + + return fmt.Sprintf("%s", listVals) +} + +// ListExact returns a Check for asserting equality between the +// supplied []Check and the value passed to the CheckValue method. +// This is an order-dependent check. +func ListExact(value []Check) listExact { + return listExact{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list_partial.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list_partial.go new file mode 100644 index 00000000..7d6e7ee2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list_partial.go @@ -0,0 +1,89 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "bytes" + "fmt" + "sort" + "strings" +) + +var _ Check = listPartial{} + +type listPartial struct { + value map[int]Check +} + +// CheckValue determines whether the passed value is of type []any, and +// contains matching slice entries in the same sequence. +func (v listPartial) CheckValue(other any) error { + otherVal, ok := other.([]any) + + if !ok { + return fmt.Errorf("expected []any value for ListPartial check, got: %T", other) + } + + var keys []int + + for k := range v.value { + keys = append(keys, k) + } + + sort.SliceStable(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) + + for _, k := range keys { + if len(otherVal) <= k { + return fmt.Errorf("missing element index %d for ListPartial check", k) + } + + if err := v.value[k].CheckValue(otherVal[k]); err != nil { + return fmt.Errorf("list element %d: %s", k, err) + } + } + + return nil +} + +// String returns the string representation of the value. +func (v listPartial) String() string { + var b bytes.Buffer + + b.WriteString("[") + + var keys []int + + var listVals []string + + for k := range v.value { + keys = append(keys, k) + } + + sort.SliceStable(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) + + for _, k := range keys { + listVals = append(listVals, fmt.Sprintf("%d:%s", k, v.value[k])) + } + + b.WriteString(strings.Join(listVals, " ")) + + b.WriteString("]") + + return b.String() +} + +// ListPartial returns a Check for asserting partial equality between the +// supplied map[int]Check and the value passed to the CheckValue method. The +// map keys represent the zero-ordered element indices within the list that is +// being checked. Only the elements at the indices defined within the +// supplied map[int]Check are checked. +func ListPartial(value map[int]Check) listPartial { + return listPartial{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list_size.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list_size.go new file mode 100644 index 00000000..d9519231 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/list_size.go @@ -0,0 +1,55 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" + "strconv" +) + +var _ Check = listSizeExact{} + +type listSizeExact struct { + size int +} + +// CheckValue verifies that the passed value is a list, map, object, +// or set, and contains a matching number of elements. +func (v listSizeExact) CheckValue(other any) error { + otherVal, ok := other.([]any) + + if !ok { + return fmt.Errorf("expected []any value for ListSizeExact check, got: %T", other) + } + + if len(otherVal) != v.size { + expectedElements := "elements" + actualElements := "elements" + + if v.size == 1 { + expectedElements = "element" + } + + if len(otherVal) == 1 { + actualElements = "element" + } + + return fmt.Errorf("expected %d %s for ListSizeExact check, got %d %s", v.size, expectedElements, len(otherVal), actualElements) + } + + return nil +} + +// String returns the string representation of the value. +func (v listSizeExact) String() string { + return strconv.FormatInt(int64(v.size), 10) +} + +// ListSizeExact returns a Check for asserting that +// a list has size elements. +func ListSizeExact(size int) listSizeExact { + return listSizeExact{ + size: size, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map.go new file mode 100644 index 00000000..f4027c9d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map.go @@ -0,0 +1,93 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" + "sort" +) + +var _ Check = mapExact{} + +type mapExact struct { + value map[string]Check +} + +// CheckValue determines whether the passed value is of type map[string]any, and +// contains matching map entries. +func (v mapExact) CheckValue(other any) error { + otherVal, ok := other.(map[string]any) + + if !ok { + return fmt.Errorf("expected map[string]any value for MapExact check, got: %T", other) + } + + if len(otherVal) != len(v.value) { + expectedElements := "elements" + actualElements := "elements" + + if len(v.value) == 1 { + expectedElements = "element" + } + + if len(otherVal) == 1 { + actualElements = "element" + } + + return fmt.Errorf("expected %d %s for MapExact check, got %d %s", len(v.value), expectedElements, len(otherVal), actualElements) + } + + var keys []string + + for k := range v.value { + keys = append(keys, k) + } + + sort.SliceStable(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) + + for _, k := range keys { + otherValItem, ok := otherVal[k] + + if !ok { + return fmt.Errorf("missing element %s for MapExact check", k) + } + + if err := v.value[k].CheckValue(otherValItem); err != nil { + return fmt.Errorf("%s map element: %s", k, err) + } + } + + return nil +} + +// String returns the string representation of the value. +func (v mapExact) String() string { + var keys []string + + for k := range v.value { + keys = append(keys, k) + } + + sort.SliceStable(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) + + mapVals := make(map[string]string, len(keys)) + + for _, k := range keys { + mapVals[k] = v.value[k].String() + } + + return fmt.Sprintf("%v", mapVals) +} + +// MapExact returns a Check for asserting equality between the +// supplied map[string]Check and the value passed to the CheckValue method. +func MapExact(value map[string]Check) mapExact { + return mapExact{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map_partial.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map_partial.go new file mode 100644 index 00000000..860b2adf --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map_partial.go @@ -0,0 +1,80 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" + "sort" +) + +var _ Check = mapPartial{} + +type mapPartial struct { + value map[string]Check +} + +// CheckValue determines whether the passed value is of type map[string]any, and +// contains matching map entries. +func (v mapPartial) CheckValue(other any) error { + otherVal, ok := other.(map[string]any) + + if !ok { + return fmt.Errorf("expected map[string]any value for MapPartial check, got: %T", other) + } + + var keys []string + + for k := range v.value { + keys = append(keys, k) + } + + sort.SliceStable(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) + + for _, k := range keys { + otherValItem, ok := otherVal[k] + + if !ok { + return fmt.Errorf("missing element %s for MapPartial check", k) + } + + if err := v.value[k].CheckValue(otherValItem); err != nil { + return fmt.Errorf("%s map element: %s", k, err) + } + } + + return nil +} + +// String returns the string representation of the value. +func (v mapPartial) String() string { + var keys []string + + for k := range v.value { + keys = append(keys, k) + } + + sort.SliceStable(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) + + mapVals := make(map[string]string, len(keys)) + + for _, k := range keys { + mapVals[k] = v.value[k].String() + } + + return fmt.Sprintf("%v", mapVals) +} + +// MapPartial returns a Check for asserting partial equality between the +// supplied map[string]Check and the value passed to the CheckValue method. Only +// the elements at the map keys defined within the supplied map[string]Check are +// checked. +func MapPartial(value map[string]Check) mapPartial { + return mapPartial{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map_size.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map_size.go new file mode 100644 index 00000000..c0966823 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/map_size.go @@ -0,0 +1,55 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" + "strconv" +) + +var _ Check = mapSizeExact{} + +type mapSizeExact struct { + size int +} + +// CheckValue verifies that the passed value is a list, map, object, +// or set, and contains a matching number of elements. +func (v mapSizeExact) CheckValue(other any) error { + otherVal, ok := other.(map[string]any) + + if !ok { + return fmt.Errorf("expected map[string]any value for MapSizeExact check, got: %T", other) + } + + if len(otherVal) != v.size { + expectedElements := "elements" + actualElements := "elements" + + if v.size == 1 { + expectedElements = "element" + } + + if len(otherVal) == 1 { + actualElements = "element" + } + + return fmt.Errorf("expected %d %s for MapSizeExact check, got %d %s", v.size, expectedElements, len(otherVal), actualElements) + } + + return nil +} + +// String returns the string representation of the value. +func (v mapSizeExact) String() string { + return strconv.Itoa(v.size) +} + +// MapSizeExact returns a Check for asserting that +// a map has size elements. +func MapSizeExact(size int) mapSizeExact { + return mapSizeExact{ + size: size, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/not_null.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/not_null.go new file mode 100644 index 00000000..d7ae6890 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/not_null.go @@ -0,0 +1,32 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" +) + +var _ Check = notNull{} + +type notNull struct{} + +// CheckValue determines whether the passed value is nil. +func (v notNull) CheckValue(other any) error { + if other == nil { + return fmt.Errorf("expected non-nil value for NotNull check, got: %T", other) + } + + return nil +} + +// String returns the string representation of notNull. +func (v notNull) String() string { + return "not-null" +} + +// NotNull returns a Check for asserting the value passed +// to the CheckValue method is not nil. +func NotNull() notNull { + return notNull{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/null.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/null.go new file mode 100644 index 00000000..24e6b7e2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/null.go @@ -0,0 +1,32 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" +) + +var _ Check = null{} + +type null struct{} + +// CheckValue determines whether the passed value is nil. +func (v null) CheckValue(other any) error { + if other != nil { + return fmt.Errorf("expected nil value for Null check, got: %T", other) + } + + return nil +} + +// String returns the string representation of null. +func (v null) String() string { + return "null" +} + +// Null returns a Check for asserting the value passed +// to the CheckValue method is nil. +func Null() null { + return null{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/number.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/number.go new file mode 100644 index 00000000..d101b1f6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/number.go @@ -0,0 +1,56 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "encoding/json" + "fmt" + "math/big" +) + +var _ Check = numberExact{} + +type numberExact struct { + value *big.Float +} + +// CheckValue determines whether the passed value is of type *big.Float, and +// contains a matching *big.Float value. +func (v numberExact) CheckValue(other any) error { + if v.value == nil { + return fmt.Errorf("value in NumberExact check is nil") + } + + jsonNum, ok := other.(json.Number) + + if !ok { + return fmt.Errorf("expected json.Number value for NumberExact check, got: %T", other) + } + + otherVal, _, err := big.ParseFloat(jsonNum.String(), 10, 512, big.ToNearestEven) + + if err != nil { + return fmt.Errorf("expected json.Number to be parseable as big.Float value for NumberExact check: %s", err) + } + + if v.value.Cmp(otherVal) != 0 { + return fmt.Errorf("expected value %s for NumberExact check, got: %s", v.String(), otherVal.Text('f', -1)) + } + + return nil +} + +// String returns the string representation of the *big.Float value. +func (v numberExact) String() string { + return v.value.Text('f', -1) +} + +// NumberExact returns a Check for asserting equality between the +// supplied *big.Float and the value passed to the CheckValue method. +// The CheckValue method uses 512-bit precision to perform this assertion. +func NumberExact(value *big.Float) numberExact { + return numberExact{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/object.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/object.go new file mode 100644 index 00000000..87eabfb6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/object.go @@ -0,0 +1,94 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" + "sort" +) + +var _ Check = objectExact{} + +type objectExact struct { + value map[string]Check +} + +// CheckValue determines whether the passed value is of type map[string]any, and +// contains matching object entries. +func (v objectExact) CheckValue(other any) error { + otherVal, ok := other.(map[string]any) + + if !ok { + return fmt.Errorf("expected map[string]any value for ObjectExact check, got: %T", other) + } + + if len(otherVal) != len(v.value) { + expectedAttributes := "attributes" + actualAttributes := "attributes" + + if len(v.value) == 1 { + expectedAttributes = "attribute" + } + + if len(otherVal) == 1 { + actualAttributes = "attribute" + } + + return fmt.Errorf("expected %d %s for ObjectExact check, got %d %s", len(v.value), expectedAttributes, len(otherVal), actualAttributes) + } + + var keys []string + + for k := range v.value { + keys = append(keys, k) + } + + sort.SliceStable(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) + + for _, k := range keys { + otherValItem, ok := otherVal[k] + + if !ok { + return fmt.Errorf("missing attribute %s for ObjectExact check", k) + } + + if err := v.value[k].CheckValue(otherValItem); err != nil { + return fmt.Errorf("%s object attribute: %s", k, err) + } + } + + return nil +} + +// String returns the string representation of the value. +func (v objectExact) String() string { + var keys []string + + for k := range v.value { + keys = append(keys, k) + } + + sort.SliceStable(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) + + mapVals := make(map[string]string, len(keys)) + + for _, k := range keys { + mapVals[k] = v.value[k].String() + } + + return fmt.Sprintf("%v", mapVals) +} + +// ObjectExact returns a Check for asserting equality between the supplied +// map[string]Check and the value passed to the CheckValue method. The map +// keys represent object attribute names. +func ObjectExact(value map[string]Check) objectExact { + return objectExact{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/object_partial.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/object_partial.go new file mode 100644 index 00000000..775ab4c3 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/object_partial.go @@ -0,0 +1,80 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" + "sort" +) + +var _ Check = objectPartial{} + +type objectPartial struct { + value map[string]Check +} + +// CheckValue determines whether the passed value is of type map[string]any, and +// contains matching map entries. +func (v objectPartial) CheckValue(other any) error { + otherVal, ok := other.(map[string]any) + + if !ok { + return fmt.Errorf("expected map[string]any value for ObjectPartial check, got: %T", other) + } + + var keys []string + + for k := range v.value { + keys = append(keys, k) + } + + sort.SliceStable(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) + + for _, k := range keys { + otherValItem, ok := otherVal[k] + + if !ok { + return fmt.Errorf("missing attribute %s for ObjectPartial check", k) + } + + if err := v.value[k].CheckValue(otherValItem); err != nil { + return fmt.Errorf("%s object attribute: %s", k, err) + } + } + + return nil +} + +// String returns the string representation of the value. +func (v objectPartial) String() string { + var keys []string + + for k := range v.value { + keys = append(keys, k) + } + + sort.SliceStable(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) + + mapVals := make(map[string]string, len(keys)) + + for _, k := range keys { + mapVals[k] = v.value[k].String() + } + + return fmt.Sprintf("%v", mapVals) +} + +// ObjectPartial returns a Check for asserting partial equality between the +// supplied map[string]Check and the value passed to the CheckValue method. The map +// keys represent object attribute names. Only the object attributes defined by the +// map keys within the supplied map[string]Check are checked. +func ObjectPartial(value map[string]Check) objectPartial { + return objectPartial{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set.go new file mode 100644 index 00000000..206f2669 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set.go @@ -0,0 +1,86 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" +) + +var _ Check = setExact{} + +type setExact struct { + value []Check +} + +// CheckValue determines whether the passed value is of type []any, and +// contains matching slice entries independent of the sequence. +func (v setExact) CheckValue(other any) error { + otherVal, ok := other.([]any) + + if !ok { + return fmt.Errorf("expected []any value for SetExact check, got: %T", other) + } + + if len(otherVal) != len(v.value) { + expectedElements := "elements" + actualElements := "elements" + + if len(v.value) == 1 { + expectedElements = "element" + } + + if len(otherVal) == 1 { + actualElements = "element" + } + + return fmt.Errorf("expected %d %s for SetExact check, got %d %s", len(v.value), expectedElements, len(otherVal), actualElements) + } + + otherValCopy := make([]any, len(otherVal)) + + copy(otherValCopy, otherVal) + + for i := 0; i < len(v.value); i++ { + err := fmt.Errorf("missing value %s for SetExact check", v.value[i].String()) + + for j := 0; j < len(otherValCopy); j++ { + checkValueErr := v.value[i].CheckValue(otherValCopy[j]) + + if checkValueErr == nil { + otherValCopy[j] = otherValCopy[len(otherValCopy)-1] + otherValCopy = otherValCopy[:len(otherValCopy)-1] + + err = nil + + break + } + } + + if err != nil { + return err + } + } + + return nil +} + +// String returns the string representation of the value. +func (v setExact) String() string { + var setVals []string + + for _, val := range v.value { + setVals = append(setVals, val.String()) + } + + return fmt.Sprintf("%s", setVals) +} + +// SetExact returns a Check for asserting equality between the +// supplied []Check and the value passed to the CheckValue method. +// This is an order-independent check. +func SetExact(value []Check) setExact { + return setExact{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set_partial.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set_partial.go new file mode 100644 index 00000000..dcbcd2ff --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set_partial.go @@ -0,0 +1,72 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" +) + +var _ Check = setPartial{} + +type setPartial struct { + value []Check +} + +// CheckValue determines whether the passed value is of type []any, and +// contains matching slice entries in any sequence. +func (v setPartial) CheckValue(other any) error { + otherVal, ok := other.([]any) + + if !ok { + return fmt.Errorf("expected []any value for SetPartial check, got: %T", other) + } + + otherValCopy := make([]any, len(otherVal)) + + copy(otherValCopy, otherVal) + + for i := 0; i < len(v.value); i++ { + err := fmt.Errorf("missing value %s for SetPartial check", v.value[i].String()) + + for j := 0; j < len(otherValCopy); j++ { + checkValueErr := v.value[i].CheckValue(otherValCopy[j]) + + if checkValueErr == nil { + otherValCopy[j] = otherValCopy[len(otherValCopy)-1] + otherValCopy = otherValCopy[:len(otherValCopy)-1] + + err = nil + + break + } + } + + if err != nil { + return err + } + } + + return nil +} + +// String returns the string representation of the value. +func (v setPartial) String() string { + var setVals []string + + for _, val := range v.value { + setVals = append(setVals, val.String()) + } + + return fmt.Sprintf("%s", setVals) +} + +// SetPartial returns a Check for asserting partial equality between the +// supplied []Check and the value passed to the CheckValue method. Only the +// elements defined within the supplied []Check are checked. This is an +// order-independent check. +func SetPartial(value []Check) setPartial { + return setPartial{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set_size.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set_size.go new file mode 100644 index 00000000..aa3cce17 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/set_size.go @@ -0,0 +1,55 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" + "strconv" +) + +var _ Check = setSizeExact{} + +type setSizeExact struct { + size int +} + +// CheckValue verifies that the passed value is a list, map, object, +// or set, and contains a matching number of elements. +func (v setSizeExact) CheckValue(other any) error { + otherVal, ok := other.([]any) + + if !ok { + return fmt.Errorf("expected []any value for SetElementExact check, got: %T", other) + } + + if len(otherVal) != v.size { + expectedElements := "elements" + actualElements := "elements" + + if v.size == 1 { + expectedElements = "element" + } + + if len(otherVal) == 1 { + actualElements = "element" + } + + return fmt.Errorf("expected %d %s for SetElementExact check, got %d %s", v.size, expectedElements, len(otherVal), actualElements) + } + + return nil +} + +// String returns the string representation of the value. +func (v setSizeExact) String() string { + return strconv.FormatInt(int64(v.size), 10) +} + +// SetSizeExact returns a Check for asserting that +// a set has size elements. +func SetSizeExact(size int) setSizeExact { + return setSizeExact{ + size: size, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/string.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/string.go new file mode 100644 index 00000000..63d03a50 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/string.go @@ -0,0 +1,41 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import "fmt" + +var _ Check = stringExact{} + +type stringExact struct { + value string +} + +// CheckValue determines whether the passed value is of type string, and +// contains a matching sequence of bytes. +func (v stringExact) CheckValue(other any) error { + otherVal, ok := other.(string) + + if !ok { + return fmt.Errorf("expected string value for StringExact check, got: %T", other) + } + + if otherVal != v.value { + return fmt.Errorf("expected value %s for StringExact check, got: %s", v.value, otherVal) + } + + return nil +} + +// String returns the string representation of the value. +func (v stringExact) String() string { + return v.value +} + +// StringExact returns a Check for asserting equality between the +// supplied string and a value passed to the CheckValue method. +func StringExact(value string) stringExact { + return stringExact{ + value: value, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/string_regexp.go b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/string_regexp.go new file mode 100644 index 00000000..782e2974 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/knownvalue/string_regexp.go @@ -0,0 +1,45 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" + "regexp" +) + +var _ Check = stringRegexp{} + +type stringRegexp struct { + regex *regexp.Regexp +} + +// CheckValue determines whether the passed value is of type string, and +// contains a sequence of bytes that match the regular expression supplied +// to StringRegexp. +func (v stringRegexp) CheckValue(other any) error { + otherVal, ok := other.(string) + + if !ok { + return fmt.Errorf("expected string value for StringRegexp check, got: %T", other) + } + + if !v.regex.MatchString(otherVal) { + return fmt.Errorf("expected regex match %s for StringRegexp check, got: %s", v.regex.String(), otherVal) + } + + return nil +} + +// String returns the string representation of the value. +func (v stringRegexp) String() string { + return v.regex.String() +} + +// StringRegexp returns a Check for asserting equality between the +// supplied regular expression and a value passed to the CheckValue method. +func StringRegexp(regex *regexp.Regexp) stringRegexp { + return stringRegexp{ + regex: regex, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/doc.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/doc.go new file mode 100644 index 00000000..eceda6fa --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/doc.go @@ -0,0 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package plancheck contains the plan check interface, request/response structs, and common plan check implementations. +package plancheck diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_empty_plan.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_empty_plan.go new file mode 100644 index 00000000..8df2e281 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_empty_plan.go @@ -0,0 +1,39 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "errors" + "fmt" +) + +var _ PlanCheck = expectEmptyPlan{} + +type expectEmptyPlan struct{} + +// CheckPlan implements the plan check logic. +func (e expectEmptyPlan) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + var result []error + + for output, change := range req.Plan.OutputChanges { + if !change.Actions.NoOp() { + result = append(result, fmt.Errorf("expected empty plan, but output %q has planned action(s): %v", output, change.Actions)) + } + } + + for _, rc := range req.Plan.ResourceChanges { + if !rc.Change.Actions.NoOp() { + result = append(result, fmt.Errorf("expected empty plan, but %s has planned action(s): %v", rc.Address, rc.Change.Actions)) + } + } + + resp.Error = errors.Join(result...) +} + +// ExpectEmptyPlan returns a plan check that asserts that there are no output or resource changes in the plan. +// All output and resource changes found will be aggregated and returned in a plan check error. +func ExpectEmptyPlan() PlanCheck { + return expectEmptyPlan{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_output_value.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_output_value.go new file mode 100644 index 00000000..bc954c8e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_output_value.go @@ -0,0 +1,68 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +// Resource Plan Check +var _ PlanCheck = expectKnownOutputValue{} + +type expectKnownOutputValue struct { + outputAddress string + knownValue knownvalue.Check +} + +// CheckPlan implements the plan check logic. +func (e expectKnownOutputValue) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + var change *tfjson.Change + + if req.Plan == nil { + resp.Error = fmt.Errorf("plan is nil") + } + + for address, oc := range req.Plan.OutputChanges { + if e.outputAddress == address { + change = oc + + break + } + } + + if change == nil { + resp.Error = fmt.Errorf("%s - Output not found in plan", e.outputAddress) + + return + } + + result, err := tfjsonpath.Traverse(change.After, tfjsonpath.Path{}) + + if err != nil { + resp.Error = err + + return + } + + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = fmt.Errorf("error checking value for output at path: %s, err: %s", e.outputAddress, err) + + return + } +} + +// ExpectKnownOutputValue returns a plan check that asserts that the specified value +// has a known type, and value. +func ExpectKnownOutputValue(outputAddress string, knownValue knownvalue.Check) PlanCheck { + return expectKnownOutputValue{ + outputAddress: outputAddress, + knownValue: knownValue, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_output_value_at_path.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_output_value_at_path.go new file mode 100644 index 00000000..42f07a15 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_output_value_at_path.go @@ -0,0 +1,71 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +// Resource Plan Check +var _ PlanCheck = expectKnownOutputValueAtPath{} + +type expectKnownOutputValueAtPath struct { + outputAddress string + outputPath tfjsonpath.Path + knownValue knownvalue.Check +} + +// CheckPlan implements the plan check logic. +func (e expectKnownOutputValueAtPath) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + var change *tfjson.Change + + if req.Plan == nil { + resp.Error = fmt.Errorf("plan is nil") + } + + for address, oc := range req.Plan.OutputChanges { + if e.outputAddress == address { + change = oc + + break + } + } + + if change == nil { + resp.Error = fmt.Errorf("%s - Output not found in plan", e.outputAddress) + + return + } + + result, err := tfjsonpath.Traverse(change.After, e.outputPath) + + if err != nil { + resp.Error = err + + return + } + + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = fmt.Errorf("error checking value for output at path: %s.%s, err: %s", e.outputAddress, e.outputPath.String(), err) + + return + } +} + +// ExpectKnownOutputValueAtPath returns a plan check that asserts that the specified output at the given path +// has a known type and value. Prior to Terraform v1.3.0 a planned output is marked as fully unknown +// if any attribute is unknown. +func ExpectKnownOutputValueAtPath(outputAddress string, outputPath tfjsonpath.Path, knownValue knownvalue.Check) PlanCheck { + return expectKnownOutputValueAtPath{ + outputAddress: outputAddress, + outputPath: outputPath, + knownValue: knownValue, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_value.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_value.go new file mode 100644 index 00000000..ae6ea6d8 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_known_value.go @@ -0,0 +1,70 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +// Resource Plan Check +var _ PlanCheck = expectKnownValue{} + +type expectKnownValue struct { + resourceAddress string + attributePath tfjsonpath.Path + knownValue knownvalue.Check +} + +// CheckPlan implements the plan check logic. +func (e expectKnownValue) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + var rc *tfjson.ResourceChange + + if req.Plan == nil { + resp.Error = fmt.Errorf("plan is nil") + } + + for _, resourceChange := range req.Plan.ResourceChanges { + if e.resourceAddress == resourceChange.Address { + rc = resourceChange + + break + } + } + + if rc == nil { + resp.Error = fmt.Errorf("%s - Resource not found in plan", e.resourceAddress) + + return + } + + result, err := tfjsonpath.Traverse(rc.Change.After, e.attributePath) + + if err != nil { + resp.Error = err + + return + } + + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = fmt.Errorf("error checking value for attribute at path: %s.%s, err: %s", e.resourceAddress, e.attributePath.String(), err) + + return + } +} + +// ExpectKnownValue returns a plan check that asserts that the specified attribute at the given resource +// has a known type and value. +func ExpectKnownValue(resourceAddress string, attributePath tfjsonpath.Path, knownValue knownvalue.Check) PlanCheck { + return expectKnownValue{ + resourceAddress: resourceAddress, + attributePath: attributePath, + knownValue: knownValue, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_non_empty_plan.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_non_empty_plan.go new file mode 100644 index 00000000..482321ec --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_non_empty_plan.go @@ -0,0 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "errors" +) + +var _ PlanCheck = expectNonEmptyPlan{} + +type expectNonEmptyPlan struct{} + +// CheckPlan implements the plan check logic. +func (e expectNonEmptyPlan) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + for _, change := range req.Plan.OutputChanges { + if !change.Actions.NoOp() { + return + } + } + + for _, rc := range req.Plan.ResourceChanges { + if !rc.Change.Actions.NoOp() { + return + } + } + + resp.Error = errors.New("expected a non-empty plan, but got an empty plan") +} + +// ExpectNonEmptyPlan returns a plan check that asserts there is at least one output or resource change in the plan. +func ExpectNonEmptyPlan() PlanCheck { + return expectNonEmptyPlan{} +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_null_output_value.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_null_output_value.go new file mode 100644 index 00000000..92fbf89d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_null_output_value.go @@ -0,0 +1,74 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +var _ PlanCheck = expectNullOutputValue{} + +type expectNullOutputValue struct { + outputAddress string +} + +// CheckPlan implements the plan check logic. +func (e expectNullOutputValue) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + var change *tfjson.Change + + for address, oc := range req.Plan.OutputChanges { + if e.outputAddress == address { + change = oc + + break + } + } + + if change == nil { + resp.Error = fmt.Errorf("%s - Output not found in plan OutputChanges", e.outputAddress) + + return + } + + var result any + var err error + + switch { + case change.Actions.Create(): + result, err = tfjsonpath.Traverse(change.After, tfjsonpath.Path{}) + default: + result, err = tfjsonpath.Traverse(change.Before, tfjsonpath.Path{}) + } + + if err != nil { + resp.Error = err + + return + } + + if result != nil { + resp.Error = fmt.Errorf("attribute at path is not null") + + return + } +} + +// ExpectNullOutputValue returns a plan check that asserts that the specified output has a null value. +// +// Due to implementation differences between the terraform-plugin-sdk and the terraform-plugin-framework, representation of null +// values may differ. For example, terraform-plugin-sdk based providers may have less precise representations of null values, such +// as marking whole maps as null rather than individual element values. +// +// Deprecated: Use [plancheck.ExpectKnownOutputValue] with [knownvalue.Null] instead. +// ExpectNullOutputValue will be removed in the next major version release. +func ExpectNullOutputValue(outputAddress string) PlanCheck { + return expectNullOutputValue{ + outputAddress: outputAddress, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_null_output_value_at_path.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_null_output_value_at_path.go new file mode 100644 index 00000000..69f237d5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_null_output_value_at_path.go @@ -0,0 +1,76 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +var _ PlanCheck = expectNullOutputValueAtPath{} + +type expectNullOutputValueAtPath struct { + outputAddress string + valuePath tfjsonpath.Path +} + +// CheckPlan implements the plan check logic. +func (e expectNullOutputValueAtPath) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + var change *tfjson.Change + + for address, oc := range req.Plan.OutputChanges { + if e.outputAddress == address { + change = oc + + break + } + } + + if change == nil { + resp.Error = fmt.Errorf("%s - Output not found in plan OutputChanges", e.outputAddress) + + return + } + + var result any + var err error + + switch { + case change.Actions.Create(): + result, err = tfjsonpath.Traverse(change.After, e.valuePath) + default: + result, err = tfjsonpath.Traverse(change.Before, e.valuePath) + } + + if err != nil { + resp.Error = err + + return + } + + if result != nil { + resp.Error = fmt.Errorf("attribute at path is not null") + + return + } +} + +// ExpectNullOutputValueAtPath returns a plan check that asserts that the specified output has a null value. +// +// Due to implementation differences between the terraform-plugin-sdk and the terraform-plugin-framework, representation of null +// values may differ. For example, terraform-plugin-sdk based providers may have less precise representations of null values, such +// as marking whole maps as null rather than individual element values. +// +// Deprecated: Use [plancheck.ExpectKnownOutputValueAtPath] with [knownvalue.Null] instead. +// ExpectNullOutputValueAtPath will be removed in the next major version release. +func ExpectNullOutputValueAtPath(outputAddress string, valuePath tfjsonpath.Path) PlanCheck { + return expectNullOutputValueAtPath{ + outputAddress: outputAddress, + valuePath: valuePath, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_resource_action.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_resource_action.go new file mode 100644 index 00000000..37a2336d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_resource_action.go @@ -0,0 +1,90 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "fmt" +) + +var _ PlanCheck = expectResourceAction{} + +type expectResourceAction struct { + resourceAddress string + actionType ResourceActionType +} + +// CheckPlan implements the plan check logic. +func (e expectResourceAction) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + foundResource := false + + for _, rc := range req.Plan.ResourceChanges { + if e.resourceAddress != rc.Address { + continue + } + + switch e.actionType { + case ResourceActionNoop: + if !rc.Change.Actions.NoOp() { + resp.Error = fmt.Errorf("'%s' - expected %s, got action(s): %v", rc.Address, e.actionType, rc.Change.Actions) + return + } + case ResourceActionCreate: + if !rc.Change.Actions.Create() { + resp.Error = fmt.Errorf("'%s' - expected %s, got action(s): %v", rc.Address, e.actionType, rc.Change.Actions) + return + } + case ResourceActionRead: + if !rc.Change.Actions.Read() { + resp.Error = fmt.Errorf("'%s' - expected %s, got action(s): %v", rc.Address, e.actionType, rc.Change.Actions) + return + } + case ResourceActionUpdate: + if !rc.Change.Actions.Update() { + resp.Error = fmt.Errorf("'%s' - expected %s, got action(s): %v", rc.Address, e.actionType, rc.Change.Actions) + return + } + case ResourceActionDestroy: + if !rc.Change.Actions.Delete() { + resp.Error = fmt.Errorf("'%s' - expected %s, got action(s): %v", rc.Address, e.actionType, rc.Change.Actions) + return + } + case ResourceActionDestroyBeforeCreate: + if !rc.Change.Actions.DestroyBeforeCreate() { + resp.Error = fmt.Errorf("'%s' - expected %s, got action(s): %v", rc.Address, e.actionType, rc.Change.Actions) + return + } + case ResourceActionCreateBeforeDestroy: + if !rc.Change.Actions.CreateBeforeDestroy() { + resp.Error = fmt.Errorf("'%s' - expected %s, got action(s): %v", rc.Address, e.actionType, rc.Change.Actions) + return + } + case ResourceActionReplace: + if !rc.Change.Actions.Replace() { + resp.Error = fmt.Errorf("%s - expected %s, got action(s): %v", rc.Address, e.actionType, rc.Change.Actions) + return + } + default: + resp.Error = fmt.Errorf("%s - unexpected ResourceActionType: %s", rc.Address, e.actionType) + return + } + + foundResource = true + break + } + + if !foundResource { + resp.Error = fmt.Errorf("%s - Resource not found in plan ResourceChanges", e.resourceAddress) + return + } +} + +// ExpectResourceAction returns a plan check that asserts that a given resource will have a specific resource change type in the plan. +// Valid actionType are an enum of type plancheck.ResourceActionType, examples: NoOp, DestroyBeforeCreate, Update (in-place), etc. +func ExpectResourceAction(resourceAddress string, actionType ResourceActionType) PlanCheck { + return expectResourceAction{ + resourceAddress: resourceAddress, + actionType: actionType, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_sensitive_value.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_sensitive_value.go new file mode 100644 index 00000000..b6c3a519 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_sensitive_value.go @@ -0,0 +1,61 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +var _ PlanCheck = expectSensitiveValue{} + +type expectSensitiveValue struct { + resourceAddress string + attributePath tfjsonpath.Path +} + +// CheckPlan implements the plan check logic. +func (e expectSensitiveValue) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + + for _, rc := range req.Plan.ResourceChanges { + if e.resourceAddress != rc.Address { + continue + } + + result, err := tfjsonpath.Traverse(rc.Change.AfterSensitive, e.attributePath) + if err != nil { + resp.Error = err + return + } + + isSensitive, ok := result.(bool) + if !ok { + resp.Error = fmt.Errorf("invalid path: the path value cannot be asserted as bool") + return + } + + if !isSensitive { + resp.Error = fmt.Errorf("attribute at path is not sensitive") + return + } + + return + } + + resp.Error = fmt.Errorf("%s - Resource not found in plan ResourceChanges", e.resourceAddress) +} + +// ExpectSensitiveValue returns a plan check that asserts that the specified attribute at the given resource has a sensitive value. +// +// Due to implementation differences between the terraform-plugin-sdk and the terraform-plugin-framework, representation of sensitive +// values may differ. For example, terraform-plugin-sdk based providers may have less precise representations of sensitive values, such +// as marking whole maps as sensitive rather than individual element values. +func ExpectSensitiveValue(resourceAddress string, attributePath tfjsonpath.Path) PlanCheck { + return expectSensitiveValue{ + resourceAddress: resourceAddress, + attributePath: attributePath, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_output_value.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_output_value.go new file mode 100644 index 00000000..f3af398c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_output_value.go @@ -0,0 +1,71 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +var _ PlanCheck = expectUnknownOutputValue{} + +type expectUnknownOutputValue struct { + outputAddress string +} + +// CheckPlan implements the plan check logic. +func (e expectUnknownOutputValue) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + var change *tfjson.Change + + for address, oc := range req.Plan.OutputChanges { + if e.outputAddress == address { + change = oc + + break + } + } + + if change == nil { + resp.Error = fmt.Errorf("%s - Output not found in plan OutputChanges", e.outputAddress) + + return + } + + result, err := tfjsonpath.Traverse(change.AfterUnknown, tfjsonpath.Path{}) + + if err != nil { + resp.Error = err + + return + } + + isUnknown, ok := result.(bool) + + if !ok { + resp.Error = fmt.Errorf("invalid path: the path value cannot be asserted as bool") + + return + } + + if !isUnknown { + resp.Error = fmt.Errorf("attribute at path is known") + + return + } +} + +// ExpectUnknownOutputValue returns a plan check that asserts that the specified output has an unknown value. +// +// Due to implementation differences between the terraform-plugin-sdk and the terraform-plugin-framework, representation of unknown +// values may differ. For example, terraform-plugin-sdk based providers may have less precise representations of unknown values, such +// as marking whole maps as unknown rather than individual element values. +func ExpectUnknownOutputValue(outputAddress string) PlanCheck { + return expectUnknownOutputValue{ + outputAddress: outputAddress, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_output_value_at_path.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_output_value_at_path.go new file mode 100644 index 00000000..74f694e2 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_output_value_at_path.go @@ -0,0 +1,73 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +var _ PlanCheck = expectUnknownOutputValueAtPath{} + +type expectUnknownOutputValueAtPath struct { + outputAddress string + valuePath tfjsonpath.Path +} + +// CheckPlan implements the plan check logic. +func (e expectUnknownOutputValueAtPath) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + var change *tfjson.Change + + for address, oc := range req.Plan.OutputChanges { + if e.outputAddress == address { + change = oc + + break + } + } + + if change == nil { + resp.Error = fmt.Errorf("%s - Output not found in plan OutputChanges", e.outputAddress) + + return + } + + result, err := tfjsonpath.Traverse(change.AfterUnknown, e.valuePath) + + if err != nil { + resp.Error = err + + return + } + + isUnknown, ok := result.(bool) + + if !ok { + resp.Error = fmt.Errorf("invalid path: the path value cannot be asserted as bool") + + return + } + + if !isUnknown { + resp.Error = fmt.Errorf("attribute at path is known") + + return + } +} + +// ExpectUnknownOutputValueAtPath returns a plan check that asserts that the specified output has an unknown value. +// +// Due to implementation differences between the terraform-plugin-sdk and the terraform-plugin-framework, representation of unknown +// values may differ. For example, terraform-plugin-sdk based providers may have less precise representations of unknown values, such +// as marking whole maps as unknown rather than individual element values. +func ExpectUnknownOutputValueAtPath(outputAddress string, valuePath tfjsonpath.Path) PlanCheck { + return expectUnknownOutputValueAtPath{ + outputAddress: outputAddress, + valuePath: valuePath, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_value.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_value.go new file mode 100644 index 00000000..1569397c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/expect_unknown_value.go @@ -0,0 +1,61 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +var _ PlanCheck = expectUnknownValue{} + +type expectUnknownValue struct { + resourceAddress string + attributePath tfjsonpath.Path +} + +// CheckPlan implements the plan check logic. +func (e expectUnknownValue) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { + + for _, rc := range req.Plan.ResourceChanges { + if e.resourceAddress != rc.Address { + continue + } + + result, err := tfjsonpath.Traverse(rc.Change.AfterUnknown, e.attributePath) + if err != nil { + resp.Error = err + return + } + + isUnknown, ok := result.(bool) + if !ok { + resp.Error = fmt.Errorf("invalid path: the path value cannot be asserted as bool") + return + } + + if !isUnknown { + resp.Error = fmt.Errorf("attribute at path is known") + return + } + + return + } + + resp.Error = fmt.Errorf("%s - Resource not found in plan ResourceChanges", e.resourceAddress) +} + +// ExpectUnknownValue returns a plan check that asserts that the specified attribute at the given resource has an unknown value. +// +// Due to implementation differences between the terraform-plugin-sdk and the terraform-plugin-framework, representation of unknown +// values may differ. For example, terraform-plugin-sdk based providers may have less precise representations of unknown values, such +// as marking whole maps as unknown rather than individual element values. +func ExpectUnknownValue(resourceAddress string, attributePath tfjsonpath.Path) PlanCheck { + return expectUnknownValue{ + resourceAddress: resourceAddress, + attributePath: attributePath, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/plan_check.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/plan_check.go new file mode 100644 index 00000000..b6ec0d19 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/plan_check.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +import ( + "context" + + tfjson "github.com/hashicorp/terraform-json" +) + +// PlanCheck defines an interface for implementing test logic that checks a plan file and then returns an error +// if the plan file does not match what is expected. +type PlanCheck interface { + // CheckPlan should perform the plan check. + CheckPlan(context.Context, CheckPlanRequest, *CheckPlanResponse) +} + +// CheckPlanRequest is a request for an invoke of the CheckPlan function. +type CheckPlanRequest struct { + // Plan represents a parsed plan file, retrieved via the `terraform show -json` command. + Plan *tfjson.Plan +} + +// CheckPlanResponse is a response to an invoke of the CheckPlan function. +type CheckPlanResponse struct { + // Error is used to report the failure of a plan check assertion and is combined with other PlanCheck errors + // to be reported as a test failure. + Error error +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/resource_action.go b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/resource_action.go new file mode 100644 index 00000000..ff4afebc --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/plancheck/resource_action.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plancheck + +// ResourceActionType is a string enum type that routes to a specific terraform-json.Actions function for asserting resource changes. +// - https://pkg.go.dev/github.com/hashicorp/terraform-json#Actions +// +// More information about expected resource behavior can be found at: https://developer.hashicorp.com/terraform/language/resources/behavior +type ResourceActionType string + +const ( + // ResourceActionNoop occurs when a resource is not planned to change (no-op). + // - Routes to: https://pkg.go.dev/github.com/hashicorp/terraform-json#Actions.NoOp + ResourceActionNoop ResourceActionType = "NoOp" + + // ResourceActionCreate occurs when a resource is planned to be created. + // - Routes to: https://pkg.go.dev/github.com/hashicorp/terraform-json#Actions.Create + ResourceActionCreate ResourceActionType = "Create" + + // ResourceActionRead occurs when a data source is planned to be read during the apply stage (data sources are read during plan stage when possible). + // See the data source documentation for more information on this behavior: https://developer.hashicorp.com/terraform/language/data-sources#data-resource-behavior + // - Routes to: https://pkg.go.dev/github.com/hashicorp/terraform-json#Actions.Read + ResourceActionRead ResourceActionType = "Read" + + // ResourceActionUpdate occurs when a resource is planned to be updated in-place. + // - Routes to: https://pkg.go.dev/github.com/hashicorp/terraform-json#Actions.Update + ResourceActionUpdate ResourceActionType = "Update" + + // ResourceActionDestroy occurs when a resource is planned to be deleted. + // - Routes to: https://pkg.go.dev/github.com/hashicorp/terraform-json#Actions.Delete + ResourceActionDestroy ResourceActionType = "Destroy" + + // ResourceActionDestroyBeforeCreate occurs when a resource is planned to be deleted and then re-created. This is the default + // behavior when terraform must change a resource argument that cannot be updated in-place due to remote API limitations. + // - Routes to: https://pkg.go.dev/github.com/hashicorp/terraform-json#Actions.DestroyBeforeCreate + ResourceActionDestroyBeforeCreate ResourceActionType = "DestroyBeforeCreate" + + // ResourceActionCreateBeforeDestroy occurs when a resource is planned to be created and then deleted. This is opt-in behavior that + // is enabled with the [create_before_destroy] meta-argument. + // - Routes to: https://pkg.go.dev/github.com/hashicorp/terraform-json#Actions.CreateBeforeDestroy + // + // [create_before_destroy]: https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#create_before_destroy + ResourceActionCreateBeforeDestroy ResourceActionType = "CreateBeforeDestroy" + + // ResourceActionReplace can be used to verify a resource is planned to be deleted and re-created (where the order of delete and create actions are not important). + // This action matches both ResourceActionDestroyBeforeCreate and ResourceActionCreateBeforeDestroy. + // - Routes to: https://pkg.go.dev/github.com/hashicorp/terraform-json#Actions.Replace + ResourceActionReplace ResourceActionType = "Replace" +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/doc.go b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/doc.go new file mode 100644 index 00000000..eba32447 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/doc.go @@ -0,0 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package statecheck contains the state check interface, request/response structs, and common state check implementations. +package statecheck diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_output_value.go b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_output_value.go new file mode 100644 index 00000000..951a3640 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_output_value.go @@ -0,0 +1,76 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck + +import ( + "context" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +// Resource State Check +var _ StateCheck = expectKnownOutputValue{} + +type expectKnownOutputValue struct { + outputAddress string + knownValue knownvalue.Check +} + +// CheckState implements the state check logic. +func (e expectKnownOutputValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { + var output *tfjson.StateOutput + + if req.State == nil { + resp.Error = fmt.Errorf("state is nil") + + return + } + + if req.State.Values == nil { + resp.Error = fmt.Errorf("state does not contain any state values") + + return + } + + for address, oc := range req.State.Values.Outputs { + if e.outputAddress == address { + output = oc + + break + } + } + + if output == nil { + resp.Error = fmt.Errorf("%s - Output not found in state", e.outputAddress) + + return + } + + result, err := tfjsonpath.Traverse(output.Value, tfjsonpath.Path{}) + + if err != nil { + resp.Error = err + + return + } + + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = fmt.Errorf("error checking value for output at path: %s, err: %s", e.outputAddress, err) + + return + } +} + +// ExpectKnownOutputValue returns a state check that asserts that the specified value +// has a known type, and value. +func ExpectKnownOutputValue(outputAddress string, knownValue knownvalue.Check) StateCheck { + return expectKnownOutputValue{ + outputAddress: outputAddress, + knownValue: knownValue, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_output_value_at_path.go b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_output_value_at_path.go new file mode 100644 index 00000000..1cdfcea7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_output_value_at_path.go @@ -0,0 +1,78 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck + +import ( + "context" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +// Resource State Check +var _ StateCheck = expectKnownOutputValueAtPath{} + +type expectKnownOutputValueAtPath struct { + outputAddress string + outputPath tfjsonpath.Path + knownValue knownvalue.Check +} + +// CheckState implements the state check logic. +func (e expectKnownOutputValueAtPath) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { + var output *tfjson.StateOutput + + if req.State == nil { + resp.Error = fmt.Errorf("state is nil") + + return + } + + if req.State.Values == nil { + resp.Error = fmt.Errorf("state does not contain any state values") + + return + } + + for address, oc := range req.State.Values.Outputs { + if e.outputAddress == address { + output = oc + + break + } + } + + if output == nil { + resp.Error = fmt.Errorf("%s - Output not found in state", e.outputAddress) + + return + } + + result, err := tfjsonpath.Traverse(output.Value, e.outputPath) + + if err != nil { + resp.Error = err + + return + } + + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = fmt.Errorf("error checking value for output at path: %s.%s, err: %s", e.outputAddress, e.outputPath.String(), err) + + return + } +} + +// ExpectKnownOutputValueAtPath returns a state check that asserts that the specified output at the given path +// has a known type and value. +func ExpectKnownOutputValueAtPath(outputAddress string, outputPath tfjsonpath.Path, knownValue knownvalue.Check) StateCheck { + return expectKnownOutputValueAtPath{ + outputAddress: outputAddress, + outputPath: outputPath, + knownValue: knownValue, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_value.go b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_value.go new file mode 100644 index 00000000..aca58c4d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_known_value.go @@ -0,0 +1,84 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck + +import ( + "context" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +// Resource State Check +var _ StateCheck = expectKnownValue{} + +type expectKnownValue struct { + resourceAddress string + attributePath tfjsonpath.Path + knownValue knownvalue.Check +} + +// CheckState implements the state check logic. +func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { + var resource *tfjson.StateResource + + if req.State == nil { + resp.Error = fmt.Errorf("state is nil") + + return + } + + if req.State.Values == nil { + resp.Error = fmt.Errorf("state does not contain any state values") + + return + } + + if req.State.Values.RootModule == nil { + resp.Error = fmt.Errorf("state does not contain a root module") + + return + } + + for _, r := range req.State.Values.RootModule.Resources { + if e.resourceAddress == r.Address { + resource = r + + break + } + } + + if resource == nil { + resp.Error = fmt.Errorf("%s - Resource not found in state", e.resourceAddress) + + return + } + + result, err := tfjsonpath.Traverse(resource.AttributeValues, e.attributePath) + + if err != nil { + resp.Error = err + + return + } + + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = fmt.Errorf("error checking value for attribute at path: %s.%s, err: %s", e.resourceAddress, e.attributePath.String(), err) + + return + } +} + +// ExpectKnownValue returns a state check that asserts that the specified attribute at the given resource +// has a known type and value. +func ExpectKnownValue(resourceAddress string, attributePath tfjsonpath.Path, knownValue knownvalue.Check) StateCheck { + return expectKnownValue{ + resourceAddress: resourceAddress, + attributePath: attributePath, + knownValue: knownValue, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_sensitive_value.go b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_sensitive_value.go new file mode 100644 index 00000000..ea467111 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/expect_sensitive_value.go @@ -0,0 +1,101 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck + +import ( + "context" + "encoding/json" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +var _ StateCheck = expectSensitiveValue{} + +type expectSensitiveValue struct { + resourceAddress string + attributePath tfjsonpath.Path +} + +// CheckState implements the state check logic. +func (e expectSensitiveValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { + var resource *tfjson.StateResource + + if req.State == nil { + resp.Error = fmt.Errorf("state is nil") + + return + } + + if req.State.Values == nil { + resp.Error = fmt.Errorf("state does not contain any state values") + + return + } + + if req.State.Values.RootModule == nil { + resp.Error = fmt.Errorf("state does not contain a root module") + + return + } + + for _, r := range req.State.Values.RootModule.Resources { + if e.resourceAddress == r.Address { + resource = r + + break + } + } + + if resource == nil { + resp.Error = fmt.Errorf("%s - Resource not found in state", e.resourceAddress) + + return + } + + var data map[string]any + + err := json.Unmarshal(resource.SensitiveValues, &data) + + if err != nil { + resp.Error = fmt.Errorf("could not unmarshal SensitiveValues: %s", err) + + return + } + + result, err := tfjsonpath.Traverse(data, e.attributePath) + + if err != nil { + resp.Error = err + + return + } + + isSensitive, ok := result.(bool) + if !ok { + resp.Error = fmt.Errorf("invalid path: the path value cannot be asserted as bool") + + return + } + + if !isSensitive { + resp.Error = fmt.Errorf("attribute at path is not sensitive") + + return + } +} + +// ExpectSensitiveValue returns a state check that asserts that the specified attribute at the given resource has a sensitive value. +// +// Due to implementation differences between the terraform-plugin-sdk and the terraform-plugin-framework, representation of sensitive +// values may differ. For example, terraform-plugin-sdk based providers may have less precise representations of sensitive values, such +// as marking whole maps as sensitive rather than individual element values. +func ExpectSensitiveValue(resourceAddress string, attributePath tfjsonpath.Path) StateCheck { + return expectSensitiveValue{ + resourceAddress: resourceAddress, + attributePath: attributePath, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/state_check.go b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/state_check.go new file mode 100644 index 00000000..cfd2da6b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/statecheck/state_check.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck + +import ( + "context" + + tfjson "github.com/hashicorp/terraform-json" +) + +// StateCheck defines an interface for implementing test logic that checks a state file and then returns an error +// if the state file does not match what is expected. +type StateCheck interface { + // CheckState should perform the state check. + CheckState(context.Context, CheckStateRequest, *CheckStateResponse) +} + +// CheckStateRequest is a request for an invoke of the CheckState function. +type CheckStateRequest struct { + // State represents a parsed state file, retrieved via the `terraform show -json` command. + State *tfjson.State +} + +// CheckStateResponse is a response to an invoke of the CheckState function. +type CheckStateResponse struct { + // Error is used to report the failure of a state check assertion and is combined with other StateCheck errors + // to be reported as a test failure. + Error error +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/diff.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/diff.go new file mode 100644 index 00000000..f70e46e4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/diff.go @@ -0,0 +1,1055 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package terraform + +import ( + "fmt" + "log" + "reflect" + "regexp" + "sort" + "strconv" + "strings" + "sync" + + "github.com/hashicorp/go-cty/cty" + + "github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema" + "github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim" +) + +// diffChangeType is an enum with the kind of changes a diff has planned. +type diffChangeType byte + +const ( + diffInvalid diffChangeType = iota //nolint:deadcode,varcheck + diffNone + diffCreate + diffUpdate + diffDestroy + diffDestroyCreate +) + +// multiVal matches the index key to a flatmapped set, list or map +var multiVal = regexp.MustCompile(`\.(#|%)$`) + +// InstanceDiff is the diff of a resource from some state to another. +// +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type InstanceDiff struct { + mu sync.Mutex + Attributes map[string]*ResourceAttrDiff + Destroy bool + DestroyDeposed bool + DestroyTainted bool + + RawConfig cty.Value + RawState cty.Value + RawPlan cty.Value + + // Meta is a simple K/V map that is stored in a diff and persisted to + // plans but otherwise is completely ignored by Terraform core. It is + // meant to be used for additional data a resource may want to pass through. + // The value here must only contain Go primitives and collections. + Meta map[string]interface{} +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) Lock() { d.mu.Lock() } + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) Unlock() { d.mu.Unlock() } + +// ApplyToValue merges the receiver into the given base value, returning a +// new value that incorporates the planned changes. The given value must +// conform to the given schema, or this method will panic. +// +// This method is intended for shimming old subsystems that still use this +// legacy diff type to work with the new-style types. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) ApplyToValue(base cty.Value, schema *configschema.Block) (cty.Value, error) { + // Create an InstanceState attributes from our existing state. + // We can use this to more easily apply the diff changes. + attrs := hcl2shim.FlatmapValueFromHCL2(base) + applied, err := d.Apply(attrs, schema) + if err != nil { + return base, err + } + + val, err := hcl2shim.HCL2ValueFromFlatmap(applied, schema.ImpliedType()) + if err != nil { + return base, err + } + + return schema.CoerceValue(val) +} + +// Apply applies the diff to the provided flatmapped attributes, +// returning the new instance attributes. +// +// This method is intended for shimming old subsystems that still use this +// legacy diff type to work with the new-style types. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) Apply(attrs map[string]string, schema *configschema.Block) (map[string]string, error) { + // We always build a new value here, even if the given diff is "empty", + // because we might be planning to create a new instance that happens + // to have no attributes set, and so we want to produce an empty object + // rather than just echoing back the null old value. + if attrs == nil { + attrs = map[string]string{} + } + + // Rather applying the diff to mutate the attrs, we'll copy new values into + // here to avoid the possibility of leaving stale values. + result := map[string]string{} + + if d.Destroy || d.DestroyDeposed || d.DestroyTainted { + return result, nil + } + + return d.applyBlockDiff(nil, attrs, schema) +} + +func (d *InstanceDiff) applyBlockDiff(path []string, attrs map[string]string, schema *configschema.Block) (map[string]string, error) { + result := map[string]string{} + name := "" + if len(path) > 0 { + name = path[len(path)-1] + } + + // localPrefix is used to build the local result map + localPrefix := "" + if name != "" { + localPrefix = name + "." + } + + // iterate over the schema rather than the attributes, so we can handle + // different block types separately from plain attributes + for n, attrSchema := range schema.Attributes { + var err error + newAttrs, err := d.applyAttrDiff(append(path, n), attrs, attrSchema) + + if err != nil { + return result, err + } + + for k, v := range newAttrs { + result[localPrefix+k] = v + } + } + + blockPrefix := strings.Join(path, ".") + if blockPrefix != "" { + blockPrefix += "." + } + for n, block := range schema.BlockTypes { + // we need to find the set of all keys that traverse this block + candidateKeys := map[string]bool{} + blockKey := blockPrefix + n + "." + localBlockPrefix := localPrefix + n + "." + + // we can only trust the diff for sets, since the path changes, so don't + // count existing values as candidate keys. If it turns out we're + // keeping the attributes, we will catch it down below with "keepBlock" + // after we check the set count. + if block.Nesting != configschema.NestingSet { + for k := range attrs { + if strings.HasPrefix(k, blockKey) { + nextDot := strings.Index(k[len(blockKey):], ".") + if nextDot < 0 { + continue + } + nextDot += len(blockKey) + candidateKeys[k[len(blockKey):nextDot]] = true + } + } + } + + for k, diff := range d.Attributes { + // helper/schema should not insert nil diff values, but don't panic + // if it does. + if diff == nil { + continue + } + + if strings.HasPrefix(k, blockKey) { + nextDot := strings.Index(k[len(blockKey):], ".") + if nextDot < 0 { + continue + } + + if diff.NewRemoved { + continue + } + + nextDot += len(blockKey) + candidateKeys[k[len(blockKey):nextDot]] = true + } + } + + // check each set candidate to see if it was removed. + // we need to do this, because when entire sets are removed, they may + // have the wrong key, and ony show diffs going to "" + if block.Nesting == configschema.NestingSet { + for k := range candidateKeys { + indexPrefix := strings.Join(append(path, n, k), ".") + "." + keep := false + // now check each set element to see if it's a new diff, or one + // that we're dropping. Since we're only applying the "New" + // portion of the set, we can ignore diffs that only contain "Old" + for attr, diff := range d.Attributes { + // helper/schema should not insert nil diff values, but don't panic + // if it does. + if diff == nil { + continue + } + + if !strings.HasPrefix(attr, indexPrefix) { + continue + } + + // check for empty "count" keys + if (strings.HasSuffix(attr, ".#") || strings.HasSuffix(attr, ".%")) && diff.New == "0" { + continue + } + + // removed items don't count either + if diff.NewRemoved { + continue + } + + // this must be a diff to keep + keep = true + break + } + if !keep { + delete(candidateKeys, k) + } + } + } + + for k := range candidateKeys { + newAttrs, err := d.applyBlockDiff(append(path, n, k), attrs, &block.Block) + if err != nil { + return result, err + } + + for attr, v := range newAttrs { + result[localBlockPrefix+attr] = v + } + } + + keepBlock := true + // check this block's count diff directly first, since we may not + // have candidates because it was removed and only set to "0" + if diff, ok := d.Attributes[blockKey+"#"]; ok { + if diff.New == "0" || diff.NewRemoved { + keepBlock = false + } + } + + // if there was no diff at all, then we need to keep the block attributes + if len(candidateKeys) == 0 && keepBlock { + for k, v := range attrs { + if strings.HasPrefix(k, blockKey) { + // we need the key relative to this block, so remove the + // entire prefix, then re-insert the block name. + localKey := localBlockPrefix + k[len(blockKey):] + result[localKey] = v + } + } + } + + countAddr := strings.Join(append(path, n, "#"), ".") + if countDiff, ok := d.Attributes[countAddr]; ok { + if countDiff.NewComputed { + result[localBlockPrefix+"#"] = hcl2shim.UnknownVariableValue + } else { + result[localBlockPrefix+"#"] = countDiff.New + + // While sets are complete, list are not, and we may not have all the + // information to track removals. If the list was truncated, we need to + // remove the extra items from the result. + if block.Nesting == configschema.NestingList && + countDiff.New != "" && countDiff.New != hcl2shim.UnknownVariableValue { + length, _ := strconv.Atoi(countDiff.New) + for k := range result { + if !strings.HasPrefix(k, localBlockPrefix) { + continue + } + + index := k[len(localBlockPrefix):] + nextDot := strings.Index(index, ".") + if nextDot < 1 { + continue + } + index = index[:nextDot] + i, err := strconv.Atoi(index) + if err != nil { + // this shouldn't happen since we added these + // ourself, but make note of it just in case. + log.Printf("[ERROR] bad list index in %q: %s", k, err) + continue + } + if i >= length { + delete(result, k) + } + } + } + } + } else if origCount, ok := attrs[countAddr]; ok && keepBlock { + result[localBlockPrefix+"#"] = origCount + } else { + result[localBlockPrefix+"#"] = countFlatmapContainerValues(localBlockPrefix+"#", result) + } + } + + return result, nil +} + +func (d *InstanceDiff) applyAttrDiff(path []string, attrs map[string]string, attrSchema *configschema.Attribute) (map[string]string, error) { + ty := attrSchema.Type + switch { + case ty.IsListType(), ty.IsTupleType(), ty.IsMapType(): + return d.applyCollectionDiff(path, attrs, attrSchema) + case ty.IsSetType(): + return d.applySetDiff(path, attrs, attrSchema) + default: + return d.applySingleAttrDiff(path, attrs, attrSchema) + } +} + +func (d *InstanceDiff) applySingleAttrDiff(path []string, attrs map[string]string, attrSchema *configschema.Attribute) (map[string]string, error) { + currentKey := strings.Join(path, ".") + + attr := path[len(path)-1] + + result := map[string]string{} + diff := d.Attributes[currentKey] + old, exists := attrs[currentKey] + + if diff != nil && diff.NewComputed { + result[attr] = hcl2shim.UnknownVariableValue + return result, nil + } + + // "id" must exist and not be an empty string, or it must be unknown. + // This only applied to top-level "id" fields. + if attr == "id" && len(path) == 1 { + if old == "" { + result[attr] = hcl2shim.UnknownVariableValue + } else { + result[attr] = old + } + return result, nil + } + + // attribute diffs are sometimes missed, so assume no diff means keep the + // old value + if diff == nil { + if exists { + result[attr] = old + } else { + // We need required values, so set those with an empty value. It + // must be set in the config, since if it were missing it would have + // failed validation. + if attrSchema.Required { + // we only set a missing string here, since bool or number types + // would have distinct zero value which shouldn't have been + // lost. + if attrSchema.Type == cty.String { + result[attr] = "" + } + } + } + return result, nil + } + + // check for missmatched diff values + if exists && + old != diff.Old && + old != hcl2shim.UnknownVariableValue && + diff.Old != hcl2shim.UnknownVariableValue { + return result, fmt.Errorf("diff apply conflict for %s: diff expects %q, but prior value has %q", attr, diff.Old, old) + } + + if diff.NewRemoved { + // don't set anything in the new value + return map[string]string{}, nil + } + + if diff.Old == diff.New && diff.New == "" { + // this can only be a valid empty string + if attrSchema.Type == cty.String { + result[attr] = "" + } + return result, nil + } + + if attrSchema.Computed && diff.NewComputed { + result[attr] = hcl2shim.UnknownVariableValue + return result, nil + } + + result[attr] = diff.New + + return result, nil +} + +func (d *InstanceDiff) applyCollectionDiff(path []string, attrs map[string]string, attrSchema *configschema.Attribute) (map[string]string, error) { + result := map[string]string{} + + prefix := "" + if len(path) > 1 { + prefix = strings.Join(path[:len(path)-1], ".") + "." + } + + name := "" + if len(path) > 0 { + name = path[len(path)-1] + } + + currentKey := prefix + name + + // check the index first for special handling + for k, diff := range d.Attributes { + // check the index value, which can be set, and 0 + if k == currentKey+".#" || k == currentKey+".%" || k == currentKey { + if diff.NewRemoved { + return result, nil + } + + if diff.NewComputed { + result[k[len(prefix):]] = hcl2shim.UnknownVariableValue + return result, nil + } + + // do what the diff tells us to here, so that it's consistent with applies + if diff.New == "0" { + result[k[len(prefix):]] = "0" + return result, nil + } + } + } + + // collect all the keys from the diff and the old state + noDiff := true + keys := map[string]bool{} + for k := range d.Attributes { + if !strings.HasPrefix(k, currentKey+".") { + continue + } + noDiff = false + keys[k] = true + } + + noAttrs := true + for k := range attrs { + if !strings.HasPrefix(k, currentKey+".") { + continue + } + noAttrs = false + keys[k] = true + } + + // If there's no diff and no attrs, then there's no value at all. + // This prevents an unexpected zero-count attribute in the attributes. + if noDiff && noAttrs { + return result, nil + } + + idx := "#" + if attrSchema.Type.IsMapType() { + idx = "%" + } + + for k := range keys { + // generate an schema placeholder for the values + elSchema := &configschema.Attribute{ + Type: attrSchema.Type.ElementType(), + } + + res, err := d.applySingleAttrDiff(append(path, k[len(currentKey)+1:]), attrs, elSchema) + if err != nil { + return result, err + } + + for k, v := range res { + result[name+"."+k] = v + } + } + + // Just like in nested list blocks, for simple lists we may need to fill in + // missing empty strings. + countKey := name + "." + idx + count := result[countKey] + length, _ := strconv.Atoi(count) + + if count != "" && count != hcl2shim.UnknownVariableValue && + attrSchema.Type.Equals(cty.List(cty.String)) { + // insert empty strings into missing indexes + for i := 0; i < length; i++ { + key := fmt.Sprintf("%s.%d", name, i) + if _, ok := result[key]; !ok { + result[key] = "" + } + } + } + + // now check for truncation in any type of list + if attrSchema.Type.IsListType() { + for key := range result { + if key == countKey { + continue + } + + if len(key) <= len(name)+1 { + // not sure what this is, but don't panic + continue + } + + index := key[len(name)+1:] + + // It is possible to have nested sets or maps, so look for another dot + dot := strings.Index(index, ".") + if dot > 0 { + index = index[:dot] + } + + // This shouldn't have any more dots, since the element type is only string. + num, err := strconv.Atoi(index) + if err != nil { + log.Printf("[ERROR] bad list index in %q: %s", currentKey, err) + continue + } + + if num >= length { + delete(result, key) + } + } + } + + // Fill in the count value if it wasn't present in the diff for some reason, + // or if there is no count at all. + _, countDiff := d.Attributes[countKey] + if result[countKey] == "" || (!countDiff && len(keys) != len(result)) { + result[countKey] = countFlatmapContainerValues(countKey, result) + } + + return result, nil +} + +func (d *InstanceDiff) applySetDiff(path []string, attrs map[string]string, attrSchema *configschema.Attribute) (map[string]string, error) { + // We only need this special behavior for sets of object. + if !attrSchema.Type.ElementType().IsObjectType() { + // The normal collection apply behavior will work okay for this one, then. + return d.applyCollectionDiff(path, attrs, attrSchema) + } + + // When we're dealing with a set of an object type we actually want to + // use our normal _block type_ apply behaviors, so we'll construct ourselves + // a synthetic schema that treats the object type as a block type and + // then delegate to our block apply method. + synthSchema := &configschema.Block{ + Attributes: make(map[string]*configschema.Attribute), + } + + for name, ty := range attrSchema.Type.ElementType().AttributeTypes() { + // We can safely make everything into an attribute here because in the + // event that there are nested set attributes we'll end up back in + // here again recursively and can then deal with the next level of + // expansion. + synthSchema.Attributes[name] = &configschema.Attribute{ + Type: ty, + Optional: true, + } + } + + parentPath := path[:len(path)-1] + childName := path[len(path)-1] + containerSchema := &configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + childName: { + Nesting: configschema.NestingSet, + Block: *synthSchema, + }, + }, + } + + return d.applyBlockDiff(parentPath, attrs, containerSchema) +} + +// countFlatmapContainerValues returns the number of values in the flatmapped container +// (set, map, list) indexed by key. The key argument is expected to include the +// trailing ".#", or ".%". +func countFlatmapContainerValues(key string, attrs map[string]string) string { + if len(key) < 3 || !(strings.HasSuffix(key, ".#") || strings.HasSuffix(key, ".%")) { + panic(fmt.Sprintf("invalid index value %q", key)) + } + + prefix := key[:len(key)-1] + items := map[string]int{} + + for k := range attrs { + if k == key { + continue + } + if !strings.HasPrefix(k, prefix) { + continue + } + + suffix := k[len(prefix):] + dot := strings.Index(suffix, ".") + if dot > 0 { + suffix = suffix[:dot] + } + + items[suffix]++ + } + return strconv.Itoa(len(items)) +} + +// ResourceAttrDiff is the diff of a single attribute of a resource. +// +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type ResourceAttrDiff struct { + Old string // Old Value + New string // New Value + NewComputed bool // True if new value is computed (unknown currently) + NewRemoved bool // True if this attribute is being removed + NewExtra interface{} // Extra information for the provider + RequiresNew bool // True if change requires new resource + Sensitive bool // True if the data should not be displayed in UI output + Type diffAttrType +} + +func (d *ResourceAttrDiff) GoString() string { + return fmt.Sprintf("*%#v", *d) +} + +// DiffAttrType is an enum type that says whether a resource attribute +// diff is an input attribute (comes from the configuration) or an +// output attribute (comes as a result of applying the configuration). An +// example input would be "ami" for AWS and an example output would be +// "private_ip". +type diffAttrType byte + +// Deprecated: This function is unintentionally exported by this Go module and +// not supported for external consumption. It will be removed in the next major +// version. +func NewInstanceDiff() *InstanceDiff { + return &InstanceDiff{Attributes: make(map[string]*ResourceAttrDiff)} +} + +// ChangeType returns the diffChangeType represented by the diff +// for this single instance. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) ChangeType() diffChangeType { + if d.Empty() { + return diffNone + } + + if d.RequiresNew() && (d.GetDestroy() || d.GetDestroyTainted()) { + return diffDestroyCreate + } + + if d.GetDestroy() || d.GetDestroyDeposed() { + return diffDestroy + } + + if d.RequiresNew() { + return diffCreate + } + + return diffUpdate +} + +// Empty returns true if this diff encapsulates no changes. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) Empty() bool { + if d == nil { + return true + } + + d.mu.Lock() + defer d.mu.Unlock() + return !d.Destroy && + !d.DestroyTainted && + !d.DestroyDeposed && + len(d.Attributes) == 0 +} + +// Equal compares two diffs for exact equality. +// +// This is different from the Same comparison that is supported which +// checks for operation equality taking into account computed values. Equal +// instead checks for exact equality. +// TODO: investigate why removing this unused method causes panic in tests +func (d *InstanceDiff) Equal(d2 *InstanceDiff) bool { + // If one is nil, they must both be nil + if d == nil || d2 == nil { + return d == d2 + } + + // Use DeepEqual + return reflect.DeepEqual(d, d2) +} + +func (d *InstanceDiff) GoString() string { + return fmt.Sprintf("*%#v", InstanceDiff{ + Attributes: d.Attributes, + Destroy: d.Destroy, + DestroyTainted: d.DestroyTainted, + DestroyDeposed: d.DestroyDeposed, + }) +} + +// RequiresNew returns true if the diff requires the creation of a new +// resource (implying the destruction of the old). +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) RequiresNew() bool { + if d == nil { + return false + } + + d.mu.Lock() + defer d.mu.Unlock() + + return d.requiresNew() +} + +func (d *InstanceDiff) requiresNew() bool { + if d == nil { + return false + } + + if d.DestroyTainted { + return true + } + + for _, rd := range d.Attributes { + if rd != nil && rd.RequiresNew { + return true + } + } + + return false +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) GetDestroyDeposed() bool { + d.mu.Lock() + defer d.mu.Unlock() + + return d.DestroyDeposed +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) GetDestroyTainted() bool { + d.mu.Lock() + defer d.mu.Unlock() + + return d.DestroyTainted +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) GetDestroy() bool { + d.mu.Lock() + defer d.mu.Unlock() + + return d.Destroy +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) GetAttribute(key string) (*ResourceAttrDiff, bool) { + d.mu.Lock() + defer d.mu.Unlock() + + attr, ok := d.Attributes[key] + return attr, ok +} + +// Safely copies the Attributes map +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) CopyAttributes() map[string]*ResourceAttrDiff { + d.mu.Lock() + defer d.mu.Unlock() + + attrs := make(map[string]*ResourceAttrDiff) + for k, v := range d.Attributes { + attrs[k] = v + } + + return attrs +} + +// Same checks whether or not two InstanceDiff's are the "same". When +// we say "same", it is not necessarily exactly equal. Instead, it is +// just checking that the same attributes are changing, a destroy +// isn't suddenly happening, etc. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) { + // we can safely compare the pointers without a lock + switch { + case d == nil && d2 == nil: + return true, "" + case d == nil || d2 == nil: + return false, "one nil" + case d == d2: + return true, "" + } + + d.mu.Lock() + defer d.mu.Unlock() + + // If we're going from requiring new to NOT requiring new, then we have + // to see if all required news were computed. If so, it is allowed since + // computed may also mean "same value and therefore not new". + oldNew := d.requiresNew() + newNew := d2.RequiresNew() + if oldNew && !newNew { + oldNew = false + + // This section builds a list of ignorable attributes for requiresNew + // by removing off any elements of collections going to zero elements. + // For collections going to zero, they may not exist at all in the + // new diff (and hence RequiresNew == false). + ignoreAttrs := make(map[string]struct{}) + for k, diffOld := range d.Attributes { + if !strings.HasSuffix(k, ".%") && !strings.HasSuffix(k, ".#") { + continue + } + + // This case is in here as a protection measure. The bug that this + // code originally fixed (GH-11349) didn't have to deal with computed + // so I'm not 100% sure what the correct behavior is. Best to leave + // the old behavior. + if diffOld.NewComputed { + continue + } + + // We're looking for the case a map goes to exactly 0. + if diffOld.New != "0" { + continue + } + + // Found it! Ignore all of these. The prefix here is stripping + // off the "%" so it is just "k." + prefix := k[:len(k)-1] + for k2 := range d.Attributes { + if strings.HasPrefix(k2, prefix) { + ignoreAttrs[k2] = struct{}{} + } + } + } + + for k, rd := range d.Attributes { + if _, ok := ignoreAttrs[k]; ok { + continue + } + + // If the field is requires new and NOT computed, then what + // we have is a diff mismatch for sure. We set that the old + // diff does REQUIRE a ForceNew. + if rd != nil && rd.RequiresNew && !rd.NewComputed { + oldNew = true + break + } + } + } + + if oldNew != newNew { + return false, fmt.Sprintf( + "diff RequiresNew; old: %t, new: %t", oldNew, newNew) + } + + // Verify that destroy matches. The second boolean here allows us to + // have mismatching Destroy if we're moving from RequiresNew true + // to false above. Therefore, the second boolean will only pass if + // we're moving from Destroy: true to false as well. + if d.Destroy != d2.GetDestroy() && d.requiresNew() == oldNew { + return false, fmt.Sprintf( + "diff: Destroy; old: %t, new: %t", d.Destroy, d2.GetDestroy()) + } + + // Go through the old diff and make sure the new diff has all the + // same attributes. To start, build up the check map to be all the keys. + checkOld := make(map[string]struct{}) + checkNew := make(map[string]struct{}) + for k := range d.Attributes { + checkOld[k] = struct{}{} + } + for k := range d2.CopyAttributes() { + checkNew[k] = struct{}{} + } + + // Make an ordered list so we are sure the approximated hashes are left + // to process at the end of the loop + keys := make([]string, 0, len(d.Attributes)) + for k := range d.Attributes { + keys = append(keys, k) + } + sort.StringSlice(keys).Sort() + + for _, k := range keys { + diffOld := d.Attributes[k] + + if _, ok := checkOld[k]; !ok { + // We're not checking this key for whatever reason (see where + // check is modified). + continue + } + + // Remove this key since we'll never hit it again + delete(checkOld, k) + delete(checkNew, k) + + _, ok := d2.GetAttribute(k) + if !ok { + // If there's no new attribute, and the old diff expected the attribute + // to be removed, that's just fine. + if diffOld.NewRemoved { + continue + } + + // If the last diff was a computed value then the absence of + // that value is allowed since it may mean the value ended up + // being the same. + if diffOld.NewComputed { + ok = true + } + + // No exact match, but maybe this is a set containing computed + // values. So check if there is an approximate hash in the key + // and if so, try to match the key. + if strings.Contains(k, "~") { + parts := strings.Split(k, ".") + parts2 := append([]string(nil), parts...) + + re := regexp.MustCompile(`^~\d+$`) + for i, part := range parts { + if re.MatchString(part) { + // we're going to consider this the base of a + // computed hash, and remove all longer matching fields + ok = true + + parts2[i] = `\d+` + parts2 = parts2[:i+1] + break + } + } + + re, err := regexp.Compile("^" + strings.Join(parts2, `\.`)) + if err != nil { + return false, fmt.Sprintf("regexp failed to compile; err: %#v", err) + } + + for k2 := range checkNew { + if re.MatchString(k2) { + delete(checkNew, k2) + } + } + } + + // This is a little tricky, but when a diff contains a computed + // list, set, or map that can only be interpolated after the apply + // command has created the dependent resources, it could turn out + // that the result is actually the same as the existing state which + // would remove the key from the diff. + if diffOld.NewComputed && (strings.HasSuffix(k, ".#") || strings.HasSuffix(k, ".%")) { + ok = true + } + + // Similarly, in a RequiresNew scenario, a list that shows up in the plan + // diff can disappear from the apply diff, which is calculated from an + // empty state. + if d.requiresNew() && (strings.HasSuffix(k, ".#") || strings.HasSuffix(k, ".%")) { + ok = true + } + + if !ok { + return false, fmt.Sprintf("attribute mismatch: %s", k) + } + } + + // search for the suffix of the base of a [computed] map, list or set. + match := multiVal.FindStringSubmatch(k) + + if diffOld.NewComputed && len(match) == 2 { + matchLen := len(match[1]) + + // This is a computed list, set, or map, so remove any keys with + // this prefix from the check list. + kprefix := k[:len(k)-matchLen] + for k2 := range checkOld { + if strings.HasPrefix(k2, kprefix) { + delete(checkOld, k2) + } + } + for k2 := range checkNew { + if strings.HasPrefix(k2, kprefix) { + delete(checkNew, k2) + } + } + } + + // We don't compare the values because we can't currently actually + // guarantee to generate the same value two two diffs created from + // the same state+config: we have some pesky interpolation functions + // that do not behave as pure functions (uuid, timestamp) and so they + // can be different each time a diff is produced. + // FIXME: Re-organize our config handling so that we don't re-evaluate + // expressions when we produce a second comparison diff during + // apply (for EvalCompareDiff). + } + + // Check for leftover attributes + if len(checkNew) > 0 { + extras := make([]string, 0, len(checkNew)) + for attr := range checkNew { + extras = append(extras, attr) + } + return false, + fmt.Sprintf("extra attributes: %s", strings.Join(extras, ", ")) + } + + return true, "" +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/instancetype.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/instancetype.go new file mode 100644 index 00000000..18714458 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/instancetype.go @@ -0,0 +1,19 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package terraform + +// This code was previously generated with a go:generate directive calling: +// go run golang.org/x/tools/cmd/stringer -type=instanceType instancetype.go +// However, it is now considered frozen and the tooling dependency has been +// removed. The String method can be manually updated if necessary. + +// instanceType is an enum of the various types of instances store in the State +type instanceType int + +const ( + typeInvalid instanceType = iota + typePrimary + typeTainted + typeDeposed +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/instancetype_string.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/instancetype_string.go new file mode 100644 index 00000000..782ef90c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/instancetype_string.go @@ -0,0 +1,26 @@ +// Code generated by "stringer -type=instanceType instancetype.go"; DO NOT EDIT. + +package terraform + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[typeInvalid-0] + _ = x[typePrimary-1] + _ = x[typeTainted-2] + _ = x[typeDeposed-3] +} + +const _instanceType_name = "typeInvalidtypePrimarytypeTaintedtypeDeposed" + +var _instanceType_index = [...]uint8{0, 11, 22, 33, 44} + +func (i instanceType) String() string { + if i < 0 || i >= instanceType(len(_instanceType_index)-1) { + return "instanceType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _instanceType_name[_instanceType_index[i]:_instanceType_index[i+1]] +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource.go new file mode 100644 index 00000000..e5887b53 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource.go @@ -0,0 +1,362 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package terraform + +import ( + "fmt" + "reflect" + "sort" + "strconv" + "strings" + + "github.com/hashicorp/go-cty/cty" + + "github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema" + "github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim" +) + +// InstanceInfo is used to hold information about the instance and/or +// resource being modified. +// +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type InstanceInfo struct { + // Id is a unique name to represent this instance. This is not related + // to InstanceState.ID in any way. + Id string + + // ModulePath is the complete path of the module containing this + // instance. + ModulePath []string + + // Type is the resource type of this instance + Type string +} + +// ResourceConfig is a legacy type that was formerly used to represent +// interpolatable configuration blocks. It is now only used to shim to old +// APIs that still use this type, via NewResourceConfigShimmed. +// +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type ResourceConfig struct { + ComputedKeys []string + Raw map[string]interface{} + Config map[string]interface{} +} + +// NewResourceConfigRaw constructs a ResourceConfig whose content is exactly +// the given value. +// +// The given value may contain hcl2shim.UnknownVariableValue to signal that +// something is computed, but it must not contain unprocessed interpolation +// sequences as we might've seen in Terraform v0.11 and prior. +// +// Deprecated: This function is unintentionally exported by this Go module and +// not supported for external consumption. It will be removed in the next major +// version. Use real Terraform configuration instead. +func NewResourceConfigRaw(raw map[string]interface{}) *ResourceConfig { + v := hcl2shim.HCL2ValueFromConfigValue(raw) + + // This is a little weird but we round-trip the value through the hcl2shim + // package here for two reasons: firstly, because that reduces the risk + // of it including something unlike what NewResourceConfigShimmed would + // produce, and secondly because it creates a copy of "raw" just in case + // something is relying on the fact that in the old world the raw and + // config maps were always distinct, and thus you could in principle mutate + // one without affecting the other. (I sure hope nobody was doing that, though!) + //nolint:forcetypeassert + cfg := hcl2shim.ConfigValueFromHCL2(v).(map[string]interface{}) + + return &ResourceConfig{ + Raw: raw, + Config: cfg, + + ComputedKeys: newResourceConfigShimmedComputedKeys(v, ""), + } +} + +// NewResourceConfigShimmed wraps a cty.Value of object type in a legacy +// ResourceConfig object, so that it can be passed to older APIs that expect +// this wrapping. +// +// The returned ResourceConfig is already interpolated and cannot be +// re-interpolated. It is, therefore, useful only to functions that expect +// an already-populated ResourceConfig which they then treat as read-only. +// +// If the given value is not of an object type that conforms to the given +// schema then this function will panic. +// +// Deprecated: This function is unintentionally exported by this Go module and +// not supported for external consumption. It will be removed in the next major +// version. +func NewResourceConfigShimmed(val cty.Value, schema *configschema.Block) *ResourceConfig { + if !val.Type().IsObjectType() { + panic(fmt.Errorf("NewResourceConfigShimmed given %#v; an object type is required", val.Type())) + } + ret := &ResourceConfig{} + + legacyVal := hcl2shim.ConfigValueFromHCL2Block(val, schema) + if legacyVal != nil { + ret.Config = legacyVal + + // Now we need to walk through our structure and find any unknown values, + // producing the separate list ComputedKeys to represent these. We use the + // schema here so that we can preserve the expected invariant + // that an attribute is always either wholly known or wholly unknown, while + // a child block can be partially unknown. + ret.ComputedKeys = newResourceConfigShimmedComputedKeys(val, "") + } else { + ret.Config = make(map[string]interface{}) + } + ret.Raw = ret.Config + + return ret +} + +// Record the any config values in ComputedKeys. This field had been unused in +// helper/schema, but in the new protocol we're using this so that the SDK can +// now handle having an unknown collection. The legacy diff code doesn't +// properly handle the unknown, because it can't be expressed in the same way +// between the config and diff. +func newResourceConfigShimmedComputedKeys(val cty.Value, path string) []string { + var ret []string + ty := val.Type() + + if val.IsNull() { + return ret + } + + if !val.IsKnown() { + // we shouldn't have an entirely unknown resource, but prevent empty + // strings just in case + if len(path) > 0 { + ret = append(ret, path) + } + return ret + } + + if path != "" { + path += "." + } + switch { + case ty.IsListType(), ty.IsTupleType(), ty.IsSetType(): + i := 0 + for it := val.ElementIterator(); it.Next(); i++ { + _, subVal := it.Element() + keys := newResourceConfigShimmedComputedKeys(subVal, fmt.Sprintf("%s%d", path, i)) + ret = append(ret, keys...) + } + + case ty.IsMapType(), ty.IsObjectType(): + for it := val.ElementIterator(); it.Next(); { + subK, subVal := it.Element() + keys := newResourceConfigShimmedComputedKeys(subVal, fmt.Sprintf("%s%s", path, subK.AsString())) + ret = append(ret, keys...) + } + } + + return ret +} + +// DeepCopy performs a deep copy of the configuration. This makes it safe +// to modify any of the structures that are part of the resource config without +// affecting the original configuration. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (c *ResourceConfig) DeepCopy() *ResourceConfig { + // DeepCopying a nil should return a nil to avoid panics + if c == nil { + return nil + } + + copied := &ResourceConfig{} + + if c.ComputedKeys != nil { + copied.ComputedKeys = make([]string, len(c.ComputedKeys)) + + copy(copied.ComputedKeys, c.ComputedKeys) + } + + if c.Config != nil { + copied.Config = make(map[string]any, len(c.Config)) + + for key, value := range c.Config { + copied.Config[key] = value + } + } + + if c.Raw != nil { + copied.Raw = make(map[string]any, len(c.Raw)) + + for key, value := range c.Raw { + copied.Raw[key] = value + } + } + + return copied +} + +// Equal checks the equality of two resource configs. +func (c *ResourceConfig) Equal(c2 *ResourceConfig) bool { + // If either are nil, then they're only equal if they're both nil + if c == nil || c2 == nil { + return c == c2 + } + + // Sort the computed keys so they're deterministic + sort.Strings(c.ComputedKeys) + sort.Strings(c2.ComputedKeys) + + // Two resource configs if their exported properties are equal. + // We don't compare "raw" because it is never used again after + // initialization and for all intents and purposes they are equal + // if the exported properties are equal. + check := [][2]interface{}{ + {c.ComputedKeys, c2.ComputedKeys}, + {c.Raw, c2.Raw}, + {c.Config, c2.Config}, + } + for _, pair := range check { + if !reflect.DeepEqual(pair[0], pair[1]) { + return false + } + } + + return true +} + +// Get looks up a configuration value by key and returns the value. +// +// The second return value is true if the get was successful. Get will +// return the raw value if the key is computed, so you should pair this +// with IsComputed. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (c *ResourceConfig) Get(k string) (interface{}, bool) { + // We aim to get a value from the configuration. If it is computed, + // then we return the pure raw value. + source := c.Config + if c.IsComputed(k) { + source = c.Raw + } + + return c.get(k, source) +} + +// GetRaw looks up a configuration value by key and returns the value, +// from the raw, uninterpolated config. +// +// The second return value is true if the get was successful. Get will +// not succeed if the value is being computed. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (c *ResourceConfig) GetRaw(k string) (interface{}, bool) { + return c.get(k, c.Raw) +} + +// IsComputed returns whether the given key is computed or not. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (c *ResourceConfig) IsComputed(k string) bool { + // The next thing we do is check the config if we get a computed + // value out of it. + v, ok := c.get(k, c.Config) + if !ok { + return false + } + + // If value is nil, then it isn't computed + if v == nil { + return false + } + + // Test if the value contains an unknown value + return unknownValueWalk(reflect.ValueOf(v)) +} + +func (c *ResourceConfig) get( + k string, raw map[string]interface{}) (interface{}, bool) { + parts := strings.Split(k, ".") + if len(parts) == 1 && parts[0] == "" { + parts = nil + } + + var current interface{} = raw + var previous interface{} = nil + for i, part := range parts { + if current == nil { + return nil, false + } + + cv := reflect.ValueOf(current) + switch cv.Kind() { + case reflect.Map: + previous = current + v := cv.MapIndex(reflect.ValueOf(part)) + if !v.IsValid() { + if i > 0 && i != (len(parts)-1) { + tryKey := strings.Join(parts[i:], ".") + v := cv.MapIndex(reflect.ValueOf(tryKey)) + if !v.IsValid() { + return nil, false + } + + return v.Interface(), true + } + + return nil, false + } + + current = v.Interface() + case reflect.Slice: + previous = current + + if part == "#" { + // If any value in a list is computed, this whole thing + // is computed and we can't read any part of it. + for i := 0; i < cv.Len(); i++ { + if v := cv.Index(i).Interface(); v == hcl2shim.UnknownVariableValue { + return v, true + } + } + + current = cv.Len() + } else { + i, err := strconv.ParseInt(part, 0, 0) + if err != nil { + return nil, false + } + if int(i) < 0 || int(i) >= cv.Len() { + return nil, false + } + current = cv.Index(int(i)).Interface() + } + case reflect.String: + // This happens when map keys contain "." and have a common + // prefix so were split as path components above. + actualKey := strings.Join(parts[i-1:], ".") + if prevMap, ok := previous.(map[string]interface{}); ok { + v, ok := prevMap[actualKey] + return v, ok + } + + return nil, false + default: + panic(fmt.Sprintf("Unknown kind: %s", cv.Kind())) + } + } + + return current, true +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_address.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_address.go new file mode 100644 index 00000000..8d92fbb5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_address.go @@ -0,0 +1,229 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package terraform + +import ( + "fmt" + "reflect" + "regexp" + "strconv" + "strings" +) + +// resourceAddress is a way of identifying an individual resource (or, +// eventually, a subset of resources) within the state. It is used for Targets. +type resourceAddress struct { + // Addresses a resource falling somewhere in the module path + // When specified alone, addresses all resources within a module path + Path []string + + // Addresses a specific resource that occurs in a list + Index int + + InstanceType instanceType + InstanceTypeSet bool + Name string + Type string + Mode ResourceMode // significant only if InstanceTypeSet +} + +// String outputs the address that parses into this address. +func (r *resourceAddress) String() string { + var result []string + for _, p := range r.Path { + result = append(result, "module", p) + } + + switch r.Mode { + case ManagedResourceMode: + // nothing to do + case DataResourceMode: + result = append(result, "data") + default: + panic(fmt.Errorf("unsupported resource mode %s", r.Mode)) + } + + if r.Type != "" { + result = append(result, r.Type) + } + + if r.Name != "" { + name := r.Name + if r.InstanceTypeSet { + switch r.InstanceType { + case typePrimary: + name += ".primary" + case typeDeposed: + name += ".deposed" + case typeTainted: + name += ".tainted" + } + } + + if r.Index >= 0 { + name += fmt.Sprintf("[%d]", r.Index) + } + result = append(result, name) + } + + return strings.Join(result, ".") +} + +func parseResourceAddress(s string) (*resourceAddress, error) { + matches, err := tokenizeResourceAddress(s) + if err != nil { + return nil, err + } + mode := ManagedResourceMode + if matches["data_prefix"] != "" { + mode = DataResourceMode + } + resourceIndex, err := parseResourceIndex(matches["index"]) + if err != nil { + return nil, err + } + instanceType, err := parseInstanceType(matches["instance_type"]) + if err != nil { + return nil, err + } + path := parseResourcePath(matches["path"]) + + // not allowed to say "data." without a type following + if mode == DataResourceMode && matches["type"] == "" { + return nil, fmt.Errorf( + "invalid resource address %q: must target specific data instance", + s, + ) + } + + return &resourceAddress{ + Path: path, + Index: resourceIndex, + InstanceType: instanceType, + InstanceTypeSet: matches["instance_type"] != "", + Name: matches["name"], + Type: matches["type"], + Mode: mode, + }, nil +} + +// Less returns true if and only if the receiver should be sorted before +// the given address when presenting a list of resource addresses to +// an end-user. +// +// This sort uses lexicographic sorting for most components, but uses +// numeric sort for indices, thus causing index 10 to sort after +// index 9, rather than after index 1. +func (addr *resourceAddress) Less(other *resourceAddress) bool { + + switch { + + case len(addr.Path) != len(other.Path): + return len(addr.Path) < len(other.Path) + + case !reflect.DeepEqual(addr.Path, other.Path): + // If the two paths are the same length but don't match, we'll just + // cheat and compare the string forms since it's easier than + // comparing all of the path segments in turn, and lexicographic + // comparison is correct for the module path portion. + addrStr := addr.String() + otherStr := other.String() + return addrStr < otherStr + + case addr.Mode != other.Mode: + return addr.Mode == DataResourceMode + + case addr.Type != other.Type: + return addr.Type < other.Type + + case addr.Name != other.Name: + return addr.Name < other.Name + + case addr.Index != other.Index: + // Since "Index" is -1 for an un-indexed address, this also conveniently + // sorts unindexed addresses before indexed ones, should they both + // appear for some reason. + return addr.Index < other.Index + + case addr.InstanceTypeSet != other.InstanceTypeSet: + return !addr.InstanceTypeSet + + case addr.InstanceType != other.InstanceType: + // InstanceType is actually an enum, so this is just an arbitrary + // sort based on the enum numeric values, and thus not particularly + // meaningful. + return addr.InstanceType < other.InstanceType + + default: + return false + + } +} + +func parseResourceIndex(s string) (int, error) { + if s == "" { + return -1, nil + } + return strconv.Atoi(s) +} + +func parseResourcePath(s string) []string { + if s == "" { + return nil + } + parts := strings.Split(s, ".") + path := make([]string, 0, len(parts)) + for _, s := range parts { + // Due to the limitations of the regexp match below, the path match has + // some noise in it we have to filter out :| + if s == "" || s == "module" { + continue + } + path = append(path, s) + } + return path +} + +func parseInstanceType(s string) (instanceType, error) { + switch s { + case "", "primary": + return typePrimary, nil + case "deposed": + return typeDeposed, nil + case "tainted": + return typeTainted, nil + default: + return typeInvalid, fmt.Errorf("Unexpected value for instanceType field: %q", s) + } +} + +func tokenizeResourceAddress(s string) (map[string]string, error) { + // Example of portions of the regexp below using the + // string "aws_instance.web.tainted[1]" + re := regexp.MustCompile(`\A` + + // "module.foo.module.bar" (optional) + `(?P(?:module\.(?P[^.]+)\.?)*)` + + // possibly "data.", if targeting is a data resource + `(?P(?:data\.)?)` + + // "aws_instance.web" (optional when module path specified) + `(?:(?P[^.]+)\.(?P[^.[]+))?` + + // "tainted" (optional, omission implies: "primary") + `(?:\.(?P\w+))?` + + // "1" (optional, omission implies: "0") + `(?:\[(?P\d+)\])?` + + `\z`) + + groupNames := re.SubexpNames() + rawMatches := re.FindAllStringSubmatch(s, -1) + if len(rawMatches) != 1 { + return nil, fmt.Errorf("invalid resource address %q", s) + } + + matches := make(map[string]string) + for i, m := range rawMatches[0] { + matches[groupNames[i]] = m + } + + return matches, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_mode.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_mode.go new file mode 100644 index 00000000..2d7b10bc --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_mode.go @@ -0,0 +1,18 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package terraform + +// This code was previously generated with a go:generate directive calling: +// go run golang.org/x/tools/cmd/stringer -type=ResourceMode -output=resource_mode_string.go resource_mode.go +// However, it is now considered frozen and the tooling dependency has been +// removed. The String method can be manually updated if necessary. + +// ResourceMode is deprecated, use addrs.ResourceMode instead. +// It has been preserved for backwards compatibility. +type ResourceMode int + +const ( + ManagedResourceMode ResourceMode = iota + DataResourceMode +) diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_mode_string.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_mode_string.go new file mode 100644 index 00000000..ba84346a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_mode_string.go @@ -0,0 +1,24 @@ +// Code generated by "stringer -type=ResourceMode -output=resource_mode_string.go resource_mode.go"; DO NOT EDIT. + +package terraform + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ManagedResourceMode-0] + _ = x[DataResourceMode-1] +} + +const _ResourceMode_name = "ManagedResourceModeDataResourceMode" + +var _ResourceMode_index = [...]uint8{0, 19, 35} + +func (i ResourceMode) String() string { + if i < 0 || i >= ResourceMode(len(_ResourceMode_index)-1) { + return "ResourceMode(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _ResourceMode_name[_ResourceMode_index[i]:_ResourceMode_index[i+1]] +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_provider.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_provider.go new file mode 100644 index 00000000..6de28354 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/resource_provider.go @@ -0,0 +1,37 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package terraform + +// ResourceType is a type of resource that a resource provider can manage. +// +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type ResourceType struct { + Name string // Name of the resource, example "instance" (no provider prefix) + Importable bool // Whether this resource supports importing + + // SchemaAvailable is set if the provider supports the ProviderSchema, + // ResourceTypeSchema and DataSourceSchema methods. Although it is + // included on each resource type, it's actually a provider-wide setting + // that's smuggled here only because that avoids a breaking change to + // the plugin protocol. + SchemaAvailable bool +} + +// DataSource is a data source that a resource provider implements. +// +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type DataSource struct { + Name string + + // SchemaAvailable is set if the provider supports the ProviderSchema, + // ResourceTypeSchema and DataSourceSchema methods. Although it is + // included on each resource type, it's actually a provider-wide setting + // that's smuggled here only because that avoids a breaking change to + // the plugin protocol. + SchemaAvailable bool +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/schemas.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/schemas.go new file mode 100644 index 00000000..1cec2eb6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/schemas.go @@ -0,0 +1,37 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package terraform + +import ( + "github.com/hashicorp/terraform-plugin-testing/internal/configs/configschema" +) + +// ProviderSchema represents the schema for a provider's own configuration +// and the configuration for some or all of its resources and data sources. +// +// The completeness of this structure depends on how it was constructed. +// When constructed for a configuration, it will generally include only +// resource types and data sources used by that configuration. +// +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type ProviderSchema struct { + Provider *configschema.Block + ResourceTypes map[string]*configschema.Block + DataSources map[string]*configschema.Block + + ResourceTypeSchemaVersions map[string]uint64 +} + +// ProviderSchemaRequest is used to describe to a ResourceProvider which +// aspects of schema are required, when calling the GetSchema method. +// +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type ProviderSchemaRequest struct { + ResourceTypes []string + DataSources []string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/state.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/state.go new file mode 100644 index 00000000..68267757 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/state.go @@ -0,0 +1,1876 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package terraform + +import ( + "bufio" + "bytes" + "encoding/json" + "errors" + "fmt" + "log" + "os" + "reflect" + "sort" + "strconv" + "strings" + "sync" + + "github.com/hashicorp/go-cty/cty" + "github.com/hashicorp/go-uuid" + + "github.com/hashicorp/terraform-plugin-testing/internal/addrs" + "github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim" +) + +const ( + // StateVersion is the current version for our state file + stateVersion = 3 +) + +// rootModulePath is the path of the root module +var rootModulePath = []string{"root"} + +// normalizeModulePath transforms a legacy module path (which may or may not +// have a redundant "root" label at the start of it) into an +// addrs.ModuleInstance representing the same module. +// +// For legacy reasons, different parts of Terraform disagree about whether the +// root module has the path []string{} or []string{"root"}, and so this +// function accepts both and trims off the "root". An implication of this is +// that it's not possible to actually have a module call in the root module +// that is itself named "root", since that would be ambiguous. +// +// normalizeModulePath takes a raw module path and returns a path that +// has the rootModulePath prepended to it. If I could go back in time I +// would've never had a rootModulePath (empty path would be root). We can +// still fix this but thats a big refactor that my branch doesn't make sense +// for. Instead, this function normalizes paths. +func normalizeModulePath(p []string) addrs.ModuleInstance { + // FIXME: Remove this once everyone is using addrs.ModuleInstance. + + if len(p) > 0 && p[0] == "root" { + p = p[1:] + } + + ret := make(addrs.ModuleInstance, len(p)) + for i, name := range p { + // For now we don't actually support modules with multiple instances + // identified by keys, so we just treat every path element as a + // step with no key. + ret[i] = addrs.ModuleInstanceStep{ + Name: name, + } + } + return ret +} + +// State keeps track of a snapshot state-of-the-world that Terraform +// can use to keep track of what real world resources it is actually +// managing. +type State struct { + // Version is the state file protocol version. + Version int `json:"version"` + + // TFVersion is the version of Terraform that wrote this state. + TFVersion string `json:"terraform_version,omitempty"` + + // Serial is incremented on any operation that modifies + // the State file. It is used to detect potentially conflicting + // updates. + Serial int64 `json:"serial"` + + // Lineage is set when a new, blank state is created and then + // never updated. This allows us to determine whether the serials + // of two states can be meaningfully compared. + // Apart from the guarantee that collisions between two lineages + // are very unlikely, this value is opaque and external callers + // should only compare lineage strings byte-for-byte for equality. + Lineage string `json:"lineage"` + + // Remote is used to track the metadata required to + // pull and push state files from a remote storage endpoint. + // + // Deprecated: This field is unintentionally exported by this Go module and + // external consumption is not supported. It will be removed in the next + // major version. + Remote *RemoteState `json:"remote,omitempty"` + + // Backend tracks the configuration for the backend in use with + // this state. This is used to track any changes in the backend + // configuration. + // + // Deprecated: This field is unintentionally exported by this Go module and + // external consumption is not supported. It will be removed in the next + // major version. + Backend *BackendState `json:"backend,omitempty"` + + // Modules contains all the modules in a breadth-first order + Modules []*ModuleState `json:"modules"` + + mu sync.Mutex + + // IsBinaryDrivenTest is a special flag that assists with a binary driver + // heuristic, it should not be set externally + // + // Deprecated: This field is unintentionally exported by this Go module and + // external consumption is not supported. It will be removed in the next + // major version. + IsBinaryDrivenTest bool +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) Lock() { s.mu.Lock() } + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) Unlock() { s.mu.Unlock() } + +// NewState is used to initialize a blank state +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func NewState() *State { + s := &State{} + s.init() + return s +} + +// Children returns the ModuleStates that are direct children of +// the given path. If the path is "root", for example, then children +// returned might be "root.child", but not "root.child.grandchild". +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) Children(path []string) []*ModuleState { + s.Lock() + defer s.Unlock() + // TODO: test + + return s.children(path) +} + +func (s *State) children(path []string) []*ModuleState { + result := make([]*ModuleState, 0) + for _, m := range s.Modules { + if m == nil { + continue + } + + if len(m.Path) != len(path)+1 { + continue + } + if !reflect.DeepEqual(path, m.Path[:len(path)]) { + continue + } + + result = append(result, m) + } + + return result +} + +// AddModule adds the module with the given path to the state. +// +// This should be the preferred method to add module states since it +// allows us to optimize lookups later as well as control sorting. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) AddModule(path addrs.ModuleInstance) *ModuleState { + s.Lock() + defer s.Unlock() + + return s.addModule(path) +} + +func (s *State) addModule(path addrs.ModuleInstance) *ModuleState { + // check if the module exists first + m := s.moduleByPath(path) + if m != nil { + return m + } + + // Lower the new-style address into a legacy-style address. + // This requires that none of the steps have instance keys, which is + // true for all addresses at the time of implementing this because + // "count" and "for_each" are not yet implemented for modules. + // For the purposes of state, the legacy address format also includes + // a redundant extra prefix element "root". It is important to include + // this because the "prune" method will remove any module that has a + // path length less than one, and other parts of the state code will + // trim off the first element indiscriminately. + legacyPath := make([]string, len(path)+1) + legacyPath[0] = "root" + for i, step := range path { + if step.InstanceKey != addrs.NoKey { + // FIXME: Once the rest of Terraform is ready to use count and + // for_each, remove all of this and just write the addrs.ModuleInstance + // value itself into the ModuleState. + panic("state cannot represent modules with count or for_each keys") + } + + legacyPath[i+1] = step.Name + } + + m = &ModuleState{Path: legacyPath} + m.init() + s.Modules = append(s.Modules, m) + s.sort() + return m +} + +// ModuleByPath is used to lookup the module state for the given path. +// This should be the preferred lookup mechanism as it allows for future +// lookup optimizations. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) ModuleByPath(path addrs.ModuleInstance) *ModuleState { + if s == nil { + return nil + } + s.Lock() + defer s.Unlock() + + return s.moduleByPath(path) +} + +func (s *State) moduleByPath(path addrs.ModuleInstance) *ModuleState { + for _, mod := range s.Modules { + if mod == nil { + continue + } + if mod.Path == nil { + panic("missing module path") + } + modPath := normalizeModulePath(mod.Path) + if modPath.String() == path.String() { + return mod + } + } + return nil +} + +// Empty returns true if the state is empty. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) Empty() bool { + if s == nil { + return true + } + s.Lock() + defer s.Unlock() + + return len(s.Modules) == 0 +} + +// HasResources returns true if the state contains any resources. +// +// This is similar to !s.Empty, but returns true also in the case where the +// state has modules but all of them are devoid of resources. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) HasResources() bool { + if s.Empty() { + return false + } + + for _, mod := range s.Modules { + if len(mod.Resources) > 0 { + return true + } + } + + return false +} + +// IsRemote returns true if State represents a state that exists and is +// remote. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) IsRemote() bool { + if s == nil { + return false + } + s.Lock() + defer s.Unlock() + + if s.Remote == nil { + return false + } + if s.Remote.Type == "" { + return false + } + + return true +} + +// Validate validates the integrity of this state file. +// +// Certain properties of the statefile are expected by Terraform in order +// to behave properly. The core of Terraform will assume that once it +// receives a State structure that it has been validated. This validation +// check should be called to ensure that. +// +// If this returns an error, then the user should be notified. The error +// response will include detailed information on the nature of the error. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) Validate() error { + s.Lock() + defer s.Unlock() + + var result []error + + // !!!! FOR DEVELOPERS !!!! + // + // Any errors returned from this Validate function will BLOCK TERRAFORM + // from loading a state file. Therefore, this should only contain checks + // that are only resolvable through manual intervention. + // + // !!!! FOR DEVELOPERS !!!! + + // Make sure there are no duplicate module states. We open a new + // block here so we can use basic variable names and future validations + // can do the same. + { + found := make(map[string]struct{}) + for _, ms := range s.Modules { + if ms == nil { + continue + } + + key := strings.Join(ms.Path, ".") + if _, ok := found[key]; ok { + result = append(result, fmt.Errorf( + strings.TrimSpace(stateValidateErrMultiModule), key)) + continue + } + + found[key] = struct{}{} + } + } + + return errors.Join(result...) +} + +// Remove removes the item in the state at the given address, returning +// any errors that may have occurred. +// +// If the address references a module state or resource, it will delete +// all children as well. To check what will be deleted, use a StateFilter +// first. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) Remove(addr ...string) error { + s.Lock() + defer s.Unlock() + + // Filter out what we need to delete + filter := &stateFilter{State: s} + results, err := filter.filter(addr...) + if err != nil { + return err + } + + // If we have no results, just exit early, we're not going to do anything. + // While what happens below is fairly fast, this is an important early + // exit since the prune below might modify the state more and we don't + // want to modify the state if we don't have to. + if len(results) == 0 { + return nil + } + + // Go through each result and grab what we need + removed := make(map[interface{}]struct{}) + for _, r := range results { + // Convert the path to our own type + path := append([]string{"root"}, r.Path...) + + // If we removed this already, then ignore + if _, ok := removed[r.Value]; ok { + continue + } + + // If we removed the parent already, then ignore + if r.Parent != nil { + if _, ok := removed[r.Parent.Value]; ok { + continue + } + } + + // Add this to the removed list + removed[r.Value] = struct{}{} + + switch v := r.Value.(type) { + case *ModuleState: + s.removeModule(v) + case *ResourceState: + s.removeResource(path, v) + case *InstanceState: + //nolint:forcetypeassert + s.removeInstance(r.Parent.Value.(*ResourceState), v) + default: + return fmt.Errorf("unknown type to delete: %T", r.Value) + } + } + + // Prune since the removal functions often do the bare minimum to + // remove a thing and may leave around dangling empty modules, resources, + // etc. Prune will clean that all up. + s.prune() + + return nil +} + +func (s *State) removeModule(v *ModuleState) { + for i, m := range s.Modules { + if m == v { + s.Modules, s.Modules[len(s.Modules)-1] = append(s.Modules[:i], s.Modules[i+1:]...), nil + return + } + } +} + +func (s *State) removeResource(path []string, v *ResourceState) { + // Get the module this resource lives in. If it doesn't exist, we're done. + mod := s.moduleByPath(normalizeModulePath(path)) + if mod == nil { + return + } + + // Find this resource. This is a O(N) lookup when if we had the key + // it could be O(1) but even with thousands of resources this shouldn't + // matter right now. We can easily up performance here when the time comes. + for k, r := range mod.Resources { + if r == v { + // Found it + delete(mod.Resources, k) + return + } + } +} + +func (s *State) removeInstance(r *ResourceState, v *InstanceState) { + // Go through the resource and find the instance that matches this + // (if any) and remove it. + + // Check primary + if r.Primary == v { + r.Primary = nil + return + } +} + +// RootModule returns the ModuleState for the root module +func (s *State) RootModule() *ModuleState { + root := s.ModuleByPath(addrs.RootModuleInstance) + if root == nil { + panic("missing root module") + } + return root +} + +// Equal tests if one state is equal to another. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) Equal(other *State) bool { + // If one is nil, we do a direct check + if s == nil || other == nil { + return s == other + } + + s.Lock() + defer s.Unlock() + return s.equal(other) +} + +func (s *State) equal(other *State) bool { + if s == nil || other == nil { + return s == other + } + + // If the versions are different, they're certainly not equal + if s.Version != other.Version { + return false + } + + // If any of the modules are not equal, then this state isn't equal + if len(s.Modules) != len(other.Modules) { + return false + } + for _, m := range s.Modules { + // This isn't very optimal currently but works. + otherM := other.moduleByPath(normalizeModulePath(m.Path)) + if otherM == nil { + return false + } + + // If they're not equal, then we're not equal! + if !m.Equal(otherM) { + return false + } + } + + return true +} + +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type StateAgeComparison int + +const ( + StateAgeEqual StateAgeComparison = 0 + StateAgeReceiverNewer StateAgeComparison = 1 + StateAgeReceiverOlder StateAgeComparison = -1 +) + +// CompareAges compares one state with another for which is "older". +// +// This is a simple check using the state's serial, and is thus only as +// reliable as the serial itself. In the normal case, only one state +// exists for a given combination of lineage/serial, but Terraform +// does not guarantee this and so the result of this method should be +// used with care. +// +// Returns an integer that is negative if the receiver is older than +// the argument, positive if the converse, and zero if they are equal. +// An error is returned if the two states are not of the same lineage, +// in which case the integer returned has no meaning. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) CompareAges(other *State) (StateAgeComparison, error) { + // nil states are "older" than actual states + switch { + case s != nil && other == nil: + return StateAgeReceiverNewer, nil + case s == nil && other != nil: + return StateAgeReceiverOlder, nil + case s == nil && other == nil: + return StateAgeEqual, nil + } + + if !s.SameLineage(other) { + return StateAgeEqual, fmt.Errorf( + "can't compare two states of differing lineage", + ) + } + + s.Lock() + defer s.Unlock() + + switch { + case s.Serial < other.Serial: + return StateAgeReceiverOlder, nil + case s.Serial > other.Serial: + return StateAgeReceiverNewer, nil + default: + return StateAgeEqual, nil + } +} + +// SameLineage returns true only if the state given in argument belongs +// to the same "lineage" of states as the receiver. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) SameLineage(other *State) bool { + s.Lock() + defer s.Unlock() + + // If one of the states has no lineage then it is assumed to predate + // this concept, and so we'll accept it as belonging to any lineage + // so that a lineage string can be assigned to newer versions + // without breaking compatibility with older versions. + if s.Lineage == "" || other.Lineage == "" { + return true + } + + return s.Lineage == other.Lineage +} + +// DeepCopy performs a deep copy of the state structure and returns +// a new structure. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) DeepCopy() *State { + if s == nil { + return nil + } + + copied := &State{ + IsBinaryDrivenTest: s.IsBinaryDrivenTest, + Lineage: s.Lineage, + Serial: s.Serial, + TFVersion: s.TFVersion, + Version: s.Version, + } + + if s.Backend != nil { + copied.Backend = &BackendState{ + Hash: s.Backend.Hash, + ConfigRaw: s.Backend.ConfigRaw, + Type: s.Backend.Type, + } + } + + // Best effort single level copy is fine; this is method is not used by this + // Go module and its already deprecated. + if s.Modules != nil { + copied.Modules = make([]*ModuleState, len(s.Modules)) + + copy(copied.Modules, s.Modules) + } + + if s.Remote != nil { + copied.Remote = &RemoteState{ + Type: s.Remote.Type, + } + + if s.Remote.Config != nil { + copied.Remote.Config = make(map[string]string, len(s.Remote.Config)) + + for key, value := range s.Remote.Config { + copied.Remote.Config[key] = value + } + } + } + + return copied +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) Init() { + s.Lock() + defer s.Unlock() + s.init() +} + +func (s *State) init() { + if s.Version == 0 { + s.Version = stateVersion + } + + if s.moduleByPath(addrs.RootModuleInstance) == nil { + s.addModule(addrs.RootModuleInstance) + } + s.ensureHasLineage() + + for _, mod := range s.Modules { + if mod != nil { + mod.init() + } + } + + if s.Remote != nil { + s.Remote.init() + } + +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) EnsureHasLineage() { + s.Lock() + defer s.Unlock() + + s.ensureHasLineage() +} + +func (s *State) ensureHasLineage() { + if s.Lineage == "" { + lineage, err := uuid.GenerateUUID() + if err != nil { + panic(fmt.Errorf("Failed to generate lineage: %v", err)) + } + s.Lineage = lineage + if os.Getenv("TF_ACC") == "" || os.Getenv("TF_ACC_STATE_LINEAGE") == "1" { + log.Printf("[DEBUG] New state was assigned lineage %q\n", s.Lineage) + } + } else { + if os.Getenv("TF_ACC") == "" || os.Getenv("TF_ACC_STATE_LINEAGE") == "1" { + log.Printf("[TRACE] Preserving existing state lineage %q\n", s.Lineage) + } + } +} + +// AddModuleState insert this module state and override any existing ModuleState +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *State) AddModuleState(mod *ModuleState) { + mod.init() + s.Lock() + defer s.Unlock() + + s.addModuleState(mod) +} + +func (s *State) addModuleState(mod *ModuleState) { + for i, m := range s.Modules { + if reflect.DeepEqual(m.Path, mod.Path) { + s.Modules[i] = mod + return + } + } + + s.Modules = append(s.Modules, mod) + s.sort() +} + +// prune is used to remove any resources that are no longer required +func (s *State) prune() { + if s == nil { + return + } + + // Filter out empty modules. + // A module is always assumed to have a path, and it's length isn't always + // bounds checked later on. Modules may be "emptied" during destroy, but we + // never want to store those in the state. + for i := 0; i < len(s.Modules); i++ { + if s.Modules[i] == nil || len(s.Modules[i].Path) == 0 { + s.Modules = append(s.Modules[:i], s.Modules[i+1:]...) + i-- + } + } + + for _, mod := range s.Modules { + mod.prune() + } + if s.Remote != nil && s.Remote.Empty() { + s.Remote = nil + } +} + +// sort sorts the modules +func (s *State) sort() { + sort.Sort(moduleStateSort(s.Modules)) + + // Allow modules to be sorted + for _, m := range s.Modules { + if m != nil { + m.sort() + } + } +} + +func (s *State) String() string { + if s == nil { + return "" + } + s.Lock() + defer s.Unlock() + + var buf bytes.Buffer + for _, m := range s.Modules { + mStr := m.String() + + // If we're the root module, we just write the output directly. + if reflect.DeepEqual(m.Path, rootModulePath) { + buf.WriteString(mStr + "\n") + continue + } + + buf.WriteString(fmt.Sprintf("module.%s:\n", strings.Join(m.Path[1:], "."))) + + s := bufio.NewScanner(strings.NewReader(mStr)) + for s.Scan() { + text := s.Text() + if text != "" { + text = " " + text + } + + buf.WriteString(fmt.Sprintf("%s\n", text)) + } + } + + return strings.TrimSpace(buf.String()) +} + +// BackendState stores the configuration to connect to a remote backend. +// +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type BackendState struct { + Type string `json:"type"` // Backend type + ConfigRaw json.RawMessage `json:"config"` // Backend raw config + Hash uint64 `json:"hash"` // Hash of portion of configuration from config files +} + +// RemoteState is used to track the information about a remote +// state store that we push/pull state to. +// +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type RemoteState struct { + // Type controls the client we use for the remote state + Type string `json:"type"` + + // Config is used to store arbitrary configuration that + // is type specific + Config map[string]string `json:"config"` + + mu sync.Mutex +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *RemoteState) Lock() { s.mu.Lock() } + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *RemoteState) Unlock() { s.mu.Unlock() } + +func (r *RemoteState) init() { + r.Lock() + defer r.Unlock() + + if r.Config == nil { + r.Config = make(map[string]string) + } +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (r *RemoteState) Empty() bool { + if r == nil { + return true + } + r.Lock() + defer r.Unlock() + + return r.Type == "" +} + +// OutputState is used to track the state relevant to a single output. +type OutputState struct { + // Sensitive describes whether the output is considered sensitive, + // which may lead to masking the value on screen in some cases. + Sensitive bool `json:"sensitive"` + // Type describes the structure of Value. Valid values are "string", + // "map" and "list" + Type string `json:"type"` + // Value contains the value of the output, in the structure described + // by the Type field. + Value interface{} `json:"value"` + + mu sync.Mutex +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *OutputState) Lock() { s.mu.Lock() } + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *OutputState) Unlock() { s.mu.Unlock() } + +func (s *OutputState) String() string { + return fmt.Sprintf("%#v", s.Value) +} + +// Equal compares two OutputState structures for equality. nil values are +// considered equal. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *OutputState) Equal(other *OutputState) bool { + if s == nil && other == nil { + return true + } + + if s == nil || other == nil { + return false + } + s.Lock() + defer s.Unlock() + + if s.Type != other.Type { + return false + } + + if s.Sensitive != other.Sensitive { + return false + } + + if !reflect.DeepEqual(s.Value, other.Value) { + return false + } + + return true +} + +// ModuleState is used to track all the state relevant to a single +// module. Previous to Terraform 0.3, all state belonged to the "root" +// module. +type ModuleState struct { + // Path is the import path from the root module. Modules imports are + // always disjoint, so the path represents amodule tree + Path []string `json:"path"` + + // Locals are kept only transiently in-memory, because we can always + // re-compute them. + Locals map[string]interface{} `json:"-"` + + // Outputs declared by the module and maintained for each module + // even though only the root module technically needs to be kept. + // This allows operators to inspect values at the boundaries. + Outputs map[string]*OutputState `json:"outputs"` + + // Resources is a mapping of the logically named resource to + // the state of the resource. Each resource may actually have + // N instances underneath, although a user only needs to think + // about the 1:1 case. + Resources map[string]*ResourceState `json:"resources"` + + // Dependencies are a list of things that this module relies on + // existing to remain intact. For example: an module may depend + // on a VPC ID given by an aws_vpc resource. + // + // Terraform uses this information to build valid destruction + // orders and to warn the user if they're destroying a module that + // another resource depends on. + // + // Things can be put into this list that may not be managed by + // Terraform. If Terraform doesn't find a matching ID in the + // overall state, then it assumes it isn't managed and doesn't + // worry about it. + Dependencies []string `json:"depends_on"` + + mu sync.Mutex +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *ModuleState) Lock() { s.mu.Lock() } + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *ModuleState) Unlock() { s.mu.Unlock() } + +// Equal tests whether one module state is equal to another. +func (m *ModuleState) Equal(other *ModuleState) bool { + m.Lock() + defer m.Unlock() + + // Paths must be equal + if !reflect.DeepEqual(m.Path, other.Path) { + return false + } + + // Outputs must be equal + if len(m.Outputs) != len(other.Outputs) { + return false + } + for k, v := range m.Outputs { + if !other.Outputs[k].Equal(v) { + return false + } + } + + // Dependencies must be equal. This sorts these in place but + // this shouldn't cause any problems. + sort.Strings(m.Dependencies) + sort.Strings(other.Dependencies) + if len(m.Dependencies) != len(other.Dependencies) { + return false + } + for i, d := range m.Dependencies { + if other.Dependencies[i] != d { + return false + } + } + + // Resources must be equal + if len(m.Resources) != len(other.Resources) { + return false + } + for k, r := range m.Resources { + otherR, ok := other.Resources[k] + if !ok { + return false + } + + if !r.Equal(otherR) { + return false + } + } + + return true +} + +func (m *ModuleState) init() { + m.Lock() + defer m.Unlock() + + if m.Path == nil { + m.Path = []string{} + } + if m.Outputs == nil { + m.Outputs = make(map[string]*OutputState) + } + if m.Resources == nil { + m.Resources = make(map[string]*ResourceState) + } + + if m.Dependencies == nil { + m.Dependencies = make([]string, 0) + } + + for _, rs := range m.Resources { + rs.init() + } +} + +// prune is used to remove any resources that are no longer required +func (m *ModuleState) prune() { + m.Lock() + defer m.Unlock() + + for k, v := range m.Resources { + if v == nil || (v.Primary == nil || v.Primary.ID == "") && len(v.Deposed) == 0 { + delete(m.Resources, k) + continue + } + + v.prune() + } + + for k, v := range m.Outputs { + if v.Value == hcl2shim.UnknownVariableValue { + delete(m.Outputs, k) + } + } + + m.Dependencies = uniqueStrings(m.Dependencies) +} + +func (m *ModuleState) sort() { + for _, v := range m.Resources { + v.sort() + } +} + +func (m *ModuleState) String() string { + m.Lock() + defer m.Unlock() + + var buf bytes.Buffer + + if len(m.Resources) == 0 { + buf.WriteString("") + } + + names := make([]string, 0, len(m.Resources)) + for name := range m.Resources { + names = append(names, name) + } + + sort.Sort(resourceNameSort(names)) + + for _, k := range names { + rs := m.Resources[k] + var id string + if rs.Primary != nil { + id = rs.Primary.ID + } + if id == "" { + id = "" + } + + taintStr := "" + if rs.Primary.Tainted { + taintStr = " (tainted)" + } + + deposedStr := "" + if len(rs.Deposed) > 0 { + deposedStr = fmt.Sprintf(" (%d deposed)", len(rs.Deposed)) + } + + buf.WriteString(fmt.Sprintf("%s:%s%s\n", k, taintStr, deposedStr)) + buf.WriteString(fmt.Sprintf(" ID = %s\n", id)) + if rs.Provider != "" { + buf.WriteString(fmt.Sprintf(" provider = %s\n", rs.Provider)) + } + + var attributes map[string]string + if rs.Primary != nil { + attributes = rs.Primary.Attributes + } + attrKeys := make([]string, 0, len(attributes)) + for ak := range attributes { + if ak == "id" { + continue + } + + attrKeys = append(attrKeys, ak) + } + + sort.Strings(attrKeys) + + for _, ak := range attrKeys { + av := attributes[ak] + buf.WriteString(fmt.Sprintf(" %s = %s\n", ak, av)) + } + + for idx, t := range rs.Deposed { + taintStr := "" + if t.Tainted { + taintStr = " (tainted)" + } + buf.WriteString(fmt.Sprintf(" Deposed ID %d = %s%s\n", idx+1, t.ID, taintStr)) + } + + if len(rs.Dependencies) > 0 { + buf.WriteString("\n Dependencies:\n") + for _, dep := range rs.Dependencies { + buf.WriteString(fmt.Sprintf(" %s\n", dep)) + } + } + } + + if len(m.Outputs) > 0 { + buf.WriteString("\nOutputs:\n\n") + + ks := make([]string, 0, len(m.Outputs)) + for k := range m.Outputs { + ks = append(ks, k) + } + + sort.Strings(ks) + + for _, k := range ks { + v := m.Outputs[k] + switch vTyped := v.Value.(type) { + case string: + buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) + case []interface{}: + buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) + case map[string]interface{}: + var mapKeys []string + for key := range vTyped { + mapKeys = append(mapKeys, key) + } + sort.Strings(mapKeys) + + var mapBuf bytes.Buffer + mapBuf.WriteString("{") + for _, key := range mapKeys { + mapBuf.WriteString(fmt.Sprintf("%s:%s ", key, vTyped[key])) + } + mapBuf.WriteString("}") + + buf.WriteString(fmt.Sprintf("%s = %s\n", k, mapBuf.String())) + } + } + } + + return buf.String() +} + +// ResourceStateKey is a structured representation of the key used for the +// ModuleState.Resources mapping +type ResourceStateKey struct { + Name string + Type string + Mode ResourceMode + Index int +} + +// Equal determines whether two ResourceStateKeys are the same +func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool { + if rsk == nil || other == nil { + return false + } + if rsk.Mode != other.Mode { + return false + } + if rsk.Type != other.Type { + return false + } + if rsk.Name != other.Name { + return false + } + if rsk.Index != other.Index { + return false + } + return true +} + +func (rsk *ResourceStateKey) String() string { + if rsk == nil { + return "" + } + var prefix string + switch rsk.Mode { + case ManagedResourceMode: + prefix = "" + case DataResourceMode: + prefix = "data." + default: + panic(fmt.Errorf("unknown resource mode %s", rsk.Mode)) + } + if rsk.Index == -1 { + return fmt.Sprintf("%s%s.%s", prefix, rsk.Type, rsk.Name) + } + return fmt.Sprintf("%s%s.%s.%d", prefix, rsk.Type, rsk.Name, rsk.Index) +} + +// ParseResourceStateKey accepts a key in the format used by +// ModuleState.Resources and returns a resource name and resource index. In the +// state, a resource has the format "type.name.index" or "type.name". In the +// latter case, the index is returned as -1. +func parseResourceStateKey(k string) (*ResourceStateKey, error) { + parts := strings.Split(k, ".") + mode := ManagedResourceMode + if len(parts) > 0 && parts[0] == "data" { + mode = DataResourceMode + // Don't need the constant "data" prefix for parsing + // now that we've figured out the mode. + parts = parts[1:] + } + if len(parts) < 2 || len(parts) > 3 { + return nil, fmt.Errorf("Malformed resource state key: %s", k) + } + rsk := &ResourceStateKey{ + Mode: mode, + Type: parts[0], + Name: parts[1], + Index: -1, + } + if len(parts) == 3 { + index, err := strconv.Atoi(parts[2]) + if err != nil { + return nil, fmt.Errorf("Malformed resource state key index: %s", k) + } + rsk.Index = index + } + return rsk, nil +} + +// ResourceState holds the state of a resource that is used so that +// a provider can find and manage an existing resource as well as for +// storing attributes that are used to populate variables of child +// resources. +// +// Attributes has attributes about the created resource that are +// queryable in interpolation: "${type.id.attr}" +// +// Extra is just extra data that a provider can return that we store +// for later, but is not exposed in any way to the user. +type ResourceState struct { + // This is filled in and managed by Terraform, and is the resource + // type itself such as "mycloud_instance". If a resource provider sets + // this value, it won't be persisted. + Type string `json:"type"` + + // Dependencies are a list of things that this resource relies on + // existing to remain intact. For example: an AWS instance might + // depend on a subnet (which itself might depend on a VPC, and so + // on). + // + // Terraform uses this information to build valid destruction + // orders and to warn the user if they're destroying a resource that + // another resource depends on. + // + // Things can be put into this list that may not be managed by + // Terraform. If Terraform doesn't find a matching ID in the + // overall state, then it assumes it isn't managed and doesn't + // worry about it. + Dependencies []string `json:"depends_on"` + + // Primary is the current active instance for this resource. + // It can be replaced but only after a successful creation. + // This is the instances on which providers will act. + Primary *InstanceState `json:"primary"` + + // Deposed is used in the mechanics of CreateBeforeDestroy: the existing + // Primary is Deposed to get it out of the way for the replacement Primary to + // be created by Apply. If the replacement Primary creates successfully, the + // Deposed instance is cleaned up. + // + // If there were problems creating the replacement Primary, the Deposed + // instance and the (now tainted) replacement Primary will be swapped so the + // tainted replacement will be cleaned up instead. + // + // An instance will remain in the Deposed list until it is successfully + // destroyed and purged. + Deposed []*InstanceState `json:"deposed"` + + // Provider is used when a resource is connected to a provider with an alias. + // If this string is empty, the resource is connected to the default provider, + // e.g. "aws_instance" goes with the "aws" provider. + // If the resource block contained a "provider" key, that value will be set here. + Provider string `json:"provider"` + + mu sync.Mutex +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *ResourceState) Lock() { s.mu.Lock() } + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *ResourceState) Unlock() { s.mu.Unlock() } + +// Equal tests whether two ResourceStates are equal. +func (s *ResourceState) Equal(other *ResourceState) bool { + s.Lock() + defer s.Unlock() + + if s.Type != other.Type { + return false + } + + if s.Provider != other.Provider { + return false + } + + // Dependencies must be equal + sort.Strings(s.Dependencies) + sort.Strings(other.Dependencies) + if len(s.Dependencies) != len(other.Dependencies) { + return false + } + for i, d := range s.Dependencies { + if other.Dependencies[i] != d { + return false + } + } + + // States must be equal + return s.Primary.Equal(other.Primary) +} + +func (s *ResourceState) init() { + s.Lock() + defer s.Unlock() + + if s.Primary == nil { + s.Primary = &InstanceState{} + } + s.Primary.init() + + if s.Dependencies == nil { + s.Dependencies = []string{} + } + + if s.Deposed == nil { + s.Deposed = make([]*InstanceState, 0) + } +} + +// prune is used to remove any instances that are no longer required +func (s *ResourceState) prune() { + s.Lock() + defer s.Unlock() + + n := len(s.Deposed) + for i := 0; i < n; i++ { + inst := s.Deposed[i] + if inst == nil || inst.ID == "" { + copy(s.Deposed[i:], s.Deposed[i+1:]) + s.Deposed[n-1] = nil + n-- + i-- + } + } + s.Deposed = s.Deposed[:n] + + s.Dependencies = uniqueStrings(s.Dependencies) +} + +func (s *ResourceState) sort() { + s.Lock() + defer s.Unlock() + + sort.Strings(s.Dependencies) +} + +func (s *ResourceState) String() string { + s.Lock() + defer s.Unlock() + + var buf bytes.Buffer + buf.WriteString(fmt.Sprintf("Type = %s", s.Type)) + return buf.String() +} + +// InstanceState is used to track the unique state information belonging +// to a given instance. +type InstanceState struct { + // A unique ID for this resource. This is opaque to Terraform + // and is only meant as a lookup mechanism for the providers. + ID string `json:"id"` + + // Attributes are basic information about the resource. Any keys here + // are accessible in variable format within Terraform configurations: + // ${resourcetype.name.attribute}. + Attributes map[string]string `json:"attributes"` + + // Ephemeral is used to store any state associated with this instance + // that is necessary for the Terraform run to complete, but is not + // persisted to a state file. + Ephemeral EphemeralState `json:"-"` + + // Meta is a simple K/V map that is persisted to the State but otherwise + // ignored by Terraform core. It's meant to be used for accounting by + // external client code. The value here must only contain Go primitives + // and collections. + Meta map[string]interface{} `json:"meta"` + + ProviderMeta cty.Value + + RawConfig cty.Value + RawState cty.Value + RawPlan cty.Value + + // Tainted is used to mark a resource for recreation. + Tainted bool `json:"tainted"` + + mu sync.Mutex +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *InstanceState) Lock() { s.mu.Lock() } + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *InstanceState) Unlock() { s.mu.Unlock() } + +func (s *InstanceState) init() { + s.Lock() + defer s.Unlock() + + if s.Attributes == nil { + s.Attributes = make(map[string]string) + } + if s.Meta == nil { + s.Meta = make(map[string]interface{}) + } + s.Ephemeral.init() +} + +// NewInstanceStateShimmedFromValue is a shim method to lower a new-style +// object value representing the attributes of an instance object into the +// legacy InstanceState representation. +// +// This is for shimming to old components only and should not be used in new code. +// +// Deprecated: This function is unintentionally exported by this Go module and +// not supported for external consumption. It will be removed in the next major +// version. +func NewInstanceStateShimmedFromValue(state cty.Value, schemaVersion int) *InstanceState { + attrs := hcl2shim.FlatmapValueFromHCL2(state) + return &InstanceState{ + ID: attrs["id"], + Attributes: attrs, + Meta: map[string]interface{}{ + "schema_version": schemaVersion, + }, + } +} + +// AttrsAsObjectValue shims from the legacy InstanceState representation to +// a new-style cty object value representation of the state attributes, using +// the given type for guidance. +// +// The given type must be the implied type of the schema of the resource type +// of the object whose state is being converted, or the result is undefined. +// +// This is for shimming from old components only and should not be used in +// new code. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *InstanceState) AttrsAsObjectValue(ty cty.Type) (cty.Value, error) { + if s == nil { + // if the state is nil, we need to construct a complete cty.Value with + // null attributes, rather than a single cty.NullVal(ty) + s = &InstanceState{} + } + + if s.Attributes == nil { + s.Attributes = map[string]string{} + } + + // make sure ID is included in the attributes. The InstanceState.ID value + // takes precedence. + if s.ID != "" { + s.Attributes["id"] = s.ID + } + + return hcl2shim.HCL2ValueFromFlatmap(s.Attributes, ty) +} + +// Copy all the Fields from another InstanceState +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *InstanceState) Set(from *InstanceState) { + s.Lock() + defer s.Unlock() + + from.Lock() + defer from.Unlock() + + s.ID = from.ID + s.Attributes = from.Attributes + s.Ephemeral = from.Ephemeral + s.Meta = from.Meta + s.Tainted = from.Tainted +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *InstanceState) DeepCopy() *InstanceState { + if s == nil { + return nil + } + + copied := &InstanceState{ + Ephemeral: EphemeralState{ + ConnInfo: s.Ephemeral.ConnInfo, + Type: s.Ephemeral.Type, + }, + ID: s.ID, + ProviderMeta: s.ProviderMeta, + RawConfig: s.RawConfig, + RawPlan: s.RawPlan, + RawState: s.RawState, + Tainted: s.Tainted, + } + + if s.Attributes != nil { + copied.Attributes = make(map[string]string, len(s.Attributes)) + + for k, v := range s.Attributes { + copied.Attributes[k] = v + } + } + + // Best effort single level copy is fine; this is not used by this Go module + // and its already deprecated. + if s.Meta != nil { + copied.Meta = make(map[string]any, len(s.Meta)) + + for k, v := range s.Meta { + copied.Meta[k] = v + } + } + + return copied +} + +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *InstanceState) Empty() bool { + if s == nil { + return true + } + s.Lock() + defer s.Unlock() + + return s.ID == "" +} + +func (s *InstanceState) Equal(other *InstanceState) bool { + // Short circuit some nil checks + if s == nil || other == nil { + return s == other + } + s.Lock() + defer s.Unlock() + + // IDs must be equal + if s.ID != other.ID { + return false + } + + // Attributes must be equal + if len(s.Attributes) != len(other.Attributes) { + return false + } + for k, v := range s.Attributes { + otherV, ok := other.Attributes[k] + if !ok { + return false + } + + if v != otherV { + return false + } + } + + // Meta must be equal + if len(s.Meta) != len(other.Meta) { + return false + } + if s.Meta != nil && other.Meta != nil { + // We only do the deep check if both are non-nil. If one is nil + // we treat it as equal since their lengths are both zero (check + // above). + // + // Since this can contain numeric values that may change types during + // serialization, let's compare the serialized values. + sMeta, err := json.Marshal(s.Meta) + if err != nil { + // marshaling primitives shouldn't ever error out + panic(err) + } + otherMeta, err := json.Marshal(other.Meta) + if err != nil { + panic(err) + } + + if !bytes.Equal(sMeta, otherMeta) { + return false + } + } + + if s.Tainted != other.Tainted { + return false + } + + return true +} + +// MergeDiff takes a ResourceDiff and merges the attributes into +// this resource state in order to generate a new state. This new +// state can be used to provide updated attribute lookups for +// variable interpolation. +// +// If the diff attribute requires computing the value, and hence +// won't be available until apply, the value is replaced with the +// computeID. +// +// Deprecated: This method is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState { + result := s.DeepCopy() + if result == nil { + result = new(InstanceState) + } + result.init() + + if s != nil { + s.Lock() + defer s.Unlock() + for k, v := range s.Attributes { + result.Attributes[k] = v + } + } + if d != nil { + for k, diff := range d.CopyAttributes() { + if diff.NewRemoved { + delete(result.Attributes, k) + continue + } + if diff.NewComputed { + result.Attributes[k] = hcl2shim.UnknownVariableValue + continue + } + + result.Attributes[k] = diff.New + } + } + + return result +} + +func (s *InstanceState) String() string { + notCreated := "" + + if s == nil { + return notCreated + } + + s.Lock() + defer s.Unlock() + + var buf bytes.Buffer + + if s.ID == "" { + return notCreated + } + + buf.WriteString(fmt.Sprintf("ID = %s\n", s.ID)) + + attributes := s.Attributes + attrKeys := make([]string, 0, len(attributes)) + for ak := range attributes { + if ak == "id" { + continue + } + + attrKeys = append(attrKeys, ak) + } + sort.Strings(attrKeys) + + for _, ak := range attrKeys { + av := attributes[ak] + buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av)) + } + + buf.WriteString(fmt.Sprintf("Tainted = %t\n", s.Tainted)) + + return buf.String() +} + +// EphemeralState is used for transient state that is only kept in-memory +// +// Deprecated: This type is unintentionally exported by this Go module and not +// supported for external consumption. It will be removed in the next major +// version. +type EphemeralState struct { + // ConnInfo is used for the providers to export information which is + // used to connect to the resource for provisioning. For example, + // this could contain SSH or WinRM credentials. + ConnInfo map[string]string `json:"-"` + + // Type is used to specify the resource type for this instance. This is only + // required for import operations (as documented). If the documentation + // doesn't state that you need to set this, then don't worry about + // setting it. + Type string `json:"-"` +} + +func (e *EphemeralState) init() { + if e.ConnInfo == nil { + e.ConnInfo = make(map[string]string) + } +} + +// resourceNameSort implements the sort.Interface to sort name parts lexically for +// strings and numerically for integer indexes. +type resourceNameSort []string + +func (r resourceNameSort) Len() int { return len(r) } +func (r resourceNameSort) Swap(i, j int) { r[i], r[j] = r[j], r[i] } + +func (r resourceNameSort) Less(i, j int) bool { + iParts := strings.Split(r[i], ".") + jParts := strings.Split(r[j], ".") + + end := len(iParts) + if len(jParts) < end { + end = len(jParts) + } + + for idx := 0; idx < end; idx++ { + if iParts[idx] == jParts[idx] { + continue + } + + // sort on the first non-matching part + iInt, iIntErr := strconv.Atoi(iParts[idx]) + jInt, jIntErr := strconv.Atoi(jParts[idx]) + + switch { + case iIntErr == nil && jIntErr == nil: + // sort numerically if both parts are integers + return iInt < jInt + case iIntErr == nil: + // numbers sort before strings + return true + case jIntErr == nil: + return false + default: + return iParts[idx] < jParts[idx] + } + } + + return r[i] < r[j] +} + +// moduleStateSort implements sort.Interface to sort module states +type moduleStateSort []*ModuleState + +func (s moduleStateSort) Len() int { + return len(s) +} + +func (s moduleStateSort) Less(i, j int) bool { + a := s[i] + b := s[j] + + // If either is nil, then the nil one is "less" than + if a == nil || b == nil { + return a == nil + } + + // If the lengths are different, then the shorter one always wins + if len(a.Path) != len(b.Path) { + return len(a.Path) < len(b.Path) + } + + // Otherwise, compare lexically + return strings.Join(a.Path, ".") < strings.Join(b.Path, ".") +} + +func (s moduleStateSort) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +const stateValidateErrMultiModule = ` +Multiple modules with the same path: %s + +This means that there are multiple entries in the "modules" field +in your state file that point to the same module. This will cause Terraform +to behave in unexpected and error prone ways and is invalid. Please back up +and modify your state file manually to resolve this. +` diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/state_filter.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/state_filter.go new file mode 100644 index 00000000..caf2c796 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/state_filter.go @@ -0,0 +1,273 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package terraform + +import ( + "fmt" + "sort" +) + +// stateFilter is responsible for filtering and searching a state. +// +// This is a separate struct from State rather than a method on State +// because StateFilter might create sidecar data structures to optimize +// filtering on the state. +// +// If you change the State, the filter created is invalid and either +// Reset should be called or a new one should be allocated. StateFilter +// will not watch State for changes and do this for you. If you filter after +// changing the State without calling Reset, the behavior is not defined. +type stateFilter struct { + State *State +} + +// Filter takes the addresses specified by fs and finds all the matches. +// The values of fs are resource addressing syntax that can be parsed by +// parseResourceAddress. +func (f *stateFilter) filter(fs ...string) ([]*stateFilterResult, error) { + // Parse all the addresses + var as []*resourceAddress + + if len(fs) == 0 { + // If we weren't given any filters, then we list all + as = []*resourceAddress{{Index: -1}} + } else { + as = make([]*resourceAddress, len(fs)) + } + + for i, v := range fs { + a, err := parseResourceAddress(v) + if err != nil { + return nil, fmt.Errorf("Error parsing address '%s': %s", v, err) + } + + as[i] = a + } + + // Filter each of the address. We keep track of this in a map to + // strip duplicates. + resultSet := make(map[string]*stateFilterResult) + for _, a := range as { + for _, r := range f.filterSingle(a) { + resultSet[r.String()] = r + } + } + + // Make the result list + results := make([]*stateFilterResult, 0, len(resultSet)) + for _, v := range resultSet { + results = append(results, v) + } + + // Sort them and return + sort.Sort(stateFilterResultSlice(results)) + return results, nil +} + +func (f *stateFilter) filterSingle(a *resourceAddress) []*stateFilterResult { + // The slice to keep track of results + var results []*stateFilterResult + + // Go through modules first. + modules := make([]*ModuleState, 0, len(f.State.Modules)) + for _, m := range f.State.Modules { + if f.relevant(a, m) { + modules = append(modules, m) + + // Only add the module to the results if we haven't specified a type. + // We also ignore the root module. + if a.Type == "" && len(m.Path) > 1 { + results = append(results, &stateFilterResult{ + Path: m.Path[1:], + Address: (&resourceAddress{Path: m.Path[1:]}).String(), + Value: m, + }) + } + } + } + + // With the modules set, go through all the resources within + // the modules to find relevant resources. + for _, m := range modules { + for n, r := range m.Resources { + // The name in the state contains valuable information. Parse. + key, err := parseResourceStateKey(n) + if err != nil { + // If we get an error parsing, then just ignore it + // out of the state. + continue + } + + // Older states and test fixtures often don't contain the + // type directly on the ResourceState. We add this so StateFilter + // is a bit more robust. + if r.Type == "" { + r.Type = key.Type + } + + if f.relevant(a, r) { + if a.Name != "" && a.Name != key.Name { + // Name doesn't match + continue + } + + if a.Index >= 0 && key.Index != a.Index { + // Index doesn't match + continue + } + + if a.Name != "" && a.Name != key.Name { + continue + } + + // Build the address for this resource + addr := &resourceAddress{ + Path: m.Path[1:], + Name: key.Name, + Type: key.Type, + Index: key.Index, + } + + // Add the resource level result + resourceResult := &stateFilterResult{ + Path: addr.Path, + Address: addr.String(), + Value: r, + } + if !a.InstanceTypeSet { + results = append(results, resourceResult) + } + + // Add the instances + if r.Primary != nil { + addr.InstanceType = typePrimary + addr.InstanceTypeSet = false + results = append(results, &stateFilterResult{ + Path: addr.Path, + Address: addr.String(), + Parent: resourceResult, + Value: r.Primary, + }) + } + + for _, instance := range r.Deposed { + if f.relevant(a, instance) { + addr.InstanceType = typeDeposed + addr.InstanceTypeSet = true + results = append(results, &stateFilterResult{ + Path: addr.Path, + Address: addr.String(), + Parent: resourceResult, + Value: instance, + }) + } + } + } + } + } + + return results +} + +// relevant checks for relevance of this address against the given value. +func (f *stateFilter) relevant(addr *resourceAddress, raw interface{}) bool { + switch v := raw.(type) { + case *ModuleState: + path := v.Path[1:] + + if len(addr.Path) > len(path) { + // Longer path in address means there is no way we match. + return false + } + + // Check for a prefix match + for i, p := range addr.Path { + if path[i] != p { + // Any mismatches don't match. + return false + } + } + + return true + case *ResourceState: + if addr.Type == "" { + // If we have no resource type, then we're interested in all! + return true + } + + // If the type doesn't match we fail immediately + if v.Type != addr.Type { + return false + } + + return true + default: + // If we don't know about it, let's just say no + return false + } +} + +// stateFilterResult is a single result from a filter operation. Filter +// can match multiple things within a state (module, resource, instance, etc.) +// and this unifies that. +type stateFilterResult struct { + // Module path of the result + Path []string + + // Address is the address that can be used to reference this exact result. + Address string + + // Parent, if non-nil, is a parent of this result. For instances, the + // parent would be a resource. For resources, the parent would be + // a module. For modules, this is currently nil. + Parent *stateFilterResult + + // Value is the actual value. This must be type switched on. It can be + // any data structures that `State` can hold: `ModuleState`, + // `ResourceState`, `InstanceState`. + Value interface{} +} + +func (r *stateFilterResult) String() string { + return fmt.Sprintf("%T: %s", r.Value, r.Address) +} + +func (r *stateFilterResult) sortedType() int { + switch r.Value.(type) { + case *ModuleState: + return 0 + case *ResourceState: + return 1 + case *InstanceState: + return 2 + default: + return 50 + } +} + +// stateFilterResultSlice is a slice of results that implements +// sort.Interface. The sorting goal is what is most appealing to +// human output. +type stateFilterResultSlice []*stateFilterResult + +func (s stateFilterResultSlice) Len() int { return len(s) } +func (s stateFilterResultSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s stateFilterResultSlice) Less(i, j int) bool { + a, b := s[i], s[j] + + // if these address contain an index, we want to sort by index rather than name + addrA, errA := parseResourceAddress(a.Address) + addrB, errB := parseResourceAddress(b.Address) + if errA == nil && errB == nil && addrA.Name == addrB.Name && addrA.Index != addrB.Index { + return addrA.Index < addrB.Index + } + + // If the addresses are different it is just lexographic sorting + if a.Address != b.Address { + return a.Address < b.Address + } + + // Addresses are the same, which means it matters on the type + return a.sortedType() < b.sortedType() +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/unknown_value_walk.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/unknown_value_walk.go new file mode 100644 index 00000000..66e12954 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/unknown_value_walk.go @@ -0,0 +1,85 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package terraform + +import ( + "reflect" + + "github.com/hashicorp/terraform-plugin-testing/internal/configs/hcl2shim" +) + +// unknownValueWalk is a reimplementation of the prior walk() logic from +// github.com/mitchellh/reflectwalk and the only walker implemented in this +// module that checked values for hcl2shim.UnknownVariableValue. +// +// Using reflection instead of known logic here is a Go anti-pattern, however +// this logic will be removed in the next major version, so the reflection +// approach is preserved to minimize reimplementation effort. +func unknownValueWalk(v reflect.Value) bool { + for { + switch v.Kind() { + case reflect.Interface: + v = v.Elem() + + continue + case reflect.Pointer: + v = reflect.Indirect(v) + + continue + } + + break + } + + switch v.Kind() { + case reflect.Bool, + reflect.Complex128, + reflect.Complex64, + reflect.Float32, + reflect.Float64, + reflect.Int, + reflect.Int16, + reflect.Int32, + reflect.Int64, + reflect.Int8, + reflect.Uint, + reflect.Uint16, + reflect.Uint32, + reflect.Uint64, + reflect.Uint8, + reflect.Uintptr, + reflect.String: + value := v.Interface() + + return value == hcl2shim.UnknownVariableValue + case reflect.Map: + for _, k := range v.MapKeys() { + value := v.MapIndex(k) + + if foundUnknown := unknownValueWalk(value); foundUnknown { + return true + } + } + case reflect.Array, reflect.Slice: + for index := 0; index < v.Len(); index++ { + value := v.Index(index) + + if foundUnknown := unknownValueWalk(value); foundUnknown { + return true + } + } + case reflect.Struct: + for index := 0; index < v.Type().NumField(); index++ { + value := v.FieldByIndex([]int{index}) + + if foundUnknown := unknownValueWalk(value); foundUnknown { + return true + } + } + default: + panic("unsupported reflect type: " + v.Kind().String()) + } + + return false +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/util.go b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/util.go new file mode 100644 index 00000000..6353ad27 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/terraform/util.go @@ -0,0 +1,25 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package terraform + +import ( + "sort" +) + +// deduplicate a slice of strings +func uniqueStrings(s []string) []string { + if len(s) < 2 { + return s + } + + sort.Strings(s) + result := make([]string, 1, len(s)) + result[0] = s[0] + for i := 1; i < len(s); i++ { + if s[i] != result[len(result)-1] { + result = append(result, s[i]) + } + } + return result +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/doc.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/doc.go new file mode 100644 index 00000000..4b1a4923 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package tfjsonpath implements terraform-json path functionality, which defines +// traversals into Terraform JSON data, for testing purposes. +package tfjsonpath diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/path.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/path.go new file mode 100644 index 00000000..c29ae260 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/path.go @@ -0,0 +1,135 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfjsonpath + +import ( + "fmt" + "strings" +) + +// Path represents exact traversal steps specifying a value inside +// Terraform JSON data. These steps always start from a MapStep with a key +// specifying the name of a top-level JSON object or array. +// +// The [terraform-json] library serves as the de facto documentation +// for JSON format of Terraform data. +// +// Use the New() function to create a Path with an initial AtMapKey() step. +// Path functionality follows a builder pattern, which allows for chaining method +// calls to construct a full path. The available traversal steps after Path +// creation are: +// +// - AtSliceIndex(): Step into a slice at a specific 0-based index +// - AtMapKey(): Step into a map at a specific key +// +// For example, to represent the first element of a JSON array +// underneath a "some_array" property of this JSON value: +// +// { +// "some_array": [true] +// } +// +// The path code would be represented by: +// +// tfjsonpath.New("some_array").AtSliceIndex(0) +// +// [terraform-json]: (https://pkg.go.dev/github.com/hashicorp/terraform-json) +type Path struct { + steps []step +} + +// New creates a new path with an initial MapStep or SliceStep. +func New[T int | string](firstStep T) Path { + switch t := any(firstStep).(type) { + case int: + return Path{ + steps: []step{ + SliceStep(t), + }, + } + case string: + return Path{ + steps: []step{ + MapStep(t), + }, + } + } + + // Unreachable code + return Path{} +} + +// AtSliceIndex returns a copied Path with a new SliceStep at the end. +func (s Path) AtSliceIndex(index int) Path { + newSteps := append(s.steps, SliceStep(index)) + s.steps = newSteps + return s +} + +// AtMapKey returns a copied Path with a new MapStep at the end. +func (s Path) AtMapKey(key string) Path { + newSteps := append(s.steps, MapStep(key)) + s.steps = newSteps + return s +} + +// String returns a string representation of the Path. +func (s Path) String() string { + var pathStr []string + + for _, step := range s.steps { + pathStr = append(pathStr, fmt.Sprintf("%v", step)) + } + + return strings.Join(pathStr, ".") +} + +// Traverse returns the element found when traversing the given +// object using the specified Path. The object is an unmarshalled +// JSON object representing Terraform data. +// +// Traverse returns an error if the value specified by the Path +// is not found in the given object or if the given object does not +// conform to format of Terraform JSON data. +func Traverse(object any, attrPath Path) (any, error) { + result := object + + var steps []string + + for _, step := range attrPath.steps { + switch s := step.(type) { + case MapStep: + steps = append(steps, string(s)) + + mapObj, ok := result.(map[string]any) + + if !ok { + return nil, fmt.Errorf("path not found: cannot convert object at MapStep %s to map[string]any", strings.Join(steps, ".")) + } + + result, ok = mapObj[string(s)] + + if !ok { + return nil, fmt.Errorf("path not found: specified key %s not found in map at %s", string(s), strings.Join(steps, ".")) + } + + case SliceStep: + steps = append(steps, fmt.Sprint(s)) + + sliceObj, ok := result.([]any) + + if !ok { + return nil, fmt.Errorf("path not found: cannot convert object at SliceStep %s to []any", strings.Join(steps, ".")) + } + + if int(s) >= len(sliceObj) { + return nil, fmt.Errorf("path not found: SliceStep index %s is out of range with slice length %d", strings.Join(steps, "."), len(sliceObj)) + } + + result = sliceObj[s] + } + } + + return result, nil +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/step.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/step.go new file mode 100644 index 00000000..5a779640 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfjsonpath/step.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfjsonpath + +// step represents a traversal type indicating the underlying Go type +// representation for a Terraform JSON value. +type step any + +// MapStep represents a traversal for map[string]any +type MapStep string + +// SliceStep represents a traversal for []any +type SliceStep int diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/all.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/all.go new file mode 100644 index 00000000..78e1f178 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/all.go @@ -0,0 +1,45 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import ( + "context" +) + +// All will return the first non-nil error or non-empty skip message +// if any of the given checks return a non-nil error or non-empty skip message. +// Otherwise, it will return a nil error and empty skip message (run the test) +// +// Use of All is only necessary when used in conjunction with Any as the +// TerraformVersionChecks field automatically applies a logical AND. +func All(terraformVersionChecks ...TerraformVersionCheck) TerraformVersionCheck { + return allCheck{ + terraformVersionChecks: terraformVersionChecks, + } +} + +// allCheck implements the TerraformVersionCheck interface +type allCheck struct { + terraformVersionChecks []TerraformVersionCheck +} + +// CheckTerraformVersion satisfies the TerraformVersionCheck interface. +func (a allCheck) CheckTerraformVersion(ctx context.Context, req CheckTerraformVersionRequest, resp *CheckTerraformVersionResponse) { + + for _, subCheck := range a.terraformVersionChecks { + checkResp := CheckTerraformVersionResponse{} + + subCheck.CheckTerraformVersion(ctx, CheckTerraformVersionRequest{TerraformVersion: req.TerraformVersion}, &checkResp) + + if checkResp.Error != nil { + resp.Error = checkResp.Error + return + } + + if checkResp.Skip != "" { + resp.Skip = checkResp.Skip + return + } + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/any.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/any.go new file mode 100644 index 00000000..2fee9cb1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/any.go @@ -0,0 +1,54 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import ( + "context" + "errors" + "strings" +) + +// Any will return a nil error and empty skip message (run the test) +// if any of the given checks return a nil error and empty skip message. +// Otherwise, it will return all errors and fail the test if any of the given +// checks return a non-nil error, or it will return all skip messages +// and skip (pass) the test. +func Any(terraformVersionChecks ...TerraformVersionCheck) TerraformVersionCheck { + return anyCheck{ + terraformVersionChecks: terraformVersionChecks, + } +} + +// anyCheck implements the TerraformVersionCheck interface +type anyCheck struct { + terraformVersionChecks []TerraformVersionCheck +} + +// CheckTerraformVersion satisfies the TerraformVersionCheck interface. +func (a anyCheck) CheckTerraformVersion(ctx context.Context, req CheckTerraformVersionRequest, resp *CheckTerraformVersionResponse) { + var joinedErrors []error + strBuilder := strings.Builder{} + + for _, subCheck := range a.terraformVersionChecks { + checkResp := CheckTerraformVersionResponse{} + + subCheck.CheckTerraformVersion(ctx, CheckTerraformVersionRequest{TerraformVersion: req.TerraformVersion}, &checkResp) + + if checkResp.Error == nil && checkResp.Skip == "" { + resp.Error = nil + resp.Skip = "" + return + } + + joinedErrors = append(joinedErrors, checkResp.Error) + + if checkResp.Skip != "" { + strBuilder.WriteString(checkResp.Skip) + strBuilder.WriteString("\n") + } + } + + resp.Error = errors.Join(joinedErrors...) + resp.Skip = strings.TrimSpace(strBuilder.String()) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/doc.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/doc.go new file mode 100644 index 00000000..d73b474d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/doc.go @@ -0,0 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package tfversion contains the Terraform version check interface, request/response structs, and common version check implementations. +package tfversion diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_above.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_above.go new file mode 100644 index 00000000..4734bcf6 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_above.go @@ -0,0 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import ( + "context" + "fmt" + + "github.com/hashicorp/go-version" +) + +// RequireAbove will fail the test if the Terraform CLI +// version is below the given version. For example, if given +// version.Must(version.NewVersion("0.15.0")), then 0.14.x or +// any other prior minor versions will fail the test. +func RequireAbove(minimumVersion *version.Version) TerraformVersionCheck { + return requireAboveCheck{ + minimumVersion: minimumVersion, + } +} + +// requireAboveCheck implements the TerraformVersionCheck interface +type requireAboveCheck struct { + minimumVersion *version.Version +} + +// CheckTerraformVersion satisfies the TerraformVersionCheck interface. +func (r requireAboveCheck) CheckTerraformVersion(ctx context.Context, req CheckTerraformVersionRequest, resp *CheckTerraformVersionResponse) { + + if req.TerraformVersion.LessThan(r.minimumVersion) { + resp.Error = fmt.Errorf("expected Terraform CLI version above %s but detected version is %s", + r.minimumVersion, req.TerraformVersion) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_below.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_below.go new file mode 100644 index 00000000..99efa534 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_below.go @@ -0,0 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import ( + "context" + "fmt" + + "github.com/hashicorp/go-version" +) + +// RequireBelow will fail the test if the Terraform CLI +// version is above the given version. For example, if given +// version.Must(version.NewVersion("0.15.0")), then versions 0.15.x and +// above will fail the test. +func RequireBelow(maximumVersion *version.Version) TerraformVersionCheck { + return requireBelowCheck{ + maximumVersion: maximumVersion, + } +} + +// requireBelowCheck implements the TerraformVersionCheck interface +type requireBelowCheck struct { + maximumVersion *version.Version +} + +// CheckTerraformVersion satisfies the TerraformVersionCheck interface. +func (s requireBelowCheck) CheckTerraformVersion(ctx context.Context, req CheckTerraformVersionRequest, resp *CheckTerraformVersionResponse) { + + if req.TerraformVersion.GreaterThan(s.maximumVersion) { + resp.Error = fmt.Errorf("expected Terraform CLI version below %s but detected version is %s", + s.maximumVersion, req.TerraformVersion) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_between.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_between.go new file mode 100644 index 00000000..b9929792 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_between.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import ( + "context" + "fmt" + + "github.com/hashicorp/go-version" +) + +// RequireBetween will fail the test if the Terraform CLI +// version is outside the given minimum (exclusive) and maximum (inclusive). +// For example, if given a minimum version of version.Must(version.NewVersion("0.15.0")) +// and a maximum version of version.Must(version.NewVersion("1.0.0")), then 0.15.x or +// any other prior versions and versions greater than 1.0.0 will fail the test. +func RequireBetween(minimumVersion, maximumVersion *version.Version) TerraformVersionCheck { + return requireBetweenCheck{ + minimumVersion: minimumVersion, + maximumVersion: maximumVersion, + } +} + +// requireBetweenCheck implements the TerraformVersionCheck interface +type requireBetweenCheck struct { + minimumVersion *version.Version + maximumVersion *version.Version +} + +// CheckTerraformVersion satisfies the TerraformVersionCheck interface. +func (s requireBetweenCheck) CheckTerraformVersion(ctx context.Context, req CheckTerraformVersionRequest, resp *CheckTerraformVersionResponse) { + + if req.TerraformVersion.LessThan(s.minimumVersion) || req.TerraformVersion.GreaterThanOrEqual(s.maximumVersion) { + resp.Error = fmt.Errorf("expected Terraform CLI version between %s and %s but detected version is %s", + s.minimumVersion, s.maximumVersion, req.TerraformVersion) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_not.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_not.go new file mode 100644 index 00000000..18a9b68d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/require_not.go @@ -0,0 +1,32 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import ( + "context" + "fmt" + + "github.com/hashicorp/go-version" +) + +// RequireNot will fail the test if the Terraform CLI +// version matches the given version. +func RequireNot(version *version.Version) TerraformVersionCheck { + return requireNotCheck{ + version: version, + } +} + +// requireNotCheck implements the TerraformVersionCheck interface +type requireNotCheck struct { + version *version.Version +} + +// CheckTerraformVersion satisfies the TerraformVersionCheck interface. +func (s requireNotCheck) CheckTerraformVersion(ctx context.Context, req CheckTerraformVersionRequest, resp *CheckTerraformVersionResponse) { + + if req.TerraformVersion.Equal(s.version) { + resp.Error = fmt.Errorf("unexpected Terraform CLI version: %s", s.version) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_above.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_above.go new file mode 100644 index 00000000..ffc69b85 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_above.go @@ -0,0 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import ( + "context" + "fmt" + + "github.com/hashicorp/go-version" +) + +// SkipAbove will skip (pass) the test if the Terraform CLI +// version is below the given version. For example, if given +// version.Must(version.NewVersion("0.15.0")), then 0.14.x or +// any other prior minor versions will skip the test. +func SkipAbove(maximumVersion *version.Version) TerraformVersionCheck { + return skipAboveCheck{ + maximumVersion: maximumVersion, + } +} + +// skipAboveCheck implements the TerraformVersionCheck interface +type skipAboveCheck struct { + maximumVersion *version.Version +} + +// CheckTerraformVersion satisfies the TerraformVersionCheck interface. +func (s skipAboveCheck) CheckTerraformVersion(ctx context.Context, req CheckTerraformVersionRequest, resp *CheckTerraformVersionResponse) { + + if req.TerraformVersion.GreaterThan(s.maximumVersion) { + resp.Skip = fmt.Sprintf("Terraform CLI version %s is above maximum version %s: skipping test", + req.TerraformVersion, s.maximumVersion) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_below.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_below.go new file mode 100644 index 00000000..0b3dffdd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_below.go @@ -0,0 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import ( + "context" + "fmt" + + "github.com/hashicorp/go-version" +) + +// SkipBelow will skip (pass) the test if the Terraform CLI +// version is below the given version. For example, if given +// version.Must(version.NewVersion("0.15.0")), then 0.14.x or +// any other prior minor versions will skip the test. +func SkipBelow(minimumVersion *version.Version) TerraformVersionCheck { + return skipBelowCheck{ + minimumVersion: minimumVersion, + } +} + +// skipBelowCheck implements the TerraformVersionCheck interface +type skipBelowCheck struct { + minimumVersion *version.Version +} + +// CheckTerraformVersion satisfies the TerraformVersionCheck interface. +func (s skipBelowCheck) CheckTerraformVersion(ctx context.Context, req CheckTerraformVersionRequest, resp *CheckTerraformVersionResponse) { + + if req.TerraformVersion.LessThan(s.minimumVersion) { + resp.Skip = fmt.Sprintf("Terraform CLI version %s is below minimum version %s: skipping test", + req.TerraformVersion, s.minimumVersion) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_between.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_between.go new file mode 100644 index 00000000..fb6e9410 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_between.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import ( + "context" + "fmt" + + "github.com/hashicorp/go-version" +) + +// SkipBetween will skip the test if the Terraform CLI +// version is between the given minimum (inclusive) and maximum (exclusive). +// For example, if given a minimum version of version.Must(version.NewVersion("0.15.0")) +// and a maximum version of version.Must(version.NewVersion("0.16.0")), then versions 0.15.x +// will skip the test. +func SkipBetween(minimumVersion, maximumVersion *version.Version) TerraformVersionCheck { + return skipBetweenCheck{ + minimumVersion: minimumVersion, + maximumVersion: maximumVersion, + } +} + +// skipBetweenCheck implements the TerraformVersionCheck interface +type skipBetweenCheck struct { + minimumVersion *version.Version + maximumVersion *version.Version +} + +// CheckTerraformVersion satisfies the TerraformVersionCheck interface. +func (s skipBetweenCheck) CheckTerraformVersion(ctx context.Context, req CheckTerraformVersionRequest, resp *CheckTerraformVersionResponse) { + + if req.TerraformVersion.GreaterThanOrEqual(s.minimumVersion) && req.TerraformVersion.LessThan(s.maximumVersion) { + resp.Skip = fmt.Sprintf("Terraform CLI version %s is between %s and %s: skipping test.", + req.TerraformVersion, s.minimumVersion, s.maximumVersion) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_if.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_if.go new file mode 100644 index 00000000..6ece5e05 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/skip_if.go @@ -0,0 +1,32 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import ( + "context" + "fmt" + + "github.com/hashicorp/go-version" +) + +// SkipIf will skip (pass) the test if the Terraform CLI +// version matches the given version. +func SkipIf(version *version.Version) TerraformVersionCheck { + return skipIfCheck{ + version: version, + } +} + +// skipIfCheck implements the TerraformVersionCheck interface +type skipIfCheck struct { + version *version.Version +} + +// CheckTerraformVersion satisfies the TerraformVersionCheck interface. +func (s skipIfCheck) CheckTerraformVersion(ctx context.Context, req CheckTerraformVersionRequest, resp *CheckTerraformVersionResponse) { + + if req.TerraformVersion.Equal(s.version) { + resp.Skip = fmt.Sprintf("Terraform CLI version is %s: skipping test.", s.version) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/version_check.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/version_check.go new file mode 100644 index 00000000..554ec224 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/version_check.go @@ -0,0 +1,39 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import ( + "context" + + "github.com/hashicorp/go-version" +) + +// TerraformVersionCheck is the interface for writing check logic against the Terraform CLI version. +// The Terraform CLI version is determined by the binary selected by the TF_ACC_TERRAFORM_PATH environment +// variable value, installed by the TF_ACC_TERRAFORM_VERSION value, or already existing based on the PATH environment +// variable. This logic is executed at the beginning of the TestCase before any TestStep is executed. +// +// This package contains some built-in functionality that implements the interface, otherwise consumers can use this +// interface for implementing their own custom logic. +type TerraformVersionCheck interface { + // CheckTerraformVersion should implement the logic to either pass, error (failing the test), or skip (passing the test). + CheckTerraformVersion(context.Context, CheckTerraformVersionRequest, *CheckTerraformVersionResponse) +} + +// CheckTerraformVersionRequest is the request received for the CheckTerraformVersion method of the +// TerraformVersionCheck interface. The response of that method is CheckTerraformVersionResponse. +type CheckTerraformVersionRequest struct { + // TerraformVersion is the version associated with the selected Terraform CLI binary. + TerraformVersion *version.Version +} + +// CheckTerraformVersionResponse is the response returned for the CheckTerraformVersion method of the +// TerraformVersionCheck interface. The request of that method is CheckTerraformVersionRequest. +type CheckTerraformVersionResponse struct { + // Error will result in failing the test with a given error message. + Error error + + // Skip will result in passing the test with a given skip message. + Skip string +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/versions.go b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/versions.go new file mode 100644 index 00000000..21f0727a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-testing/tfversion/versions.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfversion + +import "github.com/hashicorp/go-version" + +// Common use version variables to simplify provider testing implementations. +// This list is not intended to be exhaustive of all Terraform versions, +// however these should at least include cases where Terraform +// introduced new configuration language features. +var ( + // Version0_12_26 is the first Terraform CLI version supported + // by the testing code. + Version0_12_26 *version.Version = version.Must(version.NewVersion("0.12.26")) + + // Major versions + + Version1_0_0 *version.Version = version.Must(version.NewVersion("1.0.0")) + Version2_0_0 *version.Version = version.Must(version.NewVersion("2.0.0")) + + // Minor versions + + Version0_13_0 *version.Version = version.Must(version.NewVersion("0.13.0")) + Version0_14_0 *version.Version = version.Must(version.NewVersion("0.14.0")) + Version0_15_0 *version.Version = version.Must(version.NewVersion("0.15.0")) + Version1_1_0 *version.Version = version.Must(version.NewVersion("1.1.0")) + Version1_2_0 *version.Version = version.Must(version.NewVersion("1.2.0")) + Version1_3_0 *version.Version = version.Must(version.NewVersion("1.3.0")) + Version1_4_0 *version.Version = version.Must(version.NewVersion("1.4.0")) + // Version1_4_6 fixed inclusion of sensitive values in `terraform show -json` output. + // Reference: https://github.com/hashicorp/terraform/releases/tag/v1.4.6 + Version1_4_6 *version.Version = version.Must(version.NewVersion("1.4.6")) + Version1_5_0 *version.Version = version.Must(version.NewVersion("1.5.0")) + Version1_6_0 *version.Version = version.Must(version.NewVersion("1.6.0")) + Version1_7_0 *version.Version = version.Must(version.NewVersion("1.7.0")) + Version1_8_0 *version.Version = version.Must(version.NewVersion("1.8.0")) +) diff --git a/vendor/github.com/mattn/go-runewidth/.travis.yml b/vendor/github.com/mattn/go-runewidth/.travis.yml new file mode 100644 index 00000000..6a21813a --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/.travis.yml @@ -0,0 +1,16 @@ +language: go +sudo: false +go: + - 1.13.x + - tip + +before_install: + - go get -t -v ./... + +script: + - go generate + - git diff --cached --exit-code + - ./go.test.sh + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/mattn/go-runewidth/LICENSE b/vendor/github.com/mattn/go-runewidth/LICENSE new file mode 100644 index 00000000..91b5cef3 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +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/mattn/go-runewidth/README.md b/vendor/github.com/mattn/go-runewidth/README.md new file mode 100644 index 00000000..aa56ab96 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/README.md @@ -0,0 +1,27 @@ +go-runewidth +============ + +[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth) +[![Codecov](https://codecov.io/gh/mattn/go-runewidth/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-runewidth) +[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth) +[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth) + +Provides functions to get fixed width of the character or string. + +Usage +----- + +```go +runewidth.StringWidth("つのだ☆HIRO") == 12 +``` + + +Author +------ + +Yasuhiro Matsumoto + +License +------- + +under the MIT License: http://mattn.mit-license.org/2013 diff --git a/vendor/github.com/mattn/go-runewidth/go.test.sh b/vendor/github.com/mattn/go-runewidth/go.test.sh new file mode 100644 index 00000000..012162b0 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/go.test.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -e +echo "" > coverage.txt + +for d in $(go list ./... | grep -v vendor); do + go test -race -coverprofile=profile.out -covermode=atomic "$d" + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go new file mode 100644 index 00000000..19f8e044 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth.go @@ -0,0 +1,257 @@ +package runewidth + +import ( + "os" +) + +//go:generate go run script/generate.go + +var ( + // EastAsianWidth will be set true if the current locale is CJK + EastAsianWidth bool + + // ZeroWidthJoiner is flag to set to use UTR#51 ZWJ + ZeroWidthJoiner bool + + // DefaultCondition is a condition in current locale + DefaultCondition = &Condition{} +) + +func init() { + handleEnv() +} + +func handleEnv() { + env := os.Getenv("RUNEWIDTH_EASTASIAN") + if env == "" { + EastAsianWidth = IsEastAsian() + } else { + EastAsianWidth = env == "1" + } + // update DefaultCondition + DefaultCondition.EastAsianWidth = EastAsianWidth + DefaultCondition.ZeroWidthJoiner = ZeroWidthJoiner +} + +type interval struct { + first rune + last rune +} + +type table []interval + +func inTables(r rune, ts ...table) bool { + for _, t := range ts { + if inTable(r, t) { + return true + } + } + return false +} + +func inTable(r rune, t table) bool { + if r < t[0].first { + return false + } + + bot := 0 + top := len(t) - 1 + for top >= bot { + mid := (bot + top) >> 1 + + switch { + case t[mid].last < r: + bot = mid + 1 + case t[mid].first > r: + top = mid - 1 + default: + return true + } + } + + return false +} + +var private = table{ + {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD}, +} + +var nonprint = table{ + {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, + {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, + {0x2028, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, +} + +// Condition have flag EastAsianWidth whether the current locale is CJK or not. +type Condition struct { + EastAsianWidth bool + ZeroWidthJoiner bool +} + +// NewCondition return new instance of Condition which is current locale. +func NewCondition() *Condition { + return &Condition{ + EastAsianWidth: EastAsianWidth, + ZeroWidthJoiner: ZeroWidthJoiner, + } +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func (c *Condition) RuneWidth(r rune) int { + switch { + case r < 0 || r > 0x10FFFF || inTables(r, nonprint, combining, notassigned): + return 0 + case (c.EastAsianWidth && IsAmbiguousWidth(r)) || inTables(r, doublewidth): + return 2 + default: + return 1 + } +} + +func (c *Condition) stringWidth(s string) (width int) { + for _, r := range []rune(s) { + width += c.RuneWidth(r) + } + return width +} + +func (c *Condition) stringWidthZeroJoiner(s string) (width int) { + r1, r2 := rune(0), rune(0) + for _, r := range []rune(s) { + if r == 0xFE0E || r == 0xFE0F { + continue + } + w := c.RuneWidth(r) + if r2 == 0x200D && inTables(r, emoji) && inTables(r1, emoji) { + if width < w { + width = w + } + } else { + width += w + } + r1, r2 = r2, r + } + return width +} + +// StringWidth return width as you can see +func (c *Condition) StringWidth(s string) (width int) { + if c.ZeroWidthJoiner { + return c.stringWidthZeroJoiner(s) + } + return c.stringWidth(s) +} + +// Truncate return string truncated with w cells +func (c *Condition) Truncate(s string, w int, tail string) string { + if c.StringWidth(s) <= w { + return s + } + r := []rune(s) + tw := c.StringWidth(tail) + w -= tw + width := 0 + i := 0 + for ; i < len(r); i++ { + cw := c.RuneWidth(r[i]) + if width+cw > w { + break + } + width += cw + } + return string(r[0:i]) + tail +} + +// Wrap return string wrapped with w cells +func (c *Condition) Wrap(s string, w int) string { + width := 0 + out := "" + for _, r := range []rune(s) { + cw := RuneWidth(r) + if r == '\n' { + out += string(r) + width = 0 + continue + } else if width+cw > w { + out += "\n" + width = 0 + out += string(r) + width += cw + continue + } + out += string(r) + width += cw + } + return out +} + +// FillLeft return string filled in left by spaces in w cells +func (c *Condition) FillLeft(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return string(b) + s + } + return s +} + +// FillRight return string filled in left by spaces in w cells +func (c *Condition) FillRight(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return s + string(b) + } + return s +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func RuneWidth(r rune) int { + return DefaultCondition.RuneWidth(r) +} + +// IsAmbiguousWidth returns whether is ambiguous width or not. +func IsAmbiguousWidth(r rune) bool { + return inTables(r, private, ambiguous) +} + +// IsNeutralWidth returns whether is neutral width or not. +func IsNeutralWidth(r rune) bool { + return inTable(r, neutral) +} + +// StringWidth return width as you can see +func StringWidth(s string) (width int) { + return DefaultCondition.StringWidth(s) +} + +// Truncate return string truncated with w cells +func Truncate(s string, w int, tail string) string { + return DefaultCondition.Truncate(s, w, tail) +} + +// Wrap return string wrapped with w cells +func Wrap(s string, w int) string { + return DefaultCondition.Wrap(s, w) +} + +// FillLeft return string filled in left by spaces in w cells +func FillLeft(s string, w int) string { + return DefaultCondition.FillLeft(s, w) +} + +// FillRight return string filled in left by spaces in w cells +func FillRight(s string, w int) string { + return DefaultCondition.FillRight(s, w) +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go b/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go new file mode 100644 index 00000000..7d99f6e5 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go @@ -0,0 +1,8 @@ +// +build appengine + +package runewidth + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + return false +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_js.go b/vendor/github.com/mattn/go-runewidth/runewidth_js.go new file mode 100644 index 00000000..c5fdf40b --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_js.go @@ -0,0 +1,9 @@ +// +build js +// +build !appengine + +package runewidth + +func IsEastAsian() bool { + // TODO: Implement this for the web. Detect east asian in a compatible way, and return true. + return false +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go new file mode 100644 index 00000000..480ad748 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go @@ -0,0 +1,82 @@ +// +build !windows +// +build !js +// +build !appengine + +package runewidth + +import ( + "os" + "regexp" + "strings" +) + +var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) + +var mblenTable = map[string]int{ + "utf-8": 6, + "utf8": 6, + "jis": 8, + "eucjp": 3, + "euckr": 2, + "euccn": 2, + "sjis": 2, + "cp932": 2, + "cp51932": 2, + "cp936": 2, + "cp949": 2, + "cp950": 2, + "big5": 2, + "gbk": 2, + "gb2312": 2, +} + +func isEastAsian(locale string) bool { + charset := strings.ToLower(locale) + r := reLoc.FindStringSubmatch(locale) + if len(r) == 2 { + charset = strings.ToLower(r[1]) + } + + if strings.HasSuffix(charset, "@cjk_narrow") { + return false + } + + for pos, b := range []byte(charset) { + if b == '@' { + charset = charset[:pos] + break + } + } + max := 1 + if m, ok := mblenTable[charset]; ok { + max = m + } + if max > 1 && (charset[0] != 'u' || + strings.HasPrefix(locale, "ja") || + strings.HasPrefix(locale, "ko") || + strings.HasPrefix(locale, "zh")) { + return true + } + return false +} + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + locale := os.Getenv("LC_ALL") + if locale == "" { + locale = os.Getenv("LC_CTYPE") + } + if locale == "" { + locale = os.Getenv("LANG") + } + + // ignore C locale + if locale == "POSIX" || locale == "C" { + return false + } + if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { + return false + } + + return isEastAsian(locale) +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_table.go b/vendor/github.com/mattn/go-runewidth/runewidth_table.go new file mode 100644 index 00000000..b27d77d8 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_table.go @@ -0,0 +1,437 @@ +// Code generated by script/generate.go. DO NOT EDIT. + +package runewidth + +var combining = table{ + {0x0300, 0x036F}, {0x0483, 0x0489}, {0x07EB, 0x07F3}, + {0x0C00, 0x0C00}, {0x0C04, 0x0C04}, {0x0D00, 0x0D01}, + {0x135D, 0x135F}, {0x1A7F, 0x1A7F}, {0x1AB0, 0x1AC0}, + {0x1B6B, 0x1B73}, {0x1DC0, 0x1DF9}, {0x1DFB, 0x1DFF}, + {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2DE0, 0x2DFF}, + {0x3099, 0x309A}, {0xA66F, 0xA672}, {0xA674, 0xA67D}, + {0xA69E, 0xA69F}, {0xA6F0, 0xA6F1}, {0xA8E0, 0xA8F1}, + {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, {0x10376, 0x1037A}, + {0x10EAB, 0x10EAC}, {0x10F46, 0x10F50}, {0x11300, 0x11301}, + {0x1133B, 0x1133C}, {0x11366, 0x1136C}, {0x11370, 0x11374}, + {0x16AF0, 0x16AF4}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172}, + {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, + {0x1D242, 0x1D244}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, + {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, + {0x1E8D0, 0x1E8D6}, +} + +var doublewidth = table{ + {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, + {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, + {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, + {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, + {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, + {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, + {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, + {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, + {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, + {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, + {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, + {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, + {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, + {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, + {0x3105, 0x312F}, {0x3131, 0x318E}, {0x3190, 0x31E3}, + {0x31F0, 0x321E}, {0x3220, 0x3247}, {0x3250, 0x4DBF}, + {0x4E00, 0xA48C}, {0xA490, 0xA4C6}, {0xA960, 0xA97C}, + {0xAC00, 0xD7A3}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, + {0xFE30, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, + {0xFF01, 0xFF60}, {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4}, + {0x16FF0, 0x16FF1}, {0x17000, 0x187F7}, {0x18800, 0x18CD5}, + {0x18D00, 0x18D08}, {0x1B000, 0x1B11E}, {0x1B150, 0x1B152}, + {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1F004, 0x1F004}, + {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, + {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, + {0x1F250, 0x1F251}, {0x1F260, 0x1F265}, {0x1F300, 0x1F320}, + {0x1F32D, 0x1F335}, {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, + {0x1F3A0, 0x1F3CA}, {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, + {0x1F3F4, 0x1F3F4}, {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, + {0x1F442, 0x1F4FC}, {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, + {0x1F550, 0x1F567}, {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, + {0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, + {0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2}, {0x1F6D5, 0x1F6D7}, + {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6FC}, {0x1F7E0, 0x1F7EB}, + {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F978}, + {0x1F97A, 0x1F9CB}, {0x1F9CD, 0x1F9FF}, {0x1FA70, 0x1FA74}, + {0x1FA78, 0x1FA7A}, {0x1FA80, 0x1FA86}, {0x1FA90, 0x1FAA8}, + {0x1FAB0, 0x1FAB6}, {0x1FAC0, 0x1FAC2}, {0x1FAD0, 0x1FAD6}, + {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD}, +} + +var ambiguous = table{ + {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, + {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, + {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, + {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, + {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, + {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, + {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, + {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, + {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, + {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, + {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, + {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, + {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, + {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, + {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, + {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, + {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, + {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F}, + {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, + {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, + {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, + {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, + {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, + {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, + {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, + {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105}, + {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, + {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, + {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, + {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199}, + {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4}, + {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, + {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, + {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, + {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, + {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, + {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, + {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267}, + {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, + {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, + {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, + {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, + {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1}, + {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, + {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, + {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, + {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, + {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E}, + {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, + {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, + {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF}, + {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1}, + {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1}, + {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC}, + {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F}, + {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, + {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, + {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, + {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF}, + {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, +} +var notassigned = table{ + {0x27E6, 0x27ED}, {0x2985, 0x2986}, +} + +var neutral = table{ + {0x0000, 0x001F}, {0x007F, 0x00A0}, {0x00A9, 0x00A9}, + {0x00AB, 0x00AB}, {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, + {0x00C0, 0x00C5}, {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, + {0x00D9, 0x00DD}, {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, + {0x00EB, 0x00EB}, {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, + {0x00F4, 0x00F6}, {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, + {0x00FF, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112}, + {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A}, + {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E}, + {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C}, + {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A}, + {0x016C, 0x01CD}, {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, + {0x01D3, 0x01D3}, {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, + {0x01D9, 0x01D9}, {0x01DB, 0x01DB}, {0x01DD, 0x0250}, + {0x0252, 0x0260}, {0x0262, 0x02C3}, {0x02C5, 0x02C6}, + {0x02C8, 0x02C8}, {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, + {0x02D1, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE}, + {0x02E0, 0x02FF}, {0x0370, 0x0377}, {0x037A, 0x037F}, + {0x0384, 0x038A}, {0x038C, 0x038C}, {0x038E, 0x0390}, + {0x03AA, 0x03B0}, {0x03C2, 0x03C2}, {0x03CA, 0x0400}, + {0x0402, 0x040F}, {0x0450, 0x0450}, {0x0452, 0x052F}, + {0x0531, 0x0556}, {0x0559, 0x058A}, {0x058D, 0x058F}, + {0x0591, 0x05C7}, {0x05D0, 0x05EA}, {0x05EF, 0x05F4}, + {0x0600, 0x061C}, {0x061E, 0x070D}, {0x070F, 0x074A}, + {0x074D, 0x07B1}, {0x07C0, 0x07FA}, {0x07FD, 0x082D}, + {0x0830, 0x083E}, {0x0840, 0x085B}, {0x085E, 0x085E}, + {0x0860, 0x086A}, {0x08A0, 0x08B4}, {0x08B6, 0x08C7}, + {0x08D3, 0x0983}, {0x0985, 0x098C}, {0x098F, 0x0990}, + {0x0993, 0x09A8}, {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, + {0x09B6, 0x09B9}, {0x09BC, 0x09C4}, {0x09C7, 0x09C8}, + {0x09CB, 0x09CE}, {0x09D7, 0x09D7}, {0x09DC, 0x09DD}, + {0x09DF, 0x09E3}, {0x09E6, 0x09FE}, {0x0A01, 0x0A03}, + {0x0A05, 0x0A0A}, {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, + {0x0A2A, 0x0A30}, {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, + {0x0A38, 0x0A39}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, + {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, + {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A76}, + {0x0A81, 0x0A83}, {0x0A85, 0x0A8D}, {0x0A8F, 0x0A91}, + {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, + {0x0AB5, 0x0AB9}, {0x0ABC, 0x0AC5}, {0x0AC7, 0x0AC9}, + {0x0ACB, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE3}, + {0x0AE6, 0x0AF1}, {0x0AF9, 0x0AFF}, {0x0B01, 0x0B03}, + {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, {0x0B13, 0x0B28}, + {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, {0x0B35, 0x0B39}, + {0x0B3C, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D}, + {0x0B55, 0x0B57}, {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B63}, + {0x0B66, 0x0B77}, {0x0B82, 0x0B83}, {0x0B85, 0x0B8A}, + {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, {0x0B99, 0x0B9A}, + {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4}, + {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, {0x0BBE, 0x0BC2}, + {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD}, {0x0BD0, 0x0BD0}, + {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BFA}, {0x0C00, 0x0C0C}, + {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, {0x0C2A, 0x0C39}, + {0x0C3D, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, + {0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C63}, + {0x0C66, 0x0C6F}, {0x0C77, 0x0C8C}, {0x0C8E, 0x0C90}, + {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, + {0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD}, + {0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE3}, + {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, {0x0D00, 0x0D0C}, + {0x0D0E, 0x0D10}, {0x0D12, 0x0D44}, {0x0D46, 0x0D48}, + {0x0D4A, 0x0D4F}, {0x0D54, 0x0D63}, {0x0D66, 0x0D7F}, + {0x0D81, 0x0D83}, {0x0D85, 0x0D96}, {0x0D9A, 0x0DB1}, + {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6}, + {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6}, + {0x0DD8, 0x0DDF}, {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4}, + {0x0E01, 0x0E3A}, {0x0E3F, 0x0E5B}, {0x0E81, 0x0E82}, + {0x0E84, 0x0E84}, {0x0E86, 0x0E8A}, {0x0E8C, 0x0EA3}, + {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EBD}, {0x0EC0, 0x0EC4}, + {0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, + {0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C}, + {0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC}, + {0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7}, + {0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1160, 0x1248}, + {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, + {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, + {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, + {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, + {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, + {0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5}, + {0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8}, + {0x1700, 0x170C}, {0x170E, 0x1714}, {0x1720, 0x1736}, + {0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, + {0x1772, 0x1773}, {0x1780, 0x17DD}, {0x17E0, 0x17E9}, + {0x17F0, 0x17F9}, {0x1800, 0x180E}, {0x1810, 0x1819}, + {0x1820, 0x1878}, {0x1880, 0x18AA}, {0x18B0, 0x18F5}, + {0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B}, + {0x1940, 0x1940}, {0x1944, 0x196D}, {0x1970, 0x1974}, + {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA}, + {0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C}, + {0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD}, + {0x1AB0, 0x1AC0}, {0x1B00, 0x1B4B}, {0x1B50, 0x1B7C}, + {0x1B80, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49}, + {0x1C4D, 0x1C88}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CC7}, + {0x1CD0, 0x1CFA}, {0x1D00, 0x1DF9}, {0x1DFB, 0x1F15}, + {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, + {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, + {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, + {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB}, + {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE}, + {0x2000, 0x200F}, {0x2011, 0x2012}, {0x2017, 0x2017}, + {0x201A, 0x201B}, {0x201E, 0x201F}, {0x2023, 0x2023}, + {0x2028, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034}, + {0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064}, + {0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080}, + {0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8}, + {0x20AA, 0x20AB}, {0x20AD, 0x20BF}, {0x20D0, 0x20F0}, + {0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108}, + {0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120}, + {0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152}, + {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F}, + {0x217A, 0x2188}, {0x218A, 0x218B}, {0x219A, 0x21B7}, + {0x21BA, 0x21D1}, {0x21D3, 0x21D3}, {0x21D5, 0x21E6}, + {0x21E8, 0x21FF}, {0x2201, 0x2201}, {0x2204, 0x2206}, + {0x2209, 0x220A}, {0x220C, 0x220E}, {0x2210, 0x2210}, + {0x2212, 0x2214}, {0x2216, 0x2219}, {0x221B, 0x221C}, + {0x2221, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226}, + {0x222D, 0x222D}, {0x222F, 0x2233}, {0x2238, 0x223B}, + {0x223E, 0x2247}, {0x2249, 0x224B}, {0x224D, 0x2251}, + {0x2253, 0x225F}, {0x2262, 0x2263}, {0x2268, 0x2269}, + {0x226C, 0x226D}, {0x2270, 0x2281}, {0x2284, 0x2285}, + {0x2288, 0x2294}, {0x2296, 0x2298}, {0x229A, 0x22A4}, + {0x22A6, 0x22BE}, {0x22C0, 0x2311}, {0x2313, 0x2319}, + {0x231C, 0x2328}, {0x232B, 0x23E8}, {0x23ED, 0x23EF}, + {0x23F1, 0x23F2}, {0x23F4, 0x2426}, {0x2440, 0x244A}, + {0x24EA, 0x24EA}, {0x254C, 0x254F}, {0x2574, 0x257F}, + {0x2590, 0x2591}, {0x2596, 0x259F}, {0x25A2, 0x25A2}, + {0x25AA, 0x25B1}, {0x25B4, 0x25B5}, {0x25B8, 0x25BB}, + {0x25BE, 0x25BF}, {0x25C2, 0x25C5}, {0x25C9, 0x25CA}, + {0x25CC, 0x25CD}, {0x25D2, 0x25E1}, {0x25E6, 0x25EE}, + {0x25F0, 0x25FC}, {0x25FF, 0x2604}, {0x2607, 0x2608}, + {0x260A, 0x260D}, {0x2610, 0x2613}, {0x2616, 0x261B}, + {0x261D, 0x261D}, {0x261F, 0x263F}, {0x2641, 0x2641}, + {0x2643, 0x2647}, {0x2654, 0x265F}, {0x2662, 0x2662}, + {0x2666, 0x2666}, {0x266B, 0x266B}, {0x266E, 0x266E}, + {0x2670, 0x267E}, {0x2680, 0x2692}, {0x2694, 0x269D}, + {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, {0x26AC, 0x26BC}, + {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, {0x26E4, 0x26E7}, + {0x2700, 0x2704}, {0x2706, 0x2709}, {0x270C, 0x2727}, + {0x2729, 0x273C}, {0x273E, 0x274B}, {0x274D, 0x274D}, + {0x274F, 0x2752}, {0x2756, 0x2756}, {0x2758, 0x2775}, + {0x2780, 0x2794}, {0x2798, 0x27AF}, {0x27B1, 0x27BE}, + {0x27C0, 0x27E5}, {0x27EE, 0x2984}, {0x2987, 0x2B1A}, + {0x2B1D, 0x2B4F}, {0x2B51, 0x2B54}, {0x2B5A, 0x2B73}, + {0x2B76, 0x2B95}, {0x2B97, 0x2C2E}, {0x2C30, 0x2C5E}, + {0x2C60, 0x2CF3}, {0x2CF9, 0x2D25}, {0x2D27, 0x2D27}, + {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D70}, + {0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, + {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, + {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, + {0x2DE0, 0x2E52}, {0x303F, 0x303F}, {0x4DC0, 0x4DFF}, + {0xA4D0, 0xA62B}, {0xA640, 0xA6F7}, {0xA700, 0xA7BF}, + {0xA7C2, 0xA7CA}, {0xA7F5, 0xA82C}, {0xA830, 0xA839}, + {0xA840, 0xA877}, {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9}, + {0xA8E0, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD}, + {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36}, + {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2}, + {0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, + {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, + {0xAB30, 0xAB6B}, {0xAB70, 0xABED}, {0xABF0, 0xABF9}, + {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF}, + {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36}, + {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, + {0xFB43, 0xFB44}, {0xFB46, 0xFBC1}, {0xFBD3, 0xFD3F}, + {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFD}, + {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B}, + {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, + {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, + {0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E}, + {0x10190, 0x1019C}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD}, + {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB}, + {0x10300, 0x10323}, {0x1032D, 0x1034A}, {0x10350, 0x1037A}, + {0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5}, + {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, + {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, + {0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755}, + {0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808}, + {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, + {0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF}, + {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B}, + {0x1091F, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x109B7}, + {0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A05, 0x10A06}, + {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, + {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, {0x10A50, 0x10A58}, + {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6}, + {0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72}, + {0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, + {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, + {0x10CFA, 0x10D27}, {0x10D30, 0x10D39}, {0x10E60, 0x10E7E}, + {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, {0x10EB0, 0x10EB1}, + {0x10F00, 0x10F27}, {0x10F30, 0x10F59}, {0x10FB0, 0x10FCB}, + {0x10FE0, 0x10FF6}, {0x11000, 0x1104D}, {0x11052, 0x1106F}, + {0x1107F, 0x110C1}, {0x110CD, 0x110CD}, {0x110D0, 0x110E8}, + {0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11147}, + {0x11150, 0x11176}, {0x11180, 0x111DF}, {0x111E1, 0x111F4}, + {0x11200, 0x11211}, {0x11213, 0x1123E}, {0x11280, 0x11286}, + {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, + {0x1129F, 0x112A9}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9}, + {0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, + {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, + {0x11335, 0x11339}, {0x1133B, 0x11344}, {0x11347, 0x11348}, + {0x1134B, 0x1134D}, {0x11350, 0x11350}, {0x11357, 0x11357}, + {0x1135D, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, + {0x11400, 0x1145B}, {0x1145D, 0x11461}, {0x11480, 0x114C7}, + {0x114D0, 0x114D9}, {0x11580, 0x115B5}, {0x115B8, 0x115DD}, + {0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, + {0x11680, 0x116B8}, {0x116C0, 0x116C9}, {0x11700, 0x1171A}, + {0x1171D, 0x1172B}, {0x11730, 0x1173F}, {0x11800, 0x1183B}, + {0x118A0, 0x118F2}, {0x118FF, 0x11906}, {0x11909, 0x11909}, + {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935}, + {0x11937, 0x11938}, {0x1193B, 0x11946}, {0x11950, 0x11959}, + {0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E4}, + {0x11A00, 0x11A47}, {0x11A50, 0x11AA2}, {0x11AC0, 0x11AF8}, + {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45}, + {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7}, + {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, + {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D}, + {0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65}, + {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91}, + {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11EE0, 0x11EF8}, + {0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399}, + {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, + {0x13000, 0x1342E}, {0x13430, 0x13438}, {0x14400, 0x14646}, + {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, + {0x16A6E, 0x16A6F}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5}, + {0x16B00, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, + {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16E40, 0x16E9A}, + {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F}, + {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, + {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3}, {0x1D000, 0x1D0F5}, + {0x1D100, 0x1D126}, {0x1D129, 0x1D1E8}, {0x1D200, 0x1D245}, + {0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356}, {0x1D360, 0x1D378}, + {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, + {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, + {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, + {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, + {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, + {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, + {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B}, + {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, + {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, + {0x1E026, 0x1E02A}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D}, + {0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E2C0, 0x1E2F9}, + {0x1E2FF, 0x1E2FF}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6}, + {0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, + {0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03}, + {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, + {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, + {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, + {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, + {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, + {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, + {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, + {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, + {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, + {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, + {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1}, + {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, {0x1F030, 0x1F093}, + {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CE}, + {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10F}, {0x1F12E, 0x1F12F}, + {0x1F16A, 0x1F16F}, {0x1F1AD, 0x1F1AD}, {0x1F1E6, 0x1F1FF}, + {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, + {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF}, + {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F}, + {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A}, + {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594}, + {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F}, + {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6D3, 0x1F6D4}, + {0x1F6E0, 0x1F6EA}, {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, + {0x1F780, 0x1F7D8}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, + {0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, + {0x1F8B0, 0x1F8B1}, {0x1F900, 0x1F90B}, {0x1F93B, 0x1F93B}, + {0x1F946, 0x1F946}, {0x1FA00, 0x1FA53}, {0x1FA60, 0x1FA6D}, + {0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBCA}, {0x1FBF0, 0x1FBF9}, + {0xE0001, 0xE0001}, {0xE0020, 0xE007F}, +} + +var emoji = table{ + {0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122}, + {0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA}, + {0x231A, 0x231B}, {0x2328, 0x2328}, {0x2388, 0x2388}, + {0x23CF, 0x23CF}, {0x23E9, 0x23F3}, {0x23F8, 0x23FA}, + {0x24C2, 0x24C2}, {0x25AA, 0x25AB}, {0x25B6, 0x25B6}, + {0x25C0, 0x25C0}, {0x25FB, 0x25FE}, {0x2600, 0x2605}, + {0x2607, 0x2612}, {0x2614, 0x2685}, {0x2690, 0x2705}, + {0x2708, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716}, + {0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728}, + {0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747}, + {0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755}, + {0x2757, 0x2757}, {0x2763, 0x2767}, {0x2795, 0x2797}, + {0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, + {0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C}, + {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030}, + {0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299}, + {0x1F000, 0x1F0FF}, {0x1F10D, 0x1F10F}, {0x1F12F, 0x1F12F}, + {0x1F16C, 0x1F171}, {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E}, + {0x1F191, 0x1F19A}, {0x1F1AD, 0x1F1E5}, {0x1F201, 0x1F20F}, + {0x1F21A, 0x1F21A}, {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A}, + {0x1F23C, 0x1F23F}, {0x1F249, 0x1F3FA}, {0x1F400, 0x1F53D}, + {0x1F546, 0x1F64F}, {0x1F680, 0x1F6FF}, {0x1F774, 0x1F77F}, + {0x1F7D5, 0x1F7FF}, {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, + {0x1F85A, 0x1F85F}, {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F8FF}, + {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1FAFF}, + {0x1FC00, 0x1FFFD}, +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go new file mode 100644 index 00000000..d6a61777 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go @@ -0,0 +1,28 @@ +// +build windows +// +build !appengine + +package runewidth + +import ( + "syscall" +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32") + procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") +) + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + r1, _, _ := procGetConsoleOutputCP.Call() + if r1 == 0 { + return false + } + + switch int(r1) { + case 932, 51932, 936, 949, 950: + return true + } + + return false +} diff --git a/vendor/github.com/russross/blackfriday/.gitignore b/vendor/github.com/russross/blackfriday/.gitignore deleted file mode 100644 index 75623dcc..00000000 --- a/vendor/github.com/russross/blackfriday/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.out -*.swp -*.8 -*.6 -_obj -_test* -markdown -tags diff --git a/vendor/github.com/russross/blackfriday/.travis.yml b/vendor/github.com/russross/blackfriday/.travis.yml deleted file mode 100644 index a49fff15..00000000 --- a/vendor/github.com/russross/blackfriday/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -sudo: false -language: go -go: - - "1.9.x" - - "1.10.x" - - "1.11.x" - - tip -matrix: - fast_finish: true - allow_failures: - - go: tip -install: - - # Do nothing. This is needed to prevent default install action "go get -t -v ./..." from happening here (we want it to happen inside script step). -script: - - go get -t -v ./... - - diff -u <(echo -n) <(gofmt -d -s .) - - go tool vet . - - go test -v -race ./... diff --git a/vendor/github.com/russross/blackfriday/LICENSE.txt b/vendor/github.com/russross/blackfriday/LICENSE.txt deleted file mode 100644 index 7fbb253a..00000000 --- a/vendor/github.com/russross/blackfriday/LICENSE.txt +++ /dev/null @@ -1,28 +0,0 @@ -Blackfriday is distributed under the Simplified BSD License: - -Copyright © 2011 Russ Ross -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided with - the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/russross/blackfriday/README.md b/vendor/github.com/russross/blackfriday/README.md deleted file mode 100644 index 997ef5d4..00000000 --- a/vendor/github.com/russross/blackfriday/README.md +++ /dev/null @@ -1,364 +0,0 @@ -Blackfriday -[![Build Status][BuildV2SVG]][BuildV2URL] -[![PkgGoDev][PkgGoDevV2SVG]][PkgGoDevV2URL] -=========== - -Blackfriday is a [Markdown][1] processor implemented in [Go][2]. It -is paranoid about its input (so you can safely feed it user-supplied -data), it is fast, it supports common extensions (tables, smart -punctuation substitutions, etc.), and it is safe for all utf-8 -(unicode) input. - -HTML output is currently supported, along with Smartypants -extensions. - -It started as a translation from C of [Sundown][3]. - - -Installation ------------- - -Blackfriday is compatible with modern Go releases in module mode. -With Go installed: - - go get github.com/russross/blackfriday - -will resolve and add the package to the current development module, -then build and install it. Alternatively, you can achieve the same -if you import it in a package: - - import "github.com/russross/blackfriday" - -and `go get` without parameters. - -Old versions of Go and legacy GOPATH mode might work, -but no effort is made to keep them working. - - -Versions --------- - -Currently maintained and recommended version of Blackfriday is `v2`. It's being -developed on its own branch: https://github.com/russross/blackfriday/tree/v2 and the -documentation is available at -https://pkg.go.dev/github.com/russross/blackfriday/v2. - -It is `go get`-able in module mode at `github.com/russross/blackfriday/v2`. - -Version 2 offers a number of improvements over v1: - -* Cleaned up API -* A separate call to [`Parse`][4], which produces an abstract syntax tree for - the document -* Latest bug fixes -* Flexibility to easily add your own rendering extensions - -Potential drawbacks: - -* Our benchmarks show v2 to be slightly slower than v1. Currently in the - ballpark of around 15%. -* API breakage. If you can't afford modifying your code to adhere to the new API - and don't care too much about the new features, v2 is probably not for you. -* Several bug fixes are trailing behind and still need to be forward-ported to - v2. See issue [#348](https://github.com/russross/blackfriday/issues/348) for - tracking. - -If you are still interested in the legacy `v1`, you can import it from -`github.com/russross/blackfriday`. Documentation for the legacy v1 can be found -here: https://pkg.go.dev/github.com/russross/blackfriday. - - -Usage ------ - -### v1 - -For basic usage, it is as simple as getting your input into a byte -slice and calling: - -```go -output := blackfriday.MarkdownBasic(input) -``` - -This renders it with no extensions enabled. To get a more useful -feature set, use this instead: - -```go -output := blackfriday.MarkdownCommon(input) -``` - -### v2 - -For the most sensible markdown processing, it is as simple as getting your input -into a byte slice and calling: - -```go -output := blackfriday.Run(input) -``` - -Your input will be parsed and the output rendered with a set of most popular -extensions enabled. If you want the most basic feature set, corresponding with -the bare Markdown specification, use: - -```go -output := blackfriday.Run(input, blackfriday.WithNoExtensions()) -``` - -### Sanitize untrusted content - -Blackfriday itself does nothing to protect against malicious content. If you are -dealing with user-supplied markdown, we recommend running Blackfriday's output -through HTML sanitizer such as [Bluemonday][5]. - -Here's an example of simple usage of Blackfriday together with Bluemonday: - -```go -import ( - "github.com/microcosm-cc/bluemonday" - "github.com/russross/blackfriday" -) - -// ... -unsafe := blackfriday.Run(input) -html := bluemonday.UGCPolicy().SanitizeBytes(unsafe) -``` - -### Custom options, v1 - -If you want to customize the set of options, first get a renderer -(currently only the HTML output engine), then use it to -call the more general `Markdown` function. For examples, see the -implementations of `MarkdownBasic` and `MarkdownCommon` in -`markdown.go`. - -### Custom options, v2 - -If you want to customize the set of options, use `blackfriday.WithExtensions`, -`blackfriday.WithRenderer` and `blackfriday.WithRefOverride`. - -### `blackfriday-tool` - -You can also check out `blackfriday-tool` for a more complete example -of how to use it. Download and install it using: - - go get github.com/russross/blackfriday-tool - -This is a simple command-line tool that allows you to process a -markdown file using a standalone program. You can also browse the -source directly on github if you are just looking for some example -code: - -* - -Note that if you have not already done so, installing -`blackfriday-tool` will be sufficient to download and install -blackfriday in addition to the tool itself. The tool binary will be -installed in `$GOPATH/bin`. This is a statically-linked binary that -can be copied to wherever you need it without worrying about -dependencies and library versions. - -### Sanitized anchor names - -Blackfriday includes an algorithm for creating sanitized anchor names -corresponding to a given input text. This algorithm is used to create -anchors for headings when `EXTENSION_AUTO_HEADER_IDS` is enabled. The -algorithm has a specification, so that other packages can create -compatible anchor names and links to those anchors. - -The specification is located at https://pkg.go.dev/github.com/russross/blackfriday#hdr-Sanitized_Anchor_Names. - -[`SanitizedAnchorName`](https://pkg.go.dev/github.com/russross/blackfriday#SanitizedAnchorName) exposes this functionality, and can be used to -create compatible links to the anchor names generated by blackfriday. -This algorithm is also implemented in a small standalone package at -[`github.com/shurcooL/sanitized_anchor_name`](https://pkg.go.dev/github.com/shurcooL/sanitized_anchor_name). It can be useful for clients -that want a small package and don't need full functionality of blackfriday. - - -Features --------- - -All features of Sundown are supported, including: - -* **Compatibility**. The Markdown v1.0.3 test suite passes with - the `--tidy` option. Without `--tidy`, the differences are - mostly in whitespace and entity escaping, where blackfriday is - more consistent and cleaner. - -* **Common extensions**, including table support, fenced code - blocks, autolinks, strikethroughs, non-strict emphasis, etc. - -* **Safety**. Blackfriday is paranoid when parsing, making it safe - to feed untrusted user input without fear of bad things - happening. The test suite stress tests this and there are no - known inputs that make it crash. If you find one, please let me - know and send me the input that does it. - - NOTE: "safety" in this context means *runtime safety only*. In order to - protect yourself against JavaScript injection in untrusted content, see - [this example](https://github.com/russross/blackfriday#sanitize-untrusted-content). - -* **Fast processing**. It is fast enough to render on-demand in - most web applications without having to cache the output. - -* **Thread safety**. You can run multiple parsers in different - goroutines without ill effect. There is no dependence on global - shared state. - -* **Minimal dependencies**. Blackfriday only depends on standard - library packages in Go. The source code is pretty - self-contained, so it is easy to add to any project, including - Google App Engine projects. - -* **Standards compliant**. Output successfully validates using the - W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional. - - -Extensions ----------- - -In addition to the standard markdown syntax, this package -implements the following extensions: - -* **Intra-word emphasis supression**. The `_` character is - commonly used inside words when discussing code, so having - markdown interpret it as an emphasis command is usually the - wrong thing. Blackfriday lets you treat all emphasis markers as - normal characters when they occur inside a word. - -* **Tables**. Tables can be created by drawing them in the input - using a simple syntax: - - ``` - Name | Age - --------|------ - Bob | 27 - Alice | 23 - ``` - -* **Fenced code blocks**. In addition to the normal 4-space - indentation to mark code blocks, you can explicitly mark them - and supply a language (to make syntax highlighting simple). Just - mark it like this: - - ```go - func getTrue() bool { - return true - } - ``` - - You can use 3 or more backticks to mark the beginning of the - block, and the same number to mark the end of the block. - - To preserve classes of fenced code blocks while using the bluemonday - HTML sanitizer, use the following policy: - - ```go - p := bluemonday.UGCPolicy() - p.AllowAttrs("class").Matching(regexp.MustCompile("^language-[a-zA-Z0-9]+$")).OnElements("code") - html := p.SanitizeBytes(unsafe) - ``` - -* **Definition lists**. A simple definition list is made of a single-line - term followed by a colon and the definition for that term. - - Cat - : Fluffy animal everyone likes - - Internet - : Vector of transmission for pictures of cats - - Terms must be separated from the previous definition by a blank line. - -* **Footnotes**. A marker in the text that will become a superscript number; - a footnote definition that will be placed in a list of footnotes at the - end of the document. A footnote looks like this: - - This is a footnote.[^1] - - [^1]: the footnote text. - -* **Autolinking**. Blackfriday can find URLs that have not been - explicitly marked as links and turn them into links. - -* **Strikethrough**. Use two tildes (`~~`) to mark text that - should be crossed out. - -* **Hard line breaks**. With this extension enabled (it is off by - default in the `MarkdownBasic` and `MarkdownCommon` convenience - functions), newlines in the input translate into line breaks in - the output. - -* **Smart quotes**. Smartypants-style punctuation substitution is - supported, turning normal double- and single-quote marks into - curly quotes, etc. - -* **LaTeX-style dash parsing** is an additional option, where `--` - is translated into `–`, and `---` is translated into - `—`. This differs from most smartypants processors, which - turn a single hyphen into an ndash and a double hyphen into an - mdash. - -* **Smart fractions**, where anything that looks like a fraction - is translated into suitable HTML (instead of just a few special - cases like most smartypant processors). For example, `4/5` - becomes `45`, which renders as - 45. - - -Other renderers ---------------- - -Blackfriday is structured to allow alternative rendering engines. Here -are a few of note: - -* [github_flavored_markdown](https://pkg.go.dev/github.com/shurcooL/github_flavored_markdown): - provides a GitHub Flavored Markdown renderer with fenced code block - highlighting, clickable heading anchor links. - - It's not customizable, and its goal is to produce HTML output - equivalent to the [GitHub Markdown API endpoint](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode), - except the rendering is performed locally. - -* [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt, - but for markdown. - -* [LaTeX output](https://gitlab.com/ambrevar/blackfriday-latex): - renders output as LaTeX. - -* [bfchroma](https://github.com/Depado/bfchroma/): provides convenience - integration with the [Chroma](https://github.com/alecthomas/chroma) code - highlighting library. bfchroma is only compatible with v2 of Blackfriday and - provides a drop-in renderer ready to use with Blackfriday, as well as - options and means for further customization. - -* [Blackfriday-Confluence](https://github.com/kentaro-m/blackfriday-confluence): provides a [Confluence Wiki Markup](https://confluence.atlassian.com/doc/confluence-wiki-markup-251003035.html) renderer. - -* [Blackfriday-Slack](https://github.com/karriereat/blackfriday-slack): converts markdown to slack message style - - -TODO ----- - -* More unit testing -* Improve Unicode support. It does not understand all Unicode - rules (about what constitutes a letter, a punctuation symbol, - etc.), so it may fail to detect word boundaries correctly in - some instances. It is safe on all UTF-8 input. - - -License -------- - -[Blackfriday is distributed under the Simplified BSD License](LICENSE.txt) - - - [1]: https://daringfireball.net/projects/markdown/ "Markdown" - [2]: https://golang.org/ "Go Language" - [3]: https://github.com/vmg/sundown "Sundown" - [4]: https://pkg.go.dev/github.com/russross/blackfriday/v2#Parse "Parse func" - [5]: https://github.com/microcosm-cc/bluemonday "Bluemonday" - - [BuildV2SVG]: https://travis-ci.org/russross/blackfriday.svg?branch=v2 - [BuildV2URL]: https://travis-ci.org/russross/blackfriday - [PkgGoDevV2SVG]: https://pkg.go.dev/badge/github.com/russross/blackfriday/v2 - [PkgGoDevV2URL]: https://pkg.go.dev/github.com/russross/blackfriday/v2 diff --git a/vendor/github.com/russross/blackfriday/block.go b/vendor/github.com/russross/blackfriday/block.go deleted file mode 100644 index 563cb290..00000000 --- a/vendor/github.com/russross/blackfriday/block.go +++ /dev/null @@ -1,1480 +0,0 @@ -// -// Blackfriday Markdown Processor -// Available at http://github.com/russross/blackfriday -// -// Copyright © 2011 Russ Ross . -// Distributed under the Simplified BSD License. -// See README.md for details. -// - -// -// Functions to parse block-level elements. -// - -package blackfriday - -import ( - "bytes" - "strings" - "unicode" -) - -// Parse block-level data. -// Note: this function and many that it calls assume that -// the input buffer ends with a newline. -func (p *parser) block(out *bytes.Buffer, data []byte) { - if len(data) == 0 || data[len(data)-1] != '\n' { - panic("block input is missing terminating newline") - } - - // this is called recursively: enforce a maximum depth - if p.nesting >= p.maxNesting { - return - } - p.nesting++ - - // parse out one block-level construct at a time - for len(data) > 0 { - // prefixed header: - // - // # Header 1 - // ## Header 2 - // ... - // ###### Header 6 - if p.isPrefixHeader(data) { - data = data[p.prefixHeader(out, data):] - continue - } - - // block of preformatted HTML: - // - //
- // ... - //
- if data[0] == '<' { - if i := p.html(out, data, true); i > 0 { - data = data[i:] - continue - } - } - - // title block - // - // % stuff - // % more stuff - // % even more stuff - if p.flags&EXTENSION_TITLEBLOCK != 0 { - if data[0] == '%' { - if i := p.titleBlock(out, data, true); i > 0 { - data = data[i:] - continue - } - } - } - - // blank lines. note: returns the # of bytes to skip - if i := p.isEmpty(data); i > 0 { - data = data[i:] - continue - } - - // indented code block: - // - // func max(a, b int) int { - // if a > b { - // return a - // } - // return b - // } - if p.codePrefix(data) > 0 { - data = data[p.code(out, data):] - continue - } - - // fenced code block: - // - // ``` go info string here - // func fact(n int) int { - // if n <= 1 { - // return n - // } - // return n * fact(n-1) - // } - // ``` - if p.flags&EXTENSION_FENCED_CODE != 0 { - if i := p.fencedCodeBlock(out, data, true); i > 0 { - data = data[i:] - continue - } - } - - // horizontal rule: - // - // ------ - // or - // ****** - // or - // ______ - if p.isHRule(data) { - p.r.HRule(out) - var i int - for i = 0; data[i] != '\n'; i++ { - } - data = data[i:] - continue - } - - // block quote: - // - // > A big quote I found somewhere - // > on the web - if p.quotePrefix(data) > 0 { - data = data[p.quote(out, data):] - continue - } - - // table: - // - // Name | Age | Phone - // ------|-----|--------- - // Bob | 31 | 555-1234 - // Alice | 27 | 555-4321 - if p.flags&EXTENSION_TABLES != 0 { - if i := p.table(out, data); i > 0 { - data = data[i:] - continue - } - } - - // an itemized/unordered list: - // - // * Item 1 - // * Item 2 - // - // also works with + or - - if p.uliPrefix(data) > 0 { - data = data[p.list(out, data, 0):] - continue - } - - // a numbered/ordered list: - // - // 1. Item 1 - // 2. Item 2 - if p.oliPrefix(data) > 0 { - data = data[p.list(out, data, LIST_TYPE_ORDERED):] - continue - } - - // definition lists: - // - // Term 1 - // : Definition a - // : Definition b - // - // Term 2 - // : Definition c - if p.flags&EXTENSION_DEFINITION_LISTS != 0 { - if p.dliPrefix(data) > 0 { - data = data[p.list(out, data, LIST_TYPE_DEFINITION):] - continue - } - } - - // anything else must look like a normal paragraph - // note: this finds underlined headers, too - data = data[p.paragraph(out, data):] - } - - p.nesting-- -} - -func (p *parser) isPrefixHeader(data []byte) bool { - if data[0] != '#' { - return false - } - - if p.flags&EXTENSION_SPACE_HEADERS != 0 { - level := 0 - for level < 6 && data[level] == '#' { - level++ - } - if data[level] != ' ' { - return false - } - } - return true -} - -func (p *parser) prefixHeader(out *bytes.Buffer, data []byte) int { - level := 0 - for level < 6 && data[level] == '#' { - level++ - } - i := skipChar(data, level, ' ') - end := skipUntilChar(data, i, '\n') - skip := end - id := "" - if p.flags&EXTENSION_HEADER_IDS != 0 { - j, k := 0, 0 - // find start/end of header id - for j = i; j < end-1 && (data[j] != '{' || data[j+1] != '#'); j++ { - } - for k = j + 1; k < end && data[k] != '}'; k++ { - } - // extract header id iff found - if j < end && k < end { - id = string(data[j+2 : k]) - end = j - skip = k + 1 - for end > 0 && data[end-1] == ' ' { - end-- - } - } - } - for end > 0 && data[end-1] == '#' { - if isBackslashEscaped(data, end-1) { - break - } - end-- - } - for end > 0 && data[end-1] == ' ' { - end-- - } - if end > i { - if id == "" && p.flags&EXTENSION_AUTO_HEADER_IDS != 0 { - id = SanitizedAnchorName(string(data[i:end])) - } - work := func() bool { - p.inline(out, data[i:end]) - return true - } - p.r.Header(out, work, level, id) - } - return skip -} - -func (p *parser) isUnderlinedHeader(data []byte) int { - // test of level 1 header - if data[0] == '=' { - i := skipChar(data, 1, '=') - i = skipChar(data, i, ' ') - if data[i] == '\n' { - return 1 - } else { - return 0 - } - } - - // test of level 2 header - if data[0] == '-' { - i := skipChar(data, 1, '-') - i = skipChar(data, i, ' ') - if data[i] == '\n' { - return 2 - } else { - return 0 - } - } - - return 0 -} - -func (p *parser) titleBlock(out *bytes.Buffer, data []byte, doRender bool) int { - if data[0] != '%' { - return 0 - } - splitData := bytes.Split(data, []byte("\n")) - var i int - for idx, b := range splitData { - if !bytes.HasPrefix(b, []byte("%")) { - i = idx // - 1 - break - } - } - - data = bytes.Join(splitData[0:i], []byte("\n")) - p.r.TitleBlock(out, data) - - return len(data) -} - -func (p *parser) html(out *bytes.Buffer, data []byte, doRender bool) int { - var i, j int - - // identify the opening tag - if data[0] != '<' { - return 0 - } - curtag, tagfound := p.htmlFindTag(data[1:]) - - // handle special cases - if !tagfound { - // check for an HTML comment - if size := p.htmlComment(out, data, doRender); size > 0 { - return size - } - - // check for an
tag - if size := p.htmlHr(out, data, doRender); size > 0 { - return size - } - - // check for HTML CDATA - if size := p.htmlCDATA(out, data, doRender); size > 0 { - return size - } - - // no special case recognized - return 0 - } - - // look for an unindented matching closing tag - // followed by a blank line - found := false - /* - closetag := []byte("\n") - j = len(curtag) + 1 - for !found { - // scan for a closing tag at the beginning of a line - if skip := bytes.Index(data[j:], closetag); skip >= 0 { - j += skip + len(closetag) - } else { - break - } - - // see if it is the only thing on the line - if skip := p.isEmpty(data[j:]); skip > 0 { - // see if it is followed by a blank line/eof - j += skip - if j >= len(data) { - found = true - i = j - } else { - if skip := p.isEmpty(data[j:]); skip > 0 { - j += skip - found = true - i = j - } - } - } - } - */ - - // if not found, try a second pass looking for indented match - // but not if tag is "ins" or "del" (following original Markdown.pl) - if !found && curtag != "ins" && curtag != "del" { - i = 1 - for i < len(data) { - i++ - for i < len(data) && !(data[i-1] == '<' && data[i] == '/') { - i++ - } - - if i+2+len(curtag) >= len(data) { - break - } - - j = p.htmlFindEnd(curtag, data[i-1:]) - - if j > 0 { - i += j - 1 - found = true - break - } - } - } - - if !found { - return 0 - } - - // the end of the block has been found - if doRender { - // trim newlines - end := i - for end > 0 && data[end-1] == '\n' { - end-- - } - p.r.BlockHtml(out, data[:end]) - } - - return i -} - -func (p *parser) renderHTMLBlock(out *bytes.Buffer, data []byte, start int, doRender bool) int { - // html block needs to end with a blank line - if i := p.isEmpty(data[start:]); i > 0 { - size := start + i - if doRender { - // trim trailing newlines - end := size - for end > 0 && data[end-1] == '\n' { - end-- - } - p.r.BlockHtml(out, data[:end]) - } - return size - } - return 0 -} - -// HTML comment, lax form -func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int { - i := p.inlineHTMLComment(out, data) - return p.renderHTMLBlock(out, data, i, doRender) -} - -// HTML CDATA section -func (p *parser) htmlCDATA(out *bytes.Buffer, data []byte, doRender bool) int { - const cdataTag = "') { - i++ - } - i++ - // no end-of-comment marker - if i >= len(data) { - return 0 - } - return p.renderHTMLBlock(out, data, i, doRender) -} - -// HR, which is the only self-closing block tag considered -func (p *parser) htmlHr(out *bytes.Buffer, data []byte, doRender bool) int { - if data[0] != '<' || (data[1] != 'h' && data[1] != 'H') || (data[2] != 'r' && data[2] != 'R') { - return 0 - } - if data[3] != ' ' && data[3] != '/' && data[3] != '>' { - // not an
tag after all; at least not a valid one - return 0 - } - - i := 3 - for data[i] != '>' && data[i] != '\n' { - i++ - } - - if data[i] == '>' { - return p.renderHTMLBlock(out, data, i+1, doRender) - } - - return 0 -} - -func (p *parser) htmlFindTag(data []byte) (string, bool) { - i := 0 - for isalnum(data[i]) { - i++ - } - key := string(data[:i]) - if _, ok := blockTags[key]; ok { - return key, true - } - return "", false -} - -func (p *parser) htmlFindEnd(tag string, data []byte) int { - // assume data[0] == '<' && data[1] == '/' already tested - - // check if tag is a match - closetag := []byte("") - if !bytes.HasPrefix(data, closetag) { - return 0 - } - i := len(closetag) - - // check that the rest of the line is blank - skip := 0 - if skip = p.isEmpty(data[i:]); skip == 0 { - return 0 - } - i += skip - skip = 0 - - if i >= len(data) { - return i - } - - if p.flags&EXTENSION_LAX_HTML_BLOCKS != 0 { - return i - } - if skip = p.isEmpty(data[i:]); skip == 0 { - // following line must be blank - return 0 - } - - return i + skip -} - -func (*parser) isEmpty(data []byte) int { - // it is okay to call isEmpty on an empty buffer - if len(data) == 0 { - return 0 - } - - var i int - for i = 0; i < len(data) && data[i] != '\n'; i++ { - if data[i] != ' ' && data[i] != '\t' { - return 0 - } - } - return i + 1 -} - -func (*parser) isHRule(data []byte) bool { - i := 0 - - // skip up to three spaces - for i < 3 && data[i] == ' ' { - i++ - } - - // look at the hrule char - if data[i] != '*' && data[i] != '-' && data[i] != '_' { - return false - } - c := data[i] - - // the whole line must be the char or whitespace - n := 0 - for data[i] != '\n' { - switch { - case data[i] == c: - n++ - case data[i] != ' ': - return false - } - i++ - } - - return n >= 3 -} - -// isFenceLine checks if there's a fence line (e.g., ``` or ``` go) at the beginning of data, -// and returns the end index if so, or 0 otherwise. It also returns the marker found. -// If syntax is not nil, it gets set to the syntax specified in the fence line. -// A final newline is mandatory to recognize the fence line, unless newlineOptional is true. -func isFenceLine(data []byte, info *string, oldmarker string, newlineOptional bool) (end int, marker string) { - i, size := 0, 0 - - // skip up to three spaces - for i < len(data) && i < 3 && data[i] == ' ' { - i++ - } - - // check for the marker characters: ~ or ` - if i >= len(data) { - return 0, "" - } - if data[i] != '~' && data[i] != '`' { - return 0, "" - } - - c := data[i] - - // the whole line must be the same char or whitespace - for i < len(data) && data[i] == c { - size++ - i++ - } - - // the marker char must occur at least 3 times - if size < 3 { - return 0, "" - } - marker = string(data[i-size : i]) - - // if this is the end marker, it must match the beginning marker - if oldmarker != "" && marker != oldmarker { - return 0, "" - } - - // TODO(shurcooL): It's probably a good idea to simplify the 2 code paths here - // into one, always get the info string, and discard it if the caller doesn't care. - if info != nil { - infoLength := 0 - i = skipChar(data, i, ' ') - - if i >= len(data) { - if newlineOptional && i == len(data) { - return i, marker - } - return 0, "" - } - - infoStart := i - - if data[i] == '{' { - i++ - infoStart++ - - for i < len(data) && data[i] != '}' && data[i] != '\n' { - infoLength++ - i++ - } - - if i >= len(data) || data[i] != '}' { - return 0, "" - } - - // strip all whitespace at the beginning and the end - // of the {} block - for infoLength > 0 && isspace(data[infoStart]) { - infoStart++ - infoLength-- - } - - for infoLength > 0 && isspace(data[infoStart+infoLength-1]) { - infoLength-- - } - - i++ - } else { - for i < len(data) && !isverticalspace(data[i]) { - infoLength++ - i++ - } - } - - *info = strings.TrimSpace(string(data[infoStart : infoStart+infoLength])) - } - - i = skipChar(data, i, ' ') - if i >= len(data) { - if newlineOptional { - return i, marker - } - return 0, "" - } - if data[i] == '\n' { - i++ // Take newline into account - } - - return i, marker -} - -// fencedCodeBlock returns the end index if data contains a fenced code block at the beginning, -// or 0 otherwise. It writes to out if doRender is true, otherwise it has no side effects. -// If doRender is true, a final newline is mandatory to recognize the fenced code block. -func (p *parser) fencedCodeBlock(out *bytes.Buffer, data []byte, doRender bool) int { - var infoString string - beg, marker := isFenceLine(data, &infoString, "", false) - if beg == 0 || beg >= len(data) { - return 0 - } - - var work bytes.Buffer - - for { - // safe to assume beg < len(data) - - // check for the end of the code block - newlineOptional := !doRender - fenceEnd, _ := isFenceLine(data[beg:], nil, marker, newlineOptional) - if fenceEnd != 0 { - beg += fenceEnd - break - } - - // copy the current line - end := skipUntilChar(data, beg, '\n') + 1 - - // did we reach the end of the buffer without a closing marker? - if end >= len(data) { - return 0 - } - - // verbatim copy to the working buffer - if doRender { - work.Write(data[beg:end]) - } - beg = end - } - - if doRender { - p.r.BlockCode(out, work.Bytes(), infoString) - } - - return beg -} - -func (p *parser) table(out *bytes.Buffer, data []byte) int { - var header bytes.Buffer - i, columns := p.tableHeader(&header, data) - if i == 0 { - return 0 - } - - var body bytes.Buffer - - for i < len(data) { - pipes, rowStart := 0, i - for ; data[i] != '\n'; i++ { - if data[i] == '|' { - pipes++ - } - } - - if pipes == 0 { - i = rowStart - break - } - - // include the newline in data sent to tableRow - i++ - p.tableRow(&body, data[rowStart:i], columns, false) - } - - p.r.Table(out, header.Bytes(), body.Bytes(), columns) - - return i -} - -// check if the specified position is preceded by an odd number of backslashes -func isBackslashEscaped(data []byte, i int) bool { - backslashes := 0 - for i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\' { - backslashes++ - } - return backslashes&1 == 1 -} - -func (p *parser) tableHeader(out *bytes.Buffer, data []byte) (size int, columns []int) { - i := 0 - colCount := 1 - for i = 0; data[i] != '\n'; i++ { - if data[i] == '|' && !isBackslashEscaped(data, i) { - colCount++ - } - } - - // doesn't look like a table header - if colCount == 1 { - return - } - - // include the newline in the data sent to tableRow - header := data[:i+1] - - // column count ignores pipes at beginning or end of line - if data[0] == '|' { - colCount-- - } - if i > 2 && data[i-1] == '|' && !isBackslashEscaped(data, i-1) { - colCount-- - } - - columns = make([]int, colCount) - - // move on to the header underline - i++ - if i >= len(data) { - return - } - - if data[i] == '|' && !isBackslashEscaped(data, i) { - i++ - } - i = skipChar(data, i, ' ') - - // each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3 - // and trailing | optional on last column - col := 0 - for data[i] != '\n' { - dashes := 0 - - if data[i] == ':' { - i++ - columns[col] |= TABLE_ALIGNMENT_LEFT - dashes++ - } - for data[i] == '-' { - i++ - dashes++ - } - if data[i] == ':' { - i++ - columns[col] |= TABLE_ALIGNMENT_RIGHT - dashes++ - } - for data[i] == ' ' { - i++ - } - - // end of column test is messy - switch { - case dashes < 3: - // not a valid column - return - - case data[i] == '|' && !isBackslashEscaped(data, i): - // marker found, now skip past trailing whitespace - col++ - i++ - for data[i] == ' ' { - i++ - } - - // trailing junk found after last column - if col >= colCount && data[i] != '\n' { - return - } - - case (data[i] != '|' || isBackslashEscaped(data, i)) && col+1 < colCount: - // something else found where marker was required - return - - case data[i] == '\n': - // marker is optional for the last column - col++ - - default: - // trailing junk found after last column - return - } - } - if col != colCount { - return - } - - p.tableRow(out, header, columns, true) - size = i + 1 - return -} - -func (p *parser) tableRow(out *bytes.Buffer, data []byte, columns []int, header bool) { - i, col := 0, 0 - var rowWork bytes.Buffer - - if data[i] == '|' && !isBackslashEscaped(data, i) { - i++ - } - - for col = 0; col < len(columns) && i < len(data); col++ { - for data[i] == ' ' { - i++ - } - - cellStart := i - - for (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\n' { - i++ - } - - cellEnd := i - - // skip the end-of-cell marker, possibly taking us past end of buffer - i++ - - for cellEnd > cellStart && data[cellEnd-1] == ' ' { - cellEnd-- - } - - var cellWork bytes.Buffer - p.inline(&cellWork, data[cellStart:cellEnd]) - - if header { - p.r.TableHeaderCell(&rowWork, cellWork.Bytes(), columns[col]) - } else { - p.r.TableCell(&rowWork, cellWork.Bytes(), columns[col]) - } - } - - // pad it out with empty columns to get the right number - for ; col < len(columns); col++ { - if header { - p.r.TableHeaderCell(&rowWork, nil, columns[col]) - } else { - p.r.TableCell(&rowWork, nil, columns[col]) - } - } - - // silently ignore rows with too many cells - - p.r.TableRow(out, rowWork.Bytes()) -} - -// returns blockquote prefix length -func (p *parser) quotePrefix(data []byte) int { - i := 0 - for i < 3 && data[i] == ' ' { - i++ - } - if data[i] == '>' { - if data[i+1] == ' ' { - return i + 2 - } - return i + 1 - } - return 0 -} - -// blockquote ends with at least one blank line -// followed by something without a blockquote prefix -func (p *parser) terminateBlockquote(data []byte, beg, end int) bool { - if p.isEmpty(data[beg:]) <= 0 { - return false - } - if end >= len(data) { - return true - } - return p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0 -} - -// parse a blockquote fragment -func (p *parser) quote(out *bytes.Buffer, data []byte) int { - var raw bytes.Buffer - beg, end := 0, 0 - for beg < len(data) { - end = beg - // Step over whole lines, collecting them. While doing that, check for - // fenced code and if one's found, incorporate it altogether, - // irregardless of any contents inside it - for data[end] != '\n' { - if p.flags&EXTENSION_FENCED_CODE != 0 { - if i := p.fencedCodeBlock(out, data[end:], false); i > 0 { - // -1 to compensate for the extra end++ after the loop: - end += i - 1 - break - } - } - end++ - } - end++ - - if pre := p.quotePrefix(data[beg:]); pre > 0 { - // skip the prefix - beg += pre - } else if p.terminateBlockquote(data, beg, end) { - break - } - - // this line is part of the blockquote - raw.Write(data[beg:end]) - beg = end - } - - var cooked bytes.Buffer - p.block(&cooked, raw.Bytes()) - p.r.BlockQuote(out, cooked.Bytes()) - return end -} - -// returns prefix length for block code -func (p *parser) codePrefix(data []byte) int { - if data[0] == ' ' && data[1] == ' ' && data[2] == ' ' && data[3] == ' ' { - return 4 - } - return 0 -} - -func (p *parser) code(out *bytes.Buffer, data []byte) int { - var work bytes.Buffer - - i := 0 - for i < len(data) { - beg := i - for data[i] != '\n' { - i++ - } - i++ - - blankline := p.isEmpty(data[beg:i]) > 0 - if pre := p.codePrefix(data[beg:i]); pre > 0 { - beg += pre - } else if !blankline { - // non-empty, non-prefixed line breaks the pre - i = beg - break - } - - // verbatim copy to the working buffeu - if blankline { - work.WriteByte('\n') - } else { - work.Write(data[beg:i]) - } - } - - // trim all the \n off the end of work - workbytes := work.Bytes() - eol := len(workbytes) - for eol > 0 && workbytes[eol-1] == '\n' { - eol-- - } - if eol != len(workbytes) { - work.Truncate(eol) - } - - work.WriteByte('\n') - - p.r.BlockCode(out, work.Bytes(), "") - - return i -} - -// returns unordered list item prefix -func (p *parser) uliPrefix(data []byte) int { - i := 0 - - // start with up to 3 spaces - for i < 3 && data[i] == ' ' { - i++ - } - - // need a *, +, or - followed by a space - if (data[i] != '*' && data[i] != '+' && data[i] != '-') || - data[i+1] != ' ' { - return 0 - } - return i + 2 -} - -// returns ordered list item prefix -func (p *parser) oliPrefix(data []byte) int { - i := 0 - - // start with up to 3 spaces - for i < 3 && data[i] == ' ' { - i++ - } - - // count the digits - start := i - for data[i] >= '0' && data[i] <= '9' { - i++ - } - - // we need >= 1 digits followed by a dot and a space - if start == i || data[i] != '.' || data[i+1] != ' ' { - return 0 - } - return i + 2 -} - -// returns definition list item prefix -func (p *parser) dliPrefix(data []byte) int { - i := 0 - - // need a : followed by a spaces - if data[i] != ':' || data[i+1] != ' ' { - return 0 - } - for data[i] == ' ' { - i++ - } - return i + 2 -} - -// parse ordered or unordered list block -func (p *parser) list(out *bytes.Buffer, data []byte, flags int) int { - i := 0 - flags |= LIST_ITEM_BEGINNING_OF_LIST - work := func() bool { - for i < len(data) { - skip := p.listItem(out, data[i:], &flags) - i += skip - - if skip == 0 || flags&LIST_ITEM_END_OF_LIST != 0 { - break - } - flags &= ^LIST_ITEM_BEGINNING_OF_LIST - } - return true - } - - p.r.List(out, work, flags) - return i -} - -// Parse a single list item. -// Assumes initial prefix is already removed if this is a sublist. -func (p *parser) listItem(out *bytes.Buffer, data []byte, flags *int) int { - // keep track of the indentation of the first line - itemIndent := 0 - for itemIndent < 3 && data[itemIndent] == ' ' { - itemIndent++ - } - - i := p.uliPrefix(data) - if i == 0 { - i = p.oliPrefix(data) - } - if i == 0 { - i = p.dliPrefix(data) - // reset definition term flag - if i > 0 { - *flags &= ^LIST_TYPE_TERM - } - } - if i == 0 { - // if in defnition list, set term flag and continue - if *flags&LIST_TYPE_DEFINITION != 0 { - *flags |= LIST_TYPE_TERM - } else { - return 0 - } - } - - // skip leading whitespace on first line - for data[i] == ' ' { - i++ - } - - // find the end of the line - line := i - for i > 0 && data[i-1] != '\n' { - i++ - } - - // process the following lines - containsBlankLine := false - sublist := 0 - codeBlockMarker := "" - if p.flags&EXTENSION_FENCED_CODE != 0 && i > line { - // determine if codeblock starts on the first line - _, codeBlockMarker = isFenceLine(data[line:i], nil, "", false) - } - - // get working buffer - var raw bytes.Buffer - - // put the first line into the working buffer - raw.Write(data[line:i]) - line = i - -gatherlines: - for line < len(data) { - i++ - - // find the end of this line - for data[i-1] != '\n' { - i++ - } - // if it is an empty line, guess that it is part of this item - // and move on to the next line - if p.isEmpty(data[line:i]) > 0 { - containsBlankLine = true - raw.Write(data[line:i]) - line = i - continue - } - - // calculate the indentation - indent := 0 - for indent < 4 && line+indent < i && data[line+indent] == ' ' { - indent++ - } - - chunk := data[line+indent : i] - - if p.flags&EXTENSION_FENCED_CODE != 0 { - // determine if in or out of codeblock - // if in codeblock, ignore normal list processing - _, marker := isFenceLine(chunk, nil, codeBlockMarker, false) - if marker != "" { - if codeBlockMarker == "" { - // start of codeblock - codeBlockMarker = marker - } else { - // end of codeblock. - *flags |= LIST_ITEM_CONTAINS_BLOCK - codeBlockMarker = "" - } - } - // we are in a codeblock, write line, and continue - if codeBlockMarker != "" || marker != "" { - raw.Write(data[line+indent : i]) - line = i - continue gatherlines - } - } - - // evaluate how this line fits in - switch { - // is this a nested list item? - case (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) || - p.oliPrefix(chunk) > 0 || - p.dliPrefix(chunk) > 0: - - if containsBlankLine { - // end the list if the type changed after a blank line - if indent <= itemIndent && - ((*flags&LIST_TYPE_ORDERED != 0 && p.uliPrefix(chunk) > 0) || - (*flags&LIST_TYPE_ORDERED == 0 && p.oliPrefix(chunk) > 0)) { - - *flags |= LIST_ITEM_END_OF_LIST - break gatherlines - } - *flags |= LIST_ITEM_CONTAINS_BLOCK - } - - // to be a nested list, it must be indented more - // if not, it is the next item in the same list - if indent <= itemIndent { - break gatherlines - } - - // is this the first item in the nested list? - if sublist == 0 { - sublist = raw.Len() - } - - // is this a nested prefix header? - case p.isPrefixHeader(chunk): - // if the header is not indented, it is not nested in the list - // and thus ends the list - if containsBlankLine && indent < 4 { - *flags |= LIST_ITEM_END_OF_LIST - break gatherlines - } - *flags |= LIST_ITEM_CONTAINS_BLOCK - - // anything following an empty line is only part - // of this item if it is indented 4 spaces - // (regardless of the indentation of the beginning of the item) - case containsBlankLine && indent < 4: - if *flags&LIST_TYPE_DEFINITION != 0 && i < len(data)-1 { - // is the next item still a part of this list? - next := i - for data[next] != '\n' { - next++ - } - for next < len(data)-1 && data[next] == '\n' { - next++ - } - if i < len(data)-1 && data[i] != ':' && data[next] != ':' { - *flags |= LIST_ITEM_END_OF_LIST - } - } else { - *flags |= LIST_ITEM_END_OF_LIST - } - break gatherlines - - // a blank line means this should be parsed as a block - case containsBlankLine: - *flags |= LIST_ITEM_CONTAINS_BLOCK - } - - containsBlankLine = false - - // add the line into the working buffer without prefix - raw.Write(data[line+indent : i]) - - line = i - } - - // If reached end of data, the Renderer.ListItem call we're going to make below - // is definitely the last in the list. - if line >= len(data) { - *flags |= LIST_ITEM_END_OF_LIST - } - - rawBytes := raw.Bytes() - - // render the contents of the list item - var cooked bytes.Buffer - if *flags&LIST_ITEM_CONTAINS_BLOCK != 0 && *flags&LIST_TYPE_TERM == 0 { - // intermediate render of block item, except for definition term - if sublist > 0 { - p.block(&cooked, rawBytes[:sublist]) - p.block(&cooked, rawBytes[sublist:]) - } else { - p.block(&cooked, rawBytes) - } - } else { - // intermediate render of inline item - if sublist > 0 { - p.inline(&cooked, rawBytes[:sublist]) - p.block(&cooked, rawBytes[sublist:]) - } else { - p.inline(&cooked, rawBytes) - } - } - - // render the actual list item - cookedBytes := cooked.Bytes() - parsedEnd := len(cookedBytes) - - // strip trailing newlines - for parsedEnd > 0 && cookedBytes[parsedEnd-1] == '\n' { - parsedEnd-- - } - p.r.ListItem(out, cookedBytes[:parsedEnd], *flags) - - return line -} - -// render a single paragraph that has already been parsed out -func (p *parser) renderParagraph(out *bytes.Buffer, data []byte) { - if len(data) == 0 { - return - } - - // trim leading spaces - beg := 0 - for data[beg] == ' ' { - beg++ - } - - // trim trailing newline - end := len(data) - 1 - - // trim trailing spaces - for end > beg && data[end-1] == ' ' { - end-- - } - - work := func() bool { - p.inline(out, data[beg:end]) - return true - } - p.r.Paragraph(out, work) -} - -func (p *parser) paragraph(out *bytes.Buffer, data []byte) int { - // prev: index of 1st char of previous line - // line: index of 1st char of current line - // i: index of cursor/end of current line - var prev, line, i int - - // keep going until we find something to mark the end of the paragraph - for i < len(data) { - // mark the beginning of the current line - prev = line - current := data[i:] - line = i - - // did we find a blank line marking the end of the paragraph? - if n := p.isEmpty(current); n > 0 { - // did this blank line followed by a definition list item? - if p.flags&EXTENSION_DEFINITION_LISTS != 0 { - if i < len(data)-1 && data[i+1] == ':' { - return p.list(out, data[prev:], LIST_TYPE_DEFINITION) - } - } - - p.renderParagraph(out, data[:i]) - return i + n - } - - // an underline under some text marks a header, so our paragraph ended on prev line - if i > 0 { - if level := p.isUnderlinedHeader(current); level > 0 { - // render the paragraph - p.renderParagraph(out, data[:prev]) - - // ignore leading and trailing whitespace - eol := i - 1 - for prev < eol && data[prev] == ' ' { - prev++ - } - for eol > prev && data[eol-1] == ' ' { - eol-- - } - - // render the header - // this ugly double closure avoids forcing variables onto the heap - work := func(o *bytes.Buffer, pp *parser, d []byte) func() bool { - return func() bool { - pp.inline(o, d) - return true - } - }(out, p, data[prev:eol]) - - id := "" - if p.flags&EXTENSION_AUTO_HEADER_IDS != 0 { - id = SanitizedAnchorName(string(data[prev:eol])) - } - - p.r.Header(out, work, level, id) - - // find the end of the underline - for data[i] != '\n' { - i++ - } - return i - } - } - - // if the next line starts a block of HTML, then the paragraph ends here - if p.flags&EXTENSION_LAX_HTML_BLOCKS != 0 { - if data[i] == '<' && p.html(out, current, false) > 0 { - // rewind to before the HTML block - p.renderParagraph(out, data[:i]) - return i - } - } - - // if there's a prefixed header or a horizontal rule after this, paragraph is over - if p.isPrefixHeader(current) || p.isHRule(current) { - p.renderParagraph(out, data[:i]) - return i - } - - // if there's a fenced code block, paragraph is over - if p.flags&EXTENSION_FENCED_CODE != 0 { - if p.fencedCodeBlock(out, current, false) > 0 { - p.renderParagraph(out, data[:i]) - return i - } - } - - // if there's a definition list item, prev line is a definition term - if p.flags&EXTENSION_DEFINITION_LISTS != 0 { - if p.dliPrefix(current) != 0 { - return p.list(out, data[prev:], LIST_TYPE_DEFINITION) - } - } - - // if there's a list after this, paragraph is over - if p.flags&EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK != 0 { - if p.uliPrefix(current) != 0 || - p.oliPrefix(current) != 0 || - p.quotePrefix(current) != 0 || - p.codePrefix(current) != 0 { - p.renderParagraph(out, data[:i]) - return i - } - } - - // otherwise, scan to the beginning of the next line - for data[i] != '\n' { - i++ - } - i++ - } - - p.renderParagraph(out, data[:i]) - return i -} - -// SanitizedAnchorName returns a sanitized anchor name for the given text. -// -// It implements the algorithm specified in the package comment. -func SanitizedAnchorName(text string) string { - var anchorName []rune - futureDash := false - for _, r := range text { - switch { - case unicode.IsLetter(r) || unicode.IsNumber(r): - if futureDash && len(anchorName) > 0 { - anchorName = append(anchorName, '-') - } - futureDash = false - anchorName = append(anchorName, unicode.ToLower(r)) - default: - futureDash = true - } - } - return string(anchorName) -} diff --git a/vendor/github.com/russross/blackfriday/doc.go b/vendor/github.com/russross/blackfriday/doc.go deleted file mode 100644 index 9656c42a..00000000 --- a/vendor/github.com/russross/blackfriday/doc.go +++ /dev/null @@ -1,32 +0,0 @@ -// Package blackfriday is a Markdown processor. -// -// It translates plain text with simple formatting rules into HTML or LaTeX. -// -// Sanitized Anchor Names -// -// Blackfriday includes an algorithm for creating sanitized anchor names -// corresponding to a given input text. This algorithm is used to create -// anchors for headings when EXTENSION_AUTO_HEADER_IDS is enabled. The -// algorithm is specified below, so that other packages can create -// compatible anchor names and links to those anchors. -// -// The algorithm iterates over the input text, interpreted as UTF-8, -// one Unicode code point (rune) at a time. All runes that are letters (category L) -// or numbers (category N) are considered valid characters. They are mapped to -// lower case, and included in the output. All other runes are considered -// invalid characters. Invalid characters that preceed the first valid character, -// as well as invalid character that follow the last valid character -// are dropped completely. All other sequences of invalid characters -// between two valid characters are replaced with a single dash character '-'. -// -// SanitizedAnchorName exposes this functionality, and can be used to -// create compatible links to the anchor names generated by blackfriday. -// This algorithm is also implemented in a small standalone package at -// github.com/shurcooL/sanitized_anchor_name. It can be useful for clients -// that want a small package and don't need full functionality of blackfriday. -package blackfriday - -// NOTE: Keep Sanitized Anchor Name algorithm in sync with package -// github.com/shurcooL/sanitized_anchor_name. -// Otherwise, users of sanitized_anchor_name will get anchor names -// that are incompatible with those generated by blackfriday. diff --git a/vendor/github.com/russross/blackfriday/html.go b/vendor/github.com/russross/blackfriday/html.go deleted file mode 100644 index fa044ca2..00000000 --- a/vendor/github.com/russross/blackfriday/html.go +++ /dev/null @@ -1,945 +0,0 @@ -// -// Blackfriday Markdown Processor -// Available at http://github.com/russross/blackfriday -// -// Copyright © 2011 Russ Ross . -// Distributed under the Simplified BSD License. -// See README.md for details. -// - -// -// -// HTML rendering backend -// -// - -package blackfriday - -import ( - "bytes" - "fmt" - "regexp" - "strconv" - "strings" -) - -// Html renderer configuration options. -const ( - HTML_SKIP_HTML = 1 << iota // skip preformatted HTML blocks - HTML_SKIP_STYLE // skip embedded